akonadi
collectioncombobox.cpp
00001 /* 00002 This file is part of Akonadi Contact. 00003 00004 Copyright (c) 2007-2009 Tobias Koenig <tokoe@kde.org> 00005 00006 This library is free software; you can redistribute it and/or modify it 00007 under the terms of the GNU Library General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or (at your 00009 option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, but WITHOUT 00012 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00014 License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to the 00018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00019 02110-1301, USA. 00020 */ 00021 00022 #include "collectioncombobox.h" 00023 #include "collectioncombobox_p.h" 00024 00025 #include "asyncselectionhandler_p.h" 00026 #include "collectiondialog.h" 00027 00028 #include <akonadi/changerecorder.h> 00029 #include <akonadi/collectionfetchscope.h> 00030 #include <akonadi/collectionfilterproxymodel.h> 00031 #include <akonadi/entityrightsfiltermodel.h> 00032 #include <akonadi/entitytreemodel.h> 00033 #include <akonadi/session.h> 00034 00035 #include <kdescendantsproxymodel.h> 00036 #include "collectionutils_p.h" 00037 00038 #include <QtCore/QAbstractItemModel> 00039 #include <QtCore/QEvent> 00040 #include <QtGui/QMouseEvent> 00041 00042 using namespace Akonadi; 00043 00044 class CollectionComboBox::Private 00045 { 00046 public: 00047 Private( QAbstractItemModel *customModel, CollectionComboBox *parent ) 00048 : mParent( parent ), mMonitor( 0 ), mModel( 0 ) 00049 { 00050 if ( customModel ) { 00051 mBaseModel = customModel; 00052 } else { 00053 mMonitor = new Akonadi::ChangeRecorder( mParent ); 00054 mMonitor->fetchCollection( true ); 00055 mMonitor->setCollectionMonitored( Akonadi::Collection::root() ); 00056 00057 mModel = new EntityTreeModel( mMonitor, mParent ); 00058 mModel->setItemPopulationStrategy( EntityTreeModel::NoItemPopulation ); 00059 00060 mBaseModel = mModel; 00061 } 00062 00063 KDescendantsProxyModel *proxyModel = new KDescendantsProxyModel( parent ); 00064 proxyModel->setDisplayAncestorData( true ); 00065 proxyModel->setSourceModel( mBaseModel ); 00066 00067 mMimeTypeFilterModel = new CollectionFilterProxyModel( parent ); 00068 mMimeTypeFilterModel->setSourceModel( proxyModel ); 00069 00070 mRightsFilterModel = new EntityRightsFilterModel( parent ); 00071 mRightsFilterModel->setSourceModel( mMimeTypeFilterModel ); 00072 00073 mParent->setModel( mRightsFilterModel ); 00074 00075 mSelectionHandler = new AsyncSelectionHandler( mRightsFilterModel, mParent ); 00076 mParent->connect( mSelectionHandler, SIGNAL( collectionAvailable( const QModelIndex& ) ), 00077 mParent, SLOT( activated( const QModelIndex& ) ) ); 00078 00079 mParent->connect( mParent, SIGNAL( activated( int ) ), 00080 mParent, SLOT( activated( int ) ) ); 00081 } 00082 00083 ~Private() 00084 { 00085 } 00086 00087 void activated( int index ); 00088 void activated( const QModelIndex& index ); 00089 00090 CollectionComboBox *mParent; 00091 00092 ChangeRecorder *mMonitor; 00093 EntityTreeModel *mModel; 00094 QAbstractItemModel *mBaseModel; 00095 CollectionFilterProxyModel *mMimeTypeFilterModel; 00096 EntityRightsFilterModel *mRightsFilterModel; 00097 AsyncSelectionHandler *mSelectionHandler; 00098 }; 00099 00100 void CollectionComboBox::Private::activated( int index ) 00101 { 00102 const QModelIndex modelIndex = mParent->model()->index( index, 0 ); 00103 if ( modelIndex.isValid() ) 00104 emit mParent->currentChanged( modelIndex.data( EntityTreeModel::CollectionRole).value<Collection>() ); 00105 } 00106 00107 void CollectionComboBox::Private::activated( const QModelIndex &index ) 00108 { 00109 mParent->setCurrentIndex( index.row() ); 00110 } 00111 00112 MobileEventHandler::MobileEventHandler( CollectionComboBox *comboBox, CollectionFilterProxyModel *mimeTypeFilter, 00113 EntityRightsFilterModel *accessRightsFilter, QAbstractItemModel *customModel ) 00114 : QObject( comboBox ), 00115 mComboBox( comboBox ), 00116 mMimeTypeFilter( mimeTypeFilter ), 00117 mAccessRightsFilter( accessRightsFilter ), 00118 mCustomModel( customModel ) 00119 { 00120 } 00121 00122 bool MobileEventHandler::eventFilter( QObject *object, QEvent *event ) 00123 { 00124 if ( object == mComboBox && mComboBox->isEnabled() && event->type() == QEvent::MouseButtonPress ) { 00125 00126 const QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event ); 00127 00128 // we receive mouse events from other widgets as well, so check for ours 00129 if ( mComboBox->rect().contains( mouseEvent->pos() ) ) { 00130 QMetaObject::invokeMethod( this, "openDialog", Qt::QueuedConnection ); 00131 } 00132 00133 return true; 00134 } 00135 00136 return QObject::eventFilter( object, event ); 00137 } 00138 00139 void MobileEventHandler::openDialog() 00140 { 00141 Akonadi::CollectionDialog dialog( mCustomModel ); 00142 dialog.setMimeTypeFilter( mMimeTypeFilter->mimeTypeFilters() ); 00143 dialog.setAccessRightsFilter( mAccessRightsFilter->accessRights() ); 00144 00145 if ( dialog.exec() ) { 00146 const Akonadi::Collection collection = dialog.selectedCollection(); 00147 const QModelIndex index = Akonadi::EntityTreeModel::modelIndexForCollection( mComboBox->model(), collection ); 00148 mComboBox->setCurrentIndex( index.row() ); 00149 } 00150 } 00151 00152 00153 CollectionComboBox::CollectionComboBox( QWidget *parent ) 00154 : KComboBox( parent ), d( new Private( 0, this ) ) 00155 { 00156 #ifdef KDEPIM_MOBILE_UI 00157 MobileEventHandler *handler = new MobileEventHandler( this, d->mMimeTypeFilterModel, d->mRightsFilterModel, d->mBaseModel ); 00158 installEventFilter( handler ); 00159 #endif 00160 } 00161 00162 CollectionComboBox::CollectionComboBox( QAbstractItemModel *model, QWidget *parent ) 00163 : KComboBox( parent ), d( new Private( model, this ) ) 00164 { 00165 #ifdef KDEPIM_MOBILE_UI 00166 MobileEventHandler *handler = new MobileEventHandler( this, d->mMimeTypeFilterModel, d->mRightsFilterModel, d->mBaseModel ); 00167 installEventFilter( handler ); 00168 #endif 00169 } 00170 00171 CollectionComboBox::~CollectionComboBox() 00172 { 00173 delete d; 00174 } 00175 00176 void CollectionComboBox::setMimeTypeFilter( const QStringList &contentMimeTypes ) 00177 { 00178 d->mMimeTypeFilterModel->clearFilters(); 00179 d->mMimeTypeFilterModel->addMimeTypeFilters( contentMimeTypes ); 00180 00181 if ( d->mMonitor ) 00182 foreach ( const QString &mimeType, contentMimeTypes ) 00183 d->mMonitor->setMimeTypeMonitored( mimeType, true ); 00184 } 00185 00186 QStringList CollectionComboBox::mimeTypeFilter() const 00187 { 00188 return d->mMimeTypeFilterModel->mimeTypeFilters(); 00189 } 00190 00191 void CollectionComboBox::setAccessRightsFilter( Collection::Rights rights ) 00192 { 00193 d->mRightsFilterModel->setAccessRights( rights ); 00194 } 00195 00196 Akonadi::Collection::Rights CollectionComboBox::accessRightsFilter() const 00197 { 00198 return d->mRightsFilterModel->accessRights(); 00199 } 00200 00201 void CollectionComboBox::setDefaultCollection( const Collection &collection ) 00202 { 00203 d->mSelectionHandler->waitForCollection( collection ); 00204 } 00205 00206 Akonadi::Collection CollectionComboBox::currentCollection() const 00207 { 00208 const QModelIndex modelIndex = model()->index( currentIndex(), 0 ); 00209 if ( modelIndex.isValid() ) 00210 return modelIndex.data( Akonadi::EntityTreeModel::CollectionRole ).value<Collection>(); 00211 else 00212 return Akonadi::Collection(); 00213 } 00214 00215 #include "collectioncombobox.moc" 00216 #include "collectioncombobox_p.moc"