• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdenetwork API Reference
  • KDE Home
  • Contact Us
 

kopete/libkopete

  • sources
  • kde-4.12
  • kdenetwork
  • kopete
  • libkopete
kopeteprotocol.cpp
Go to the documentation of this file.
1 /*
2  kopeteprotocol.cpp - Kopete Protocol
3 
4  Copyright (c) 2002 by Duncan Mac-Vicar Prett <duncan@kde.org>
5  Copyright (c) 2002-2003 by Martijn Klingens <klingens@kde.org>
6  Copyright (c) 2002-2005 by Olivier Goffart <ogoffart@kde.org>
7 
8  Kopete (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org>
9 
10  *************************************************************************
11  * *
12  * This library is free software; you can redistribute it and/or *
13  * modify it under the terms of the GNU Lesser General Public *
14  * License as published by the Free Software Foundation; either *
15  * version 2 of the License, or (at your option) any later version. *
16  * *
17  *************************************************************************
18 */
19 
20 #include "kopeteprotocol.h"
21 
22 #include <kdebug.h>
23 #include <kaction.h>
24 #include <klocale.h>
25 #include <kjob.h>
26 
27 #include "kopeteaccountmanager.h"
28 #include "kopeteaccount.h"
29 #include "kopetecontact.h"
30 #include "kopeteglobal.h"
31 #include "kopeteproperty.h"
32 #include "kopetemetacontact.h"
33 
34 namespace Kopete
35 {
36 
37 class Protocol::Private
38 {
39 public:
40  bool unloading;
41  Protocol::Capabilities capabilities;
42  bool canAddMyself;
43  /*
44  * Make sure we always have a lastSeen and a fullname property as long as
45  * a protocol is loaded
46  */
47  PropertyTmpl mStickLastSeen;
48  PropertyTmpl mStickFullName;
49 
50  Kopete::OnlineStatus accountNotConnectedStatus;
51 };
52 
53 Protocol::Protocol( const KComponentData &instance, QObject *parent, bool canAddMyself )
54 : Plugin( instance, parent ), d(new Private())
55 {
56  d->canAddMyself = canAddMyself;
57  d->mStickLastSeen = Global::Properties::self()->lastSeen();
58  d->mStickFullName = Global::Properties::self()->fullName();
59  d->unloading = false;
60  d->accountNotConnectedStatus = Kopete::OnlineStatus( Kopete::OnlineStatus::Unknown, 0, this, Kopete::OnlineStatus::AccountOffline, QStringList(QString::fromLatin1( "account_offline_overlay" )), i18n( "Account Offline" ) );
61 }
62 
63 Protocol::~Protocol()
64 {
65  // Remove all active accounts
66  foreach( Account *a , AccountManager::self()->accounts() )
67  {
68  if( a->protocol() == this )
69  {
70  kWarning( 14010 ) << "Deleting protocol with existing accounts! Did the account unloading go wrong? account: "
71  << a->accountId() << endl;
72 
73  delete a;
74  }
75  }
76  delete d;
77 }
78 
79 Protocol::Capabilities Protocol::capabilities() const
80 {
81  return d->capabilities;
82 }
83 
84 void Protocol::setCapabilities( Protocol::Capabilities capabilities )
85 {
86  d->capabilities = capabilities;
87 }
88 
89 bool Protocol::canAddMyself() const
90 {
91  return d->canAddMyself;
92 }
93 
94 Kopete::OnlineStatus Protocol::accountOfflineStatus() const
95 {
96  return d->accountNotConnectedStatus;
97 }
98 
99 void Protocol::slotAccountOnlineStatusChanged( Contact *self )
100 {//slot connected in aboutToUnload
101  if ( !self || !self->account() || self->account()->isConnected())
102  return;
103  // some protocols change status several times during shutdown. We should only call deleteLater() once
104  disconnect( self, 0, this, 0 );
105 
106  connect( self->account(), SIGNAL(destroyed()),
107  this, SLOT(slotAccountDestroyed()) );
108 
109  self->account()->deleteLater();
110 }
111 
112 void Protocol::slotAccountDestroyed( )
113 {
114  foreach( Account *a , AccountManager::self()->accounts() )
115  {
116  if( a->protocol() == this )
117  {
118  //all accounts has not been deleted yet
119  return;
120  }
121  }
122 
123  // While at this point we are still in a stack trace from the destroyed
124  // account it's safe to emit readyForUnload already, because it uses a
125  // deleteLater rather than a delete for exactly this reason, to keep the
126  // API managable
127  emit( readyForUnload() );
128 }
129 
130 void Protocol::aboutToUnload()
131 {
132 
133  d->unloading = true;
134 
135  int accountcountcount=0;
136  // Disconnect all accounts
137  foreach( Account *a , AccountManager::self()->accounts() )
138  {
139  if( a->protocol() == this )
140  {
141  accountcountcount++;
142 
143  if ( a->myself() && a->myself()->isOnline() )
144  {
145  kDebug( 14010 ) << a->accountId() <<
146  " is still connected, disconnecting..." << endl;
147 
148  QObject::connect( a->myself(),
149  SIGNAL(onlineStatusChanged(Kopete::Contact*,Kopete::OnlineStatus,Kopete::OnlineStatus)),
150  this, SLOT(slotAccountOnlineStatusChanged(Kopete::Contact*)) );
151  a->disconnect();
152  }
153  else
154  {
155  // Remove account, it's already disconnected
156  kDebug( 14010 ) << a->accountId() <<
157  " is already disconnected, deleting..." << endl;
158 
159  QObject::connect( a, SIGNAL(destroyed()),
160  this, SLOT(slotAccountDestroyed()) );
161  a->deleteLater();
162  }
163  }
164  }
165 
166  if( accountcountcount == 0 )
167  {
168  //no accounts in there anymore , we can unload safelly
169  emit readyForUnload();
170  }
171 }
172 
173 
174 
175 void Protocol::serialize( MetaContact *metaContact )
176 {
177  QList< QMap<QString, QString> > serializedDataList;
178  QListIterator<Contact *> cit(metaContact->contacts());
179  while ( cit.hasNext() )
180  {
181  Contact *c = cit.next();
182  if( c->protocol()->pluginId() != pluginId() )
183  continue;
184 
185  QMap<QString, QString> sd;
186  QMap<QString, QString> ad;
187 
188  // Preset the contactId, if the plugin doesn't want to save
189  // them, or use its own format, it can call clear() on the provided list
190  sd[ QString::fromLatin1( "contactId" ) ] = c->contactId();
191  if(c->account())
192  sd[ QString::fromLatin1( "accountId" ) ] = c->account()->accountId();
193 
194  // If there's an index field preset it too
195  QString index = c->protocol()->addressBookIndexField();
196  if( !index.isEmpty() )
197  ad[ index ] = c->contactId();
198 
199  c->serializeProperties( sd );
200  c->serialize( sd, ad );
201 
202  serializedDataList.append( sd );
203  }
204 
205  // Pass all returned fields to the contact list even if empty (will remove the old one)
206  metaContact->setPluginContactData( this, serializedDataList );
207 
208 #if 0
209  // FIXME: This isn't used anywhere right now.
210  for( it = addressBookData.begin(); it != addressBookData.end(); ++it )
211  {
212  //kDebug( 14010 ) << "Protocol::metaContactAboutToSave: addressBookData: key: " << it.key() << ", data: " << it.data();
213  // FIXME: This is a terrible hack to check the key name for the phrase "messaging/"
214  // to indicate what app name to use, but for now it's by far the easiest
215  // way to get this working.
216  // Once all this is in CVS and the actual storage in libkabc is working
217  // we can devise a better API, but with the constantly changing
218  // requirements every time I learn more about kabc I'd better no touch
219  // the API yet - Martijn
220  if( it.key().startsWith( QString::fromLatin1( "messaging/" ) ) )
221  {
222  metaContact->setAddressBookField( this, it.key(), QString::fromLatin1( "All" ), it.value() );
223 // kDebug(14010) << "metaContact->setAddressBookField( " << this << ", " << it.key() << ", \"All\", " << it.data() << " );";
224  }
225  else
226  metaContact->setAddressBookField( this, QString::fromLatin1( "kopete" ), it.key(), it.value() );
227  }
228 #endif
229 }
230 
231 void Protocol::deserializeContactList( MetaContact *metaContact, const QList< QMap<QString, QString> > &dataList )
232 {
233  foreach ( const ContactListElement::ContactData &sd, dataList )
234  {
235  const QString& accountId = sd[ QString::fromLatin1( "accountId" ) ];
236  if( !d->canAddMyself && accountId == sd[ QString::fromLatin1( "contactId" ) ] )
237  {
238  kDebug( 14010 ) << "Myself contact was on the contactlist.xml for account " << accountId << ". Ignore it";
239  continue;
240  }
241 
242  // FIXME: This code almost certainly breaks when having more than
243  // one contact in a meta contact. There are solutions, but
244  // they are all hacky and the API needs revision anyway (see
245  // FIXME a few lines below :), so I'm not going to add that
246  // for now.
247  // Note that even though it breaks, the current code will
248  // never notice, since none of the plugins use the address
249  // book data in the deserializer yet, only when serializing.
250  // - Martijn
251  QMap<QString, QString> ad;
252 #if 0
253  QStringList kabcFields = addressBookFields();
254  for( QStringList::Iterator fieldIt = kabcFields.begin(); fieldIt != kabcFields.end(); ++fieldIt )
255  {
256  // FIXME: This hack is even more ugly, and has the same reasons as the similar
257  // hack in the serialize code.
258  // Once this code is actually capable of talking to kabc this hack
259  // should be removed ASAP! - Martijn
260  if( ( *fieldIt ).startsWith( QString::fromLatin1( "messaging/" ) ) )
261  ad[ *fieldIt ] = metaContact->addressBookField( this, *fieldIt, QString::fromLatin1( "All" ) );
262  else
263  ad[ *fieldIt ] = metaContact->addressBookField( this, QString::fromLatin1( "kopete" ), *fieldIt );
264  }
265  // Check if we have an account id. If not we're deserializing a Kopete 0.6 contact
266  // (our our config is corrupted). Pick the first available account there. This
267  // might not be what you want for corrupted accounts, but it's correct for people
268  // who migrate from 0.6, as there's only one account in that case
269  if( accountId.isNull() )
270  {
271  Q3Dict<Account> accounts = AccountManager::self()->accounts( this );
272  if ( accounts.count() > 0 )
273  {
274  sd[ QString::fromLatin1( "accountId" ) ] = Q3DictIterator<Account>( accounts ).currentKey();
275  }
276  else
277  {
278  kWarning( 14010 ) <<
279  "No account available and account not set in " \
280  "contactlist.xml either!" << endl
281  << "Not deserializing this contact." << endl;
282  return;
283  }
284  }
285 #endif
286 
287  Contact *c = deserializeContact( metaContact, sd, ad );
288  if (c) // should never be null but I do not like crashes
289  c->deserializeProperties( sd );
290  }
291 }
292 
293 void Protocol::deserialize( MetaContact *metaContact, const QMap<QString, QString> &data )
294 {
295  Q_UNUSED( metaContact )
296  Q_UNUSED( data )
297 }
298 
299 Contact *Protocol::deserializeContact(
300  MetaContact * metaContact,
301  const QMap<QString, QString> & serializedData,
302  const QMap<QString, QString> & addressBookData )
303 {
304  Q_UNUSED( metaContact )
305  Q_UNUSED( serializedData )
306  Q_UNUSED( addressBookData )
307  /* Default implementation does nothing */
308  return 0;
309 }
310 
311 KJob *Protocol::createProtocolTask(const QString &taskType)
312 {
313  // Default implementation does nothing
314  Q_UNUSED( taskType )
315  return 0;
316 }
317 
318 bool Protocol::validatePassword( const QString & password ) const
319 {
320  Q_UNUSED( password )
321  return true;
322 }
323 
324 } //END namespace Kopete
325 
326 #include "kopeteprotocol.moc"
327 
kopetemetacontact.h
Kopete::OnlineStatus
Definition: kopeteonlinestatus.h:68
Kopete::Account::protocol
Protocol * protocol() const
Definition: kopeteaccount.cpp:214
Kopete::Account::disconnect
virtual void disconnect()=0
Go offline for this service.
Kopete::Account::myself
Contact * myself() const
Retrieve the 'myself' contact.
Definition: kopeteaccount.cpp:535
kopeteproperty.h
Kopete::Global::Properties::self
static Properties * self()
Singleton accessor for this class.
Definition: kopeteglobal.cpp:49
Kopete::Protocol::deserializeContact
virtual Contact * deserializeContact(MetaContact *metaContact, const QMap< QString, QString > &serializedData, const QMap< QString, QString > &addressBookData)
Deserialize a single contact.
Definition: kopeteprotocol.cpp:299
kopeteaccount.h
Kopete::Contact::contactId
QString contactId
Definition: kopetecontact.h:70
Kopete::Protocol::setCapabilities
void setCapabilities(Capabilities)
Sets the capabilities of this protcol.
Definition: kopeteprotocol.cpp:84
Kopete::OnlineStatus::Unknown
Refers to protocols where state cannot be determined.
Definition: kopeteonlinestatus.h:90
Kopete::OnlineStatus::AccountOffline
The account this contact belongs to is offline.
Definition: kopeteonlinestatus.h:147
Kopete::Contact::isOnline
bool isOnline
Definition: kopetecontact.h:66
Kopete::Contact::account
Account * account() const
Get the account that this contact belongs to.
Definition: kopetecontact.cpp:498
Kopete::Protocol::canAddMyself
bool canAddMyself() const
true if account can add own contact into a contact list
Definition: kopeteprotocol.cpp:89
QObject
Kopete::AccountManager::self
static AccountManager * self()
Retrieve the instance of AccountManager.
Definition: kopeteaccountmanager.cpp:76
Kopete::Plugin::addressBookFields
QStringList addressBookFields() const
Return the list of all keys from the address book in which the plugin is interested.
Definition: kopeteplugin.cpp:100
Kopete::Protocol::createProtocolTask
virtual KJob * createProtocolTask(const QString &taskType)
Factory method to create a protocol Task.
Definition: kopeteprotocol.cpp:311
Kopete::MetaContact::addressBookField
QString addressBookField(Plugin *p, const QString &app, const QString &key) const
Get or set a field for the KDE address book backend.
Definition: kopetemetacontact.cpp:1071
Kopete::Plugin::addressBookIndexField
QString addressBookIndexField() const
Return the index field as set by addAddressBookField()
Definition: kopeteplugin.cpp:105
Kopete::Global::Properties::fullName
const PropertyTmpl & fullName() const
Definition: kopeteglobal.cpp:127
Kopete::Contact::protocol
Protocol * protocol() const
Get the protocol that the contact belongs to.
Definition: kopetecontact.cpp:493
Kopete::Account::accountId
QString accountId
Definition: kopeteaccount.h:77
Kopete::Plugin::pluginId
QString pluginId() const
Get the plugin id.
Definition: kopeteplugin.cpp:46
kopeteprotocol.h
Kopete::Protocol::Protocol
Protocol(const KComponentData &instance, QObject *parent, bool canAddMyself=false)
Constructor for Protocol.
Definition: kopeteprotocol.cpp:53
Kopete::Protocol::deserialize
virtual void deserialize(MetaContact *metaContact, const QMap< QString, QString > &serializedData)
Deserialize the plugin data for a meta contact.
Definition: kopeteprotocol.cpp:293
Kopete::MetaContact::contacts
QList< Contact * > contacts() const
Retrieve the list of contacts that are part of the meta contact.
Definition: kopetemetacontact.cpp:1270
Kopete::Protocol::capabilities
Capabilities capabilities() const
a bitmask of the capabilities of this protocol
Definition: kopeteprotocol.cpp:79
Kopete::Protocol::aboutToUnload
virtual void aboutToUnload()
Reimplemented from Kopete::Plugin.
Definition: kopeteprotocol.cpp:130
Kopete::PropertyContainer::deserializeProperties
void deserializeProperties(const QMap< QString, QString > &serializedData)
Deserialize the contacts persistent properties.
Definition: kopetepropertycontainer.cpp:63
Kopete::Contact
Definition: kopetecontact.h:58
Kopete::ContactListElement::setPluginContactData
void setPluginContactData(Plugin *plugin, const ContactDataList &dataList)
Set plugin specific data for each contact.
Definition: kopetecontactlistelement.cpp:130
Kopete::Plugin::readyForUnload
void readyForUnload()
Indicate when we're ready for unload.
Kopete::PropertyContainer::serializeProperties
void serializeProperties(QMap< QString, QString > &serializedData) const
Serialize the persistent properties for storage in the contact list.
Definition: kopetepropertycontainer.cpp:46
Kopete::Plugin
Base class for all plugins or protocols.
Definition: kopeteplugin.h:84
Kopete::Global::Properties::lastSeen
const PropertyTmpl & lastSeen() const
Definition: kopeteglobal.cpp:145
Kopete::ContactListElement::ContactData
QMap< QString, QString > ContactData
Definition: kopetecontactlistelement.h:115
Kopete::Protocol::deserializeContactList
virtual void deserializeContactList(MetaContact *metaContact, const QList< QMap< QString, QString > > &dataList)
Deserialize the plugin data for a meta contact's contacts.
Definition: kopeteprotocol.cpp:231
Kopete::Protocol::serialize
void serialize(Kopete::MetaContact *metaContact)
Serialize meta contact into the metacontact's plugin data Call serialize() for all contained contacts...
Definition: kopeteprotocol.cpp:175
Kopete::Protocol::~Protocol
virtual ~Protocol()
Definition: kopeteprotocol.cpp:63
kopeteaccountmanager.h
Kopete::AccountManager::accounts
const QList< Account * > & accounts() const
Retrieve the list of accounts.
Definition: kopeteaccountmanager.cpp:312
Kopete::MetaContact
Definition: kopetemetacontact.h:54
Kopete::Protocol::accountOfflineStatus
Kopete::OnlineStatus accountOfflineStatus() const
Returns the status used for contacts when accounts of this protocol are offline.
Definition: kopeteprotocol.cpp:94
Kopete::MetaContact::setAddressBookField
void setAddressBookField(Plugin *p, const QString &app, const QString &key, const QString &value)
set an address book field
Definition: kopetemetacontact.cpp:1076
Kopete::Protocol::validatePassword
virtual bool validatePassword(const QString &password) const
Check whether a password is valid for this protocol.
Definition: kopeteprotocol.cpp:318
Kopete::Contact::serialize
virtual void serialize(QMap< QString, QString > &serializedData, QMap< QString, QString > &addressBookData)
Serialize the contact for storage in the contact list.
Definition: kopetecontact.cpp:419
Kopete::Account
The Kopete::Account class handles one account.
Definition: kopeteaccount.h:72
KJob
kopetecontact.h
kopeteglobal.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:53:51 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kopete/libkopete

Skip menu "kopete/libkopete"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdenetwork API Reference

Skip menu "kdenetwork API Reference"
  • kget
  • kopete
  •   kopete
  •   libkopete
  • krdc
  • krfb

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal