akonadi
entitylistview.cpp
00001 /* 00002 Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org> 00003 Copyright (c) 2008 Stephen Kelly <steveire@gmail.com> 00004 Copyright (c) 2009 Kevin Ottens <ervin@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 "entitylistview.h" 00023 00024 #include "dragdropmanager_p.h" 00025 #include "favoritecollectionsmodel.h" 00026 00027 #include <QtCore/QDebug> 00028 #include <QtCore/QTimer> 00029 #include <QtGui/QApplication> 00030 #include <QtGui/QDragMoveEvent> 00031 #include <QtGui/QHeaderView> 00032 #include <QtGui/QMenu> 00033 00034 #include <KAction> 00035 #include <KLocale> 00036 #include <KMessageBox> 00037 #include <KUrl> 00038 #include <KXMLGUIFactory> 00039 00040 #include <kdebug.h> 00041 #include <kxmlguiclient.h> 00042 00043 #include <akonadi/collection.h> 00044 #include <akonadi/control.h> 00045 #include <akonadi/item.h> 00046 #include <akonadi/entitytreemodel.h> 00047 00048 #include <progressspinnerdelegate_p.h> 00049 00050 using namespace Akonadi; 00051 00055 class EntityListView::Private 00056 { 00057 public: 00058 Private( EntityListView *parent ) 00059 : mParent( parent ), mDragDropManager( new DragDropManager( mParent ) ), mXmlGuiClient( 0 ) 00060 { 00061 } 00062 00063 void init(); 00064 void itemClicked( const QModelIndex& ); 00065 void itemDoubleClicked( const QModelIndex& ); 00066 void itemCurrentChanged( const QModelIndex& ); 00067 00068 EntityListView *mParent; 00069 DragDropManager *mDragDropManager; 00070 KXMLGUIClient *mXmlGuiClient; 00071 }; 00072 00073 void EntityListView::Private::init() 00074 { 00075 mParent->setEditTriggers( QAbstractItemView::EditKeyPressed ); 00076 mParent->setAcceptDrops( true ); 00077 mParent->setDropIndicatorShown( true ); 00078 mParent->setDragDropMode( DragDrop ); 00079 mParent->setDragEnabled( true ); 00080 00081 mParent->connect( mParent, SIGNAL( clicked( const QModelIndex& ) ), 00082 mParent, SLOT( itemClicked( const QModelIndex& ) ) ); 00083 mParent->connect( mParent, SIGNAL( doubleClicked( const QModelIndex& ) ), 00084 mParent, SLOT( itemDoubleClicked( const QModelIndex& ) ) ); 00085 00086 DelegateAnimator *animator = new DelegateAnimator(mParent); 00087 ProgressSpinnerDelegate *customDelegate = new ProgressSpinnerDelegate(animator, mParent); 00088 mParent->setItemDelegate(customDelegate); 00089 00090 Control::widgetNeedsAkonadi( mParent ); 00091 } 00092 00093 void EntityListView::Private::itemClicked( const QModelIndex &index ) 00094 { 00095 if ( !index.isValid() ) 00096 return; 00097 00098 const Collection collection = index.model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>(); 00099 if ( collection.isValid() ) { 00100 emit mParent->clicked( collection ); 00101 } else { 00102 const Item item = index.model()->data( index, EntityTreeModel::ItemRole ).value<Item>(); 00103 if ( item.isValid() ) 00104 emit mParent->clicked( item ); 00105 } 00106 } 00107 00108 void EntityListView::Private::itemDoubleClicked( const QModelIndex &index ) 00109 { 00110 if ( !index.isValid() ) 00111 return; 00112 00113 const Collection collection = index.model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>(); 00114 if ( collection.isValid() ) { 00115 emit mParent->doubleClicked( collection ); 00116 } else { 00117 const Item item = index.model()->data( index, EntityTreeModel::ItemRole ).value<Item>(); 00118 if ( item.isValid() ) 00119 emit mParent->doubleClicked( item ); 00120 } 00121 } 00122 00123 void EntityListView::Private::itemCurrentChanged( const QModelIndex &index ) 00124 { 00125 if ( !index.isValid() ) 00126 return; 00127 00128 const Collection collection = index.model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>(); 00129 if ( collection.isValid() ) { 00130 emit mParent->currentChanged( collection ); 00131 } else { 00132 const Item item = index.model()->data( index, EntityTreeModel::ItemRole ).value<Item>(); 00133 if ( item.isValid() ) 00134 emit mParent->currentChanged( item ); 00135 } 00136 } 00137 00138 EntityListView::EntityListView( QWidget * parent ) 00139 : QListView( parent ), 00140 d( new Private( this ) ) 00141 { 00142 setSelectionMode( QAbstractItemView::SingleSelection ); 00143 d->init(); 00144 } 00145 00146 EntityListView::EntityListView( KXMLGUIClient *xmlGuiClient, QWidget * parent ) 00147 : QListView( parent ), 00148 d( new Private( this ) ) 00149 { 00150 d->mXmlGuiClient = xmlGuiClient; 00151 d->init(); 00152 } 00153 00154 EntityListView::~EntityListView() 00155 { 00156 delete d->mDragDropManager; 00157 delete d; 00158 } 00159 00160 void EntityListView::setModel( QAbstractItemModel * model ) 00161 { 00162 if ( selectionModel() ) { 00163 disconnect( selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), 00164 this, SLOT( itemCurrentChanged( const QModelIndex& ) ) ); 00165 } 00166 00167 QListView::setModel( model ); 00168 00169 connect( selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ), 00170 SLOT( itemCurrentChanged( const QModelIndex& ) ) ); 00171 } 00172 00173 void EntityListView::dragMoveEvent( QDragMoveEvent * event ) 00174 { 00175 if ( d->mDragDropManager->dropAllowed( event ) || qobject_cast<Akonadi::FavoriteCollectionsModel*>( model() ) ) { 00176 // All urls are supported. process the event. 00177 QListView::dragMoveEvent( event ); 00178 return; 00179 } 00180 00181 event->setDropAction( Qt::IgnoreAction ); 00182 } 00183 00184 void EntityListView::dropEvent( QDropEvent * event ) 00185 { 00186 if ( d->mDragDropManager->processDropEvent( event ) || qobject_cast<Akonadi::FavoriteCollectionsModel*>( model() ) ) { 00187 QListView::dropEvent( event ); 00188 } 00189 } 00190 00191 void EntityListView::contextMenuEvent( QContextMenuEvent * event ) 00192 { 00193 if ( !d->mXmlGuiClient ) 00194 return; 00195 00196 const QModelIndex index = indexAt( event->pos() ); 00197 00198 QMenu *popup = 0; 00199 00200 // check if the index under the cursor is a collection or item 00201 const Collection collection = model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>(); 00202 if ( collection.isValid() ) { 00203 popup = static_cast<QMenu*>( d->mXmlGuiClient->factory()->container( 00204 QLatin1String( "akonadi_favoriteview_contextmenu" ), d->mXmlGuiClient ) ); 00205 } else { 00206 popup = static_cast<QMenu*>( d->mXmlGuiClient->factory()->container( 00207 QLatin1String( "akonadi_favoriteview_emptyselection_contextmenu" ), d->mXmlGuiClient) ); 00208 } 00209 00210 if ( popup ) 00211 popup->exec( event->globalPos() ); 00212 } 00213 00214 void EntityListView::setXmlGuiClient( KXMLGUIClient *xmlGuiClient ) 00215 { 00216 d->mXmlGuiClient = xmlGuiClient; 00217 } 00218 00219 void EntityListView::startDrag( Qt::DropActions supportedActions ) 00220 { 00221 d->mDragDropManager->startDrag( supportedActions ); 00222 } 00223 00224 void EntityListView::setDropActionMenuEnabled( bool enabled ) 00225 { 00226 #ifndef QT_NO_DRAGANDDROP 00227 d->mDragDropManager->setShowDropActionMenu( enabled ); 00228 #endif 00229 } 00230 00231 bool EntityListView::isDropActionMenuEnabled() const 00232 { 00233 #ifndef QT_NO_DRAGANDDROP 00234 return d->mDragDropManager->showDropActionMenu(); 00235 #else 00236 return false; 00237 #endif 00238 } 00239 00240 #include "entitylistview.moc"