Blokkal
an Extendable KDE Blogging Client
SourceForge.net Logo

blokkalblogmodel.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2007 - 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 "blokkalblogmodel.h"
00021 #include "blokkalblogmodel.moc"
00022 
00023 #include "blokkalaccountmanager.h"
00024 #include "blokkalaccount.h"
00025 #include "blokkalblog.h"
00026 #include "blokkalio/categorymanager.h"
00027 
00028 #include <kdebug.h>
00029 
00030 class Blokkal::BlogModel::Private {
00031 public:
00032         Private( void ){}
00033 };
00034 
00035 Blokkal::BlogModel::BlogModel( QObject * parent ):
00036 TreeModel( 0, parent ),
00037 d( new Private() )
00038 {
00039         Blokkal::AccountManager * manager = Blokkal::AccountManager::self();
00040         Blokkal::AccountList accounts = manager->accounts();
00041         for( Blokkal::AccountList::ConstIterator it = accounts.begin();
00042              it != accounts.end();
00043              ++it )
00044         {
00045                 addAccount( *it );
00046         }
00047 
00048         connect( manager,
00049                  SIGNAL( accountRegistered( Blokkal::Account* ) ),
00050                  SLOT( addAccount( Blokkal::Account * ) ) );
00051         connect( manager,
00052                  SIGNAL( accountUnregistered( Blokkal::Account* ) ),
00053                  SLOT( removeAccount( Blokkal::Account* ) ) );  
00054 }
00055 
00056 Blokkal::BlogModel::~BlogModel( void )
00057 {
00058         delete d;
00059 }
00060 
00061 Blokkal::BlogModel::TreeItemNode * Blokkal::BlogModel::findAccountNode( Blokkal::Account * account )
00062 {
00063         TreeItemNode * node;
00064         for( int i = 0; i != root()->children.size(); ++i ) {
00065                 node = root()->children.at(i);
00066                 if( ((Blokkal::Account*)node->data.toULongLong() ) == account ) {
00067                         return node;
00068                 }
00069         }
00070 
00071         return 0;
00072 }
00073 
00074 Blokkal::BlogModel::TreeItemNode * Blokkal::BlogModel::findBlogNode( Blokkal::Blog * blog )
00075 {
00076         TreeItemNode * accountNode = findAccountNode( blog->account() );
00077         if( !accountNode ) {
00078                 kError() << "unable to find account node for blog " << blog->id() << endl;
00079                 return 0;
00080         }
00081 
00082         TreeItemNode * node;
00083         for( int i = 0; i != accountNode->children.size(); ++i ) {
00084                 node = accountNode->children.at(i);
00085                 if( ((Blokkal::Blog*)node->data.toULongLong() ) == blog ) {
00086                         return node;
00087                 }
00088         }
00089 
00090         return 0;
00091 }
00092 
00093 void Blokkal::BlogModel::addAccount( Blokkal::Account * account )
00094 {
00095         //new nodes are always appended
00096         beginInsertRows( QModelIndex(), root()->children.size(), root()->children.size() );
00097         new TreeItemNode( root(), account );
00098         endInsertRows();
00099         
00100         connect( account,
00101                  SIGNAL( blogRegistered( Blokkal::Blog * ) ),
00102                  SLOT( addBlog( Blokkal::Blog * ) ) );
00103         connect( account,
00104                                 SIGNAL( blogUnregistered( Blokkal::Blog * ) ),
00105                                 SLOT( removeBlog( Blokkal::Blog * ) ) );        
00106         connect( account,
00107                  SIGNAL( connectionStatusChanged( Blokkal::Account* ) ),
00108                  SLOT( emitDataChanged( Blokkal::Account* ) ) );
00109 
00110         QList<Blokkal::Blog*> blogs = account->blogs(); 
00111         for( QList<Blokkal::Blog*>::ConstIterator it = blogs.begin();
00112                         it != blogs.end();
00113                         ++it )
00114         {
00115                 addBlog( *it );
00116         }
00117 }
00118 
00119 void Blokkal::BlogModel::addBlog( Blokkal::Blog * blog )
00120 {
00121         if( !blog ) {
00122                 return;
00123         }
00124 
00125         TreeItemNode * node = findAccountNode( blog->account() );
00126         if( !node ) {
00127                 kError() << "unable to find account for blog" << endl;
00128                 return;
00129         }
00130 
00131         beginInsertRows( createIndex( node->parent->children.indexOf( node ), 0, node ),
00132                          node->children.size(),
00133                          node->children.size() );
00134         new TreeItemNode( node, blog );
00135         endInsertRows();
00136 }
00137 
00138 void Blokkal::BlogModel::removeAccount( Blokkal::Account * account )
00139 {
00140         if( !account ) {
00141                 return;
00142         }
00143         
00144         QList<Blokkal::Blog*> blogs = account->blogs();
00145         for( QList<Blokkal::Blog*>::ConstIterator it = blogs.begin();
00146                         it != blogs.end();
00147                         ++it )
00148         {
00149                 removeBlog( *it );
00150         }
00151 
00152         TreeItemNode * node = findAccountNode( account );
00153         if( !node ) {
00154                 kError() << "unable to find node for account" << endl;
00155                 return;
00156         }
00157         
00158         int index = node->parent->children.indexOf( node );
00159         beginRemoveRows( QModelIndex(),
00160                          index,
00161                          index );
00162         disconnect( account,
00163                     SIGNAL( blogRegistered( Blokkal::Blog * ) ),
00164                     this,
00165                     SLOT( addBlog( Blokkal::Blog * ) ) );
00166         disconnect( account,
00167                     SIGNAL( connectionStatusChanged( Blokkal::Account* ) ),
00168                     this,
00169                     SLOT( emitDataChanged( Blokkal::Account* ) ) );
00170         delete node->parent->children.takeAt( index );
00171         endRemoveRows();
00172 }
00173 
00174 void Blokkal::BlogModel::removeBlog( Blokkal::Blog * blog )
00175 {
00176         if( !blog ) {
00177                 return;
00178         }
00179 
00180         TreeItemNode * node = findBlogNode( blog );
00181         if( !node ) {
00182                 kError() << "unable to find node for blog" << endl;
00183                 return;
00184         }
00185 
00186         int index = node->parent->children.indexOf( node );
00187         beginRemoveRows( createIndex( root()->children.indexOf( node->parent ),
00188                                       0,
00189                                       node->parent ),
00190                          index,
00191                          index );
00192         delete node->parent->children.takeAt( index );
00193         endRemoveRows();
00194 }
00195 
00196 void Blokkal::BlogModel::emitDataChanged( Blokkal::Account * account )
00197 {
00198         TreeItemNode * accountNode = findAccountNode( account );
00199         if( accountNode ) {
00200                 const QModelIndex accountIndex = createIndex( accountNode->parent->children.indexOf( accountNode ),
00201                                                               0,
00202                                                               accountNode );
00203                 if( accountNode->children.isEmpty() ) {
00204                         emit dataChanged( accountIndex, accountIndex );
00205                 }
00206                 else {
00207                         const QModelIndex blogIndex = createIndex( accountNode->children.size() - 1 ,
00208                                                                    0,
00209                                                                    accountNode->children.last() );
00210                         emit dataChanged( accountIndex, blogIndex );
00211                 }
00212         }
00213 }
00214 
00215 //------------------
00216 //BlogCategoryModel
00217 //------------------
00218 Blokkal::BlogCategoryModel::BlogCategoryModel( QObject * parent ):
00219 BlogModel( parent )
00220 {
00221         Blokkal::AccountManager * manager = Blokkal::AccountManager::self();
00222         Blokkal::AccountList accounts = manager->accounts();
00223         for( Blokkal::AccountList::ConstIterator ait = accounts.begin();
00224              ait != accounts.end();
00225              ++ait )
00226         {
00227                 BlogModel::TreeItemNode * accountNode = findAccountNode( *ait );
00228                 if( !accountNode) {
00229                         kError() << "unable to find node for account: " << (*ait)->id() << endl;
00230                         continue;
00231                 }
00232                 
00233                 Blokkal::Account * account = dynamic_cast<Blokkal::Account*>( (QObject*)accountNode->data.toULongLong() );
00234                 if( !account ) {
00235                         kError() << "account node does not have an account as data" << endl;
00236                         continue;
00237                 }
00238                         
00239                 QList<Blokkal::Blog*> blogs = account->blogs();
00240                 for( QList<Blokkal::Blog*>::ConstIterator bit = blogs.begin();
00241                                 bit != blogs.end();
00242                                 ++bit )
00243                 {
00244                         addCategories( *bit );
00245                 }
00246         }       
00247 }
00248 
00249 Blokkal::BlogCategoryModel::~BlogCategoryModel( void )
00250 {
00251 }
00252 
00253 void Blokkal::BlogCategoryModel::addBlog( Blokkal::Blog * blog )
00254 {
00255         BlogModel::addBlog( blog );
00256         addCategories( blog );
00257 }
00258 
00259 void Blokkal::BlogCategoryModel::removeBlog( Blokkal::Blog * blog )
00260 {
00261         removeCategories( blog );
00262         BlogModel::removeBlog( blog );
00263 }
00264 
00265 void Blokkal::BlogCategoryModel::addCategory( const QString & blogId, Blokkal::Io::Category * category, Blokkal::Io::CategoryManager * manager )
00266 {
00267         Blokkal::Blog * blog = findBlog( blogId, manager->account() );
00268         if( !blog ) {
00269                 kError() << "cannot find blog with id " << blogId << endl;
00270                 return;
00271         }
00272 
00273         TreeItemNode * node = findBlogNode( blog );
00274         if( !node ) {
00275                 kError() << "cannot find node for blog " << blogId << endl;
00276                 return;
00277         }
00278 
00279         beginInsertRows( createIndex( node->parent->children.indexOf( node ), 0, node->parent ),
00280                          node->children.size(),
00281                          node->children.size() );
00282         new TreeItemNode( node, category );
00283         endInsertRows();
00284 }
00285 
00286 void Blokkal::BlogCategoryModel::removeCategory( const QString & blogId, Blokkal::Io::Category * category, Blokkal::Io::CategoryManager * manager )
00287 {
00288         Blokkal::Blog * blog = findBlog( blogId, manager->account() );
00289         if( !blog ) {
00290                 kError() << "cannot find blog with id " << blogId << endl;
00291                 return;
00292         }
00293 
00294         TreeItemNode * node = findBlogNode( blog );
00295         if( !node ) {
00296                 kError() << "cannot find node for blog " << blogId << endl;
00297                 return;
00298         }
00299         
00300         TreeItemNode * categoryNode;
00301         for( int i = 0; i != node->children.size(); ++i ) {
00302                 categoryNode = node->children.at(i);
00303                 if( ((Blokkal::Io::Category*)categoryNode->data.toULongLong() ) == category ) {
00304                         break;
00305                 }
00306                 categoryNode = 0;
00307         }
00308 
00309         if( !categoryNode ) {
00310                 return;
00311         }
00312 
00313         int index = node->children.indexOf( categoryNode );
00314         beginRemoveRows( createIndex( index, 0, node ),
00315                          index,
00316                          index );
00317         delete node->children.takeAt( index );
00318         endRemoveRows();
00319 }
00320 
00321 Blokkal::Blog * Blokkal::BlogCategoryModel::findBlog( const QString & blogId, const Blokkal::Account * account )
00322 {
00323         Blokkal::Blog * blog = 0;
00324         QList<Blokkal::Blog*> blogs = account->blogs();
00325         for( QList<Blokkal::Blog*>::ConstIterator it = blogs.begin();
00326                         it != blogs.end();
00327                         ++it )
00328         {
00329                 if( (*it)->id() == blogId ) {
00330                         blog = *it;
00331                         break;
00332                 }
00333         }
00334 
00335         return blog;
00336 }
00337 
00338 void Blokkal::BlogCategoryModel::addCategories( Blokkal::Blog * blog )
00339 {
00340         BlogModel::TreeItemNode * blogNode = findBlogNode( blog );
00341         if( !blogNode) {
00342                 kError() << "unable to find node for blog: " << blog->id() << endl;
00343                 return;
00344         }
00345 
00346         Blokkal::Io::CategoryManager * manager = blog->account()->categoryManager();
00347         Blokkal::Io::CategoryList categories = manager->categories( blog->id() );
00348         for( Blokkal::Io::CategoryList::ConstIterator it = categories.begin();
00349                         it != categories.end();
00350                         ++it )
00351         {
00352                 addCategory( blog->id(), *it, manager );
00353         }
00354 
00355         connect( manager,
00356                  SIGNAL( categoryAdded( const QString&, Blokkal::Io::Category*, Blokkal::Io::CategoryManager* ) ),
00357                  SLOT( addCategory( const QString&, Blokkal::Io::Category*, Blokkal::Io::CategoryManager* ) ) );
00358         connect( manager,
00359                  SIGNAL( categoryRemoved( const QString&, Blokkal::Io::Category*, Blokkal::Io::CategoryManager* ) ),
00360                  SLOT( removeCategory( const QString&, Blokkal::Io::Category*, Blokkal::Io::CategoryManager* ) ) );
00361 }
00362 
00363 void Blokkal::BlogCategoryModel::removeCategories( Blokkal::Blog * blog )
00364 {
00365         BlogModel::TreeItemNode * blogNode = findBlogNode( blog );
00366         if( !blogNode) {
00367                 kError() << "unable to find node for blog: " << blog->id() << endl;
00368                 return;
00369         }
00370 
00371         Blokkal::Io::CategoryManager * manager = blog->account()->categoryManager();
00372         Blokkal::Io::CategoryList categories = manager->categories( blog->id() );
00373         for( Blokkal::Io::CategoryList::ConstIterator it = categories.begin();
00374                         it != categories.end();
00375                         ++it )
00376         {
00377                 removeCategory( blog->id(), *it, manager );
00378         }       
00379 }