akonadi
entitytreeview.cpp
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 using namespace Akonadi;
00047
00051 class EntityTreeView::Private
00052 {
00053 public:
00054 Private( EntityTreeView *parent )
00055 : mParent( parent ), mDragDropManager( new DragDropManager( mParent ) ), mXmlGuiClient( 0 )
00056 {
00057 }
00058
00059 void init();
00060 void itemClicked( const QModelIndex& );
00061 void itemDoubleClicked( const QModelIndex& );
00062 void itemCurrentChanged( const QModelIndex& );
00063
00064 void slotSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected );
00065
00066 EntityTreeView *mParent;
00067 QBasicTimer mDragExpandTimer;
00068 DragDropManager *mDragDropManager;
00069 KXMLGUIClient *mXmlGuiClient;
00070 };
00071
00072 void EntityTreeView::Private::init()
00073 {
00074 mParent->header()->setClickable( true );
00075 mParent->header()->setStretchLastSection( false );
00076
00077
00078
00079
00080
00081
00082
00083
00084 mParent->setSortingEnabled( true );
00085 mParent->sortByColumn( 0, Qt::AscendingOrder );
00086 mParent->setEditTriggers( QAbstractItemView::EditKeyPressed );
00087 mParent->setAcceptDrops( true );
00088 mParent->setDropIndicatorShown( true );
00089 mParent->setDragDropMode( DragDrop );
00090 mParent->setDragEnabled( true );
00091
00092 mParent->connect( mParent, SIGNAL( clicked( const QModelIndex& ) ),
00093 mParent, SLOT( itemClicked( const QModelIndex& ) ) );
00094 mParent->connect( mParent, SIGNAL( doubleClicked( const QModelIndex& ) ),
00095 mParent, SLOT( itemDoubleClicked( const QModelIndex& ) ) );
00096
00097 Control::widgetNeedsAkonadi( mParent );
00098 }
00099
00100 void EntityTreeView::Private::slotSelectionChanged( const QItemSelection & selected, const QItemSelection& )
00101 {
00102 const int column = 0;
00103 foreach ( const QItemSelectionRange &range, selected ) {
00104 const QModelIndex index = range.topLeft();
00105
00106 if ( index.column() > 0 )
00107 continue;
00108
00109 for ( int row = index.row(); row <= range.bottomRight().row(); ++row ) {
00110
00111
00112 mParent->model()->fetchMore( index.sibling( row, column ) );
00113 }
00114 }
00115 }
00116
00117 void EntityTreeView::Private::itemClicked( const QModelIndex &index )
00118 {
00119 if ( !index.isValid() )
00120 return;
00121
00122 const Collection collection = index.model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>();
00123 if ( collection.isValid() ) {
00124 emit mParent->clicked( collection );
00125 } else {
00126 const Item item = index.model()->data( index, EntityTreeModel::ItemRole ).value<Item>();
00127 if ( item.isValid() )
00128 emit mParent->clicked( item );
00129 }
00130 }
00131
00132 void EntityTreeView::Private::itemDoubleClicked( const QModelIndex &index )
00133 {
00134 if ( !index.isValid() )
00135 return;
00136
00137 const Collection collection = index.model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>();
00138 if ( collection.isValid() ) {
00139 emit mParent->doubleClicked( collection );
00140 } else {
00141 const Item item = index.model()->data( index, EntityTreeModel::ItemRole ).value<Item>();
00142 if ( item.isValid() )
00143 emit mParent->doubleClicked( item );
00144 }
00145 }
00146
00147 void EntityTreeView::Private::itemCurrentChanged( const QModelIndex &index )
00148 {
00149 if ( !index.isValid() )
00150 return;
00151
00152 const Collection collection = index.model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>();
00153 if ( collection.isValid() ) {
00154 emit mParent->currentChanged( collection );
00155 } else {
00156 const Item item = index.model()->data( index, EntityTreeModel::ItemRole ).value<Item>();
00157 if ( item.isValid() )
00158 emit mParent->currentChanged( item );
00159 }
00160 }
00161
00162 EntityTreeView::EntityTreeView( QWidget * parent )
00163 : QTreeView( parent ),
00164 d( new Private( this ) )
00165 {
00166 setSelectionMode( QAbstractItemView::SingleSelection );
00167 d->init();
00168 }
00169
00170 EntityTreeView::EntityTreeView( KXMLGUIClient *xmlGuiClient, QWidget * parent )
00171 : QTreeView( parent ),
00172 d( new Private( this ) )
00173 {
00174 d->mXmlGuiClient = xmlGuiClient;
00175 d->init();
00176 }
00177
00178 EntityTreeView::~EntityTreeView()
00179 {
00180 delete d->mDragDropManager;
00181 delete d;
00182 }
00183
00184 void EntityTreeView::setModel( QAbstractItemModel * model )
00185 {
00186 if ( selectionModel() ) {
00187 disconnect( selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
00188 this, SLOT( itemCurrentChanged( const QModelIndex& ) ) );
00189
00190 disconnect( selectionModel(), SIGNAL( selectionChanged( const QItemSelection&, const QItemSelection& ) ),
00191 this, SLOT( slotSelectionChanged( const QItemSelection&, const QItemSelection& ) ) );
00192 }
00193
00194 QTreeView::setModel( model );
00195 header()->setStretchLastSection( true );
00196
00197 connect( selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
00198 SLOT( itemCurrentChanged( const QModelIndex& ) ) );
00199
00200 connect( selectionModel(), SIGNAL( selectionChanged( const QItemSelection&, const QItemSelection& ) ),
00201 SLOT( slotSelectionChanged( const QItemSelection&, const QItemSelection& ) ) );
00202 }
00203
00204
00205 void EntityTreeView::timerEvent( QTimerEvent *event )
00206 {
00207 if ( event->timerId() == d->mDragExpandTimer.timerId() ) {
00208 const QPoint pos = viewport()->mapFromGlobal( QCursor::pos() );
00209 if ( state() == QAbstractItemView::DraggingState && viewport()->rect().contains( pos ) )
00210 setExpanded( indexAt( pos ), true );
00211 }
00212
00213 QTreeView::timerEvent( event );
00214 }
00215
00216 void EntityTreeView::dragMoveEvent( QDragMoveEvent * event )
00217 {
00218 d->mDragExpandTimer.start( QApplication::startDragTime() , this );
00219
00220 if ( d->mDragDropManager->dropAllowed( event ) ) {
00221
00222 QTreeView::dragMoveEvent( event );
00223 return;
00224 }
00225
00226 event->setDropAction( Qt::IgnoreAction );
00227 return;
00228 }
00229
00230 void EntityTreeView::dropEvent( QDropEvent * event )
00231 {
00232 if ( d->mDragDropManager->processDropEvent( event ) )
00233 QTreeView::dropEvent( event );
00234 }
00235
00236 void EntityTreeView::contextMenuEvent( QContextMenuEvent * event )
00237 {
00238 if ( !d->mXmlGuiClient || !model())
00239 return;
00240
00241 const QModelIndex index = indexAt( event->pos() );
00242
00243 QMenu *popup = 0;
00244
00245
00246 const Item item = model()->data( index, EntityTreeModel::ItemRole ).value<Item>();
00247 if ( item.isValid() )
00248 popup = static_cast<QMenu*>( d->mXmlGuiClient->factory()->container(
00249 QLatin1String( "akonadi_itemview_contextmenu" ), d->mXmlGuiClient ) );
00250 else
00251 popup = static_cast<QMenu*>( d->mXmlGuiClient->factory()->container(
00252 QLatin1String( "akonadi_collectionview_contextmenu" ), d->mXmlGuiClient ) );
00253 if ( popup )
00254 popup->exec( event->globalPos() );
00255 }
00256
00257 void EntityTreeView::setXmlGuiClient( KXMLGUIClient * xmlGuiClient )
00258 {
00259 d->mXmlGuiClient = xmlGuiClient;
00260 }
00261
00262 void EntityTreeView::startDrag( Qt::DropActions supportedActions )
00263 {
00264 d->mDragDropManager->startDrag( supportedActions );
00265 }
00266
00267 #include "entitytreeview.moc"