2 icqontact.cpp - Oscar Protocol Plugin
4 Copyright (c) 2003 by Stefan Gehn <metz@gehn.net>
5 Copyright (c) 2003 by Olivier Goffart <oggoffart@kde.org>
6 Copyright (c) 2006,2007 by Roman Jarosz <kedgedev@centrum.cz>
8 Kopete (c) 2003-2007 by the Kopete developers <kopete-devel@kde.org>
10 *************************************************************************
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
17 *************************************************************************
20 #include "icqcontact.h"
24 #include <knotification.h>
25 #include <kinputdialog.h>
27 #include <ktoggleaction.h>
30 #include "kopeteuiglobal.h"
31 #include "kopetemetacontact.h"
33 #include "icqprotocol.h"
34 #include "icqaccount.h"
35 #include "icquserinfowidget.h"
36 #include "icqauthreplydialog.h"
38 #include "oscarutils.h"
39 #include "contactmanager.h"
40 #include "oscarstatusmanager.h"
43 ICQContact::ICQContact( Kopete::Account
* account
, const QString
&name
, Kopete::MetaContact
*parent
,
44 const QString
& icon
, const OContact
& ssiItem
)
45 : ICQContactBase( account
, name
, parent
, icon
, ssiItem
)
47 mProtocol
= static_cast<ICQProtocol
*>(protocol());
50 if ( ssiItem
.waitingAuth() )
51 setOnlineStatus( mProtocol
->statusManager()->waitingForAuth() );
53 setPresenceTarget( Oscar::Presence( Oscar::Presence::Offline
) );
55 QObject::connect( mAccount
->engine(), SIGNAL( loggedIn() ), this, SLOT( loggedIn() ) );
56 //QObject::connect( mAccount->engine(), SIGNAL( userIsOnline( const QString& ) ), this, SLOT( userOnline( const QString&, UserDetails ) ) );
57 QObject::connect( mAccount
->engine(), SIGNAL( userIsOffline( const QString
& ) ), this, SLOT( userOffline( const QString
& ) ) );
58 QObject::connect( mAccount
->engine(), SIGNAL( authRequestReceived( const QString
&, const QString
& ) ),
59 this, SLOT( slotGotAuthRequest( const QString
&, const QString
& ) ) );
60 QObject::connect( mAccount
->engine(), SIGNAL( authReplyReceived( const QString
&, const QString
&, bool ) ),
61 this, SLOT( slotGotAuthReply(const QString
&, const QString
&, bool ) ) );
62 QObject::connect( mAccount
->engine(), SIGNAL( receivedIcqLongInfo( const QString
& ) ),
63 this, SLOT( receivedLongInfo( const QString
& ) ) );
64 QObject::connect( mAccount
->engine(), SIGNAL( receivedUserInfo( const QString
&, const UserDetails
& ) ),
65 this, SLOT( userInfoUpdated( const QString
&, const UserDetails
& ) ) );
68 ICQContact::~ICQContact()
73 void ICQContact::updateSSIItem()
75 //kDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << endl;
76 if ( m_ssiItem
.waitingAuth() )
77 setOnlineStatus( mProtocol
->statusManager()->waitingForAuth() );
79 if ( m_ssiItem
.type() != 0xFFFF && m_ssiItem
.waitingAuth() == false &&
80 onlineStatus() == Kopete::OnlineStatus::Unknown
)
82 //make sure they're offline
83 setPresenceTarget( Oscar::Presence( Oscar::Presence::Offline
) );
88 void ICQContact::userInfoUpdated( const QString
& contact
, const UserDetails
& details
)
90 //kDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << contact << contactId() << endl;
91 if ( Oscar::normalize( contact
) != Oscar::normalize( contactId() ) )
94 // invalidate old away message if user was offline
96 removeProperty( mProtocol
->awayMessage
);
98 kDebug( OSCAR_ICQ_DEBUG
) << k_funcinfo
<< "extendedStatus is " << details
.extendedStatus() << endl
;
99 Oscar::Presence presence
= mProtocol
->statusManager()->presenceOf( details
.extendedStatus(), details
.userClass() );
101 if ( details
.xtrazStatusSpecified() )
103 presence
.setFlags( presence
.flags() | Oscar::Presence::XStatus
);
104 presence
.setDescription( i18n("Online") );
105 presence
.setIcon( QString( "icq_xstatus%1" ).arg( details
.xtrazStatus() ) );
107 setPresenceTarget( presence
);
109 Oscar::Presence
selfPres( mProtocol
->statusManager()->presenceOf( account()->myself()->onlineStatus() ) );
110 bool selfVisible
= !(selfPres
.flags() & Oscar::Presence::Invisible
);
111 if ( presence
.type() == Oscar::Presence::Online
)
113 if ( details
.xtrazStatusSpecified() )
116 mAccount
->engine()->addICQAwayMessageRequest( contactId(), Client::ICQXStatus
);
118 mAccount
->engine()->removeICQAwayMessageRequest( contactId() );
122 mAccount
->engine()->removeICQAwayMessageRequest( contactId() );
123 removeProperty( mProtocol
->awayMessage
);
130 switch ( presence
.type() )
132 case Oscar::Presence::Away
:
133 mAccount
->engine()->addICQAwayMessageRequest( contactId(), Client::ICQAway
);
135 case Oscar::Presence::NotAvailable
:
136 mAccount
->engine()->addICQAwayMessageRequest( contactId(), Client::ICQNotAvailable
);
138 case Oscar::Presence::Occupied
:
139 mAccount
->engine()->addICQAwayMessageRequest( contactId(), Client::ICQOccupied
);
141 case Oscar::Presence::DoNotDisturb
:
142 mAccount
->engine()->addICQAwayMessageRequest( contactId(), Client::ICQDoNotDisturb
);
144 case Oscar::Presence::FreeForChat
:
145 mAccount
->engine()->addICQAwayMessageRequest( contactId(), Client::ICQFreeForChat
);
153 mAccount
->engine()->removeICQAwayMessageRequest( contactId() );
158 if ( details
.dcOutsideSpecified() )
160 if ( details
.dcExternalIp().isUnspecified() )
161 removeProperty( mProtocol
->ipAddress
);
163 setProperty( mProtocol
->ipAddress
, details
.dcExternalIp().toString() );
166 if ( details
.capabilitiesSpecified() )
168 if ( details
.clientName().isEmpty() )
169 removeProperty( mProtocol
->clientFeatures
);
171 setProperty( mProtocol
->clientFeatures
, details
.clientName() );
174 OscarContact::userInfoUpdated( contact
, details
);
177 void ICQContact::userOnline( const QString
& userId
)
179 if ( Oscar::normalize( userId
) != Oscar::normalize( contactId() ) )
182 kDebug(OSCAR_ICQ_DEBUG
) << "Setting " << userId
<< " online" << endl
;
183 setPresenceTarget( Oscar::Presence( Oscar::Presence::Online
) );
186 void ICQContact::userOffline( const QString
& userId
)
188 if ( Oscar::normalize( userId
) != Oscar::normalize( contactId() ) )
191 kDebug(OSCAR_ICQ_DEBUG
) << "Setting " << userId
<< " offline" << endl
;
192 if ( m_ssiItem
.waitingAuth() )
193 setOnlineStatus( mProtocol
->statusManager()->waitingForAuth() );
195 setPresenceTarget( Oscar::Presence( Oscar::Presence::Offline
) );
197 removeProperty( mProtocol
->awayMessage
);
200 void ICQContact::loggedIn()
202 if ( metaContact()->isTemporary() )
205 if ( m_ssiItem
.waitingAuth() )
206 setOnlineStatus( mProtocol
->statusManager()->waitingForAuth() );
208 if ( ( ( hasProperty( Kopete::Global::Properties::self()->nickName().key() )
209 && nickName() == contactId() )
210 || !hasProperty( Kopete::Global::Properties::self()->nickName().key() ) )
211 && !m_requestingNickname
&& m_ssiItem
.alias().isEmpty() )
213 m_requestingNickname
= true;
214 int time
= ( KRandom::random() % 20 ) * 1000;
215 kDebug(OSCAR_ICQ_DEBUG
) << k_funcinfo
<< "updating nickname in " << time
/1000 << " seconds" << endl
;
216 QTimer::singleShot( time
, this, SLOT( requestShortInfo() ) );
221 void ICQContact::slotRequestAuth()
223 QString reason
= KInputDialog::getText( i18n("Request Authorization"),
224 i18n("Reason for requesting authorization:") );
225 if ( !reason
.isNull() )
226 mAccount
->engine()->requestAuth( contactId(), reason
);
229 void ICQContact::slotSendAuth()
231 kDebug(OSCAR_ICQ_DEBUG
) << k_funcinfo
<< "Sending auth reply" << endl
;
232 ICQAuthReplyDialog
replyDialog( 0, false );
234 replyDialog
.setUser( property( Kopete::Global::Properties::self()->nickName() ).value().toString() );
235 if ( replyDialog
.exec() )
236 mAccount
->engine()->sendAuth( contactId(), replyDialog
.reason(), replyDialog
.grantAuth() );
239 void ICQContact::slotGotAuthReply( const QString
& contact
, const QString
& reason
, bool granted
)
241 if ( Oscar::normalize( contact
) != Oscar::normalize( contactId() ) )
244 kDebug(OSCAR_ICQ_DEBUG
) << k_funcinfo
<< endl
;
248 message
= i18n( "User %1 has granted your authorization request.\nReason: %2" ,
249 property( Kopete::Global::Properties::self()->nickName() ).value().toString() ,
252 // remove the unknown status
253 setPresenceTarget( Oscar::Presence( Oscar::Presence::Offline
) );
257 message
= i18n( "User %1 has rejected the authorization request.\nReason: %2" ,
258 property( Kopete::Global::Properties::self()->nickName() ).value().toString() ,
261 KNotification::event( QString::fromLatin1("icq_authorization"), message
);
264 void ICQContact::slotGotAuthRequest( const QString
& contact
, const QString
& reason
)
266 if ( Oscar::normalize( contact
) != Oscar::normalize( contactId() ) )
269 ICQAuthReplyDialog
*replyDialog
= new ICQAuthReplyDialog();
271 connect( replyDialog
, SIGNAL( okClicked() ), this, SLOT( slotAuthReplyDialogOkClicked() ) );
272 replyDialog
->setUser( property( Kopete::Global::Properties::self()->nickName() ).value().toString() );
273 replyDialog
->setRequestReason( reason
);
274 replyDialog
->setModal( true );
278 void ICQContact::slotAuthReplyDialogOkClicked()
280 // Do not need to delete will delete itself automatically
281 ICQAuthReplyDialog
*replyDialog
= (ICQAuthReplyDialog
*)sender();
284 mAccount
->engine()->sendAuth( contactId(), replyDialog
->reason(), replyDialog
->grantAuth() );
287 void ICQContact::receivedLongInfo( const QString
& contact
)
289 if ( Oscar::normalize( contact
) != Oscar::normalize( contactId() ) )
292 m_infoWidget
->delayedDestruct();
296 QTextCodec
* codec
= contactCodec();
298 kDebug(OSCAR_ICQ_DEBUG
) << k_funcinfo
<< "received long info from engine" << endl
;
300 ICQGeneralUserInfo genInfo
= mAccount
->engine()->getGeneralInfo( contact
);
301 if ( m_ssiItem
.alias().isEmpty() && !genInfo
.nickName
.get().isEmpty() )
302 setNickName( codec
->toUnicode( genInfo
.nickName
.get() ) );
303 emit
haveBasicInfo( genInfo
);
305 ICQWorkUserInfo workInfo
= mAccount
->engine()->getWorkInfo( contact
);
306 emit
haveWorkInfo( workInfo
);
308 ICQEmailInfo emailInfo
= mAccount
->engine()->getEmailInfo( contact
);
309 emit
haveEmailInfo( emailInfo
);
311 ICQNotesInfo notesInfo
= mAccount
->engine()->getNotesInfo( contact
);
312 emit
haveNotesInfo( notesInfo
);
314 ICQMoreUserInfo moreInfo
= mAccount
->engine()->getMoreInfo( contact
);
315 emit
haveMoreInfo( moreInfo
);
317 ICQInterestInfo interestInfo
= mAccount
->engine()->getInterestInfo( contact
);
318 emit
haveInterestInfo( interestInfo
);
320 ICQOrgAffInfo orgAffInfo
= mAccount
->engine()->getOrgAffInfo( contact
);
321 emit
haveOrgAffInfo( orgAffInfo
);
325 void ICQContact::slotContactChanged(const UserInfo
&u
)
327 if (u
.sn
!= contactName())
330 // update mInfo and general stuff from OscarContact
331 slotParseUserInfo(u
);
333 /*kDebug(14190) << k_funcinfo << "Called for '"
334 << displayName() << "', contactName()=" << contactName() << endl;*/
336 // Append client name and version in case we found one
337 if (!mInfo
.clientName
.isEmpty())
339 if (!mInfo
.clientVersion
.isEmpty())
341 capList
<< i18nc("Translators: client-name client-version",
342 "%1 %2", mInfo
.clientName
, mInfo
.clientVersion
);
346 capList
<< mInfo
.clientName
;
349 // and now for some general informative capabilities
350 if (hasCap(CAP_UTF8
))
351 capList
<< i18n("UTF-8");
352 if (hasCap(CAP_RTFMSGS
))
353 capList
<< i18n("RTF-Messages");
354 if (hasCap(CAP_IMIMAGE
))
355 capList
<< i18n("DirectIM/IMImage");
356 if (hasCap(CAP_CHAT
))
357 capList
<< i18n("Groupchat");
359 if (capList
.count() > 0)
360 setProperty(mProtocol
->clientFeatures
, capList
.join(", "));
362 removeProperty(mProtocol
->clientFeatures
);
364 unsigned int newStatus
= 0;
365 mInvisible
= (mInfo
.icqextstatus
& ICQ_STATUS_IS_INVIS
);
367 if (mInfo
.icqextstatus
& ICQ_STATUS_IS_FFC
)
368 newStatus
= OSCAR_FFC
;
369 else if (mInfo
.icqextstatus
& ICQ_STATUS_IS_DND
)
370 newStatus
= OSCAR_DND
;
371 else if (mInfo
.icqextstatus
& ICQ_STATUS_IS_OCC
)
372 newStatus
= OSCAR_OCC
;
373 else if (mInfo
.icqextstatus
& ICQ_STATUS_IS_NA
)
374 newStatus
= OSCAR_NA
;
375 else if (mInfo
.icqextstatus
& ICQ_STATUS_IS_AWAY
)
376 newStatus
= OSCAR_AWAY
;
378 newStatus
= OSCAR_ONLINE
;
380 if (this != account()->myself())
382 if(newStatus
!= onlineStatus().internalStatus())
384 if(newStatus
!= OSCAR_ONLINE
) // if user changed to some state other than online
386 mAccount
->engine()->requestAwayMessage(this);
388 else // user changed to "Online" status and has no away message anymore
390 removeProperty(mProtocol
->awayMessage
);
395 setStatus(newStatus
);
398 void ICQContact::slotOffgoingBuddy(QString sender
)
400 if(sender
!= contactName())
403 removeProperty(mProtocol
->clientFeatures
);
404 removeProperty(mProtocol
->awayMessage
);
405 setOnlineStatus(mProtocol
->statusOffline
);
408 void ICQContact::gotIM(OscarSocket::OscarMessageType
/*type*/, const QString
&message
)
410 // Build a Kopete::Message and set the body as Rich Text
411 Kopete::ContactPtrList tmpList
;
412 tmpList
.append(account()->myself());
413 Kopete::Message
msg(this, tmpList
, message
, Kopete::Message::Inbound
,
414 Kopete::Message::RichText
);
415 manager(true)->appendMessage(msg
);
419 void ICQContact::slotSendMsg(Kopete::Message
& message
, Kopete::ChatSession
*)
421 if (message
.plainBody().isEmpty()) // no text, do nothing
424 // Check to see if we're even online
425 if(!account()->isConnected())
427 KMessageBox::sorry(Kopete::UI::Global::mainWidget(),
428 i18n("<qt>You must be logged on to ICQ before you can "
429 "send a message to a user.</qt>"),
430 i18n("Not Signed On"));
434 // FIXME: We don't do HTML in ICQ
435 // we might be able to do that in AIM and we might also convert
436 // HTML to RTF for ICQ type-2 messages [mETz]
437 static_cast<OscarAccount
*>(account())->engine()->sendIM(
438 message
.plainBody(), this, false);
440 // Show the message we just sent in the chat window
441 manager(Kopete::Contact::CanCreate
)->appendMessage(message
);
442 manager(Kopete::Contact::CanCreate
)->messageSucceeded();
447 bool ICQContact::isReachable()
449 return account()->isConnected();
452 QList
<KAction
*> *ICQContact::customContextMenuActions()
454 QList
<KAction
*> *actionCollection
= new QList
<KAction
*>();
456 actionRequestAuth
= new KAction( i18n("&Request Authorization"), this );
457 //, "actionRequestAuth");
458 actionRequestAuth
->setIcon( KIcon( "mail_reply" ) );
459 QObject::connect( actionRequestAuth
, SIGNAL(triggered(bool)), this, SLOT(slotRequestAuth()) );
461 actionSendAuth
= new KAction( i18n("&Grant Authorization"), this );
462 //, "actionSendAuth");
463 actionSendAuth
->setIcon( KIcon( "mail_forward" ) );
464 QObject::connect( actionSendAuth
, SIGNAL(triggered(bool)), this, SLOT(slotSendAuth()) );
466 m_actionIgnore
= new KToggleAction(i18n("&Ignore"), this );
468 QObject::connect( m_actionIgnore
, SIGNAL(triggered(bool)), this, SLOT(slotIgnore()) );
470 m_actionVisibleTo
= new KToggleAction(i18n("Always &Visible To"), this );
471 //, "actionVisibleTo");
472 QObject::connect( m_actionVisibleTo
, SIGNAL(triggered(bool)), this, SLOT(slotVisibleTo()) );
474 m_actionInvisibleTo
= new KToggleAction(i18n("Always &Invisible To"), this );
475 //, "actionInvisibleTo");
476 QObject::connect( m_actionInvisibleTo
, SIGNAL(triggered(bool)), this, SLOT(slotInvisibleTo()) );
478 m_selectEncoding
= new KAction( i18n( "Select Encoding..." ), this );
479 //, "changeEncoding" );
480 m_selectEncoding
->setIcon( KIcon( "charset" ) );
481 QObject::connect( m_selectEncoding
, SIGNAL(triggered(bool)), this, SLOT(changeContactEncoding()) );
483 bool on
= account()->isConnected();
484 if ( m_ssiItem
.waitingAuth() )
485 actionRequestAuth
->setEnabled(on
);
487 actionRequestAuth
->setEnabled(false);
489 actionSendAuth
->setEnabled(on
);
490 m_actionIgnore
->setEnabled(on
);
491 m_actionVisibleTo
->setEnabled(on
);
492 m_actionInvisibleTo
->setEnabled(on
);
494 ContactManager
* ssi
= account()->engine()->ssiManager();
495 m_actionIgnore
->setChecked( ssi
->findItem( m_ssiItem
.name(), ROSTER_IGNORE
));
496 m_actionVisibleTo
->setChecked( ssi
->findItem( m_ssiItem
.name(), ROSTER_VISIBLE
));
497 m_actionInvisibleTo
->setChecked( ssi
->findItem( m_ssiItem
.name(), ROSTER_INVISIBLE
));
499 actionCollection
->append(actionRequestAuth
);
500 actionCollection
->append(actionSendAuth
);
501 actionCollection
->append( m_selectEncoding
);
503 actionCollection
->append(m_actionIgnore
);
504 actionCollection
->append(m_actionVisibleTo
);
505 actionCollection
->append(m_actionInvisibleTo
);
507 return actionCollection
;
511 void ICQContact::slotUserInfo()
513 m_infoWidget
= new ICQUserInfoWidget( Kopete::UI::Global::mainWidget() );
514 QObject::connect( m_infoWidget
, SIGNAL( finished() ), this, SLOT( closeUserInfoDialog() ) );
515 m_infoWidget
->setContact( this );
516 m_infoWidget
->show();
517 if ( account()->isConnected() )
518 mAccount
->engine()->requestFullInfo( contactId() );
521 void ICQContact::closeUserInfoDialog()
523 QObject::disconnect( this, 0, m_infoWidget
, 0 );
524 m_infoWidget
->delayedDestruct();
528 void ICQContact::slotIgnore()
530 account()->engine()->setIgnore( contactId(), m_actionIgnore
->isChecked() );
533 void ICQContact::slotVisibleTo()
535 account()->engine()->setVisibleTo( contactId(), m_actionVisibleTo
->isChecked() );
538 void ICQContact::slotInvisibleTo()
540 account()->engine()->setInvisibleTo( contactId(), m_actionInvisibleTo
->isChecked() );
545 void ICQContact::slotReadAwayMessage()
547 kDebug(14153) << k_funcinfo
<< "account='" << account()->accountId() <<
548 "', contact='" << displayName() << "'" << endl
;
550 if (!awayMessageDialog
)
552 awayMessageDialog
= new ICQReadAway(this, 0L, "awayMessageDialog");
553 if(!awayMessageDialog
)
555 QObject::connect(awayMessageDialog
, SIGNAL(closing()), this, SLOT(slotCloseAwayMessageDialog()));
556 awayMessageDialog
->show();
560 awayMessageDialog
->raise();
565 void ICQContact::slotCloseAwayMessageDialog()
567 awayMessageDialog
->delayedDestruct();
568 awayMessageDialog
= 0L;
572 const QString
ICQContact::awayMessage()
574 kDebug(14150) << k_funcinfo
<< property(mProtocol
->awayMessage
).value().toString() << endl
;
575 return property(mProtocol
->awayMessage
).value().toString();
579 void ICQContact::setAwayMessage(const QString
&message
)
581 /*kDebug(14150) << k_funcinfo <<
582 "Called for '" << displayName() << "', away msg='" << message << "'" << endl;*/
583 setProperty(mProtocol
->awayMessage
, message
);
584 emit
awayMessageChanged();
588 void ICQContact::slotUpdGeneralInfo(const int seq
, const ICQGeneralUserInfo
&inf
)
590 // compare reply's sequence with the one we sent with our last request
591 if(seq
!= userinfoRequestSequence
)
595 if(!generalInfo
.firstName
.isEmpty())
596 setProperty(mProtocol
->firstName
, generalInfo
.firstName
);
598 removeProperty(mProtocol
->firstName
);
600 if(!generalInfo
.lastName
.isEmpty())
601 setProperty(mProtocol
->lastName
, generalInfo
.lastName
);
603 removeProperty(mProtocol
->lastName
);
605 if(!generalInfo
.eMail
.isEmpty())
606 setProperty(mProtocol
->emailAddress
, generalInfo
.eMail
);
608 removeProperty(mProtocol
->emailAddress
);
610 if(!generalInfo.phoneNumber.isEmpty())
611 setProperty("privPhoneNum", generalInfo.phoneNumber);
613 removeProperty("privPhoneNum");
615 if(!generalInfo.faxNumber.isEmpty())
616 setProperty("privFaxNum", generalInfo.faxNumber);
618 removeProperty("privFaxNum");
620 if(!generalInfo.cellularNumber.isEmpty())
621 setProperty("privMobileNum", generalInfo.cellularNumber);
623 removeProperty("privMobileNum");
626 if(contactName() == displayName() && !generalInfo
.nickName
.isEmpty())
628 kDebug(14153) << k_funcinfo
<< "setting new displayname for former UIN-only Contact" << endl
;
629 setDisplayName(generalInfo
.nickName
);
632 incUserInfoCounter();
636 void ICQContact::slotSnacFailed(WORD snacID
)
638 if (userinfoRequestSequence
!= 0)
639 kDebug(14153) << k_funcinfo
<< "snacID = " << snacID
<< " seq = " << userinfoRequestSequence
<< endl
;
641 //TODO: ugly interaction between snacID and request sequence, see OscarSocket::sendCLI_TOICQSRV
642 if (snacID
== (0x0000 << 16) | userinfoRequestSequence
)
644 userinfoRequestSequence
= 0;
645 emit
userInfoRequestFailed();
649 void ICQContact::slotIgnore()
651 kDebug(14150) << k_funcinfo
<<
652 "Called; ignore = " << actionIgnore
->isChecked() << endl
;
653 setIgnore(actionIgnore
->isChecked(), true);
656 void ICQContact::slotVisibleTo()
658 kDebug(14150) << k_funcinfo
<<
659 "Called; visible = " << actionVisibleTo
->isChecked() << endl
;
660 setVisibleTo(actionVisibleTo
->isChecked(), true);
663 #include "icqcontact.moc"
664 //kate: indent-mode csands; tab-width 4; replace-tabs off; space-indent off;