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 ) )
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)) );
226 void EntityTreeView::timerEvent( QTimerEvent *event )
228 if ( event->timerId() == d->mDragExpandTimer.timerId() ) {
229 const QPoint pos = viewport()->mapFromGlobal( QCursor::pos() );
230 if ( state() == QAbstractItemView::DraggingState && viewport()->rect().contains( pos ) )
231 setExpanded( indexAt( pos ),
true );
234 QTreeView::timerEvent( event );
237 #ifndef QT_NO_DRAGANDDROP
238 void EntityTreeView::dragMoveEvent( QDragMoveEvent * event )
240 d->mDragExpandTimer.start( QApplication::startDragTime() ,
this );
242 if ( d->mDragDropManager->dropAllowed( event ) ) {
244 QTreeView::dragMoveEvent( event );
248 event->setDropAction( Qt::IgnoreAction );
251 void EntityTreeView::dropEvent( QDropEvent * event )
253 d->mDragExpandTimer.stop();
254 bool menuCanceled =
false;
255 if ( d->mDragDropManager->processDropEvent( event, menuCanceled, ( dropIndicatorPosition () == QAbstractItemView::OnItem ) ) )
256 QTreeView::dropEvent( event );
260 #ifndef QT_NO_CONTEXTMENU
261 void EntityTreeView::contextMenuEvent( QContextMenuEvent * event )
263 if ( !d->mXmlGuiClient || !model() ) {
267 const QModelIndex index = indexAt( event->pos() );
268 QString popupName = d->mDefaultPopupMenu;
270 if ( index.isValid() ) {
273 popupName = ( item.isValid() ? QLatin1String(
"akonadi_itemview_contextmenu" ) :
274 QLatin1String(
"akonadi_collectionview_contextmenu" ) );
277 QMenu *popup =
static_cast<QMenu*
>( d->mXmlGuiClient->factory()->container( popupName,
278 d->mXmlGuiClient ) );
280 popup->exec( event->globalPos() );
291 return d->mXmlGuiClient;
294 #ifndef QT_NO_DRAGANDDROP
295 void EntityTreeView::startDrag( Qt::DropActions supportedActions )
297 d->mDragDropManager->startDrag( supportedActions );
303 #ifndef QT_NO_DRAGANDDROP
304 d->mDragDropManager->setShowDropActionMenu( enabled );
310 #ifndef QT_NO_DRAGANDDROP
311 return d->mDragDropManager->showDropActionMenu();
319 #ifndef QT_NO_DRAGANDDROP
320 d->mDragDropManager->setManualSortingActive( active );
326 #ifndef QT_NO_DRAGANDDROP
327 return d->mDragDropManager->isManualSortingActive();
335 d->mDefaultPopupMenu = name;
338 #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.