1 /*
2 icqontact.cpp - Oscar Protocol Plugin
3
4 Copyright (c) 2003 by Stefan Gehn <metz@gehn.net>
5 Copyright (c) 2003 by Olivier Goffart <ogoffart@kde.org>
6 Copyright (c) 2006,2007 by Roman Jarosz <kedgedev@centrum.cz>
7
8 Kopete (c) 2003-2007 by the Kopete developers <kopete-devel@kde.org>
9
10 *************************************************************************
11 * *
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. *
16 * *
17 *************************************************************************
18 */
19
20 #include "icqcontact.h"
21
22 #include <qtimer.h>
23
24 #include <KActionCollection>
25 #include <KLocalizedString>
26 #include <krandom.h>
27 #include <ktoggleaction.h>
28
29 #include "kopetemetacontact.h"
30
31 #include "aimprotocol.h"
32 #include "aimaccount.h"
33
34 #include "oscarutils.h"
35 #include "contactmanager.h"
36 #include "oscarstatusmanager.h"
37
ICQContact(Kopete::Account * account,const QString & name,Kopete::MetaContact * parent,const QString & icon)38 ICQContact::ICQContact( Kopete::Account* account, const QString &name, Kopete::MetaContact *parent,
39 const QString& icon )
40 : ICQContactBase( account, name, parent, icon )
41 {
42 mProtocol = static_cast<AIMProtocol *>(protocol());
43
44 setPresenceTarget( Oscar::Presence( Oscar::Presence::Offline, Oscar::Presence::ICQ ) );
45
46 QObject::connect( mAccount->engine(), SIGNAL(loggedIn()), this, SLOT(loggedIn()) );
47 //QObject::connect( mAccount->engine(), SIGNAL(userIsOnline(QString)), this, SLOT(userOnline(QString,UserDetails)) );
48 QObject::connect( mAccount->engine(), SIGNAL(userIsOffline(QString)), this, SLOT(userOffline(QString)) );
49 QObject::connect( mAccount->engine(), SIGNAL(receivedUserInfo(QString,UserDetails)),
50 this, SLOT(userInfoUpdated(QString,UserDetails)) );
51 }
52
~ICQContact()53 ICQContact::~ICQContact()
54 {
55 }
56
setSSIItem(const OContact & ssiItem)57 void ICQContact::setSSIItem( const OContact& ssiItem )
58 {
59 if ( ssiItem.waitingAuth() )
60 setOnlineStatus( mProtocol->statusManager()->waitingForAuth() );
61
62 if ( ssiItem.type() != 0xFFFF && ssiItem.waitingAuth() == false &&
63 onlineStatus().status() == Kopete::OnlineStatus::Unknown )
64 {
65 //make sure they're offline
66 setPresenceTarget( Oscar::Presence( Oscar::Presence::Offline, Oscar::Presence::ICQ ) );
67 }
68
69 ICQContactBase::setSSIItem( ssiItem );
70 }
71
userInfoUpdated(const QString & contact,const UserDetails & details)72 void ICQContact::userInfoUpdated( const QString& contact, const UserDetails& details )
73 {
74 //kDebug(OSCAR_AIM_DEBUG) << contact << contactId();
75 if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) )
76 return;
77
78 // invalidate old away message if user was offline
79 if ( !isOnline() )
80 removeProperty( mProtocol->statusMessage );
81
82 kDebug( OSCAR_AIM_DEBUG ) << "extendedStatus is " << details.extendedStatus();
83 Oscar::Presence presence = mProtocol->statusManager()->presenceOf( details.extendedStatus(), details.userClass() );
84 setPresenceTarget( presence );
85
86 setAwayMessage( details.personalMessage() );
87 if ( presence.type() != Oscar::Presence::Online && m_details.awaySinceTime() < details.awaySinceTime() ) //prevent cyclic away message requests
88 {
89 mAccount->engine()->requestAIMAwayMessage( contactId() );
90 }
91
92 //TODO: don't know if we need this in aim
93 // if ( details.dcOutsideSpecified() )
94 // {
95 // if ( details.dcExternalIp().isUnspecified() )
96 // removeProperty( mProtocol->ipAddress );
97 // else
98 // setProperty( mProtocol->ipAddress, details.dcExternalIp().toString() );
99 // }
100
101 if ( details.capabilitiesSpecified() )
102 setProperty( mProtocol->clientFeatures, details.clientName() );
103
104 OscarContact::userInfoUpdated( contact, details );
105 }
106
userOnline(const QString & userId)107 void ICQContact::userOnline( const QString& userId )
108 {
109 if ( Oscar::normalize( userId ) != Oscar::normalize( contactId() ) )
110 return;
111
112 kDebug(OSCAR_AIM_DEBUG) << "Setting " << userId << " online";
113 setPresenceTarget( Oscar::Presence( Oscar::Presence::Online, Oscar::Presence::ICQ ) );
114 }
115
userOffline(const QString & userId)116 void ICQContact::userOffline( const QString& userId )
117 {
118 if ( Oscar::normalize( userId ) != Oscar::normalize( contactId() ) )
119 return;
120
121 m_details.clear();
122
123 kDebug(OSCAR_AIM_DEBUG) << "Setting " << userId << " offline";
124 if ( m_ssiItem.waitingAuth() )
125 setOnlineStatus( mProtocol->statusManager()->waitingForAuth() );
126 else
127 setPresenceTarget( Oscar::Presence( Oscar::Presence::Offline, Oscar::Presence::ICQ ) );
128
129 removeProperty( mProtocol->statusMessage );
130 }
131
loggedIn()132 void ICQContact::loggedIn()
133 {
134 if ( metaContact()->isTemporary() )
135 return;
136
137 if ( m_ssiItem.waitingAuth() )
138 setOnlineStatus( mProtocol->statusManager()->waitingForAuth() );
139 }
140
isReachable()141 bool ICQContact::isReachable()
142 {
143 return true;
144 }
145
customContextMenuActions()146 QList<QAction*> *ICQContact::customContextMenuActions()
147 {
148 QList<QAction*> *actions = new QList<QAction*>();
149
150 m_actionVisibleTo = new KToggleAction(i18n("Always &Visible To"), this );
151 //, "actionVisibleTo");
152 QObject::connect(m_actionVisibleTo, &KToggleAction::triggered, this, &ICQContact::slotVisibleTo);
153
154 m_actionInvisibleTo = new KToggleAction(i18n("Always &Invisible To"), this );
155 //, "actionInvisibleTo");
156 QObject::connect(m_actionInvisibleTo, &KToggleAction::triggered, this, &ICQContact::slotInvisibleTo);
157
158 bool on = account()->isConnected();
159
160 m_actionVisibleTo->setEnabled(on);
161 m_actionInvisibleTo->setEnabled(on);
162
163 ContactManager* ssi = account()->engine()->ssiManager();
164 m_actionVisibleTo->setChecked( ssi->findItem( m_ssiItem.name(), ROSTER_VISIBLE ));
165 m_actionInvisibleTo->setChecked( ssi->findItem( m_ssiItem.name(), ROSTER_INVISIBLE ));
166
167 actions->append(m_actionVisibleTo);
168 actions->append(m_actionInvisibleTo);
169
170 // temporary action collection, used to apply Kiosk policy to the actions
171 KActionCollection tempCollection((QObject*)0);
172 tempCollection.addAction(QLatin1String("oscarContactAlwaysVisibleTo"), m_actionVisibleTo);
173 tempCollection.addAction(QLatin1String("oscarContactAlwaysInvisibleTo"), m_actionInvisibleTo);
174
175 return actions;
176 }
177
slotVisibleTo()178 void ICQContact::slotVisibleTo()
179 {
180 account()->engine()->setVisibleTo( contactId(), m_actionVisibleTo->isChecked() );
181 }
182
slotInvisibleTo()183 void ICQContact::slotInvisibleTo()
184 {
185 account()->engine()->setInvisibleTo( contactId(), m_actionInvisibleTo->isChecked() );
186 }
187
188