Logo Search packages:      
Sourcecode: kmess version File versions  Download package

void MsnSwitchboardConnection::sendChatMessage ( const QString &  text  ) 

Send a message to the contact(s)

If there is at least one custom emoticon in our message, also send a message to tell our contact's clients that they have to download from us the corresponding pictures.

Definition at line 1524 of file msnswitchboardconnection.cpp.

References MsnConnection::ACK_NAK_ONLY, MimeMessage::addField(), CurrentAccount::getContactByHandle(), EmoticonManager::getFileNames(), Account::getFont(), Account::getFontColor(), Account::getHandle(), EmoticonManager::getPattern(), EmoticonManager::getThemePath(), ContactBase::hasCapability(), EmoticonManager::instance(), ContactBase::MSN_CAP_MULTI_PACKET, MimeMessage::setBody(), and WARNING_TOO_MANY_EMOTICONS.

{
  int maxSendableSingleMessageLength = 1400;

  if ( currentAccount_ == 0 )
  {
    kWarning() << "currentAccount_ is null!";
    return;
  }

  // Check if any custom emoticon is being sent in the message.
  // This has to be sent first so the receiving client will be aware that
  // there will be custom emoticons in the next message.
  QString code, pictureFile;
  QString emoticonObjects;
  QStringList addedEmoticons;
  int lastPos                             = 0;
  int matchStart                          = 0;
  EmoticonManager *manager                = EmoticonManager::instance();
  const QRegExp&                  emoticonRegExp(   manager->getPattern( true ) );
  const QHash<QString,QString>& emoticonPictures( manager->getFileNames( true ) );
  const QString&               emoticonThemePath( manager->getThemePath( true ) );

  // We'll loop until we reach the end of the string or there are no more emoticons to parse
  if( ! emoticonRegExp.isEmpty() )
  {
    while( true )
    {
      // First find if there's any custom emoticon
      matchStart = emoticonRegExp.indexIn( text, lastPos );
      if( matchStart == -1 )
      {
        break;
      }

      // Find out what emoticon has matched
      code = text.mid( matchStart, emoticonRegExp.matchedLength() );

      // Find where the emoticon code ends and the image corresponding to that code
      lastPos = matchStart + emoticonRegExp.matchedLength();
      pictureFile = emoticonPictures[ code ];

      // Do not add emoticons to the list more than once
      if( addedEmoticons.contains( code ) )
      {
        continue;
      }

      // We cannot send more than 7 different custom emoticons in each message: skip the other ones.
      // TODO add some visual confirmation or message about this.
      if( addedEmoticons.count() >= 7 )
      {
        emit showWarning( WARNING_TOO_MANY_EMOTICONS, 0 );
        break;
      }

      addedEmoticons.append( code );

      // NOTE: Behavior changed since WLM 8+, emoticon data must be sent every time.
      // Before, we could send any emoticon's msnobject just once per session.

      // No match? Strange.. but go on anyways
      if( pictureFile.isEmpty() )
      {
#ifdef KMESSDEBUG_SWITCHBOARD_EMOTICONS
        kDebug() << "Custom emoticon '" << code << "' not found!";
#endif

        continue;
      }

#ifdef KMESSDEBUG_SWITCHBOARD_EMOTICONS
      kDebug() << "Found custom emoticon '" << code << "' which file is '"
                << ( emoticonThemePath + pictureFile ) << "'." << endl;
#endif

      QFile iFile( emoticonThemePath + pictureFile );
      if( ! iFile.open( QIODevice::ReadOnly ) )
     {
#ifdef KMESSDEBUG_SWITCHBOARD_EMOTICONS
        kDebug() << "Unable to read picture '" <<  pictureFile << "'!";
#endif
        iFile.close();
        continue;
      }

      // Read the file and create an MSNObject of the emoticon
      const QByteArray& data( iFile.readAll() );
      iFile.close();
      MsnObject test( currentAccount_->getHandle(), pictureFile, QString::null, MsnObject::EMOTICON, data );

      // Only divide items between each other
      if( ! emoticonObjects.isEmpty() )
      {
        emoticonObjects += "\t";
      }

      emoticonObjects += code + "\t" + test.objectString();
    }
  }

  // Don't send the message if there is no emoticon to send
  if( ! emoticonObjects.isEmpty() )
  {
    MimeMessage emoticonMessage;
    emoticonMessage.addField("MIME-Version",    "1.0");
    emoticonMessage.addField("Content-Type",    "text/x-mms-emoticon");
    emoticonMessage.setBody( emoticonObjects );

    sendMimeMessageWhenReady( ACK_NAK_ONLY, emoticonMessage );
  }

  // Then send the real text message

  // Get the formatting properties and convert them to MSN's IM format
  const QFont&         font( currentAccount_->getFont() );
  const QString& fontFamily( QUrl::toPercentEncoding( font.family() ) );
  const QString& color     ( convertHtmlColorToMsnColor( currentAccount_->getFontColor() ) );

  // Determine effects
  QString effects;
  if( font.bold()      ) effects += "B";
  if( font.italic()    ) effects += "I";
  if( font.underline() ) effects += "U";

  // Determine text direction
  const QString& rtl( text.isRightToLeft() ? "; RL=1" : "" );

  // Create the message
  MimeMessage message;
  message.addField("MIME-Version",    "1.0");
  message.addField("Content-Type",    "text/plain; charset=UTF-8");
  message.addField("X-MMS-IM-Format", "FN=" + fontFamily + "; EF=" + effects + "; CO=" + color + "; CS=0; PF=0" + rtl);
  message.setBody(text);

  // Send the message
  int bodyLength = text.toUtf8().length();
  if( bodyLength > maxSendableSingleMessageLength )
  {
    // Check if the remote clients support the recieving of huge messages.
    ContactBase *contact;
    bool capable = true;
    foreach( const QString &handle, contactsInChat_ )
    {
      contact = currentAccount_->getContactByHandle( handle );
      if( ! contact->hasCapability( ContactBase::MSN_CAP_MULTI_PACKET ) )
      {
        capable = false;
        break;
      }
    }

    if( capable )
    {
      // Create a multipacket message
      MultiPacketMessage multiMessage( message );
      sendMimeMessageWhenReady( ACK_NAK_ONLY, multiMessage );
    }
    else
    {
      // Split the huge message and send all parts
      int pos = 0;
      int prevPos = 0;
      QString messagePart;
      const QString& body( message.getBody() );

      int parts = (int) ceil( ( (float) bodyLength / (float) maxSendableSingleMessageLength ) );

      for( int i = 0; i < parts - 1; i++ )
      {
        prevPos = pos;
        pos += maxSendableSingleMessageLength;

        // search backwards from the new split position.
        int spacePos = body.lastIndexOf( " ", pos );

        messagePart = body.mid( prevPos, pos - prevPos );

        if( spacePos > prevPos )
        {
          // use that one!
          pos++;
        }

        // send messagePart
        sendMimeMessageWhenReady( ACK_NAK_ONLY, message );
      }

      messagePart = body.mid( pos, body.length() - pos );

      sendMimeMessageWhenReady( ACK_NAK_ONLY, message );
    }
  }
  else
  {
    // Send the simple MimeMessage
    sendMimeMessageWhenReady( ACK_NAK_ONLY, message );
  }

  // Signal the presence of activity on this switchboard
  activity();
}


Generated by  Doxygen 1.6.0   Back to index