messageeventfilter.cpp

00001 /*
00002   Copyright (c) 2005-2008 by Jakob Schroeter <js@camaya.net>
00003   This file is part of the gloox library. http://camaya.net/gloox
00004 
00005   This software is distributed under a license. The full license
00006   agreement can be found in the file LICENSE in this distribution.
00007   This software may not be copied, modified, sold or distributed
00008   other than expressed in the named license agreement.
00009 
00010   This software is distributed without any warranty.
00011 */
00012 
00013 
00014 #include "messageeventfilter.h"
00015 #include "messageeventhandler.h"
00016 #include "messagesession.h"
00017 #include "stanza.h"
00018 
00019 namespace gloox
00020 {
00021 
00022   MessageEventFilter::MessageEventFilter( MessageSession *parent, int defaultEvents )
00023     : MessageFilter( parent ), m_messageEventHandler( 0 ), m_requestedEvents( 0 ),
00024       m_defaultEvents( defaultEvents ), m_lastSent( MessageEventCancel ),
00025       m_disable( false )
00026   {
00027   }
00028 
00029   MessageEventFilter::~MessageEventFilter()
00030   {
00031   }
00032 
00033   void MessageEventFilter::filter( Stanza *stanza )
00034   {
00035     if( m_disable )
00036       return;
00037 
00038     if( stanza->subtype() == StanzaMessageError )
00039     {
00040       if( stanza->error() == StanzaErrorFeatureNotImplemented )
00041         m_disable = true;
00042 
00043       return;
00044     }
00045 
00046     Tag *x = stanza->findChild( "x", "xmlns", XMLNS_X_EVENT );
00047     if( x && m_messageEventHandler )
00048     {
00049       if( stanza->body().empty() )
00050       {
00051         if( x->hasChild( "offline" ) )
00052           m_messageEventHandler->handleMessageEvent( stanza->from(), MessageEventOffline );
00053         else if( x->hasChild( "delivered" ) )
00054           m_messageEventHandler->handleMessageEvent( stanza->from(), MessageEventDelivered );
00055         else if( x->hasChild( "displayed" ) )
00056           m_messageEventHandler->handleMessageEvent( stanza->from(), MessageEventDisplayed );
00057         else if( x->hasChild( "composing" ) )
00058           m_messageEventHandler->handleMessageEvent( stanza->from(), MessageEventComposing );
00059         else
00060           m_messageEventHandler->handleMessageEvent( stanza->from(), MessageEventCancel );
00061       }
00062       else
00063       {
00064         m_lastID = stanza->findAttribute( "id" );
00065         m_requestedEvents = 0;
00066         Tag *x = stanza->findChild( "x" );
00067         if( x->hasChild( "offline" ) )
00068           m_requestedEvents |= MessageEventOffline;
00069         if( x->hasChild( "delivered" ) )
00070           m_requestedEvents |= MessageEventDelivered;
00071         if( x->hasChild( "displayed" ) )
00072           m_requestedEvents |= MessageEventDisplayed;
00073         if( x->hasChild( "composing" ) )
00074           m_requestedEvents |= MessageEventComposing;
00075       }
00076     }
00077     else if( stanza->body().empty() )
00078     {
00079       m_requestedEvents = 0;
00080       m_lastID = "";
00081     }
00082   }
00083 
00084   void MessageEventFilter::raiseMessageEvent( MessageEventType event )
00085   {
00086     if( m_disable || ( !( m_requestedEvents & event ) && ( event != MessageEventCancel ) ) )
00087       return;
00088 
00089     Tag *m = new Tag( "message" );
00090     m->addAttribute( "to", m_parent->target().full() );
00091     Tag *x = new Tag( m, "x" );
00092     x->addAttribute( "xmlns", XMLNS_X_EVENT );
00093     new Tag( x, "id", m_lastID );
00094 
00095     bool used = true;
00096     switch( event )
00097     {
00098       case MessageEventOffline:
00099         new Tag( x, "offline" );
00100         m_requestedEvents &= ~event;
00101         break;
00102       case MessageEventDelivered:
00103         new Tag( x, "delivered" );
00104         m_requestedEvents &= ~event;
00105         break;
00106       case MessageEventDisplayed:
00107         new Tag( x, "displayed" );
00108         m_requestedEvents &= ~event;
00109         break;
00110       case MessageEventComposing:
00111         if( m_lastSent != MessageEventComposing )
00112           new Tag( x, "composing" );
00113         else
00114           used = false;
00115         break;
00116       case MessageEventCancel:
00117         break;
00118     }
00119 
00120     m_lastSent = event;
00121 
00122     if( used )
00123       send( m );
00124     else
00125       delete m;
00126   }
00127 
00128   void MessageEventFilter::decorate( Tag *tag )
00129   {
00130     if( m_disable )
00131       return;
00132 
00133     if( m_defaultEvents != 0 )
00134     {
00135       Tag *x = new Tag( tag, "x" );
00136       x->addAttribute( "xmlns", XMLNS_X_EVENT );
00137 
00138       if( m_defaultEvents & MessageEventOffline )
00139         new Tag( x, "offline" );
00140       if( m_defaultEvents & MessageEventDelivered )
00141         new Tag( x, "delivered" );
00142       if( m_defaultEvents & MessageEventDisplayed )
00143         new Tag( x, "displayed" );
00144       if( m_defaultEvents & MessageEventComposing )
00145         new Tag( x, "composing" );
00146     }
00147     m_lastSent = MessageEventCancel;
00148   }
00149 
00150   void MessageEventFilter::registerMessageEventHandler( MessageEventHandler *meh )
00151   {
00152     m_messageEventHandler = meh;
00153   }
00154 
00155   void MessageEventFilter::removeMessageEventHandler()
00156   {
00157     m_messageEventHandler = 0;
00158   }
00159 
00160 }

Generated on Mon Dec 7 13:28:19 2009 for gloox by  doxygen 1.6.1