akonadi
favoritecollectionsmodel.cpp
00001 /* 00002 Copyright (c) 2009 Kevin Ottens <ervin@kde.org> 00003 00004 00005 This library is free software; you can redistribute it and/or modify it 00006 under the terms of the GNU Library General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or (at your 00008 option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, but WITHOUT 00011 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to the 00017 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00018 02110-1301, USA. 00019 */ 00020 00021 #include "favoritecollectionsmodel.h" 00022 00023 #include <QtGui/QItemSelectionModel> 00024 #include <QtCore/QMimeData> 00025 00026 #include <kconfiggroup.h> 00027 #include <klocale.h> 00028 #include <KJob> 00029 00030 #include "entitytreemodel.h" 00031 #include "mimetypechecker.h" 00032 #include "pastehelper_p.h" 00033 00034 using namespace Akonadi; 00035 00039 class FavoriteCollectionsModel::Private 00040 { 00041 public: 00042 Private( const KConfigGroup &group, FavoriteCollectionsModel *parent ) 00043 : q( parent ), configGroup( group ) 00044 { 00045 } 00046 00047 QString labelForCollection( Collection::Id collectionId ) const 00048 { 00049 if ( labelMap.contains( collectionId ) ) { 00050 return labelMap[ collectionId ]; 00051 } 00052 00053 const QModelIndex collectionIdx = EntityTreeModel::modelIndexForCollection( q->sourceModel(), Collection( collectionId ) ); 00054 00055 QString accountName; 00056 00057 const QString nameOfCollection = collectionIdx.data().toString(); 00058 00059 QModelIndex idx = collectionIdx.parent(); 00060 while ( idx != QModelIndex() ) { 00061 accountName = idx.data().toString(); 00062 idx = idx.parent(); 00063 } 00064 00065 if ( accountName.isEmpty() ) 00066 return nameOfCollection; 00067 else 00068 return nameOfCollection + QLatin1String( " (" ) + accountName + QLatin1Char( ')' ); 00069 } 00070 00071 void clearAndUpdateSelection() 00072 { 00073 q->selectionModel()->clear(); 00074 updateSelection(); 00075 } 00076 00077 void updateSelection() 00078 { 00079 foreach ( const Collection::Id &collectionId, collectionIds ) { 00080 const QModelIndex index = EntityTreeModel::modelIndexForCollection( q->sourceModel(), Collection( collectionId ) ); 00081 00082 if ( !index.isValid() ) 00083 continue; 00084 00085 q->selectionModel()->select( index, QItemSelectionModel::Select ); 00086 } 00087 } 00088 00089 void loadConfig() 00090 { 00091 collectionIds = configGroup.readEntry( "FavoriteCollectionIds", QList<qint64>() ); 00092 const QStringList labels = configGroup.readEntry( "FavoriteCollectionLabels", QStringList() ); 00093 00094 for ( int i = 0; i < collectionIds.size(); ++i ) { 00095 if ( i<labels.size() ) { 00096 labelMap[ collectionIds[i] ] = labels[i]; 00097 } 00098 } 00099 } 00100 00101 void saveConfig() 00102 { 00103 QStringList labels; 00104 00105 foreach ( const Collection::Id &collectionId, collectionIds ) { 00106 labels << labelForCollection( collectionId ); 00107 } 00108 00109 configGroup.writeEntry( "FavoriteCollectionIds", collectionIds ); 00110 configGroup.writeEntry( "FavoriteCollectionLabels", labels ); 00111 configGroup.config()->sync(); 00112 } 00113 00114 FavoriteCollectionsModel * const q; 00115 00116 QList<Collection::Id> collectionIds; 00117 QHash<qint64, QString> labelMap; 00118 KConfigGroup configGroup; 00119 }; 00120 00121 FavoriteCollectionsModel::FavoriteCollectionsModel( QAbstractItemModel *source, const KConfigGroup &group, QObject *parent ) 00122 : Akonadi::SelectionProxyModel( new QItemSelectionModel( source, parent ), parent ), 00123 d( new Private( group, this ) ) 00124 { 00125 setSourceModel( source ); 00126 setFilterBehavior( ExactSelection ); 00127 00128 connect( source, SIGNAL( modelReset() ), this, SLOT( clearAndUpdateSelection() ) ); 00129 connect( source, SIGNAL( rowsInserted( const QModelIndex&, int, int ) ), this, SLOT( updateSelection() ) ); 00130 00131 d->loadConfig(); 00132 d->clearAndUpdateSelection(); 00133 } 00134 00135 FavoriteCollectionsModel::~FavoriteCollectionsModel() 00136 { 00137 delete d; 00138 } 00139 00140 void FavoriteCollectionsModel::setCollections( const Collection::List &collections ) 00141 { 00142 d->collectionIds.clear(); 00143 foreach(const Collection &col, collections) { 00144 d->collectionIds << col.id(); 00145 } 00146 d->labelMap.clear(); 00147 d->clearAndUpdateSelection(); 00148 d->saveConfig(); 00149 } 00150 00151 void FavoriteCollectionsModel::addCollection( const Collection &collection ) 00152 { 00153 d->collectionIds << collection.id(); 00154 d->updateSelection(); 00155 d->saveConfig(); 00156 } 00157 00158 void FavoriteCollectionsModel::removeCollection( const Collection &collection ) 00159 { 00160 d->collectionIds.removeAll( collection.id() ); 00161 d->labelMap.remove( collection.id() ); 00162 00163 const QModelIndex idx = EntityTreeModel::modelIndexForCollection( sourceModel(), collection ); 00164 00165 if ( !idx.isValid() ) 00166 return; 00167 00168 selectionModel()->select( idx, 00169 QItemSelectionModel::Deselect ); 00170 00171 d->updateSelection(); 00172 d->saveConfig(); 00173 } 00174 00175 Akonadi::Collection::List FavoriteCollectionsModel::collections() const 00176 { 00177 Collection::List cols; 00178 foreach (const Collection::Id &colId, d->collectionIds) 00179 cols << Collection(colId); 00180 return cols; 00181 } 00182 00183 QList<Collection::Id> FavoriteCollectionsModel::collectionIds() const 00184 { 00185 return d->collectionIds; 00186 } 00187 00188 void Akonadi::FavoriteCollectionsModel::setFavoriteLabel( const Collection &collection, const QString &label ) 00189 { 00190 Q_ASSERT( d->collectionIds.contains( collection.id() ) ); 00191 d->labelMap[ collection.id() ] = label; 00192 d->saveConfig(); 00193 00194 const QModelIndex idx = EntityTreeModel::modelIndexForCollection( sourceModel(), collection ); 00195 00196 if ( !idx.isValid() ) 00197 return; 00198 00199 const QModelIndex index = mapFromSource( idx ); 00200 emit dataChanged( index, index ); 00201 } 00202 00203 QVariant Akonadi::FavoriteCollectionsModel::data( const QModelIndex &index, int role ) const 00204 { 00205 if ( index.column() == 0 && (role == Qt::DisplayRole || role == Qt::EditRole) ) { 00206 const QModelIndex sourceIndex = mapToSource( index ); 00207 const Collection::Id collectionId = sourceModel()->data( sourceIndex, EntityTreeModel::CollectionIdRole ).toLongLong(); 00208 00209 return d->labelForCollection( collectionId ); 00210 } else { 00211 return KSelectionProxyModel::data( index, role ); 00212 } 00213 } 00214 00215 bool FavoriteCollectionsModel::setData(const QModelIndex& index, const QVariant& value, int role) 00216 { 00217 if ( index.isValid() && index.column() == 0 && role == Qt::EditRole ) { 00218 const QString newLabel = value.toString(); 00219 if ( newLabel.isEmpty() ) 00220 return false; 00221 const QModelIndex sourceIndex = mapToSource( index ); 00222 const Collection collection = sourceModel()->data( sourceIndex, EntityTreeModel::CollectionRole ).value<Collection>(); 00223 setFavoriteLabel( collection, newLabel ); 00224 return true; 00225 } 00226 return Akonadi::SelectionProxyModel::setData(index, value, role); 00227 } 00228 00229 QString Akonadi::FavoriteCollectionsModel::favoriteLabel( const Akonadi::Collection & collection ) 00230 { 00231 if ( !collection.isValid() ) 00232 return QString(); 00233 return d->labelForCollection( collection.id() ); 00234 } 00235 00236 QVariant FavoriteCollectionsModel::headerData( int section, Qt::Orientation orientation, int role ) const 00237 { 00238 if ( section == 0 00239 && orientation == Qt::Horizontal 00240 && role == Qt::DisplayRole ) { 00241 return i18n( "Favorite Folders" ); 00242 } else { 00243 return KSelectionProxyModel::headerData( section, orientation, role ); 00244 } 00245 } 00246 00247 bool FavoriteCollectionsModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) 00248 { 00249 Q_UNUSED( action ); 00250 Q_UNUSED( row ); 00251 Q_UNUSED( column ); 00252 if ( data->hasFormat( QLatin1String( "text/uri-list" ) ) ) { 00253 const KUrl::List urls = KUrl::List::fromMimeData( data ); 00254 00255 const QModelIndex sourceIndex = mapToSource( parent ); 00256 const Collection destCollection = sourceModel()->data( sourceIndex, EntityTreeModel::CollectionRole ).value<Collection>(); 00257 00258 MimeTypeChecker mimeChecker; 00259 mimeChecker.setWantedMimeTypes( destCollection.contentMimeTypes() ); 00260 00261 foreach ( const KUrl &url, urls ) { 00262 const Collection col = Collection::fromUrl( url ); 00263 if ( col.isValid() ) { 00264 addCollection( col ); 00265 } else { 00266 const Item item = Item::fromUrl( url ); 00267 if ( item.isValid() ) 00268 { 00269 if ( item.parentCollection().id() == destCollection.id() && action != Qt::CopyAction ) { 00270 kDebug() << "Error: source and destination of move are the same."; 00271 return false; 00272 } 00273 #if 0 00274 if ( !mimeChecker.isWantedItem( item ) ) { 00275 kDebug() << "unwanted item" << mimeChecker.wantedMimeTypes() << item.mimeType(); 00276 return false; 00277 } 00278 #endif 00279 KJob *job = PasteHelper::pasteUriList( data, destCollection, action ); 00280 if ( !job ) 00281 return false; 00282 connect( job, SIGNAL( result( KJob* ) ), SLOT( pasteJobDone( KJob* ) ) ); 00283 // Accept the event so that it doesn't propagate. 00284 return true; 00285 00286 } 00287 } 00288 00289 } 00290 return true; 00291 } 00292 return false; 00293 } 00294 00295 QStringList FavoriteCollectionsModel::mimeTypes() const 00296 { 00297 QStringList mts = Akonadi::SelectionProxyModel::mimeTypes(); 00298 if ( !mts.contains( QLatin1String( "text/uri-list" ) ) ) 00299 mts.append( QLatin1String( "text/uri-list" ) ); 00300 return mts; 00301 } 00302 00303 Qt::ItemFlags FavoriteCollectionsModel::flags(const QModelIndex& index) const 00304 { 00305 Qt::ItemFlags fs = Akonadi::SelectionProxyModel::flags( index ); 00306 if ( !index.isValid() ) 00307 fs |= Qt::ItemIsDropEnabled; 00308 return fs; 00309 } 00310 00311 void FavoriteCollectionsModel::pasteJobDone( KJob *job ) 00312 { 00313 if ( job->error() ) { 00314 kDebug()<< job->errorString(); 00315 } 00316 } 00317 00318 #include "favoritecollectionsmodel.moc"