2 irccontact.cpp - IRC Contact
4 Copyright (c) 2002 by Nick Betcher <nbetcher@kde.org>
5 Copyright (c) 2004-2007 by Michel Hermier <michel.hermier@gmail.com>
7 Kopete (c) 2002-2007 by the Kopete developers <kopete-devel@kde.org>
9 *************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 *************************************************************************
19 #include "irccontact.moc"
21 #include "ircaccount.h"
22 #include "ircprotocol.h"
25 #include "kircclientsocket.h"
26 #include "kircentity.h"
28 #include "kopetechatsessionmanager.h"
29 #include "kopeteglobal.h"
30 #include "kopeteuiglobal.h"
31 #include "kopetemetacontact.h"
32 #include "kopeteview.h"
39 #include <qtextcodec.h>
42 using namespace Kopete
;
44 class IRCContact::Private
47 KIrc::Entity::Ptr entity
;
49 QMap
<ChatSessionType
, ChatSession
*> chatSessions
;
51 // QList<IRContact *> members;
53 // QList<Kopete::Contact *> mMyself;
54 Kopete::Message::MessageDirection execDir
;
56 QList
<KAction
*> actions
;
57 QList
<KAction
*> serverActions
;
58 QList
<KAction
*> channelActions
;
59 QList
<KAction
*> userActions
;
62 IRCContact::IRCContact(IRCAccount
*account
, const KIrc::Entity::Ptr
&entity
, MetaContact
*metac
, const QString
& icon
)
63 : Contact(account
, entity
->name(), metac
, icon
)
64 , d (new IRCContact::Private
)
68 kDebug(14120) << entity
->name();
74 metac
= new MetaContact();
75 metac
->setTemporary(true);
76 setMetaContact(metac
);
79 KIrc::ClientSocket
*client
= kircClient();
81 // ChatSessionManager stuff
82 // mMyself.append( static_cast<Contact*>( this ) );
85 connect(client
, SIGNAL(connectionStateChanged(KIrc::ConnectionState
)),
86 this, SLOT(updateStatus()));
88 connect(entity, SIGNAL(updated()),
89 this, SLOT(entityUpdated()));
94 IRCContact::~IRCContact()
96 // kDebug(14120) << entity->name();
97 // if (metaContact() && metaContact()->isTemporary() && !isChatting(m_chatSession))
98 // metaContact()->deleteLater();
100 emit
destroyed(this);
105 void IRCContact::deleteContact()
107 // delete m_chatSession; // qDeleteAll(d->chatSessions) ?
111 Contact::deleteContact();
115 metaContact()->removeContact(this);
116 MetaContact
*m
= new MetaContact();
117 m
->setTemporary(true);
122 IRCAccount
*IRCContact::ircAccount() const
124 return static_cast<IRCAccount
*>(account());
127 KIrc::ClientSocket
*IRCContact::kircClient() const
129 return ircAccount()->client();
132 void IRCContact::entityUpdated()
134 Global::Properties
*prop
= Global::Properties::self();
136 // Basic entity properties.
137 setProperty(prop
->nickName(), d
->entity
->name());
138 // setProperty(???->serverName(), d->entity->server());
139 // setProperty(???->type(), d->entity->type());
143 // Channel properties
144 // setProperty(???->topic(), d->entity->topic());
146 // Contact properties
148 // Update Icon properties
149 switch(m_entity->type())
151 // case KIrc::Entity::Unknown: // Use default
152 case KIrc::Entity::Server:
153 setIcon("irc_server");
155 case KIrc::Entity::Channel:
156 setIcon("irc_channel");
158 // case KIrc::Entity::Service: // Use default for now
159 // setIcon("irc_service");
161 case KIrc::Entity::User:
165 // setIcon("irc_unknown");
166 setIcon(QString::null); //krazy:exclude=nullstrassign for old broken gcc
173 QString
IRCContact::caption() const
176 QString caption = QString::fromLatin1("%1 @ %2")
177 .arg(d->entity->name()) // nickName
178 .arg(ircAccount()->networkName());
180 QString topic = d->entity->topic();
182 caption.append( QString::fromLatin1(" - %1").arg(Kopete::Message::unescape(topic)) );
186 return QLatin1String("FIXME");
189 void IRCContact::updateStatus()
191 setOnlineStatus(IRCProtocol::self()->onlineStatusFor(d
->entity
));
194 bool IRCContact::isReachable()
196 if (onlineStatus().status() != OnlineStatus::Offline
&&
197 onlineStatus().status() != OnlineStatus::Unknown
)
203 void IRCContact::setCodec(QTextCodec
*codec
)
205 d
->entity
->setCodec(codec
);
207 metaContact()->setPluginData(IRCProtocol::self(), QString::fromLatin1("Codec"), QString::number(codec
->mibEnum()));
209 // metaContact()->removePluginData(m_protocol, QString::fromLatin1("Codec"));
212 QTextCodec
*IRCContact::codec()
214 QString codecId
= metaContact()->pluginData(IRCProtocol::self(), QString::fromLatin1("Codec"));
215 QTextCodec
*codec
= ircAccount()->codec();
217 if( !codecId
.isEmpty() )
220 uint mib
= codecId
.toInt(&test
);
222 codec
= QTextCodec::codecForMib(mib
);
224 codec
= QTextCodec::codecForName(codecId
.toLatin1());
228 // FIXME: use context defaultCodec
230 return kircClient()->defaultCodec();
236 ChatSession
*IRCContact::manager(CanCreateFlags create
)
238 return chatSession(IRC::SERVER
, create
);
241 ChatSession
*IRCContact::chatSession(IRC::ChatSessionType type
, CanCreateFlags create
)
243 IRCAccount
*account
= ircAccount();
244 KIrc::ClientSocket
*engine
= kircClient();
246 Kopete::ChatSession *chatSession = d->chatSessions.get();
249 // if (engine->status() == KIrc::ClientSocket::Idle && dynamic_cast<IRCServerContact*>(this) == 0)
250 // account->connect();
252 chatSession = ChatSessionManager::self()->create(account->myself(), mMyself, account->protocol());
253 chatSession->setDisplayName(caption());
255 connect(chatSession, SIGNAL(messageSent(Message&, ChatSession *)),
256 this, SLOT(slotSendMsg(Message&, ChatSession *)));
257 connect(chatSession, SIGNAL(closing(ChatSession *)),
258 this, SLOT(chatSessionDestroyed(ChatSession *)));
260 d->chatSessions.add(type, chatSession);
268 void IRCContact::chatSessionDestroyed(ChatSession
*chatSession
)
270 // m_chatSession = 0; // d->chatSessions.remove(chatSession);
272 if (metaContact()->isTemporary() && !isChatting())
276 void IRCContact::slotSendMsg(Message
&message
, ChatSession
*chatSession
)
278 QString htmlString
= message
.escapedBody();
280 if (htmlString
.indexOf(QString::fromLatin1("</span")) > -1)
282 QRegExp
findTags( QString::fromLatin1("<span style=\"(.*)\">(.*)</span>") );
283 findTags
.setMinimal( true );
288 pos
= findTags
.indexIn(htmlString
);
291 QString styleHTML
= findTags
.cap(1);
292 QString replacement
= findTags
.cap(2);
293 QStringList styleAttrs
= styleHTML
.split(';');
295 for (QStringList::Iterator attrPair
= styleAttrs
.begin(); attrPair
!= styleAttrs
.end(); ++attrPair
)
297 QString attribute
= (*attrPair
).section(':',0,0);
298 QString value
= (*attrPair
).section(':',1);
300 if( attribute
== QString::fromLatin1("color") )
302 int ircColor
= KSParser::colorForHTML( value
);
304 replacement
.prepend( QString( QChar(0x03) ).append( QString::number(ircColor
) ) ).append( QChar( 0x03 ) );
306 else if( attribute
== QString::fromLatin1("font-weight") && value
== QString::fromLatin1("600") )
307 replacement
.prepend( QChar(0x02) ).append( QChar(0x02) );
308 else if( attribute
== QString::fromLatin1("text-decoration") && value
== QString::fromLatin1("underline") )
309 replacement
.prepend( QChar(31) ).append( QChar(31) );
312 htmlString
= htmlString
.left( pos
) + replacement
+ htmlString
.mid( pos
+ findTags
.matchedLength() );
317 htmlString
= Message::unescape(htmlString
);
319 if (htmlString
.indexOf('\n') > -1)
321 QStringList messages
= htmlString
.split('\n');
323 for( QStringList::Iterator it
= messages
.begin(); it
!= messages
.end(); ++it
)
326 Message
msg(message
.from(), message
.to());
327 msg
.setHtmlBody(Kopete::Message::escape(sendMessage(*it
)));
328 msg
.setDirection(message
.direction());
329 // Message::RichText, CHAT_VIEW, message.type());
331 // msg.setBackgroundColor(QColor());
332 // msg.setForegroundColor(QColor());
335 chatSession
->messageSucceeded();
340 message
.setHtmlBody(Kopete::Message::escape(sendMessage(htmlString
)));
342 // message.setBackgroundColor(QColor());
343 // message.setForegroundColor(QColor());
345 appendMessage(message
);
346 chatSession
->messageSucceeded();
350 QString
IRCContact::sendMessage(const QString
&msg
)
353 QString newMessage = msg;
354 uint trueLength = msg.length() + m_nickName.length() + 12;
355 if( trueLength > 512 )
357 //TODO: tell them it is truncated
358 kWarning() << "Message was to long (" << trueLength << "), it has been truncated to 512 characters";
359 newMessage.truncate( 512 - ( m_nickName.length() + 12 ) );
362 kircClient()->privmsg(m_nickName, newMessage );
369 Contact
*IRCContact::locateUser(const QString
&nick
)
372 IRCAccount *account = ircAccount();
376 if( nick == account->mySelf()->nickName() )
377 return account->mySelf();
380 ContactPtrList mMembers = m_chatSession->members();
381 for (Contact *it = mMembers.first(); it; it = mMembers.next())
383 if (static_cast<IRCContact*>(it)->nickName() == nick)
392 bool IRCContact::isChatting(ChatSession
*avoid
) const
394 IRCAccount
*account
= ircAccount();
399 foreach (ChatSession
*chatSession
, ChatSessionManager::self()->sessions())
402 if( chatSession != avoid &&
403 chatSession->account() == account &&
404 chatSession->members().contains(this) )
413 void IRCContact::appendMessage(Message
&msg
)
415 // manager(Contact::CanCreate)->appendMessage(msg);
418 void IRCServerContact::appendMessage(Kopete::Message &msg)
420 msg.setImportance( Kopete::Message::Low ); //to don't distrub the user
422 if (m_chatSession && m_chatSession->view(false))
423 m_chatSession->appendMessage(msg);
425 mMsgBuffer.append( msg );
429 void IRCContact::serialize(QMap
<QString
, QString
> & /*serializedData*/, QMap
<QString
, QString
> &addressBookData
)
431 addressBookData
[protocol()->addressBookIndexField()] = contactId() + QChar(0xE120) + account()->accountId();