diff options
Diffstat (limited to 'kopete/protocols/msn/msnchatsession.cpp')
-rw-r--r-- | kopete/protocols/msn/msnchatsession.cpp | 775 |
1 files changed, 775 insertions, 0 deletions
diff --git a/kopete/protocols/msn/msnchatsession.cpp b/kopete/protocols/msn/msnchatsession.cpp new file mode 100644 index 00000000..fabd62ab --- /dev/null +++ b/kopete/protocols/msn/msnchatsession.cpp @@ -0,0 +1,775 @@ +/* + msnchatsession.cpp - MSN Message Manager + + Copyright (c) 2002-2005 by Olivier Goffart <ogoffart at kde.org> + + Kopete (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org> + + ************************************************************************* + * * + * 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; either version 2 of the License, or * + * (at your option) any later version. * + * * + ************************************************************************* +*/ + +#include "msnchatsession.h" + +#include <tqlabel.h> +#include <tqimage.h> +#include <tqtooltip.h> +#include <tqfile.h> +#include <tqiconset.h> + + +#include <tdeconfig.h> +#include <kdebug.h> +#include <kinputdialog.h> +#include <tdelocale.h> +#include <tdemessagebox.h> +#include <tdepopupmenu.h> +#include <tdetempfile.h> +#include <tdemainwindow.h> +#include <tdetoolbar.h> +#include <krun.h> + +#include "kopetecontactaction.h" +#include "kopetemetacontact.h" +#include "kopetecontactlist.h" +#include "kopetechatsessionmanager.h" +#include "kopeteuiglobal.h" +#include "kopeteglobal.h" +#include "kopeteview.h" + +#include "msncontact.h" +#include "msnfiletransfersocket.h" +#include "msnaccount.h" +#include "msnswitchboardsocket.h" + +#include "config.h" + +#if !defined NDEBUG +#include "msndebugrawcmddlg.h" +#endif + +MSNChatSession::MSNChatSession( Kopete::Protocol *protocol, const Kopete::Contact *user, + Kopete::ContactPtrList others, const char *name ) +: Kopete::ChatSession( user, others, protocol, name ) +{ + Kopete::ChatSessionManager::self()->registerChatSession( this ); + m_chatService = 0l; + m_timeoutTimer =0L; + m_newSession = true; + m_connectionTry=0; + + setInstance(protocol->instance()); + + connect( this, TQT_SIGNAL( messageSent( Kopete::Message&, + Kopete::ChatSession* ) ), + this, TQT_SLOT( slotMessageSent( Kopete::Message&, + Kopete::ChatSession* ) ) ); + + connect( this, TQT_SIGNAL( invitation(MSNInvitation*& , const TQString & , long unsigned int , MSNChatSession* , MSNContact* ) ) , + protocol, TQT_SIGNAL( invitation(MSNInvitation*& , const TQString & , long unsigned int , MSNChatSession* , MSNContact* ) ) ); + + + m_actionInvite = new TDEActionMenu( i18n( "&Invite" ), "kontact_contacts", actionCollection(), "msnInvite" ); + connect ( m_actionInvite->popupMenu() , TQT_SIGNAL( aboutToShow() ) , this , TQT_SLOT(slotActionInviteAboutToShow() ) ) ; + + #if !defined NDEBUG + new TDEAction( i18n( "Send Raw C&ommand..." ), 0, this, TQT_SLOT( slotDebugRawCommand() ), actionCollection(), "msnDebugRawCommand" ) ; + #endif + + + m_actionNudge=new TDEAction( i18n( "Send Nudge" ), "bell", 0, this, TQT_SLOT(slotSendNudge() ), actionCollection(), "msnSendNudge" ) ; +#if MSN_WEBCAM + // Invite to receive webcam action + m_actionWebcamReceive=new TDEAction( i18n( "View Contact's Webcam" ), "webcamreceive", 0, this, TQT_SLOT(slotWebcamReceive()), actionCollection(), "msnWebcamReceive" ) ; + + //Send webcam action + m_actionWebcamSend=new TDEAction( i18n( "Send Webcam" ), "webcamsend", 0, this, TQT_SLOT(slotWebcamSend()), actionCollection(), "msnWebcamSend" ) ; +#endif + + new TDEAction( i18n( "Send File" ),"attach", 0, this, TQT_SLOT( slotSendFile() ), actionCollection(), "msnSendFile" ); + + MSNContact *c = static_cast<MSNContact*>( others.first() ); + (new TDEAction( i18n( "Request Display Picture" ), "image", 0, this, TQT_SLOT( slotRequestPicture() ), actionCollection(), "msnRequestDisplayPicture" ))->setEnabled(!c->object().isEmpty()); + + if ( !c->object().isEmpty() ) + { + + connect( c, TQT_SIGNAL( displayPictureChanged() ), this, TQT_SLOT( slotDisplayPictureChanged() ) ); + m_image = new TQLabel( 0L, "kde toolbar widget" ); + new KWidgetAction( m_image, i18n( "MSN Display Picture" ), 0, this, TQT_SLOT( slotRequestPicture() ), actionCollection(), "msnDisplayPicture" ); + if(c->hasProperty(Kopete::Global::Properties::self()->photo().key()) ) + { + //if the view doesn't exist yet, we will be unable to get the size of the toolbar + // so when the view will exist, we will show the displaypicture. + //How to know when a our view is created? We can't. + // but chances are the next created view will be for this KMM + // And if it is not? never mind. the icon will just be sized 22x22 + connect( Kopete::ChatSessionManager::self() , TQT_SIGNAL(viewActivated(KopeteView* )) , this, TQT_SLOT(slotDisplayPictureChanged()) ); + //it's viewActivated and not viewCreated because the view get his mainwindow only when it is shown. + } + } + else + { + m_image = 0L; + } + + setXMLFile("msnchatui.rc"); + + setMayInvite( true ); +} + +MSNChatSession::~MSNChatSession() +{ + delete m_image; + //force to disconnect the switchboard + //not needed since the m_chatService has us as parent + // if(m_chatService) + // delete m_chatService; + + TQMap<unsigned long int, MSNInvitation*>::Iterator it; + for( it = m_invitations.begin(); it != m_invitations.end() ; it = m_invitations.begin()) + { + delete *it; + m_invitations.remove( it ); + } +} + +void MSNChatSession::createChat( const TQString &handle, + const TQString &address, const TQString &auth, const TQString &ID ) +{ + /* disabled because i don't want to reopen a chatwindow if we just closed it + * and the contact take much time to type his message + m_newSession= !(ID.isEmpty()); + */ + + if( m_chatService ) + { + kdDebug(14140) << k_funcinfo << "Service already exists, disconnect them." << endl; + delete m_chatService; + } + +// uncomment this line if you don't want to the peer know when you close the window +// setCanBeDeleted( false ); + + m_chatService = new MSNSwitchBoardSocket( static_cast<MSNAccount*>( myself()->account() ) , this); + m_chatService->setUseHttpMethod( static_cast<MSNAccount*>( myself()->account() )->useHttpMethod() ); + m_chatService->setHandle( myself()->account()->accountId() ); + m_chatService->setMsgHandle( handle ); + m_chatService->connectToSwitchBoard( ID, address, auth ); + + connect( m_chatService, TQT_SIGNAL( userJoined(const TQString&,const TQString&,bool)), + this, TQT_SLOT( slotUserJoined(const TQString&,const TQString&,bool) ) ); + connect( m_chatService, TQT_SIGNAL( userLeft(const TQString&,const TQString&)), + this, TQT_SLOT( slotUserLeft(const TQString&,const TQString&) ) ); + connect( m_chatService, TQT_SIGNAL( msgReceived( Kopete::Message & ) ), + this, TQT_SLOT( slotMessageReceived( Kopete::Message & ) ) ); + connect( m_chatService, TQT_SIGNAL( switchBoardClosed() ), + this, TQT_SLOT( slotSwitchBoardClosed() ) ); + connect( m_chatService, TQT_SIGNAL( receivedTypingMsg( const TQString &, bool ) ), + this, TQT_SLOT( receivedTypingMsg( const TQString &, bool ) ) ); + TDEConfig *config = TDEGlobal::config(); + config->setGroup( "MSN" ); + if(config->readBoolEntry( "SendTypingNotification" , true) ) + { + connect( this, TQT_SIGNAL( myselfTyping( bool ) ), + m_chatService, TQT_SLOT( sendTypingMsg( bool ) ) ); + } + connect( m_chatService, TQT_SIGNAL( msgAcknowledgement(unsigned int, bool) ), + this, TQT_SLOT( slotAcknowledgement(unsigned int, bool) ) ); + connect( m_chatService, TQT_SIGNAL( invitation( const TQString&, const TQString& ) ), + this, TQT_SLOT( slotInvitation( const TQString&, const TQString& ) ) ); + connect( m_chatService, TQT_SIGNAL( nudgeReceived(const TQString&) ), + this, TQT_SLOT( slotNudgeReceived(const TQString&) ) ); + connect( m_chatService, TQT_SIGNAL( errorMessage(int, const TQString& ) ), static_cast<MSNAccount *>(myself()->account()), TQT_SLOT( slotErrorMessageReceived(int, const TQString& ) ) ); + + if(!m_timeoutTimer) + { + m_timeoutTimer=new TQTimer(this); + connect( m_timeoutTimer , TQT_SIGNAL(timeout()), this , TQT_SLOT(slotConnectionTimeout() ) ); + } + m_timeoutTimer->start(20000,true); +} + +void MSNChatSession::slotUserJoined( const TQString &handle, const TQString &publicName, bool IRO ) +{ + delete m_timeoutTimer; + m_timeoutTimer=0L; + + if( !account()->contacts()[ handle ] ) + account()->addContact( handle, TQString(), 0L, Kopete::Account::Temporary); + + MSNContact *c = static_cast<MSNContact*>( account()->contacts()[ handle ] ); + + c->setProperty( Kopete::Global::Properties::self()->nickName() , publicName); + + if(c->clientFlags() & MSNProtocol::MSNC4 ) + { + m_actionNudge->setEnabled(true); + } +#if MSN_WEBCAM + if(c->clientFlags() & MSNProtocol::SupportWebcam ) + { + m_actionWebcamReceive->setEnabled(true); + } +#endif + + addContact(c , IRO); // don't show notificaions when we join wesalef + if(!m_messagesQueue.empty() || !m_invitations.isEmpty()) + sendMessageQueue(); + + TDEConfig *config = TDEGlobal::config(); + config->setGroup( "MSN" ); + if ( members().count()==1 && config->readNumEntry( "DownloadPicture", 1 ) >= 1 && !c->object().isEmpty() && !c->hasProperty(Kopete::Global::Properties::self()->photo().key())) + slotRequestPicture(); +} + +void MSNChatSession::slotUserLeft( const TQString &handle, const TQString& reason ) +{ + MSNContact *c = static_cast<MSNContact*>( myself()->account()->contacts()[ handle ] ); + if(c) + removeContact(c, reason ); +} + + + +void MSNChatSession::slotSwitchBoardClosed() +{ + //kdDebug(14140) << "MSNChatSession::slotSwitchBoardClosed" << endl; + m_chatService->deleteLater(); + m_chatService=0l; + + cleanMessageQueue( i18n("Connection closed") ); + + if(m_invitations.isEmpty()) + setCanBeDeleted( true ); +} + +void MSNChatSession::slotMessageSent(Kopete::Message &message,Kopete::ChatSession *) +{ + m_newSession=false; + if(m_chatService) + { + int id = m_chatService->sendMsg(message); + if(id == -1) + { + m_messagesQueue.append(message); + kdDebug(14140) << k_funcinfo << "Message added to the queue" <<endl; + } + else if( id== -2 ) //the message has not been sent + { + //FIXME: tell the what window the message has been processed. but we havent't sent it + messageSucceeded(); //that should stop the blonking icon. + } + else if( id == -3) //the message has been sent as an immge + { + appendMessage(message); + messageSucceeded(); + } + else + { + m_messagesSent.insert( id, message ); + message.setBg(TQColor()); // clear the bgColor + message.setBody(message.plainBody() , Kopete::Message::PlainText ); //clear every custom tag which are not sent + appendMessage(message); // send the own msg to chat window + } + } + else // There's no switchboard available, so we must create a new one! + { + startChatSession(); + m_messagesQueue.append(message); +// sendMessageQueue(); + //m_msgQueued=new Kopete::Message(message); + } +} + +void MSNChatSession::slotMessageReceived( Kopete::Message &msg ) +{ + m_newSession=false; + if( msg.plainBody().startsWith( "AutoMessage: " ) ) + { + //FIXME: HardCodded color are not so good + msg.setFg( TQColor( "SlateGray3" ) ); + TQFont f; + f.setItalic( true ); + msg.setFont( f ); + } + appendMessage( msg ); +} + +void MSNChatSession::slotActionInviteAboutToShow() +{ + // We can't simply insert TDEAction in this menu bebause we don't know when to delete them. + // items inserted with insert items are automatically deleted when we call clear + + m_inviteactions.setAutoDelete(true); + m_inviteactions.clear(); + + m_actionInvite->popupMenu()->clear(); + + + TQDictIterator<Kopete::Contact> it( account()->contacts() ); + for( ; it.current(); ++it ) + { + if( !members().contains( it.current() ) && it.current()->isOnline() && it.current() != myself() ) + { + TDEAction *a=new KopeteContactAction( it.current(), this, + TQT_SLOT( slotInviteContact( Kopete::Contact * ) ), m_actionInvite ); + m_actionInvite->insert( a ); + m_inviteactions.append( a ) ; + } + } + TDEAction *b=new TDEAction( i18n ("Other..."), 0, this, TQT_SLOT( slotInviteOtherContact() ), m_actionInvite, "actionOther" ); + m_actionInvite->insert( b ); + m_inviteactions.append( b ) ; +} + +void MSNChatSession::slotCloseSession() +{ + kdDebug(14140) << k_funcinfo << m_chatService <<endl; + if(m_chatService) + m_chatService->slotCloseSession(); +} + +void MSNChatSession::slotInviteContact( Kopete::Contact *contact ) +{ + if(contact) + inviteContact( contact->contactId() ); +} + +void MSNChatSession::inviteContact(const TQString &contactId) +{ + if( m_chatService ) + m_chatService->slotInviteContact( contactId ); + else + startChatSession(); +} + +void MSNChatSession::slotInviteOtherContact() +{ + bool ok; + TQString handle = KInputDialog::getText(i18n( "MSN Plugin" ), + i18n( "Please enter the email address of the person you want to invite:" ), + TQString(), &ok ); + if( !ok ) + return; + + if( handle.contains('@') != 1 || handle.contains('.') <1) + { + KMessageBox::queuedMessageBox( Kopete::UI::Global::mainWidget(), KMessageBox::Sorry, + i18n("<qt>You must enter a valid email address.</qt>"), i18n("MSN Plugin")); + return; + } + + inviteContact(handle); +} + + +void MSNChatSession::sendMessageQueue() +{ + if(!m_chatService) + { + kdDebug(14140) <<k_funcinfo << "Service doesn't exist" <<endl; + return; + } +// kdDebug(14140) << "MSNChatSession::sendMessageQueue: " << m_messagesQueue.count() <<endl; + for ( TQValueList<Kopete::Message>::iterator it = m_messagesQueue.begin(); it!=m_messagesQueue.end(); it = m_messagesQueue.begin() ) + { + //m_chatService->sendMsg( *it) ; + slotMessageSent(*it , this); + m_messagesQueue.remove(it); + } + + + TQMap<unsigned long int, MSNInvitation*>::Iterator it; + for( it = m_invitations.begin(); it != m_invitations.end() ; ++it) + { + if(! (*it)->incoming() && (*it)->state()<MSNInvitation::Invited) + { + m_chatService->sendCommand( "MSG" , "N", true, (*it)->invitationHead().utf8() ); + (*it)->setState(MSNInvitation::Invited); + } + } +} + +void MSNChatSession::slotAcknowledgement(unsigned int id, bool ack) +{ + if ( !m_messagesSent.contains( id ) ) + { + // This is maybe a ACK/NAK for a non-messaging message + return; + } + + if ( !ack ) + { + Kopete::Message m = m_messagesSent[ id ]; + TQString body = i18n( "The following message has not been sent correctly:\n%1" ).arg( m.plainBody() ); + Kopete::Message msg = Kopete::Message( m.to().first(), members(), body, Kopete::Message::Internal, Kopete::Message::PlainText ); + appendMessage( msg ); + //stop the stupid animation + messageSucceeded(); + } + else + { + messageSucceeded(); + } + + m_messagesSent.remove( id ); +} + +void MSNChatSession::slotInvitation(const TQString &handle, const TQString &msg) +{ + //FIXME! a contact from another account can send a file + MSNContact *c = static_cast<MSNContact*>( myself()->account()->contacts()[ handle ] ); + if(!c) + return; + + TQRegExp rx("Invitation-Cookie: ([0-9]*)"); + rx.search(msg); + long unsigned int cookie=rx.cap(1).toUInt(); + + if(m_invitations.contains(cookie)) + { + MSNInvitation *msnI=m_invitations[cookie]; + msnI->parseInvitation(msg); + } + else if( msg.contains("Invitation-Command: INVITE") ) + { + if( msg.contains(MSNFileTransferSocket::applicationID()) ) + { + MSNFileTransferSocket *MFTS=new MSNFileTransferSocket(myself()->account()->accountId(),c,true,this); + connect(MFTS, TQT_SIGNAL( done(MSNInvitation*) ) , this , TQT_SLOT( invitationDone(MSNInvitation*) )); + m_invitations.insert( cookie , MFTS); + MFTS->parseInvitation(msg); + setCanBeDeleted(false); + } + else + { + MSNInvitation *i=0l; + emit invitation( i , msg, cookie, this, c ); + if(i) + { + m_invitations.insert( cookie , i ); + //don't delete this if all invitation are not done + setCanBeDeleted(false); + } + else + { + rx=TQRegExp("Application-Name: ([^\\r\\n]*)"); + rx.search(msg); + TQString inviteName = rx.cap( 1 ); + + TQString body = i18n( + "%1 has sent an unimplemented invitation, the invitation was rejected.\n" + "The invitation was: %2" ) + .arg( c->property( Kopete::Global::Properties::self()->nickName()).value().toString(), inviteName ); + Kopete::Message tmpMsg = Kopete::Message( c , members() , body , Kopete::Message::Internal, Kopete::Message::PlainText); + appendMessage(tmpMsg); + + m_chatService->sendCommand( "MSG" , "N", true, MSNInvitation::unimplemented(cookie) ); + } + } + } +} + +void MSNChatSession::invitationDone(MSNInvitation* MFTS) +{ + kdDebug(14140) << k_funcinfo <<endl; + m_invitations.remove(MFTS->cookie()); +// MFTS->deleteLater(); + delete MFTS; + if(!m_chatService && m_invitations.isEmpty()) + setCanBeDeleted(true); +} + +void MSNChatSession::sendFile(const TQString &fileLocation, const TQString &/*fileName*/, + long unsigned int fileSize) +{ + // TODO create a switchboard to send the file is one is not available. + if(m_chatService && members().getFirst()) + { + m_chatService->PeerDispatcher()->sendFile(fileLocation, (TQ_INT64)fileSize, members().getFirst()->contactId()); + } +} + +void MSNChatSession::initInvitation(MSNInvitation* invitation) +{ + connect(invitation->object(), TQT_SIGNAL( done(MSNInvitation*) ) , this , TQT_SLOT( invitationDone(MSNInvitation*) )); + m_invitations.insert( invitation->cookie() , invitation); + + if(m_chatService) + { + m_chatService->sendCommand( "MSG" , "N", true, invitation->invitationHead().utf8() ); + invitation->setState(MSNInvitation::Invited); + } + else + { + startChatSession(); + } +} + +void MSNChatSession::slotRequestPicture() +{ + TQPtrList<Kopete::Contact> mb=members(); + MSNContact *c = static_cast<MSNContact*>( mb.first() ); + if(!c) + return; + + if( !c->hasProperty(Kopete::Global::Properties::self()->photo().key())) + { + if(m_chatService) + { + if( !c->object().isEmpty() ) + m_chatService->requestDisplayPicture(); + } + else if(myself()->onlineStatus().isDefinitelyOnline() && myself()->onlineStatus().status() != Kopete::OnlineStatus::Invisible ) + startChatSession(); + } + else + { //we already have the picture, just show it. + KRun::runURL( KURL::fromPathOrURL( c->property(Kopete::Global::Properties::self()->photo()).value().toString() ), "image/png" ); + } + +} + +void MSNChatSession::slotDisplayPictureChanged() +{ + TQPtrList<Kopete::Contact> mb=members(); + MSNContact *c = static_cast<MSNContact *>( mb.first() ); + if ( c && m_image ) + { + if(c->hasProperty(Kopete::Global::Properties::self()->photo().key())) + { + int sz=22; + // get the size of the toolbar were the aciton is plugged. + // if you know a better way to get the toolbar, let me know + TDEMainWindow *w= view(false) ? dynamic_cast<TDEMainWindow*>( view(false)->mainWidget()->topLevelWidget() ) : 0L; + if(w) + { + //We connected that in the constructor. we don't need to keep this slot active. + disconnect( Kopete::ChatSessionManager::self() , TQT_SIGNAL(viewActivated(KopeteView* )) , this, TQT_SLOT(slotDisplayPictureChanged()) ); + + TQPtrListIterator<TDEToolBar> it=w->toolBarIterator() ; + TDEAction *imgAction=actionCollection()->action("msnDisplayPicture"); + if(imgAction) while(it) + { + TDEToolBar *tb=*it; + if(imgAction->isPlugged(tb)) + { + sz=tb->iconSize(); + //ipdate if the size of the toolbar change. + disconnect(tb, TQT_SIGNAL(modechange()), this, TQT_SLOT(slotDisplayPictureChanged())); + connect(tb, TQT_SIGNAL(modechange()), this, TQT_SLOT(slotDisplayPictureChanged())); + break; + } + ++it; + } + } + TQString imgURL=c->property(Kopete::Global::Properties::self()->photo()).value().toString(); + TQImage scaledImg = TQPixmap( imgURL ).convertToImage().smoothScale( sz, sz ); + if(!scaledImg.isNull()) + m_image->setPixmap( scaledImg ); + else + { //the image has maybe not been transfered correctly.. force to download again + c->removeProperty(Kopete::Global::Properties::self()->photo()); + //slotDisplayPictureChanged(); //don't do that or we might end in a infinite loop + } + TQToolTip::add( m_image, "<qt><img src=\"" + imgURL + "\"></qt>" ); + + } + else + { + TDEConfig *config = TDEGlobal::config(); + config->setGroup( "MSN" ); + if ( config->readNumEntry( "DownloadPicture", 1 ) >= 1 && !c->object().isEmpty() ) + slotRequestPicture(); + } + } +} + +void MSNChatSession::slotDebugRawCommand() +{ +#if !defined NDEBUG + if ( !m_chatService ) + return; + + MSNDebugRawCmdDlg *dlg = new MSNDebugRawCmdDlg( 0L ); + int result = dlg->exec(); + if( result == TQDialog::Accepted && m_chatService ) + { + m_chatService->sendCommand( dlg->command(), dlg->params(), + dlg->addId(), dlg->msg().replace("\n","\r\n").utf8() ); + } + delete dlg; +#endif +} + + +void MSNChatSession::receivedTypingMsg( const TQString &contactId, bool b ) +{ + MSNContact *c = dynamic_cast<MSNContact *>( account()->contacts()[ contactId ] ); + if(c && m_newSession && !view(false)) + { + //this was originaly in MSNAccount::slotCreateChat + TDEGlobal::config()->setGroup( "MSN" ); + bool notifyNewChat = TDEGlobal::config()->readBoolEntry( "NotifyNewChat", false ); + if ( notifyNewChat ) + { + // this internal message should open the window if they not exist + TQString body = i18n( "%1 has started a chat with you" ).arg( c->metaContact()->displayName() ); + Kopete::Message tmpMsg = Kopete::Message( c, members(), body, Kopete::Message::Internal, Kopete::Message::PlainText ); + appendMessage( tmpMsg ); + } + } + m_newSession=false; + if(c) + Kopete::ChatSession::receivedTypingMsg(c,b); +} + +void MSNChatSession::slotSendNudge() +{ + if(m_chatService) + { + m_chatService->sendNudge(); + Kopete::Message msg = Kopete::Message( myself(), members() , i18n ( "has sent a nudge" ), Kopete::Message::Outbound, + Kopete::Message::PlainText, TQString(), Kopete::Message::TypeAction ); + appendMessage( msg ); + + } +} + + +void MSNChatSession::slotNudgeReceived(const TQString& handle) +{ + Kopete::Contact *c = account()->contacts()[ handle ] ; + if(!c) + c=members().getFirst(); + Kopete::Message msg = Kopete::Message(c, myself(), i18n ( "has sent you a nudge" ), Kopete::Message::Inbound, + Kopete::Message::PlainText, TQString(), Kopete::Message::TypeAction ); + appendMessage( msg ); + // Emit the nudge/buzz notification (configured by user). + emitNudgeNotification(); +} + + +void MSNChatSession::slotWebcamReceive() +{ +#if MSN_WEBCAM + if(m_chatService && members().getFirst()) + { + m_chatService->PeerDispatcher()->startWebcam(myself()->contactId() , members().getFirst()->contactId() , true); + } +#endif +} + +void MSNChatSession::slotWebcamSend() +{ +#if MSN_WEBCAM + kdDebug(14140) << k_funcinfo << endl; + if(m_chatService && members().getFirst()) + { + m_chatService->PeerDispatcher()->startWebcam(myself()->contactId() , members().getFirst()->contactId() , false); + } +#endif +} + + +void MSNChatSession::slotSendFile() + { + TQPtrList<Kopete::Contact>contacts = members(); + static_cast<MSNContact *>(contacts.first())->sendFile(); + } + +void MSNChatSession::startChatSession() +{ + TQPtrList<Kopete::Contact> mb=members(); + static_cast<MSNAccount*>( account() )->slotStartChatSession( mb.first()->contactId() ); + + if(!m_timeoutTimer) + { + m_timeoutTimer=new TQTimer(this); + connect( m_timeoutTimer , TQT_SIGNAL(timeout()), this , TQT_SLOT(slotConnectionTimeout() ) ); + } + m_timeoutTimer->start(20000, true); +} + + +void MSNChatSession::cleanMessageQueue( const TQString & reason ) +{ + delete m_timeoutTimer; + m_timeoutTimer=0L; + + uint nb=m_messagesQueue.count()+m_messagesSent.count(); + if(nb==0) + return; + else if(nb==1) + { + Kopete::Message m; + if(m_messagesQueue.count() == 1) + m=m_messagesQueue.first(); + else + m=m_messagesSent.begin().data(); + + TQString body=i18n("The following message has not been sent correctly (%1): \n%2").arg(reason, m.plainBody()); + Kopete::Message msg = Kopete::Message(m.to().first() , members() , body , Kopete::Message::Internal, Kopete::Message::PlainText); + appendMessage(msg); + } + else + { + Kopete::Message m; + TQString body=i18n("These messages have not been sent correctly (%1): <br /><ul>").arg(reason); + for ( TQMap<unsigned int , Kopete::Message>::iterator it = m_messagesSent.begin(); it!=m_messagesSent.end(); it = m_messagesSent.begin() ) + { + m=it.data(); + body+= "<li>"+m.escapedBody()+"</li>"; + m_messagesSent.remove(it); + } + for ( TQValueList<Kopete::Message>::iterator it = m_messagesQueue.begin(); it!=m_messagesQueue.end(); it = m_messagesQueue.begin() ) + { + m=(*it); + body+= "<li>"+m.escapedBody()+"</li>"; + m_messagesQueue.remove(it); + } + body+="</ul>"; + Kopete::Message msg = Kopete::Message(m.to().first() , members() , body , Kopete::Message::Internal, Kopete::Message::RichText); + appendMessage(msg); + + } + m_messagesQueue.clear(); + m_messagesSent.clear(); + messageSucceeded(); //stop stupid animation +} + +void MSNChatSession::slotConnectionTimeout() +{ + m_connectionTry++; + if(m_chatService) + { + disconnect(m_chatService , 0 , this , 0 ); + m_chatService->deleteLater(); + m_chatService=0L; + } + + if( m_connectionTry > 3 ) + { + cleanMessageQueue( i18n("Impossible to establish the connection") ); + delete m_timeoutTimer; + m_timeoutTimer=0L; + return; + } + startChatSession(); + +} + + + + +#include "msnchatsession.moc" + +// vim: set noet ts=4 sts=4 sw=4: + |