QStringList Kopete::ChatSession::findUrls(const Kopete::Message &msg )
{
	Kopete::Message message = msg;
	//we check the message for every pattern
	QString tempstr = message.plainBody();
	QStringList regexppatterns = message.regexpPatterns();
	QRegExp linkregexp;
	QMap<int,QString> mapUrl;

	for (int i = 0; i < regexppatterns.size(); ++i) {
	  linkregexp.setPattern(regexppatterns[i]);
	  int pos = 0;
	  while ((pos = linkregexp.indexIn(tempstr, pos)) != -1) {
	    mapUrl.insert(pos,linkregexp.cap(0));
	    pos += linkregexp.matchedLength(); }
	}
	//we use QMap to sort links as they are in the message (if there are many links in one message)
	//lasturllist[0] - is the earliest
	QStringList lasturllist;
	QMapIterator< int, QString > i(mapUrl);
	while (i.hasNext()) { i.next(); lasturllist << i.value(); }
	lasturllist.replaceInStrings(" ", "");
	//add "http://" to link if needed to open it with a browser
	lasturllist.replaceInStrings(QRegExp( regexppatterns[1] ), QLatin1String("\\1http://\\2\\3" ));

	return lasturllist;
}
Exemplo n.º 2
0
int
GaduSession::sendMessage( uin_t recipient, const Kopete::Message& msg, int msgClass )
{
	QString sendMsg;
	QCString cpMsg;
	KGaduMessage* gadumessage;

	if ( isConnected() ) {
		gadumessage = rtf->convertToGaduMessage( msg );
		if ( gadumessage ) {
			const void* data = (const void*)gadumessage->rtf.data();
			cpMsg = textcodec->fromUnicode( gadumessage->message );
			int o;
			o = gg_send_message_richtext( session_, msgClass, recipient, (const unsigned char *)cpMsg.data(), (const unsigned char*) data, gadumessage->rtf.size() );
			gadumessage->rtf.resize(0);
			delete gadumessage;
			return o;
		}
		else {
			sendMsg = msg.plainBody();
			sendMsg.replace( QString::fromAscii( "\n" ), QString::fromAscii( "\r\n" ) );
			cpMsg = textcodec->fromUnicode( sendMsg );

			return gg_send_message( session_, msgClass, recipient, (const unsigned char *)cpMsg.data() );
		}
	}
	else {
		emit error( i18n("Not Connected"), i18n("You are not connected to the server.") );
	}

	return 1;
}
Exemplo n.º 3
0
void Kopete::ChatSession::appendMessage( Kopete::Message &msg )
{
	msg.setManager( this );

	if ( msg.direction() == Kopete::Message::Inbound )
	{
		QString nick=myself()->property(Kopete::Global::Properties::self()->nickName()).value().toString();
		if ( KopetePrefs::prefs()->highlightEnabled() && !nick.isEmpty() &&
			msg.plainBody().contains( QRegExp( QString::fromLatin1( "\\b(%1)\\b" ).arg( nick ), false ) ) )
		{
			msg.setImportance( Kopete::Message::Highlight );
		}

		emit messageReceived( msg, this );
	}

	// outbound messages here are ones the user has sent that are now
	// getting reflected back to the chatwindow. they should go down
	// the incoming chain.
	Kopete::Message::MessageDirection chainDirection = msg.direction();
	if( chainDirection == Kopete::Message::Outbound )
		chainDirection = Kopete::Message::Inbound;

	chainForDirection( chainDirection )->processMessage( msg );
//	emit messageAppended( msg, this );
}
void Kopete::ChatSession::appendMessage( Kopete::Message &msg )
{
	msg.setManager( this );

	if ( msg.direction() == Kopete::Message::Inbound )
	{
		const QString nick = myself()->nickName();
		if ( Kopete::BehaviorSettings::self()->highlightEnabled() && !nick.isEmpty() )
		{
			const QString nickNameRegExp = QString::fromLatin1( "(^|[\\W])(%1)([\\W]|$)" ).arg( QRegExp::escape( nick ) );
			if ( msg.plainBody().contains( QRegExp( nickNameRegExp, Qt::CaseInsensitive ) ) )
			{
				msg.setImportance( Kopete::Message::Highlight );
			}
		}

		emit messageReceived( msg, this );
	}

	// outbound messages here are ones the user has sent that are now
	// getting reflected back to the chatwindow. they should go down
	// the incoming chain.
	Kopete::Message::MessageDirection chainDirection = msg.direction();
	if( chainDirection == Kopete::Message::Outbound )
		chainDirection = Kopete::Message::Inbound;

	chainForDirection( chainDirection )->processMessage( msg );

	//looking for urls in the message
	urlSearch( msg );
//	emit messageAppended( msg, this );
}
Exemplo n.º 5
0
void SMSClient::send(const Kopete::Message& msg)
{
	kdWarning( 14160 ) << k_funcinfo << "m_account = " << m_account << " (should be non-zero!!)" << endl;
	if (!m_account) return;

	m_msg = msg;
	
	KConfigGroup* c = m_account->configGroup();
	QString provider = c->readEntry(QString("%1:%2").arg("SMSClient").arg("ProviderName"), QString::null);

	if (provider.isNull())
	{
		KMessageBox::error(Kopete::UI::Global::mainWidget(), i18n("No provider configured"), i18n("Could Not Send Message"));
		return;
	}

	QString programName = c->readEntry(QString("%1:%2").arg("SMSClient").arg("ProgramName"). QString::null);
	if (programName.isNull())
		programName = "/usr/bin/sms_client";

	KProcess* p = new KProcess;

	QString message = msg.plainBody();
	QString nr = msg.to().first()->contactId();

	*p << programName;
	*p << provider + ":" + nr;
	*p << message;

	QObject::connect(p, SIGNAL(processExited(KProcess *)), this, SLOT(slotSendFinished(KProcess*)));
	QObject::connect(p, SIGNAL(receivedStdout(KProcess*, char*, int)), this, SLOT(slotReceivedOutput(KProcess*, char*, int)));
	QObject::connect(p, SIGNAL(receivedStderr(KProcess*, char*, int)), this, SLOT(slotReceivedOutput(KProcess*, char*, int)));

	p->start(KProcess::Block, KProcess::AllOutput);
}
void TranslatorGUIClient::slotTranslateChat()
{
	if ( !m_manager->view() )
		return;

	Kopete::Message msg = m_manager->view()->currentMessage();
	QString body = msg.plainBody();
	if ( body.isEmpty() )
		return;

	QString src_lang = TranslatorPlugin::plugin()->m_myLang;
	QString dst_lang;

	QList<Kopete::Contact*> list = m_manager->members();
	Kopete::MetaContact *to = list.first()->metaContact();
	dst_lang = to->pluginData( TranslatorPlugin::plugin(), "languageKey" );
	if ( dst_lang.isEmpty() || dst_lang == "null" )
	{
		kDebug( 14308 ) << "Cannot determine dst Metacontact language (" << to->displayName() << ")";
		return;
	}

	// We search for src_dst
	TranslatorPlugin::plugin()->translateMessage( body, src_lang, dst_lang, this, SLOT(messageTranslated(QVariant)) );
}
void NowListeningPlugin::slotOutgoingMessage(Kopete::Message& msg)
{
	// Only do stuff if autoadvertising is on
	if(!NowListeningConfig::self()->chatAdvertising())
		return;

	QString originalBody = msg.plainBody();

	// If it is a /media message, don't process it
	if(originalBody.startsWith(NowListeningConfig::self()->header()))
		return;

	// What will be sent
	QString newBody;

	// Getting the list of contacts the message will be sent to to determine if at least
	// one of them has never gotten the current music information.
	Kopete::ContactPtrList dest = msg.to();
	bool mustSendAnyway = false;
	for( Kopete::Contact *c = dest.first() ; c ; c = dest.next() )
	{
		const QString& cId = c->contactId();
		if( 0 == d->m_musicSentTo.contains( cId ) )
		{
			mustSendAnyway = true;

			// The contact will get the music information so we put it in the list.
			d->m_musicSentTo.push_back( cId );
		}
	}

	bool newTrack = newTrackPlaying();

	// We must send the music information if someone has never gotten it or the track(s)
	// has changed since it was last sent.
	if ( mustSendAnyway || newTrack )
	{
		QString advert = mediaPlayerAdvert(false); // false since newTrackPlaying() did the update
		if( !advert.isEmpty() )
			newBody = originalBody + "<br>" + advert;

		// If we send because the information has changed since it was last sent, we must
		// rebuild the list of contacts the latest information was sent to.
		if( newTrack )
		{
			d->m_musicSentTo.clear();
			for( Kopete::Contact *c = dest.first() ; c ; c = dest.next() )
			{
				d->m_musicSentTo.push_back( c->contactId() );
			}
		}
	}

	// If the body has been modified, change the message
	if( !newBody.isEmpty() )
	{
		msg.setBody( newBody, Kopete::Message::RichText );
 	}
}
Exemplo n.º 8
0
void AIMContact::sendAutoResponse(Kopete::Message& msg)
{
	// The target time is 2 minutes later than the last message
	int delta = m_lastAutoresponseTime.secsTo( QDateTime::currentDateTime() );
	kdDebug(14152) << k_funcinfo << "Last autoresponse time: " << m_lastAutoresponseTime << endl;
	kdDebug(14152) << k_funcinfo << "Current time: " << QDateTime::currentDateTime() << endl;
	kdDebug(14152) << k_funcinfo << "Difference: " << delta << endl;
	// Check to see if we're past that time
	if(delta > 120)
	{
		kdDebug(14152) << k_funcinfo << "Sending auto response" << endl;

		// This code was yoinked straight from OscarContact::slotSendMsg()
		// If only that slot wasn't private, but I'm not gonna change it right now.
		Oscar::Message message;

		if ( m_details.hasCap( CAP_UTF8 ) )
		{
			message.setText( Oscar::Message::UCS2, msg.plainBody() );
		}
		else
		{
			QTextCodec* codec = contactCodec();
			message.setText( Oscar::Message::UserDefined, msg.plainBody(), codec );
		}

		message.setTimestamp( msg.timestamp() );
		message.setSender( mAccount->accountId() );
		message.setReceiver( mName );
		message.setType( 0x01 );

		// isAuto defaults to false
		mAccount->engine()->sendMessage( message, true);
		kdDebug(14152) << k_funcinfo << "Sent auto response" << endl;
		manager(Kopete::Contact::CanCreate)->appendMessage(msg);
		manager(Kopete::Contact::CanCreate)->messageSucceeded();
		// Update the last autoresponse time
		m_lastAutoresponseTime = QDateTime::currentDateTime();
	}
	else
	{
		kdDebug(14152) << k_funcinfo << "Not enough time since last autoresponse, NOT sending" << endl;
	}
}
Exemplo n.º 9
0
void TestbedContact::sendMessage( Kopete::Message &message )
{
    kdDebug( 14210 ) << k_funcinfo << endl;
    // convert to the what the server wants
    // For this 'protocol', there's nothing to do
    // send it
    static_cast<TestbedAccount *>( account() )->server()->sendMessage(
        message.to().first()->contactId(),
        message.plainBody() );
    // give it back to the manager to display
    manager()->appendMessage( message );
    // tell the manager it was sent successfully
    manager()->messageSucceeded();
}
Exemplo n.º 10
0
int MeanwhileSession::sendMessage(Kopete::Message &message)
{
    HERE;
    MeanwhileContact *contact =
        static_cast<MeanwhileContact *>(message.to().first());
    if (!contact) {
        mwDebug() << "No target for message!" <<endl;
        return 0;
    }

    struct mwIdBlock target = { strdup(contact->meanwhileId().toAscii()), 0L };
    struct mwConversation *conv;

    conv = mwServiceIm_getConversation(imService, &target);
    free(target.user);
    if (conv == 0L) {
        mwDebug() << "No target for conversation with '"
            << contact->meanwhileId() << "'" << endl;
        return 0;
    }

    struct ConversationData *convdata = (struct ConversationData *)
        mwConversation_getClientData(conv);

    if (convdata == 0L) {
        convdata = createConversationData(conv, contact, true);
        if (convdata == 0L) {
            mwDebug() << "No memory for conversation data!" << endl;
            return 0;
        }
    }

    /* if there's other messages in the queue, or the conversation isn't open,
     * then append to the queue instead of sending right away */
    if ((convdata->queue && !convdata->queue->isEmpty()) ||
            !mwConversation_isOpen(conv)) {
        convdata->queue->append(message);
        mwConversation_open(conv);

    } else if (!mwConversation_send(conv, mwImSend_PLAIN,
                message.plainBody().toAscii())) {
        convdata->chat->appendMessage(message);
        convdata->chat->messageSucceeded();
    }
    return 1;
}
Exemplo n.º 11
0
void AIMContact::slotSendMsg(Kopete::Message& message, Kopete::ChatSession *)
{
	Oscar::Message msg;
	QString s;

	if (message.plainBody().isEmpty()) // no text, do nothing
		return;
	//okay, now we need to change the message.escapedBody from real HTML to aimhtml.
	//looking right now for docs on that "format".
	//looks like everything except for alignment codes comes in the format of spans

	//font-style:italic -> <i>
	//font-weight:600 -> <b> (anything > 400 should be <b>, 400 is not bold)
	//text-decoration:underline -> <u>
	//font-family: -> <font face="">
	//font-size:xxpt -> <font ptsize=xx>

	s=message.escapedBody();
	s.replace ( QRegExp( QString::fromLatin1("<span style=\"([^\"]*)\">([^<]*)</span>")),
			QString::fromLatin1("<style>\\1;\"\\2</style>"));

	s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)font-style:italic;([^\"]*)\"([^<]*)</style>")),
	            QString::fromLatin1("<i><style>\\1\\2\"\\3</style></i>"));

	s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)font-weight:600;([^\"]*)\"([^<]*)</style>")),
	            QString::fromLatin1("<b><style>\\1\\2\"\\3</style></b>"));

	s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)text-decoration:underline;([^\"]*)\"([^<]*)</style>")),
	            QString::fromLatin1("<u><style>\\1\\2\"\\3</style></u>"));

	s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)font-family:([^;]*);([^\"]*)\"([^<]*)</style>")),
	            QString::fromLatin1("<font face=\"\\2\"><style>\\1\\3\"\\4</style></font>"));

	s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)font-size:([^p]*)pt;([^\"]*)\"([^<]*)</style>")),
				QString::fromLatin1("<font ptsize=\"\\2\"><style>\\1\\3\"\\4</style></font>"));

	s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)color:([^;]*);([^\"]*)\"([^<]*)</style>")),
	            QString::fromLatin1("<font color=\"\\2\"><style>\\1\\3\"\\4</style></font>"));

	s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)\"([^<]*)</style>")),
	            QString::fromLatin1("\\2"));

	//okay now change the <font ptsize="xx"> to <font size="xx">

	//0-9 are size 1
	s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"\\d\">")),
	            QString::fromLatin1("<font size=\"1\">"));
	//10-11 are size 2
	s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"1[01]\">")),
	            QString::fromLatin1("<font size=\"2\">"));
	//12-13 are size 3
	s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"1[23]\">")),
	            QString::fromLatin1("<font size=\"3\">"));
	//14-16 are size 4
	s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"1[456]\">")),
	            QString::fromLatin1("<font size=\"4\">"));
	//17-22 are size 5
	s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"(?:1[789]|2[012])\">")),
	            QString::fromLatin1("<font size=\"5\">"));
	//23-29 are size 6
	s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"2[3456789]\">")),QString::fromLatin1("<font size=\"6\">"));
	//30- (and any I missed) are size 7
	s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"[^\"]*\">")),QString::fromLatin1("<font size=\"7\">"));

	s.replace ( QRegExp ( QString::fromLatin1("<br[ /]*>")), QString::fromLatin1("<br>") );

	// strip left over line break
	s.remove( QRegExp( QString::fromLatin1( "<br>$" ) ) );

	kdDebug(14190) << k_funcinfo << "sending "
		<< s << endl;

	// XXX Need to check for message size?

	if ( m_details.hasCap( CAP_UTF8 ) )
		msg.setText( Oscar::Message::UCS2, s );
	else
		msg.setText( Oscar::Message::UserDefined, s, contactCodec() );

	msg.setReceiver(mName);
	msg.setTimestamp(message.timestamp());
	msg.setType(0x01);

	mAccount->engine()->sendMessage(msg);

	// Show the message we just sent in the chat window
	manager(Kopete::Contact::CanCreate)->appendMessage(message);
	manager(Kopete::Contact::CanCreate)->messageSucceeded();
}
Exemplo n.º 12
0
void TextEffectPlugin::slotOutgoingMessage( Kopete::Message& msg )
{
	if(msg.direction() != Kopete::Message::Outbound)
		return;

	QStringList colors=m_config->colors();

	if(m_config->colorChar() || m_config->colorWords() || m_config->lamer() || m_config->waves() )
	{
		QString original=msg.plainBody();
		QString resultat;

		unsigned int c=0;
		bool wavein=false;

		for(unsigned int f=0;f<original.length();f++)
		{
			QChar x=original[f];
			if(f==0 || m_config->colorChar() || (m_config->colorWords() && x==' ' ))
			{
				if(f!=0)
					resultat+="</font>";
				resultat+="<font color=\"";
				resultat+=colors[c];
				if(m_config->colorRandom())
					c=rand()%colors.count();
				else
				{
					c++;
					if(c >= colors.count())
						c=0;
				}
				resultat+="\">";
			}
			switch (x.latin1())
			{
				case '>':
					resultat+="&gt;";
					break;
				case '<':
					resultat+="&lt;";
					break;
				case '&':
					resultat+="&amp;";
					break;
				case '\n':
					resultat+="<br>";
				case 'a':
				case 'A':
					if(m_config->lamer())
					{
						resultat+="4";
						break;
					} //else, go to the default,  all other case have this check
				case 'e':
				case 'E':
					if(m_config->lamer())
					{
						resultat+="3";
						break;
					}//else, go to the default,  all other case have this check
				case 'i':
				case 'I':
					if(m_config->lamer())
					{
						resultat+="1";
						break;
					}//else, go to the default,  all other case have this check
				case 'l':
				case 'L':
					if(m_config->lamer())
					{
						resultat+="|";
						break;
					}//else, go to the default,  all other case have this check
				case 't':
				case 'T':
					if(m_config->lamer())
					{
						resultat+="7";
						break;
					}//else, go to the default,  all other case have this check
				case 's':
				case 'S':
					if(m_config->lamer())
					{
						resultat+="5";
						break;
					}//else, go to the default,  all other case have this check
				case 'o':
				case 'O':
					if(m_config->lamer())
					{
						resultat+="0";
						break;
					}//else, go to the default,  all other case have this check
				default:
					if(m_config->waves())
					{
						resultat+= wavein ? x.lower() : x.upper();
						wavein=!wavein;
					}
					else
						resultat+=x;
					break;
			}
		}
		if( m_config->colorChar() || m_config->colorWords() )
			resultat+="</font>";
		msg.setBody(resultat,Kopete::Message::RichText);
	}

	if(m_config->colorLines())
	{
		if(m_config->colorRandom())
		{
			last_color=rand()%colors.count();
		}
		else
		{
			last_color++;
			if(last_color >= colors.count())
				last_color=0;
		}

		msg.setFg(QColor (colors[last_color]));
	}
}
void KopeteMessage_Test::testPrimitives()
{
	/**********************************************
	 * from(), to()
	 *********************************************/

	{
		Kopete::Message msg( m_contactFrom, m_contactTo);
		Q_ASSERT(msg.from());
		Q_ASSERT(!msg.to().isEmpty());
	}

	/**********************************************
	 * Direction
	 *********************************************/

	{
		Kopete::Message msg;
		msg.setDirection( Kopete::Message::Inbound );
		QCOMPARE(msg.direction(), Kopete::Message::Inbound);
	}
	{
		Kopete::Message msg;
		msg.setDirection( Kopete::Message::Outbound );
		QCOMPARE(msg.direction(), Kopete::Message::Outbound);
	}
	{
		Kopete::Message msg;
		msg.setDirection( Kopete::Message::Internal );
		QCOMPARE(msg.direction(), Kopete::Message::Internal);
	}

	/**********************************************
	 * Message Format
	 *********************************************/

	{
		Kopete::Message msg;
		msg.setPlainBody( QLatin1String("foobar") );
		QCOMPARE(msg.format(), Qt::PlainText);
	}
	{
		Kopete::Message msg;
		msg.setHtmlBody( QLatin1String("foobar") );
		QCOMPARE(msg.format(), Qt::RichText);
	}
	{
		QString m = "foobar";
		Kopete::Message msg;

		msg.setPlainBody(m);
		QCOMPARE(msg.format(), Qt::PlainText);

		msg.setHtmlBody(m);
		QCOMPARE(msg.format(), Qt::RichText);
	}


	/**********************************************
	 * setBody()
	 *********************************************/

	{
		QString m = "foobar";
		Kopete::Message msg;
		msg.setHtmlBody( m );

		msg.setPlainBody("NEW");
		QCOMPARE(QString("NEW"), msg.plainBody());

		msg.setPlainBody("NEW_NEW");
		QCOMPARE(msg.plainBody(), QString("NEW_NEW"));
	}
	{
		QString m = "foobar";
		Kopete::Message msg;
		msg.setPlainBody( m );

		msg.setPlainBody("NEW");
		QCOMPARE(msg.plainBody(), QString("NEW"));

		msg.setHtmlBody("NEW_NEW");
		QCOMPARE(msg.plainBody(), QString("NEW_NEW"));
	}
	{
		QString m = "<html><head></head><body foo=\"bar\">   <b>HELLO WORLD</b>   </body></html>";
		Kopete::Message msg;
		msg.setPlainBody( m );
		QCOMPARE(msg.plainBody(), m);

		msg.setPlainBody("<simple> SIMPLE");
		QCOMPARE(msg.plainBody(), QString("<simple> SIMPLE"));

		msg.setHtmlBody("<simple>SIMPLE</simple>");
		QCOMPARE(msg.plainBody(),  QString("SIMPLE") );

		QCOMPARE(Kopete::Message::unescape( QString( "<simple>SIMPLE</simple>" ) ), QString("SIMPLE") );
		QCOMPARE(Kopete::Message::unescape( QString( "Foo <img src=\"foo.png\" />" ) ), QString("Foo ") );
		QCOMPARE(Kopete::Message::unescape( QString( "Foo <img src=\"foo.png\" title=\"Bar\" />" ) ), QString("Foo Bar") );

		msg.setHtmlBody(m);

//		QCOMPARE(msg.escapedBody(),           QString(" &nbsp; <b>HELLO WORLD</b> &nbsp; "));
//		QCOMPARE(msg.plainBody(),             QString("   HELLO WORLD   "));
		QCOMPARE(msg.plainBody().trimmed(),   QString("HELLO WORLD"));
//		QCOMPARE(msg.escapedBody().trimmed(), QString("&nbsp; <b>HELLO WORLD</b> &nbsp;"));
	}

	/**********************************************
	 * Copy constructor
	 *********************************************/

	{
		Kopete::Message msg1;
		msg1.setHtmlBody( QLatin1String("foo") );
		Kopete::Message msg2(msg1);

		QCOMPARE(msg1.plainBody(), msg2.plainBody());
		QCOMPARE(msg1.escapedBody(), msg2.escapedBody());

		msg1.setPlainBody("NEW");
		QCOMPARE(msg1.plainBody(), QString("NEW"));
		QCOMPARE(msg2.plainBody(), QString("foo"));
	}

	/**********************************************
	 * operator=
	 *********************************************/

	{
		Kopete::Message msg1;
		msg1.setHtmlBody( QLatin1String("foo") );
		{
			Kopete::Message msg2;

//			QCOMPARE(msg2.plainBody(), QString());

			msg2 = msg1;

			QCOMPARE(msg1.plainBody(), msg2.plainBody());
			QCOMPARE(msg1.escapedBody(), msg2.escapedBody());

			msg1.setPlainBody("NEW");
			QCOMPARE(msg1.plainBody(), QString("NEW"));
			QCOMPARE(msg2.plainBody(), QString("foo"));
		}
		QCOMPARE(msg1.plainBody(), QString("NEW"));

		msg1 = msg1;
		QCOMPARE(msg1.plainBody(), QString("NEW"));
	}
}