22 #include "entitytreeview.h"
24 #include "dragdropmanager_p.h"
26 #include <QtCore/QDebug>
27 #include <QtCore/QTimer>
28 #include <QApplication>
29 #include <QDragMoveEvent>
30 #include <QHeaderView>
35 #include <akonadi/collection.h>
36 #include <akonadi/control.h>
37 #include <akonadi/item.h>
38 #include <akonadi/entitytreemodel.h>
41 #include <kxmlguiclient.h>
42 #include <KXMLGUIFactory>
45 #include "progressspinnerdelegate_p.h"
47 using namespace Akonadi;
52 class EntityTreeView::Private
57 #ifndef QT_NO_DRAGANDDROP
58 , mDragDropManager( new DragDropManager( mParent ) )
61 , mDefaultPopupMenu( QLatin1String(
"akonadi_collectionview_contextmenu" ) )
66 void itemClicked(
const QModelIndex& );
67 void itemDoubleClicked(
const QModelIndex& );
68 void itemCurrentChanged(
const QModelIndex& );
70 void slotSelectionChanged(
const QItemSelection & selected,
const QItemSelection & deselected );
73 QBasicTimer mDragExpandTimer;
74 DragDropManager *mDragDropManager;
75 KXMLGUIClient *mXmlGuiClient;
76 QString mDefaultPopupMenu;
79 void EntityTreeView::Private::init()
81 Akonadi::DelegateAnimator *animator =
new Akonadi::DelegateAnimator( mParent );
82 Akonadi::ProgressSpinnerDelegate *customDelegate =
new Akonadi::ProgressSpinnerDelegate( animator, mParent );
83 mParent->setItemDelegate( customDelegate );
85 mParent->header()->setClickable(
true );
86 mParent->header()->setStretchLastSection(
false );
95 mParent->setSortingEnabled(
true );
96 mParent->sortByColumn( 0, Qt::AscendingOrder );
97 mParent->setEditTriggers( QAbstractItemView::EditKeyPressed );
98 mParent->setAcceptDrops(
true );
99 #ifndef QT_NO_DRAGANDDROP
100 mParent->setDropIndicatorShown(
true );
101 mParent->setDragDropMode( DragDrop );
102 mParent->setDragEnabled(
true );
105 mParent->connect( mParent, SIGNAL(clicked(QModelIndex)),
106 mParent, SLOT(itemClicked(QModelIndex)) );
107 mParent->connect( mParent, SIGNAL(doubleClicked(QModelIndex)),
108 mParent, SLOT(itemDoubleClicked(QModelIndex)) );
113 void EntityTreeView::Private::slotSelectionChanged(
const QItemSelection & selected,
const QItemSelection& )
115 const int column = 0;
116 foreach (
const QItemSelectionRange &range, selected ) {
117 const QModelIndex index = range.topLeft();
119 if ( index.column() > 0 )
122 for (
int row = index.row(); row <= range.bottomRight().row(); ++row ) {
125 mParent->model()->fetchMore( index.sibling( row, column ) );
129 if ( selected.size() == 1 ) {
130 const QItemSelectionRange &range = selected.first();
131 if ( range.topLeft().row() == range.bottomRight().row() )
132 mParent->scrollTo( range.topLeft(), QTreeView::EnsureVisible );
136 void EntityTreeView::Private::itemClicked(
const QModelIndex &index )
138 if ( !index.isValid() )
140 QModelIndex idx = index.sibling( index.row(), 0 );
144 emit mParent->clicked( collection );
147 if ( item.isValid() )
148 emit mParent->clicked( item );
152 void EntityTreeView::Private::itemDoubleClicked(
const QModelIndex &index )
154 if ( !index.isValid() )
156 QModelIndex idx = index.sibling( index.row(), 0 );
159 emit mParent->doubleClicked( collection );
162 if ( item.isValid() )
163 emit mParent->doubleClicked( item );
167 void EntityTreeView::Private::itemCurrentChanged(
const QModelIndex &index )
169 if ( !index.isValid() )
171 QModelIndex idx = index.sibling( index.row(), 0 );
174 emit mParent->currentChanged( collection );
177 if ( item.isValid() )
178 emit mParent->currentChanged( item );
183 : QTreeView( parent ),
184 d( new Private( this ) )
186 setSelectionMode( QAbstractItemView::SingleSelection );
191 : QTreeView( parent ),
192 d( new Private( this ) )
200 delete d->mDragDropManager;
206 if ( selectionModel() ) {
207 disconnect( selectionModel(), SIGNAL(
currentChanged(QModelIndex,QModelIndex)),
208 this, SLOT(itemCurrentChanged(QModelIndex)) );
210 disconnect( selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
211 this, SLOT(slotSelectionChanged(QItemSelection,QItemSelection)) );
214 QTreeView::setModel( model );
215 header()->setStretchLastSection(
true );
217 connect( selectionModel(), SIGNAL(
currentChanged(QModelIndex,QModelIndex)),
218 SLOT(itemCurrentChanged(QModelIndex)) );
220 connect( selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
221 SLOT(slotSelectionChanged(QItemSelection,QItemSelection)) );
224 void EntityTreeView::timerEvent( QTimerEvent *event )
226 if ( event->timerId() == d->mDragExpandTimer.timerId() ) {
227 const QPoint pos = viewport()->mapFromGlobal( QCursor::pos() );
228 if ( state() == QAbstractItemView::DraggingState && viewport()->rect().contains( pos ) )
229 setExpanded( indexAt( pos ),
true );
232 QTreeView::timerEvent( event );
235 #ifndef QT_NO_DRAGANDDROP
236 void EntityTreeView::dragMoveEvent( QDragMoveEvent * event )
238 d->mDragExpandTimer.start( QApplication::startDragTime() ,
this );
240 if ( d->mDragDropManager->dropAllowed( event ) ) {
242 QTreeView::dragMoveEvent( event );
246 event->setDropAction( Qt::IgnoreAction );
249 void EntityTreeView::dropEvent( QDropEvent * event )
251 d->mDragExpandTimer.stop();
252 bool menuCanceled =
false;
253 if ( d->mDragDropManager->processDropEvent( event, menuCanceled, ( dropIndicatorPosition () == QAbstractItemView::OnItem ) ) )
254 QTreeView::dropEvent( event );
258 #ifndef QT_NO_CONTEXTMENU
259 void EntityTreeView::contextMenuEvent( QContextMenuEvent * event )
261 if ( !d->mXmlGuiClient || !model() ) {
265 const QModelIndex index = indexAt( event->pos() );
266 QString popupName = d->mDefaultPopupMenu;
268 if ( index.isValid() ) {
271 popupName = ( item.isValid() ? QLatin1String(
"akonadi_itemview_contextmenu" ) :
272 QLatin1String(
"akonadi_collectionview_contextmenu" ) );
275 QMenu *popup =
static_cast<QMenu*
>( d->mXmlGuiClient->factory()->container( popupName,
276 d->mXmlGuiClient ) );
278 popup->exec( event->globalPos() );
289 return d->mXmlGuiClient;
292 #ifndef QT_NO_DRAGANDDROP
293 void EntityTreeView::startDrag( Qt::DropActions supportedActions )
295 d->mDragDropManager->startDrag( supportedActions );
301 #ifndef QT_NO_DRAGANDDROP
302 d->mDragDropManager->setShowDropActionMenu( enabled );
308 #ifndef QT_NO_DRAGANDDROP
309 return d->mDragDropManager->showDropActionMenu();
317 #ifndef QT_NO_DRAGANDDROP
318 d->mDragDropManager->setManualSortingActive( active );
324 #ifndef QT_NO_DRAGANDDROP
325 return d->mDragDropManager->isManualSortingActive();
333 d->mDefaultPopupMenu = name;
336 #include "moc_entitytreeview.cpp"
virtual ~EntityTreeView()
Destroys the entity tree view.
void setDefaultPopupMenu(const QString &name)
Set the name of the default popup menu (retrieved from the application's XMLGUI file).
Represents a collection of PIM items.
bool isManualSortingActive() const
Return true if we use an manual sorting Necessary to fix dnd menu We must show just move when we move...
void setManualSortingActive(bool active)
Set true if we automatic sorting.
KXMLGUIClient * xmlGuiClient() const
Return the XML GUI client which the view is used in.
A view to show an item/collection tree provided by an EntityTreeModel.
static void widgetNeedsAkonadi(QWidget *widget)
Disable the given widget when Akonadi is not operational and show an error overlay (given enough spac...
void setDropActionMenuEnabled(bool enabled)
Sets whether the drop action menu is enabled and will be shown on drop operation. ...
bool isDropActionMenuEnabled() const
Returns whether the drop action menu is enabled and will be shown on drop operation.
EntityTreeView(QWidget *parent=0)
Creates a new entity tree view.
virtual void setModel(QAbstractItemModel *model)
bool isValid() const
Returns whether the entity is valid.
void setXmlGuiClient(KXMLGUIClient *xmlGuiClient)
Sets the XML GUI client which the view is used in.
void currentChanged(const Akonadi::Collection &collection)
This signal is emitted whenever the current collection in the view has changed.