akonadi
collectionfilterproxymodel.cpp
00001 /* 00002 Copyright (c) 2007 Bruno Virlet <bruno.virlet@gmail.com> 00003 00004 This library is free software; you can redistribute it and/or modify it 00005 under the terms of the GNU Library General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or (at your 00007 option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, but WITHOUT 00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00012 License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to the 00016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00017 02110-1301, USA. 00018 */ 00019 00020 #include "collectionfilterproxymodel.h" 00021 00022 #include "collectionmodel.h" 00023 #include "mimetypechecker.h" 00024 00025 #include <kdebug.h> 00026 00027 #include <QtCore/QString> 00028 #include <QtCore/QStringList> 00029 #include <QTimer> 00030 00031 using namespace Akonadi; 00032 00036 class CollectionFilterProxyModel::Private 00037 { 00038 public: 00039 Private( CollectionFilterProxyModel *parent ) 00040 : mParent( parent ) 00041 { 00042 mimeChecker.addWantedMimeType( QLatin1String( "text/uri-list" ) ); 00043 } 00044 00045 bool collectionAccepted( const QModelIndex &index, bool checkResourceVisibility = true ); 00046 00047 QVector< QModelIndex > acceptedResources; 00048 CollectionFilterProxyModel *mParent; 00049 MimeTypeChecker mimeChecker; 00050 }; 00051 00052 bool CollectionFilterProxyModel::Private::collectionAccepted( const QModelIndex &index, bool checkResourceVisibility ) 00053 { 00054 // Retrieve supported mimetypes 00055 const Collection collection = mParent->sourceModel()->data( index, CollectionModel::CollectionRole ).value<Collection>(); 00056 00057 // If this collection directly contains one valid mimetype, it is accepted 00058 if ( mimeChecker.isWantedCollection( collection ) ) { 00059 // The folder will be accepted, but we need to make sure the resource is visible too. 00060 if ( checkResourceVisibility ) { 00061 00062 // find the resource 00063 QModelIndex resource = index; 00064 while ( resource.parent().isValid() ) 00065 resource = resource.parent(); 00066 00067 // See if that resource is visible, if not, invalidate the filter. 00068 if ( resource != index && !acceptedResources.contains( resource ) ) { 00069 kDebug() << "We got a new collection:" << mParent->sourceModel()->data( index ).toString() 00070 << "but the resource is not visible:" << mParent->sourceModel()->data( resource ).toString(); 00071 acceptedResources.clear(); 00072 // defer reset, the model might still be supplying new items at this point which crashs 00073 mParent->invalidateFilter(); 00074 return true; 00075 } 00076 } 00077 00078 // Keep track of all the resources that are visible. 00079 if ( !index.parent().isValid() ) 00080 acceptedResources.append( index ); 00081 00082 return true; 00083 } 00084 00085 // If this collection has a child which contains valid mimetypes, it is accepted 00086 QModelIndex childIndex = index.child( 0, 0 ); 00087 while ( childIndex.isValid() ) { 00088 if ( collectionAccepted( childIndex, false /* don't check visibility of the parent, as we are checking the child now */ ) ) { 00089 00090 // Keep track of all the resources that are visible. 00091 if ( !index.parent().isValid()) 00092 acceptedResources.append( index ); 00093 00094 return true; 00095 } 00096 childIndex = childIndex.sibling( childIndex.row() + 1, 0 ); 00097 } 00098 00099 // Or else, no reason to keep this collection. 00100 return false; 00101 } 00102 00103 00104 CollectionFilterProxyModel::CollectionFilterProxyModel( QObject *parent ) 00105 : QSortFilterProxyModel( parent ), 00106 d( new Private( this ) ) 00107 { 00108 } 00109 00110 CollectionFilterProxyModel::~CollectionFilterProxyModel() 00111 { 00112 delete d; 00113 } 00114 00115 void CollectionFilterProxyModel::addMimeTypeFilters(const QStringList &typeList) 00116 { 00117 QStringList mimeTypes = d->mimeChecker.wantedMimeTypes() + typeList; 00118 d->mimeChecker.setWantedMimeTypes( mimeTypes ); 00119 invalidateFilter(); 00120 } 00121 00122 void CollectionFilterProxyModel::addMimeTypeFilter(const QString &type) 00123 { 00124 d->mimeChecker.addWantedMimeType( type ); 00125 invalidateFilter(); 00126 } 00127 00128 bool CollectionFilterProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent) const 00129 { 00130 return d->collectionAccepted( sourceModel()->index( sourceRow, 0, sourceParent ) ); 00131 } 00132 00133 QStringList CollectionFilterProxyModel::mimeTypeFilters() const 00134 { 00135 return d->mimeChecker.wantedMimeTypes(); 00136 } 00137 00138 void CollectionFilterProxyModel::clearFilters() 00139 { 00140 d->mimeChecker = MimeTypeChecker(); 00141 invalidateFilter(); 00142 } 00143 00144 Qt::ItemFlags CollectionFilterProxyModel::flags( const QModelIndex& index ) const 00145 { 00146 if ( !index.isValid() ) { 00147 // Don't crash 00148 return 0; 00149 } 00150 00151 const Collection collection = sourceModel()->data( mapToSource( index ), CollectionModel::CollectionRole ).value<Collection>(); 00152 00153 // If this collection directly contains one valid mimetype, it is accepted 00154 if ( d->mimeChecker.isWantedCollection( collection ) ) 00155 return QSortFilterProxyModel::flags( index ); 00156 else 00157 return QSortFilterProxyModel::flags( index ) & ~( Qt::ItemIsSelectable ); 00158 } 00159 00160 #include "collectionfilterproxymodel.moc"