Blokkal
an Extendable KDE Blogging Client
SourceForge.net Logo

categoryview.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 "categoryview.h"
00021 #include "categoryview.moc"
00022 
00023 #include "../blokkalaccount.h"
00024 #include "../blokkalblog.h"
00025 #include "../blokkalentry.h"
00026 #include "../blokkalio/categorymanager.h"
00027 
00028 #include "blogdelegate.h"
00029 
00030 #include <kdebug.h>
00031 
00032 #include <QSortFilterProxyModel>
00033 
00034 class Blokkal::Ui::CategoryModel::Private {
00035 public:
00036         Private( const Blog * blog ):
00037         blog( blog ) {}
00038         const Blog * const blog;
00039 };
00040 
00041 Blokkal::Ui::CategoryModel::CategoryModel( Blokkal::Blog * blog, QObject * parent ):
00042 TreeModel( new TreeModel::TreeItemNode( 0, blog ), parent ),
00043 d( new Private( blog ) )
00044 {
00045         Blokkal::Account * account = d->blog->account();
00046         Blokkal::Io::CategoryManager * manager = account->categoryManager();
00047         Blokkal::Io::CategoryList categories = manager->categories( blog->id() );
00048         for( Blokkal::Io::CategoryList::ConstIterator it = categories.begin();
00049              it != categories.end();
00050              ++it )
00051         {
00052                 addCategory( d->blog->id(), *it );
00053         }
00054 
00055         connect( manager,
00056                  SIGNAL( categoryAdded( const QString &, Blokkal::Io::Category *  ) ),
00057                  SLOT( addCategory( const QString &, Blokkal::Io::Category * ) ) );
00058         connect( manager,
00059                  SIGNAL( categoryRemoved( const QString &, Blokkal::Io::Category *  ) ),
00060                  SLOT( removeCategory( const QString &, Blokkal::Io::Category * ) ) );
00061 }
00062 
00063 Blokkal::Ui::CategoryModel::~CategoryModel( void )
00064 {
00065 }
00066 
00067 
00068 void Blokkal::Ui::CategoryModel::addCategory( const QString & blogId, Blokkal::Io::Category * category )
00069 {
00070         if( blogId != d->blog->id() ) {
00071                 return;
00072         }
00073 
00074         beginInsertRows( QModelIndex(),
00075                          root()->children.size(),
00076                          root()->children.size() );
00077         new TreeItemNode( root(), category );
00078         endInsertRows();
00079 
00080         connect( category,
00081                  SIGNAL( updated( Blokkal::Io::Category* ) ),
00082                  SLOT( emitDataChanged( Blokkal::Io::Category* ) ) );
00083 }
00084 
00085 void Blokkal::Ui::CategoryModel::removeCategory( const QString & blogId, Blokkal::Io::Category * category )
00086 {
00087         if( blogId != d->blog->id() ) {
00088                 return;
00089         }
00090 
00091         TreeItemNode * categoryNode;
00092         for( int i = 0; i != root()->children.size(); ++i ) {
00093                 categoryNode = root()->children.at(i);
00094                 if( ((Blokkal::Io::Category*)categoryNode->data.toULongLong() ) == category ) {
00095                         break;
00096                 }
00097                 categoryNode = 0;
00098         }
00099 
00100         if( !categoryNode ) {
00101                 return;
00102         }
00103 
00104         int index = root()->children.indexOf( categoryNode );
00105         beginRemoveRows( QModelIndex(),
00106                          index,
00107                          index );
00108         delete root()->children.takeAt( index );
00109         endRemoveRows();        
00110 }
00111 
00112 
00113 void Blokkal::Ui::CategoryModel::emitDataChanged( Blokkal::Io::Category * category )
00114 {
00115         TreeItemNode * node;
00116         for( int i = 0; i != root()->children.size(); ++i ) {
00117                 node = root()->children.at(i);
00118                 if( ((Blokkal::Io::Category*)node->data.toULongLong() ) == category ) {
00119                         QModelIndex index = createIndex( node->parent->children.indexOf( node ),
00120                                                          0,
00121                                                          node );
00122                         emit dataChanged( index, index );
00123                         return;
00124                 }
00125         }
00126 }
00127 
00128 QVariant Blokkal::Ui::CategoryModel::data( const QModelIndex & index, int role ) const
00129 {
00130         if( role != SortRole ) {
00131                 return TreeModel::data( index, role );
00132         }
00133 
00134         if( !index.isValid() ) {
00135                 return QVariant();
00136         }
00137 
00138         Io::Category * const category = dynamic_cast<Io::Category*>( (QObject*) index.data().toULongLong() );
00139         if( !category ) {
00140                 kError() << "invalid data type encountered" << endl;
00141                 return QVariant();
00142         }
00143 
00144         return category->name();
00145 }
00146 
00147 //------------
00148 //CategoryView
00149 //------------
00150 class Blokkal::Ui::CategoryView::Private {
00151 public:
00152         Private( Blokkal::Entry * entry, bool exclusive ) :
00153         entry( entry ),
00154         exclusive( exclusive ){}
00155         
00156         Blokkal::Entry * entry;
00157         bool exclusive;
00158 };
00159 
00160 Blokkal::Ui::CategoryView::CategoryView( Blokkal::Entry * entry, bool exclusive, QWidget * parent ) :
00161 BlogView( parent, BlogDelegate::DisplayCheckBoxes ),
00162 d( new Private( entry, exclusive ) )
00163 {
00164         setSelectionMode( NoSelection );
00165         QSortFilterProxyModel * sortModel = new QSortFilterProxyModel( this );
00166         sortModel->setSourceModel( new CategoryModel( entry->blog() ) );
00167         sortModel->setSortRole( CategoryModel::SortRole );
00168         setModel( sortModel );
00169         
00170         model()->sort( 0 );
00171         setRootIsDecorated( FALSE );
00172 }
00173 
00174 Blokkal::Ui::CategoryView::~CategoryView( void )
00175 {
00176         delete d;
00177 }
00178 
00179 void Blokkal::Ui::CategoryView::selectCategories( const QStringList & ids )
00180 {
00181         for( int i = 0; i < model()->rowCount(); ++i ) {
00182                 QModelIndex index = model()->index( i, 0 );
00183                 Blokkal::Io::Category * category = dynamic_cast<Blokkal::Io::Category*>( (QObject*) index.data().toULongLong() );
00184                 if( !category ) {
00185                         kDebug() << "model contains data types other than categories" << endl;
00186                         continue;
00187                 }
00188 
00189                 setChecked( index, ids.contains( category->id() ) );
00190                 
00191                 if( d->exclusive && isChecked( index ) ) {
00192                         return;
00193                 }
00194         }
00195 }
00196 
00197 QStringList Blokkal::Ui::CategoryView::selectedCategories( void ) const
00198 {
00199         QStringList ids;
00200 
00201         for( int i = 0; i < model()->rowCount(); ++i ) {
00202                 QModelIndex index = model()->index( i, 0 );
00203                 Blokkal::Io::Category * category = dynamic_cast<Blokkal::Io::Category*>( (QObject*) index.data().toULongLong() );
00204                 if( !category ) {
00205                         kDebug() << "model contains data types other than categories" << endl;
00206                         continue;
00207                 }
00208 
00209                 if( isChecked( index ) ) {
00210                         ids.append( category->id() );
00211                 }
00212         }
00213         
00214         return ids;
00215 }