categorymanager.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "categorymanager.h"
00021 #include "categorymanager.moc"
00022
00023 #include "../blokkalaccount.h"
00024
00025 #include <kdebug.h>
00026
00027 #include <QDomElement>
00028 #include <QFile>
00029
00030 #include <QStringList>
00031
00032
00033
00034
00035 class Blokkal::Io::CategoryManager::Private {
00036 public:
00037 Private( Blokkal::Account * account ) :
00038 account( account ),
00039 categoryMap( QMap<QString, CategoryList >() ),
00040 categoryDocument( QDomDocument( "Categories" ) )
00041 {
00042 categoryDocument.appendChild( categoryDocument.createElement( "blogs" ) );
00043 }
00044
00045 QDomElement categoryNode( const QString & blogId, const QString & categoryId ) {
00046 QDomNode currentBlogNode = categoryDocument.firstChild().namedItem( "blog" );
00047 QDomElement currentBlogElement;
00048 while( !currentBlogNode.isNull() ) {
00049 if( currentBlogNode.isElement() && currentBlogNode.nodeName() == "blog" ) {
00050 currentBlogElement = currentBlogNode.toElement();
00051 if( currentBlogElement.attribute( "name" ) == blogId ) {
00052 QDomNode currentCategoryNode = currentBlogNode.namedItem( "category" );
00053 QDomElement currentCategoryElement;
00054 while( !currentCategoryNode.isNull() ) {
00055 if( currentCategoryNode.isElement() && currentCategoryNode.nodeName() == "category" ) {
00056 currentCategoryElement = currentCategoryNode.toElement();
00057 if( currentCategoryElement.attribute( "id" ) == categoryId ) {
00058 return currentCategoryNode.toElement();
00059 }
00060 }
00061 currentCategoryNode = currentCategoryNode.nextSibling();
00062 }
00063
00064 currentCategoryElement = categoryDocument.createElement( "category" );
00065 currentCategoryElement.setAttribute( "id", categoryId );
00066 currentBlogNode.appendChild( currentCategoryElement );
00067 return currentCategoryElement;
00068 }
00069
00070 }
00071 currentBlogNode = currentBlogNode.nextSibling();
00072 }
00073
00074
00075 currentBlogElement = categoryDocument.createElement( "blog" );
00076 currentBlogElement.setAttribute( "name", blogId );
00077 currentBlogNode = currentBlogElement;
00078 categoryDocument.firstChild().appendChild( currentBlogNode );
00079
00080
00081 QDomElement currentCategoryElement = categoryDocument.createElement( "category" );
00082 currentCategoryElement.setAttribute( "id", categoryId );
00083 currentBlogNode.appendChild( currentCategoryElement );
00084 return currentCategoryElement;
00085 }
00086
00087 Blokkal::Account * const account;
00088
00089 QMap<QString, CategoryList > categoryMap;
00090
00091 QDomDocument categoryDocument;
00092 QString categoryFileName;
00093 };
00094
00095 Blokkal::Io::CategoryManager::CategoryManager( Blokkal::Account * account ):
00096 QObject( account ),
00097 d( new Private( account ) )
00098 {
00099 d->categoryFileName = account->dataDirectory() + QString::fromLatin1( "categories.xml" );
00100
00101
00102 QFile file( d->categoryFileName );
00103 if( file.open( QIODevice::ReadOnly ) ) {
00104 if( !d->categoryDocument.setContent( &file ) ) {
00105 kError() << k_funcinfo << "error parsing category file " << file.fileName() << endl;
00106 }
00107 file.close();
00108 }
00109
00110
00111 QDomNode currentBlogNode = d->categoryDocument.firstChild().namedItem( "blog" );
00112 while( !currentBlogNode.isNull() ) {
00113 QDomElement currentBlogElement;
00114 QString blogName;
00115 if( currentBlogNode.isElement() && currentBlogNode.nodeName() == "blog" ) {
00116 currentBlogElement = currentBlogNode.toElement();
00117 blogName = currentBlogElement.attribute( "name" );
00118 d->categoryMap.insert( blogName, CategoryList() );
00119
00120 CategoryList & currentCategoryList = d->categoryMap[ blogName ];
00121 QDomNode currentCategoryNode = currentBlogNode.namedItem( "category" );
00122 while( !currentCategoryNode.isNull() ) {
00123 if( currentCategoryNode.isElement() && currentCategoryNode.nodeName() == "category" ) {
00124 QDomElement currentCategoryElement = currentCategoryNode.toElement();
00125 Category * category = new Category( this,
00126 blogName,
00127 currentCategoryElement.attribute( "id" ),
00128 currentCategoryElement.attribute( "name" ),
00129 currentCategoryElement.attribute( "html" ),
00130 currentCategoryElement.attribute( "rss" ) );
00131 currentCategoryList.append( category );
00132
00133 }
00134 currentCategoryNode = currentCategoryNode.nextSibling();
00135 }
00136
00137 }
00138 currentBlogNode = currentBlogNode.nextSibling();
00139 }
00140 }
00141
00142 Blokkal::Io::CategoryManager::~CategoryManager( void )
00143 {
00144 QFile file( d->categoryFileName );
00145 if( !file.open( QIODevice::WriteOnly ) ) {
00146 kError() << k_funcinfo << "error opening category file " << file.fileName() << endl;
00147 }
00148
00149 QTextStream fileStream( &file );
00150 d->categoryDocument.save( fileStream, 3 );
00151
00152 file.close();
00153
00154 delete d;
00155 d = 0;
00156 }
00157
00158 void Blokkal::Io::CategoryManager::setValidCategories( const QString & blogId, QStringList categories )
00159 {
00160 if( d->categoryMap.contains( blogId ) ) {
00161 CategoryList & oldCategories = d->categoryMap[blogId];
00162 for( int i = 0;
00163 i < oldCategories.size(); )
00164 {
00165 if( !categories.contains( oldCategories.value( i )->id() ) ) {
00166 Category * removedCategory = oldCategories.takeAt( i );
00167 emit categoryRemoved( blogId, removedCategory, this );
00168 removedCategory->destroy();
00169 }
00170 else {
00171 ++i;
00172 }
00173 }
00174 }
00175 }
00176
00177 Blokkal::Io::CategoryList Blokkal::Io::CategoryManager::categories( const QString & blogId ) const
00178 {
00179 if( d->categoryMap.contains( blogId ) ) {
00180 return d->categoryMap[blogId];
00181 }
00182
00183 CategoryList list;
00184 return list;
00185 }
00186
00187 Blokkal::Io::Category * Blokkal::Io::CategoryManager::category( const QString & blogId, const QString & categoryId )
00188 {
00189 CategoryList & categoryList = d->categoryMap[ blogId ];
00190 for( CategoryList::ConstIterator it = categoryList.begin();
00191 it != categoryList.end();
00192 ++it )
00193 {
00194 if( (*it)->id() == categoryId ) {
00195 return *it;
00196 }
00197 }
00198
00199 Category * category = new Category( this, blogId, categoryId );
00200 categoryList.append( category );
00201 emit categoryAdded( blogId, category, this );
00202 return category;
00203 }
00204
00205
00206
00207
00208 class Blokkal::Io::Category::Private {
00209 public:
00210 Private( QDomElement node ):
00211 node( node ){}
00212
00213 QDomElement node;
00214
00215 };
00216
00217 Blokkal::Io::Category::Category( Blokkal::Io::CategoryManager * manager, const QString & blogId, const QString & id, const QString & name, const QString & htmlUrl, const QString & rssUrl ):
00218 QObject( manager ),
00219 d( new Private( manager->d->categoryNode( blogId, id ) ) )
00220 {
00221 d->node.setAttribute( "name", name );
00222 d->node.setAttribute( "html", htmlUrl );
00223 d->node.setAttribute( "rss", rssUrl );
00224 }
00225
00226 Blokkal::Io::Category::~Category( void )
00227 {
00228 delete d;
00229 d = 0;
00230 }
00231
00232 QString Blokkal::Io::Category::id( void ) const
00233 {
00234 return d->node.attribute( "id" );
00235 }
00236
00237 QString Blokkal::Io::Category::name( void ) const
00238 {
00239 return d->node.attribute( "name" );
00240 }
00241
00242 QString Blokkal::Io::Category::htmlUrl( void ) const
00243 {
00244 return d->node.attribute( "html" );
00245 }
00246
00247 QString Blokkal::Io::Category::rssUrl( void ) const
00248 {
00249 return d->node.attribute( "rss" );
00250 }
00251
00252 void Blokkal::Io::Category::destroy( void )
00253 {
00254 d->node.parentNode().removeChild( d->node );
00255 deleteLater();
00256 }
00257
00258 void Blokkal::Io::Category::setName( const QString & name )
00259 {
00260 d->node.setAttribute( "name", name );
00261 emit updated( this );
00262 }
00263
00264 void Blokkal::Io::Category::setHtmlUrl( const QString & htmlUrl )
00265 {
00266 d->node.setAttribute( "html", htmlUrl );
00267 emit updated( this );
00268 }
00269
00270 void Blokkal::Io::Category::setRssUrl( const QString & rssUrl )
00271 {
00272 d->node.setAttribute( "rss", rssUrl );
00273 emit updated( this );
00274 }
00275
00276 Blokkal::Account * Blokkal::Io::CategoryManager::account( void ) const
00277 {
00278 return d->account;
00279 }