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>
34 #include <KLocalizedString>
35 #include <KMessageBox>
37 #include <KXMLGUIFactory>
39 #include <akonadi/collection.h>
40 #include <akonadi/control.h>
41 #include <akonadi/item.h>
42 #include <akonadi/entitytreemodel.h>
45 #include <kxmlguiclient.h>
47 #include "progressspinnerdelegate_p.h"
49 using namespace Akonadi;
54 class EntityTreeView::Private
59 #ifndef QT_NO_DRAGANDDROP
60 , mDragDropManager( new DragDropManager( mParent ) )
63 , mDefaultPopupMenu( QLatin1String(
"akonadi_collectionview_contextmenu" ) )
68 void itemClicked(
const QModelIndex& );
69 void itemDoubleClicked(
const QModelIndex& );
70 void itemCurrentChanged(
const QModelIndex& );
72 void slotSelectionChanged(
const QItemSelection & selected,
const QItemSelection & deselected );
75 QBasicTimer mDragExpandTimer;
76 DragDropManager *mDragDropManager;
77 KXMLGUIClient *mXmlGuiClient;
78 QString mDefaultPopupMenu;
81 void EntityTreeView::Private::init()
83 Akonadi::DelegateAnimator *animator =
new Akonadi::DelegateAnimator( mParent );
84 Akonadi::ProgressSpinnerDelegate *customDelegate =
new Akonadi::ProgressSpinnerDelegate( animator, mParent );
85 mParent->setItemDelegate( customDelegate );
87 mParent->header()->setClickable(
true );
88 mParent->header()->setStretchLastSection(
false );
97 mParent->setSortingEnabled(
true );
98 mParent->sortByColumn( 0, Qt::AscendingOrder );
99 mParent->setEditTriggers( QAbstractItemView::EditKeyPressed );
100 mParent->setAcceptDrops(
true );
101 #ifndef QT_NO_DRAGANDDROP
102 mParent->setDropIndicatorShown(
true );
103 mParent->setDragDropMode( DragDrop );
104 mParent->setDragEnabled(
true );
107 mParent->connect( mParent, SIGNAL(clicked(QModelIndex)),
108 mParent, SLOT(itemClicked(QModelIndex)) );
109 mParent->connect( mParent, SIGNAL(doubleClicked(QModelIndex)),
110 mParent, SLOT(itemDoubleClicked(QModelIndex)) );
115 void EntityTreeView::Private::slotSelectionChanged(
const QItemSelection & selected,
const QItemSelection& )
117 const int column = 0;
118 foreach (
const QItemSelectionRange &range, selected ) {
119 const QModelIndex index = range.topLeft();
121 if ( index.column() > 0 )
124 for (
int row = index.row(); row <= range.bottomRight().row(); ++row ) {
127 mParent->model()->fetchMore( index.sibling( row, column ) );
131 if ( selected.size() == 1 ) {
132 const QItemSelectionRange &range = selected.first();
133 if ( range.topLeft().row() == range.bottomRight().row() )
134 mParent->scrollTo( range.topLeft(), QTreeView::EnsureVisible );
138 void EntityTreeView::Private::itemClicked(
const QModelIndex &index )
140 if ( !index.isValid() )
142 QModelIndex idx = index.sibling( index.row(), 0 );
146 emit mParent->clicked( collection );
149 if ( item.isValid() )
150 emit mParent->clicked( item );
154 void EntityTreeView::Private::itemDoubleClicked(
const QModelIndex &index )
156 if ( !index.isValid() )
158 QModelIndex idx = index.sibling( index.row(), 0 );
161 emit mParent->doubleClicked( collection );
164 if ( item.isValid() )
165 emit mParent->doubleClicked( item );
169 void EntityTreeView::Private::itemCurrentChanged(
const QModelIndex &index )
171 if ( !index.isValid() )
173 QModelIndex idx = index.sibling( index.row(), 0 );
176 emit mParent->currentChanged( collection );
179 if ( item.isValid() )
180 emit mParent->currentChanged( item );
185 : QTreeView( parent ),
186 d( new Private( this ) )
188 setSelectionMode( QAbstractItemView::SingleSelection );
193 : QTreeView( parent ),
194 d( new Private( this ) )
196 d->mXmlGuiClient = xmlGuiClient;
202 delete d->mDragDropManager;
208 if ( selectionModel() ) {
209 disconnect( selectionModel(), SIGNAL(
currentChanged(QModelIndex,QModelIndex)),
210 this, SLOT(itemCurrentChanged(QModelIndex)) );
212 disconnect( selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
213 this, SLOT(slotSelectionChanged(QItemSelection,QItemSelection)) );
216 QTreeView::setModel( model );
217 header()->setStretchLastSection(
true );
219 connect( selectionModel(), SIGNAL(
currentChanged(QModelIndex,QModelIndex)),
220 SLOT(itemCurrentChanged(QModelIndex)) );
222 connect( selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
223 SLOT(slotSelectionChanged(QItemSelection,QItemSelection)) );
227 void EntityTreeView::timerEvent( QTimerEvent *event )
229 if ( event->timerId() == d->mDragExpandTimer.timerId() ) {
230 const QPoint pos = viewport()->mapFromGlobal( QCursor::pos() );
231 if ( state() == QAbstractItemView::DraggingState && viewport()->rect().contains( pos ) )
232 setExpanded( indexAt( pos ),
true );
235 QTreeView::timerEvent( event );
238 #ifndef QT_NO_DRAGANDDROP
239 void EntityTreeView::dragMoveEvent( QDragMoveEvent * event )
241 d->mDragExpandTimer.start( QApplication::startDragTime() ,
this );
243 if ( d->mDragDropManager->dropAllowed( event ) ) {
245 QTreeView::dragMoveEvent( event );
249 event->setDropAction( Qt::IgnoreAction );
252 void EntityTreeView::dropEvent( QDropEvent * event )
254 d->mDragExpandTimer.stop();
255 bool menuCanceled =
false;
256 if ( d->mDragDropManager->processDropEvent( event, menuCanceled, ( dropIndicatorPosition () == QAbstractItemView::OnItem ) ) )
257 QTreeView::dropEvent( event );
261 #ifndef QT_NO_CONTEXTMENU
262 void EntityTreeView::contextMenuEvent( QContextMenuEvent * event )
264 if ( !d->mXmlGuiClient || !model() ) {
268 const QModelIndex index = indexAt( event->pos() );
269 QString popupName = d->mDefaultPopupMenu;
271 if ( index.isValid() ) {
274 popupName = ( item.isValid() ? QLatin1String(
"akonadi_itemview_contextmenu" ) :
275 QLatin1String(
"akonadi_collectionview_contextmenu" ) );
278 QMenu *popup =
static_cast<QMenu*
>( d->mXmlGuiClient->factory()->container( popupName,
279 d->mXmlGuiClient ) );
281 popup->exec( event->globalPos() );
287 d->mXmlGuiClient = xmlGuiClient;
290 #ifndef QT_NO_DRAGANDDROP
291 void EntityTreeView::startDrag( Qt::DropActions supportedActions )
293 d->mDragDropManager->startDrag( supportedActions );
300 #ifndef QT_NO_DRAGANDDROP
301 d->mDragDropManager->setShowDropActionMenu( enabled );
307 #ifndef QT_NO_DRAGANDDROP
308 return d->mDragDropManager->showDropActionMenu();
316 #ifndef QT_NO_DRAGANDDROP
317 d->mDragDropManager->setManualSortingActive( active );
323 #ifndef QT_NO_DRAGANDDROP
324 return d->mDragDropManager->isManualSortingActive();
332 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.
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.