22#include "entitytreeview.h"
24#include "dragdropmanager_p.h"
26#include <QtCore/QDebug>
27#include <QtCore/QTimer>
28#include <QApplication>
29#include <QDragMoveEvent>
33#include <akonadi/collection.h>
34#include <akonadi/control.h>
35#include <akonadi/item.h>
36#include <akonadi/entitytreemodel.h>
39#include <kxmlguiclient.h>
40#include <KXMLGUIFactory>
42#include "progressspinnerdelegate_p.h"
49class EntityTreeView::Private
54#ifndef QT_NO_DRAGANDDROP
55 , mDragDropManager(new DragDropManager(mParent))
58 , mDefaultPopupMenu(QLatin1String(
"akonadi_collectionview_contextmenu"))
63 void itemClicked(
const QModelIndex &index);
64 void itemDoubleClicked(
const QModelIndex &index);
65 void itemCurrentChanged(
const QModelIndex &index);
67 void slotSelectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected);
70 QBasicTimer mDragExpandTimer;
71 DragDropManager *mDragDropManager;
72 KXMLGUIClient *mXmlGuiClient;
73 QString mDefaultPopupMenu;
76void EntityTreeView::Private::init()
78 Akonadi::DelegateAnimator *animator =
new Akonadi::DelegateAnimator(mParent);
79 Akonadi::ProgressSpinnerDelegate *customDelegate =
new Akonadi::ProgressSpinnerDelegate(animator, mParent);
80 mParent->setItemDelegate(customDelegate);
82 mParent->header()->setClickable(
true);
83 mParent->header()->setStretchLastSection(
false);
92 mParent->setSortingEnabled(
true);
93 mParent->sortByColumn(0, Qt::AscendingOrder);
94 mParent->setEditTriggers(QAbstractItemView::EditKeyPressed);
95 mParent->setAcceptDrops(
true);
96#ifndef QT_NO_DRAGANDDROP
97 mParent->setDropIndicatorShown(
true);
98 mParent->setDragDropMode(DragDrop);
99 mParent->setDragEnabled(
true);
102 mParent->connect(mParent, SIGNAL(
clicked(QModelIndex)),
103 mParent, SLOT(itemClicked(QModelIndex)));
104 mParent->connect(mParent, SIGNAL(
doubleClicked(QModelIndex)),
105 mParent, SLOT(itemDoubleClicked(QModelIndex)));
110void EntityTreeView::Private::slotSelectionChanged(
const QItemSelection &selected,
const QItemSelection &)
112 const int column = 0;
113 foreach (
const QItemSelectionRange &range, selected) {
114 const QModelIndex index = range.topLeft();
116 if (index.column() > 0) {
120 for (
int row = index.row(); row <= range.bottomRight().row(); ++row) {
123 mParent->model()->fetchMore(index.sibling(row, column));
127 if (selected.size() == 1) {
128 const QItemSelectionRange &range = selected.first();
129 if (range.topLeft().row() == range.bottomRight().row()) {
130 mParent->scrollTo(range.topLeft(), QTreeView::EnsureVisible);
135void EntityTreeView::Private::itemClicked(
const QModelIndex &index)
137 if (!index.isValid()) {
140 QModelIndex idx = index.sibling(index.row(), 0);
143 if (collection.isValid()) {
144 emit mParent->clicked(collection);
147 if (item.isValid()) {
148 emit mParent->clicked(item);
153void EntityTreeView::Private::itemDoubleClicked(
const QModelIndex &index)
155 if (!index.isValid()) {
158 QModelIndex idx = index.sibling(index.row(), 0);
160 if (collection.isValid()) {
161 emit mParent->doubleClicked(collection);
164 if (item.isValid()) {
165 emit mParent->doubleClicked(item);
170void EntityTreeView::Private::itemCurrentChanged(
const QModelIndex &index)
172 if (!index.isValid()) {
175 QModelIndex idx = index.sibling(index.row(), 0);
177 if (collection.isValid()) {
178 emit mParent->currentChanged(collection);
181 if (item.isValid()) {
182 emit mParent->currentChanged(item);
189 , d(new Private(this))
191 setSelectionMode(QAbstractItemView::SingleSelection);
197 , d(new Private(this))
205 delete d->mDragDropManager;
211 if (selectionModel()) {
212 disconnect(selectionModel(), SIGNAL(
currentChanged(QModelIndex,QModelIndex)),
213 this, SLOT(itemCurrentChanged(QModelIndex)));
215 disconnect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
216 this, SLOT(slotSelectionChanged(QItemSelection,QItemSelection)));
219 QTreeView::setModel(model);
220 header()->setStretchLastSection(
true);
222 connect(selectionModel(), SIGNAL(
currentChanged(QModelIndex,QModelIndex)),
223 SLOT(itemCurrentChanged(QModelIndex)));
225 connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
226 SLOT(slotSelectionChanged(QItemSelection,QItemSelection)));
229void EntityTreeView::timerEvent(QTimerEvent *event)
231 if (event->timerId() == d->mDragExpandTimer.timerId()) {
232 const QPoint pos = viewport()->mapFromGlobal(QCursor::pos());
233 if (state() == QAbstractItemView::DraggingState && viewport()->rect().contains(pos)) {
234 setExpanded(indexAt(pos),
true);
238 QTreeView::timerEvent(event);
241#ifndef QT_NO_DRAGANDDROP
242void EntityTreeView::dragMoveEvent(QDragMoveEvent *event)
244 d->mDragExpandTimer.start(QApplication::startDragTime() ,
this);
246 if (d->mDragDropManager->dropAllowed(event)) {
248 QTreeView::dragMoveEvent(event);
252 event->setDropAction(Qt::IgnoreAction);
255void EntityTreeView::dropEvent(QDropEvent *event)
257 d->mDragExpandTimer.stop();
258 bool menuCanceled =
false;
259 if (d->mDragDropManager->processDropEvent(event, menuCanceled, (dropIndicatorPosition() == QAbstractItemView::OnItem))) {
260 QTreeView::dropEvent(event);
265#ifndef QT_NO_CONTEXTMENU
266void EntityTreeView::contextMenuEvent(QContextMenuEvent *event)
268 if (!d->mXmlGuiClient || !model()) {
272 const QModelIndex index = indexAt(event->pos());
273 QString popupName = d->mDefaultPopupMenu;
275 if (index.isValid()) {
278 popupName = (item.isValid() ? QLatin1String(
"akonadi_itemview_contextmenu") :
279 QLatin1String(
"akonadi_collectionview_contextmenu"));
282 QMenu *popup =
static_cast<QMenu *
>(d->mXmlGuiClient->factory()->container(popupName, d->mXmlGuiClient));
284 popup->exec(event->globalPos());
296 return d->mXmlGuiClient;
299#ifndef QT_NO_DRAGANDDROP
300void EntityTreeView::startDrag(Qt::DropActions supportedActions)
302 d->mDragDropManager->startDrag(supportedActions);
308#ifndef QT_NO_DRAGANDDROP
309 d->mDragDropManager->setShowDropActionMenu(enabled);
315#ifndef QT_NO_DRAGANDDROP
316 return d->mDragDropManager->showDropActionMenu();
324#ifndef QT_NO_DRAGANDDROP
325 d->mDragDropManager->setManualSortingActive(active);
331#ifndef QT_NO_DRAGANDDROP
332 return d->mDragDropManager->isManualSortingActive();
340 d->mDefaultPopupMenu = name;
343#include "moc_entitytreeview.cpp"
Represents a collection of PIM items.
static void widgetNeedsAkonadi(QWidget *widget)
Disable the given widget when Akonadi is not operational and show an error overlay (given enough spac...
@ CollectionRole
The collection.
A view to show an item/collection tree provided by an EntityTreeModel.
void doubleClicked(const Akonadi::Collection &collection)
This signal is emitted whenever the user has double clicked a collection in the view.
bool isManualSortingActive() const
Return true if we use an manual sorting Necessary to fix dnd menu We must show just move when we move...
KXMLGUIClient * xmlGuiClient() const
Return the XML GUI client which the view is used in.
void setDropActionMenuEnabled(bool enabled)
Sets whether the drop action menu is enabled and will be shown on drop operation.
void clicked(const Akonadi::Collection &collection)
This signal is emitted whenever the user has clicked a collection in the view.
void setDefaultPopupMenu(const QString &name)
Set the name of the default popup menu (retrieved from the application's XMLGUI file).
virtual ~EntityTreeView()
Destroys the entity tree view.
void currentChanged(const Akonadi::Collection &collection)
This signal is emitted whenever the current collection in the view has changed.
EntityTreeView(QWidget *parent=0)
Creates a new entity tree view.
virtual void setModel(QAbstractItemModel *model)
void setXmlGuiClient(KXMLGUIClient *xmlGuiClient)
Sets the XML GUI client which the view is used in.
bool isDropActionMenuEnabled() const
Returns whether the drop action menu is enabled and will be shown on drop operation.
void setManualSortingActive(bool active)
Set true if we automatic sorting.
FreeBusyManager::Singleton.