00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "entitytreeview.h"
00022
00023 #include "dragdropmanager_p.h"
00024
00025 #include <QtCore/QDebug>
00026 #include <QtCore/QTimer>
00027 #include <QtGui/QApplication>
00028 #include <QtGui/QDragMoveEvent>
00029 #include <QtGui/QHeaderView>
00030 #include <QtGui/QMenu>
00031
00032 #include <KAction>
00033 #include <KLocale>
00034 #include <KMessageBox>
00035 #include <KUrl>
00036 #include <KXMLGUIFactory>
00037
00038 #include <akonadi/collection.h>
00039 #include <akonadi/control.h>
00040 #include <akonadi/item.h>
00041 #include <akonadi/entitytreemodel.h>
00042
00043 #include <kdebug.h>
00044 #include <kxmlguiclient.h>
00045
00046 #include "progressspinnerdelegate_p.h"
00047
00048 using namespace Akonadi;
00049
00053 class EntityTreeView::Private
00054 {
00055 public:
00056 Private( EntityTreeView *parent )
00057 : mParent( parent ), mDragDropManager( new DragDropManager( mParent ) ), mXmlGuiClient( 0 )
00058 {
00059 }
00060
00061 void init();
00062 void itemClicked( const QModelIndex& );
00063 void itemDoubleClicked( const QModelIndex& );
00064 void itemCurrentChanged( const QModelIndex& );
00065
00066 void slotSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected );
00067
00068 EntityTreeView *mParent;
00069 QBasicTimer mDragExpandTimer;
00070 DragDropManager *mDragDropManager;
00071 KXMLGUIClient *mXmlGuiClient;
00072 };
00073
00074 void EntityTreeView::Private::init()
00075 {
00076 Akonadi::DelegateAnimator *animator = new Akonadi::DelegateAnimator(mParent);
00077 Akonadi::ProgressSpinnerDelegate *customDelegate = new Akonadi::ProgressSpinnerDelegate(animator, mParent);
00078 mParent->setItemDelegate(customDelegate);
00079
00080 mParent->header()->setClickable( true );
00081 mParent->header()->setStretchLastSection( false );
00082
00083
00084
00085
00086
00087
00088
00089
00090 mParent->setSortingEnabled( true );
00091 mParent->sortByColumn( 0, Qt::AscendingOrder );
00092 mParent->setEditTriggers( QAbstractItemView::EditKeyPressed );
00093 mParent->setAcceptDrops( true );
00094 mParent->setDropIndicatorShown( true );
00095 mParent->setDragDropMode( DragDrop );
00096 mParent->setDragEnabled( true );
00097
00098 mParent->connect( mParent, SIGNAL( clicked( const QModelIndex& ) ),
00099 mParent, SLOT( itemClicked( const QModelIndex& ) ) );
00100 mParent->connect( mParent, SIGNAL( doubleClicked( const QModelIndex& ) ),
00101 mParent, SLOT( itemDoubleClicked( const QModelIndex& ) ) );
00102
00103 Control::widgetNeedsAkonadi( mParent );
00104 }
00105
00106 void EntityTreeView::Private::slotSelectionChanged( const QItemSelection & selected, const QItemSelection& )
00107 {
00108 const int column = 0;
00109 foreach ( const QItemSelectionRange &range, selected ) {
00110 const QModelIndex index = range.topLeft();
00111
00112 if ( index.column() > 0 )
00113 continue;
00114
00115 for ( int row = index.row(); row <= range.bottomRight().row(); ++row ) {
00116
00117
00118 mParent->model()->fetchMore( index.sibling( row, column ) );
00119 }
00120 }
00121 }
00122
00123 void EntityTreeView::Private::itemClicked( 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->clicked( collection );
00131 } else {
00132 const Item item = index.model()->data( index, EntityTreeModel::ItemRole ).value<Item>();
00133 if ( item.isValid() )
00134 emit mParent->clicked( item );
00135 }
00136 }
00137
00138 void EntityTreeView::Private::itemDoubleClicked( const QModelIndex &index )
00139 {
00140 if ( !index.isValid() )
00141 return;
00142
00143 const Collection collection = index.model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>();
00144 if ( collection.isValid() ) {
00145 emit mParent->doubleClicked( collection );
00146 } else {
00147 const Item item = index.model()->data( index, EntityTreeModel::ItemRole ).value<Item>();
00148 if ( item.isValid() )
00149 emit mParent->doubleClicked( item );
00150 }
00151 }
00152
00153 void EntityTreeView::Private::itemCurrentChanged( const QModelIndex &index )
00154 {
00155 if ( !index.isValid() )
00156 return;
00157
00158 const Collection collection = index.model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>();
00159 if ( collection.isValid() ) {
00160 emit mParent->currentChanged( collection );
00161 } else {
00162 const Item item = index.model()->data( index, EntityTreeModel::ItemRole ).value<Item>();
00163 if ( item.isValid() )
00164 emit mParent->currentChanged( item );
00165 }
00166 }
00167
00168 EntityTreeView::EntityTreeView( QWidget * parent )
00169 : QTreeView( parent ),
00170 d( new Private( this ) )
00171 {
00172 setSelectionMode( QAbstractItemView::SingleSelection );
00173 d->init();
00174 }
00175
00176 EntityTreeView::EntityTreeView( KXMLGUIClient *xmlGuiClient, QWidget * parent )
00177 : QTreeView( parent ),
00178 d( new Private( this ) )
00179 {
00180 d->mXmlGuiClient = xmlGuiClient;
00181 d->init();
00182 }
00183
00184 EntityTreeView::~EntityTreeView()
00185 {
00186 delete d->mDragDropManager;
00187 delete d;
00188 }
00189
00190 void EntityTreeView::setModel( QAbstractItemModel * model )
00191 {
00192 if ( selectionModel() ) {
00193 disconnect( selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
00194 this, SLOT( itemCurrentChanged( const QModelIndex& ) ) );
00195
00196 disconnect( selectionModel(), SIGNAL( selectionChanged( const QItemSelection&, const QItemSelection& ) ),
00197 this, SLOT( slotSelectionChanged( const QItemSelection&, const QItemSelection& ) ) );
00198 }
00199
00200 QTreeView::setModel( model );
00201 header()->setStretchLastSection( true );
00202
00203 connect( selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
00204 SLOT( itemCurrentChanged( const QModelIndex& ) ) );
00205
00206 connect( selectionModel(), SIGNAL( selectionChanged( const QItemSelection&, const QItemSelection& ) ),
00207 SLOT( slotSelectionChanged( const QItemSelection&, const QItemSelection& ) ) );
00208 }
00209
00210
00211 void EntityTreeView::timerEvent( QTimerEvent *event )
00212 {
00213 if ( event->timerId() == d->mDragExpandTimer.timerId() ) {
00214 const QPoint pos = viewport()->mapFromGlobal( QCursor::pos() );
00215 if ( state() == QAbstractItemView::DraggingState && viewport()->rect().contains( pos ) )
00216 setExpanded( indexAt( pos ), true );
00217 }
00218
00219 QTreeView::timerEvent( event );
00220 }
00221
00222 void EntityTreeView::dragMoveEvent( QDragMoveEvent * event )
00223 {
00224 d->mDragExpandTimer.start( QApplication::startDragTime() , this );
00225
00226 if ( d->mDragDropManager->dropAllowed( event ) ) {
00227
00228 QTreeView::dragMoveEvent( event );
00229 return;
00230 }
00231
00232 event->setDropAction( Qt::IgnoreAction );
00233 return;
00234 }
00235
00236 void EntityTreeView::dropEvent( QDropEvent * event )
00237 {
00238 if ( d->mDragDropManager->processDropEvent( event ) )
00239 QTreeView::dropEvent( event );
00240
00241 d->mDragExpandTimer.stop();
00242 }
00243
00244 void EntityTreeView::contextMenuEvent( QContextMenuEvent * event )
00245 {
00246 if ( !d->mXmlGuiClient || !model())
00247 return;
00248
00249 const QModelIndex index = indexAt( event->pos() );
00250
00251 QMenu *popup = 0;
00252
00253
00254 const Item item = model()->data( index, EntityTreeModel::ItemRole ).value<Item>();
00255 if ( item.isValid() )
00256 popup = static_cast<QMenu*>( d->mXmlGuiClient->factory()->container(
00257 QLatin1String( "akonadi_itemview_contextmenu" ), d->mXmlGuiClient ) );
00258 else
00259 popup = static_cast<QMenu*>( d->mXmlGuiClient->factory()->container(
00260 QLatin1String( "akonadi_collectionview_contextmenu" ), d->mXmlGuiClient ) );
00261 if ( popup )
00262 popup->exec( event->globalPos() );
00263 }
00264
00265 void EntityTreeView::setXmlGuiClient( KXMLGUIClient * xmlGuiClient )
00266 {
00267 d->mXmlGuiClient = xmlGuiClient;
00268 }
00269
00270 void EntityTreeView::startDrag( Qt::DropActions supportedActions )
00271 {
00272 d->mDragDropManager->startDrag( supportedActions );
00273 }
00274
00275
00276 void EntityTreeView::setDropActionMenuEnabled( bool enabled )
00277 {
00278 d->mDragDropManager->setShowDropActionMenu( enabled );
00279 }
00280
00281 bool EntityTreeView::isDropActionMenuEnabled() const
00282 {
00283 return d->mDragDropManager->showDropActionMenu();
00284 }
00285
00286 #include "entitytreeview.moc"