Blokkal
an Extendable KDE Blogging Client
SourceForge.net Logo

blokkalaccountmanager.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2006 - 2008 by Martin Mueller                           *
00003  *   orvio@orvio.de                                                        *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 #include "blokkalaccountmanager.h"
00021 #include "blokkalaccountmanager.moc"
00022 
00023 #include "blokkalaccount.h"
00024 
00025 #include "blokkalprotocol.h"
00026 #include "blokkalpluginmanager.h"
00027 
00028 #include <kstandarddirs.h>
00029 #include <kdebug.h>
00030 
00031 #include <QFile>
00032 #include <QMap>
00033 #include <QDomDocument>
00034 
00035 namespace Blokkal {
00036 class AccountManagerPrivate {
00037 public:
00038         AccountManagerPrivate( void ) :
00039         accountsDocument( QDomDocument( "BlokkalAccounts" ) ),
00040         registeredAccounts( QMap< QString, Blokkal::Account * >() ),
00041         freeAccounts( QMap< QString, QDomElement >() )
00042         {
00043                 accountsDocument.appendChild( accountsDocument.createElement( "accountlist" ) );
00044         }
00045 
00046         ~AccountManagerPrivate( void ) {
00047                 saveAccounts();
00048         }
00049 
00050         void saveAccounts( void ) {
00051                 QFile accountsFile( KStandardDirs::locateLocal( "appdata", QString::fromLatin1( "accounts.xml" ) ) );
00052                 if( !accountsFile.open( QIODevice::WriteOnly ) ) {
00053                         kError() << "error opening account file " << accountsFile.fileName() << endl;
00054                 }
00055                 QTextStream fileStream( &accountsFile );
00056                 accountsDocument.save( fileStream, 3 );
00057                 accountsFile.close();
00058         }
00059 
00060 
00061         QDomDocument accountsDocument;
00062 
00066         QMap< QString, Blokkal::Account * > registeredAccounts;
00067 
00071         QMap< QString, QDomElement > freeAccounts;
00072 
00073         Blokkal::AccountManager instance;
00074         
00075 };
00076 }
00077 
00078 K_GLOBAL_STATIC( Blokkal::AccountManagerPrivate, _bamp );
00079 
00080 Blokkal::AccountManager::AccountManager( void ):
00081 QObject( 0 )
00082 {}
00083 
00084 
00085 void Blokkal::AccountManager::loadAccounts( void )
00086 {
00087         //loading and parsing accounts file
00088         QFile accountsFile( KStandardDirs::locateLocal( "appdata", QString::fromLatin1( "accounts.xml" ) ) );
00089         if( accountsFile.open( QIODevice::ReadOnly ) ) {
00090                 if( !_bamp->accountsDocument.setContent( &accountsFile ) ) {
00091                         kError() << "error parsing account file " << accountsFile.fileName() << endl;
00092                 }
00093                 accountsFile.close();
00094         }
00095 
00096         //creating accounts
00097         QDomElement currentElement;
00098         QString protocolName;
00099         QString accountId;
00100         Protocol * protocol = 0;
00101         for( QDomNode currentNode = _bamp->accountsDocument.firstChild().firstChild();
00102              !currentNode.isNull();
00103              currentNode = currentNode.nextSibling() )
00104         {
00105                 if( currentNode.nodeName() == "account" && currentNode.isElement() ) {
00106                         currentElement = currentNode.toElement();
00107                         protocolName = currentElement.attribute( "protocol" );
00108                         if( currentElement.hasAttribute( "id" ) ) {
00109                                 accountId = currentElement.attribute( "id" );
00110                         }
00111                         else {
00112                                 accountId = currentElement.attribute( "name" );
00113                         }
00114                         
00115                         if( !protocolName.isEmpty() && !accountId.isEmpty() ) {
00116                                 protocol = PluginManager::self()->protocol( protocolName );
00117                                 if( protocol ) {
00118                                         registerAccount( protocol->createAccount( accountId ) );
00119                                 }
00120                         }
00121                 }
00122         }
00123 }
00124 
00125 void Blokkal::AccountManager::saveAccounts( void )
00126 {
00127         _bamp->saveAccounts();
00128 }
00129 
00130 Blokkal::AccountManager::~AccountManager( void )
00131 {}
00132 
00133 Blokkal::AccountManager * Blokkal::AccountManager::self( void )
00134 {
00135         return &_bamp->instance;
00136 }
00137 
00138 Blokkal::AccountList Blokkal::AccountManager::accounts( void )
00139 {
00140         return _bamp->registeredAccounts.values();
00141 }
00142 
00143 
00144 Blokkal::Account * Blokkal::AccountManager::registerAccount( Blokkal::Account * account )
00145 {
00146         if( _bamp->registeredAccounts.contains( account->id() ) ) {
00147                 if( _bamp->registeredAccounts[account->id()] == account ) {
00148                         return account;
00149                 }
00150                 else {
00151                         account->deleteLater();
00152                         return 0;
00153                 }
00154         }
00155 
00156         //this account is actually new
00157         _bamp->registeredAccounts.insert( account->id(), account);
00158         if( _bamp->freeAccounts.contains( account->id() ) ) {
00159                 _bamp->accountsDocument.firstChild().appendChild( _bamp->freeAccounts[account->id()] );
00160                 _bamp->freeAccounts.remove( account->id() );
00161                 saveAccounts();
00162         }
00163         connect( account, SIGNAL( accountDestroyed( Blokkal::Account * ) ),
00164                  this, SLOT( unregisterAccount( Blokkal::Account * ) ) );
00165 
00166         emit accountRegistered( account );
00167         return account;
00168 }
00169 
00170 
00171 void Blokkal::AccountManager::unregisterAccount( Blokkal::Account * account )
00172 {
00173         if( _bamp->registeredAccounts.contains( account->id() ) ) {
00174                 _bamp->registeredAccounts.remove( account->id() );
00175                 saveAccounts();
00176         }
00177         emit accountUnregistered( account );
00178 }
00179 
00180 
00181 
00182 Blokkal::Account * Blokkal::AccountManager::account( const QString & id )
00183 {
00184         if( _bamp->registeredAccounts.contains( id ) ) {
00185                 return _bamp->registeredAccounts[id];
00186         }
00187 
00188         return 0;
00189 }
00190 
00191 QDomElement Blokkal::AccountManager::accountNode( const QString & id )
00192 {
00193         //search the document first
00194         QDomElement currentElement;
00195         for( QDomNode currentNode = _bamp->accountsDocument.firstChild().firstChild();
00196              !currentNode.isNull();
00197              currentNode = currentNode.nextSibling() )
00198         {
00199                 if( currentNode.nodeName() == "account" && currentNode.isElement() ) {
00200                         currentElement = currentNode.toElement();
00201                         if( ( currentElement.attribute( "id" ) == id
00202                               || currentElement.attribute( "name" ) == id )
00203                             && !currentElement.attribute( "protocol" ).isEmpty() )
00204                         {
00205                                 return currentElement;
00206                         }
00207                 }
00208         }
00209 
00210         //try free accounts next
00211         if( _bamp->freeAccounts.contains( id ) ) {
00212                 return _bamp->freeAccounts[id];
00213         }
00214 
00215         //create new free account
00216         currentElement = _bamp->accountsDocument.createElement( "account" );
00217         currentElement.setAttribute( "id", id );
00218         _bamp->freeAccounts.insert( id, currentElement );
00219         return currentElement;
00220 }