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>
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"
49 class 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;
76 void 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)));
110 void 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);
135 void 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);
153 void 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);
170 void 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)));
229 void 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
242 void 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);
255 void 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
266 void 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
300 void 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"