make webinterface translatable. there are around 20 short strings, all with context...
[kdenetwork.git] / kopete / libkopete / kopeteaccountmanager.cpp
blob881f7d2c1ce59c759a8b1f4e9e07783d42c69ded
1 /*
2 kopeteaccountmanager.cpp - Kopete Account Manager
4 Copyright (c) 2002-2003 by Martijn Klingens <klingens@kde.org>
5 Copyright (c) 2003-2004 by Olivier Goffart <ogoffart@kde.org>
7 Kopete (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org>
9 *************************************************************************
10 * *
11 * This library is free software; you can redistribute it and/or *
12 * modify it under the terms of the GNU Lesser General Public *
13 * License as published by the Free Software Foundation; either *
14 * version 2 of the License, or (at your option) any later version. *
15 * *
16 *************************************************************************
19 #include "kopeteaccountmanager.h"
21 #include <QtGui/QApplication>
22 #include <QtCore/QRegExp>
23 #include <QtCore/QTimer>
24 #include <QtCore/QHash>
26 #include <ksharedconfig.h>
27 #include <kdebug.h>
28 #include <kglobal.h>
29 #include <kplugininfo.h>
30 #include <kconfiggroup.h>
31 #include <solid/networking.h>
33 #include "kopeteaccount.h"
34 #include "kopetebehaviorsettings.h"
35 #include "kopeteprotocol.h"
36 #include "kopetecontact.h"
37 #include "kopetecontactlist.h"
38 #include "kopeteidentitymanager.h"
39 #include "kopetepluginmanager.h"
40 #include "kopeteonlinestatus.h"
41 #include "kopeteonlinestatusmanager.h"
42 #include "kopetemetacontact.h"
43 #include "kopetegroup.h"
44 #include "kopetestatusmanager.h"
46 namespace Kopete {
48 static int compareAccountsByPriority( Account *a, Account *b )
50 uint priority1 = a->priority();
51 uint priority2 = b->priority();
53 if( a==b ) //two account are equal only if they are equal :-)
54 return 0; // remember than an account can be only once on the list, but two account may have the same priority when loading
55 else if( priority1 > priority2 )
56 return 1;
57 else
58 return -1;
61 class AccountManager::Private
63 public:
64 QList<Account *> accounts;
67 AccountManager * AccountManager::s_self = 0L;
69 AccountManager * AccountManager::self()
71 if ( !s_self )
72 s_self = new AccountManager;
74 return s_self;
78 AccountManager::AccountManager()
79 : QObject( qApp )
81 setObjectName( "KopeteAccountManager" );
82 d = new Private;
83 connect( Solid::Networking::notifier(), SIGNAL(shouldConnect()), this, SLOT( networkConnected() ) );
84 connect( Solid::Networking::notifier(), SIGNAL(shouldDisconnect()), this, SLOT( networkDisconnected() ) );
88 AccountManager::~AccountManager()
90 s_self = 0L;
92 delete d;
95 bool AccountManager::isAnyAccountConnected() const
97 foreach( Account *a , d->accounts )
99 if( a->isConnected() )
100 return true;
103 return false;
106 void AccountManager::setOnlineStatus( uint category, const Kopete::StatusMessage &statusMessage, uint flags )
108 kDebug() << "category: " << category;
109 OnlineStatusManager::Categories categories
110 = (OnlineStatusManager::Categories)category;
111 bool onlyChangeConnectedAccounts = isAnyAccountConnected();
113 foreach( Account *account, d->accounts )
115 Kopete::OnlineStatus status = OnlineStatusManager::self()->onlineStatus( account->protocol(), categories );
116 // Going offline is always respected
117 if ( category & Kopete::OnlineStatusManager::Offline ) {
118 account->setOnlineStatus( status, statusMessage );
119 continue;
122 if ( onlyChangeConnectedAccounts ) {
123 if ( account->isConnected() || ( (flags & ConnectIfOffline) && !account->excludeConnect() ) )
124 account->setOnlineStatus( status, statusMessage );
126 else {
127 if ( !account->excludeConnect() )
128 account->setOnlineStatus( status, statusMessage );
131 // mark ourselves as globally away if appropriate
132 Kopete::StatusManager::self()->setGlobalStatus( category, statusMessage );
135 void AccountManager::setStatusMessage(const QString &message)
137 foreach( Account *account, d->accounts )
139 account->setStatusMessage(message);
143 QColor AccountManager::guessColor( Protocol *protocol ) const
145 // In a perfect wold, we should check if the color is actually not used by the account.
146 // Anyway, this is not really required, It would be a difficult job for about nothing more.
147 // -- Olivier
148 int protocolCount = 0;
150 for ( QListIterator<Account *> it( d->accounts ); it.hasNext(); )
152 Account *a = it.next();
153 if ( a->protocol()->pluginId() == protocol->pluginId() )
154 protocolCount++;
157 // let's figure a color
158 QColor color;
159 switch ( protocolCount % 7 )
161 case 0:
162 color = QColor();
163 break;
164 case 1:
165 color = Qt::red;
166 break;
167 case 2:
168 color = Qt::green;
169 break;
170 case 3:
171 color = Qt::blue;
172 break;
173 case 4:
174 color = Qt::yellow;
175 break;
176 case 5:
177 color = Qt::magenta;
178 break;
179 case 6:
180 color = Qt::cyan;
181 break;
184 return color;
187 Account* AccountManager::registerAccount( Account *account )
189 if( !account || d->accounts.contains( account ) )
190 return account;
192 if( account->accountId().isEmpty() )
194 account->deleteLater();
195 return 0L;
198 // If this account already exists, do nothing
199 QListIterator<Account *> it( d->accounts );
200 while ( it.hasNext() )
202 Account *curracc = it.next();
203 if ( ( account->protocol() == curracc->protocol() ) && ( account->accountId() == curracc->accountId() ) )
205 account->deleteLater();
206 return 0L;
210 d->accounts.append( account );
211 qSort( d->accounts.begin(), d->accounts.end(), compareAccountsByPriority );
213 // Connect to the account's status changed signal
214 connect(account->myself(), SIGNAL(onlineStatusChanged(Kopete::Contact *,
215 const Kopete::OnlineStatus &, const Kopete::OnlineStatus &)),
216 this, SLOT(slotAccountOnlineStatusChanged(Kopete::Contact *,
217 const Kopete::OnlineStatus &, const Kopete::OnlineStatus &)));
219 connect(account, SIGNAL(accountDestroyed(const Kopete::Account *)) , this, SLOT( unregisterAccount(const Kopete::Account *) ));
221 emit accountRegistered( account );
222 return account;
225 void AccountManager::unregisterAccount( const Account *account )
227 kDebug( 14010 ) << "Unregistering account " << account->accountId();
228 d->accounts.removeAll( const_cast<Account*>(account) );
229 emit accountUnregistered( account );
232 const QList<Account *>& AccountManager::accounts() const
234 return d->accounts;
237 QList<Account*> AccountManager::accounts( Protocol* protocol ) const
239 QList<Account*> protocolAccounts;
240 foreach( Account* acct, d->accounts )
242 if ( acct->protocol() == protocol )
243 protocolAccounts.append( acct );
245 return protocolAccounts;
248 Account * AccountManager::findAccount( const QString &protocolId, const QString &accountId )
250 for ( QListIterator<Account *> it( d->accounts ); it.hasNext(); )
252 Account *a = it.next();
253 if ( a->protocol()->pluginId() == protocolId && a->accountId() == accountId )
254 return a;
256 return 0L;
259 void AccountManager::removeAccount( Account *account )
261 if(!account->removeAccount())
262 return;
264 Protocol *protocol = account->protocol();
266 KConfigGroup *configgroup = account->configGroup();
268 // Clean up the contact list
269 const QHash<QString, Kopete::Contact*> contactList = account->contacts();
270 QHash<QString, Kopete::Contact*>::ConstIterator it, itEnd = contactList.constEnd();
272 for ( it = contactList.constBegin(); it != itEnd; ++it )
274 Contact* c = it.value();
275 MetaContact* mc = c->metaContact();
276 if ( mc == ContactList::self()->myself() )
277 continue;
278 mc->removeContact( c );
279 c->deleteLater();
280 if ( mc->contacts().count() == 0 ) //we can delete the metacontact
282 //get the first group and it's members
283 Group* group = mc->groups().first();
284 MetaContact::List groupMembers = group->members();
285 ContactList::self()->removeMetaContact( mc );
286 if ( groupMembers.count() == 1 && groupMembers.indexOf( mc ) != -1 )
287 ContactList::self()->removeGroup( group );
291 // Clean up the account list
292 d->accounts.removeAll( account );
294 // Clean up configuration
295 configgroup->deleteGroup();
296 configgroup->sync();
298 delete account;
300 foreach( Account *account , d->accounts )
302 if( account->protocol() == protocol )
303 return;
305 //there is nomore account from the protocol, we can unload it
307 // FIXME: pluginId() should return the internal name and not the class name, so
308 // we can get rid of this hack - Olivier/Martijn
309 QString protocolName = protocol->pluginId().remove( QString::fromLatin1( "Protocol" ) ).toLower();
311 PluginManager::self()->setPluginEnabled( protocolName, false );
312 PluginManager::self()->unloadPlugin( protocolName );
315 void AccountManager::save()
317 //kDebug( 14010 ) ;
318 qSort( d->accounts.begin(), d->accounts.end(), compareAccountsByPriority );
320 for ( QListIterator<Account *> it( d->accounts ); it.hasNext(); )
322 Account *a = it.next();
323 KConfigGroup *config = a->configGroup();
325 config->writeEntry( "Protocol", a->protocol()->pluginId() );
326 config->writeEntry( "AccountId", a->accountId() );
329 KGlobal::config()->sync();
332 void AccountManager::load()
334 connect( PluginManager::self(), SIGNAL( pluginLoaded( Kopete::Plugin * ) ),
335 this, SLOT( slotPluginLoaded( Kopete::Plugin * ) ) );
337 // Iterate over all groups that start with "Account_" as those are accounts
338 // and load the required protocols if the account is enabled.
339 // Don't try to optimize duplicate calls out, the plugin queue is smart enough
340 // (and fast enough) to handle that without adding complexity here
341 KSharedConfig::Ptr config = KGlobal::config();
342 QStringList accountGroups = config->groupList().filter( QRegExp( QString::fromLatin1( "^Account_" ) ) );
343 for ( QStringList::Iterator it = accountGroups.begin(); it != accountGroups.end(); ++it )
345 KConfigGroup cg( config, *it );
347 QString protocol = cg.readEntry( "Protocol", QString() );
348 if ( protocol.endsWith( QString::fromLatin1( "Protocol" ) ) )
349 protocol = QString::fromLatin1( "kopete_" ) + protocol.toLower().remove( QString::fromLatin1( "protocol" ) );
351 if ( cg.readEntry( "Enabled", true ) )
352 PluginManager::self()->loadPlugin( protocol, PluginManager::LoadAsync );
356 void AccountManager::slotPluginLoaded( Plugin *plugin )
358 Protocol* protocol = dynamic_cast<Protocol*>( plugin );
359 if ( !protocol )
360 return;
362 // Iterate over all groups that start with "Account_" as those are accounts
363 // and parse them if they are from this protocol
364 KSharedConfig::Ptr config = KGlobal::config();
365 QStringList accountGroups = config->groupList().filter( QRegExp( QString::fromLatin1( "^Account_" ) ) );
366 for ( QStringList::Iterator it = accountGroups.begin(); it != accountGroups.end(); ++it )
368 KConfigGroup cg( config, *it );
370 if ( cg.readEntry( "Protocol" ) != protocol->pluginId() )
371 continue;
373 // There's no GUI for this, but developers may want to disable an account.
374 if ( !cg.readEntry( "Enabled", true ) )
375 continue;
377 QString accountId = cg.readEntry( "AccountId", QString() );
378 if ( accountId.isEmpty() )
380 kWarning( 14010 ) <<
381 "Not creating account for empty accountId." << endl;
382 continue;
385 kDebug( 14010 ) <<
386 "Creating account for '" << accountId << "'" << endl;
388 Account *account = 0L;
389 account = registerAccount( protocol->createNewAccount( accountId ) );
390 if ( !account )
392 kWarning( 14010 ) <<
393 "Failed to create account for '" << accountId << "'" << endl;
394 continue;
396 // the account's Identity must be set here instead of in the Kopete::Account ctor, because there the
397 // identity cannot pick up any state set in the derived Account ctor
398 Identity *identity = Kopete::IdentityManager::self()->findIdentity( account->configGroup()->readEntry("Identity", QString()) );
399 // if the identity was not found, use the default one which will for sure exist
400 // FIXME: get rid of this, the account's identity should always exist at this point
401 if (!identity)
403 kWarning( 14010 ) << "No identity for account " << accountId << ": falling back to default";
404 identity = Kopete::IdentityManager::self()->defaultIdentity();
406 account->setIdentity( identity );
410 void AccountManager::slotAccountOnlineStatusChanged(Contact *c,
411 const OnlineStatus &oldStatus, const OnlineStatus &newStatus)
413 Account *account = c->account();
414 if (!account)
415 return;
417 //kDebug(14010) ;
418 emit accountOnlineStatusChanged(account, oldStatus, newStatus);
421 void AccountManager::networkConnected()
423 if ( Kopete::BehaviorSettings::self()->autoConnect() )
424 setOnlineStatus( Kopete::OnlineStatusManager::Online, QString(), ConnectIfOffline );
427 void AccountManager::networkDisconnected()
429 setOnlineStatus( Kopete::OnlineStatusManager::Offline );
432 } //END namespace Kopete
434 #include "kopeteaccountmanager.moc"
435 // vim: set noet ts=4 sts=4 sw=4:
436 // kate: tab-width 4; indent-mode csands;