]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/kitemlistcontroller.cpp
Rough draft for getting back drag and drop support
[dolphin.git] / src / kitemviews / kitemlistcontroller.cpp
1 /***************************************************************************
2 * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
3 * *
4 * Based on the Itemviews NG project from Trolltech Labs: *
5 * http://qt.gitorious.org/qt-labs/itemviews-ng *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
21 ***************************************************************************/
22
23 #include "kitemlistcontroller.h"
24
25 #include "kitemlistview.h"
26 #include "kitemlistrubberband_p.h"
27 #include "kitemlistselectionmanager.h"
28
29 // TODO: Remove after moving mimeData() and createDropPixmap() into
30 // KFileItemModel/KFileItemListView
31 #include "kfileitemmodel.h"
32 #include <KIcon>
33
34 #include <QApplication>
35 #include <QDrag>
36 #include <QEvent>
37 #include <QGraphicsSceneEvent>
38 #include <QMimeData>
39
40 #include <KDebug>
41
42 KItemListController::KItemListController(QObject* parent) :
43 QObject(parent),
44 m_dragging(false),
45 m_selectionBehavior(NoSelection),
46 m_model(0),
47 m_view(0),
48 m_selectionManager(new KItemListSelectionManager(this)),
49 m_pressedIndex(-1),
50 m_pressedMousePos(),
51 m_oldSelection()
52 {
53 }
54
55 KItemListController::~KItemListController()
56 {
57 }
58
59 void KItemListController::setModel(KItemModelBase* model)
60 {
61 if (m_model == model) {
62 return;
63 }
64
65 KItemModelBase* oldModel = m_model;
66 m_model = model;
67
68 if (m_view) {
69 m_view->setModel(m_model);
70 }
71
72 m_selectionManager->setModel(m_model);
73
74 emit modelChanged(m_model, oldModel);
75 }
76
77 KItemModelBase* KItemListController::model() const
78 {
79 return m_model;
80 }
81
82 KItemListSelectionManager* KItemListController::selectionManager() const
83 {
84 return m_selectionManager;
85 }
86
87 void KItemListController::setView(KItemListView* view)
88 {
89 if (m_view == view) {
90 return;
91 }
92
93 KItemListView* oldView = m_view;
94 if (oldView) {
95 disconnect(oldView, SIGNAL(offsetChanged(qreal,qreal)), this, SLOT(slotViewOffsetChanged(qreal,qreal)));
96 }
97
98 m_view = view;
99
100 if (m_view) {
101 m_view->setController(this);
102 m_view->setModel(m_model);
103 connect(m_view, SIGNAL(offsetChanged(qreal,qreal)), this, SLOT(slotViewOffsetChanged(qreal,qreal)));
104 }
105
106 emit viewChanged(m_view, oldView);
107 }
108
109 KItemListView* KItemListController::view() const
110 {
111 return m_view;
112 }
113
114 void KItemListController::setSelectionBehavior(SelectionBehavior behavior)
115 {
116 m_selectionBehavior = behavior;
117 }
118
119 KItemListController::SelectionBehavior KItemListController::selectionBehavior() const
120 {
121 return m_selectionBehavior;
122 }
123
124 bool KItemListController::showEvent(QShowEvent* event)
125 {
126 Q_UNUSED(event);
127 return false;
128 }
129
130 bool KItemListController::hideEvent(QHideEvent* event)
131 {
132 Q_UNUSED(event);
133 return false;
134 }
135
136 bool KItemListController::keyPressEvent(QKeyEvent* event)
137 {
138 const bool shiftPressed = event->modifiers() & Qt::ShiftModifier;
139 const bool controlPressed = event->modifiers() & Qt::ControlModifier;
140 const bool shiftOrControlPressed = shiftPressed || controlPressed;
141
142 int index = m_selectionManager->currentItem();
143 const int itemCount = m_model->count();
144 const int itemsPerRow = m_view->itemsPerOffset();
145
146 // For horizontal scroll orientation, transform
147 // the arrow keys to simplify the event handling.
148 int key = event->key();
149 if (m_view->scrollOrientation() == Qt::Horizontal) {
150 switch (key) {
151 case Qt::Key_Up: key = Qt::Key_Left; break;
152 case Qt::Key_Down: key = Qt::Key_Right; break;
153 case Qt::Key_Left: key = Qt::Key_Up; break;
154 case Qt::Key_Right: key = Qt::Key_Down; break;
155 default: break;
156 }
157 }
158
159 switch (key) {
160 case Qt::Key_Home:
161 index = 0;
162 break;
163
164 case Qt::Key_End:
165 index = itemCount - 1;
166 break;
167
168 case Qt::Key_Left:
169 if (index > 0) {
170 index--;
171 }
172 break;
173
174 case Qt::Key_Right:
175 if (index < itemCount - 1) {
176 index++;
177 }
178 break;
179
180 case Qt::Key_Up:
181 if (index >= itemsPerRow) {
182 index -= itemsPerRow;
183 }
184 break;
185
186 case Qt::Key_Down:
187 if (index + itemsPerRow < itemCount) {
188 // We are not in the last row yet.
189 index += itemsPerRow;
190 }
191 else {
192 // We are either in the last row already, or we are in the second-last row,
193 // and there is no item below the current item.
194 // In the latter case, we jump to the very last item.
195 const int currentColumn = index % itemsPerRow;
196 const int lastItemColumn = (itemCount - 1) % itemsPerRow;
197 const bool inLastRow = currentColumn < lastItemColumn;
198 if (!inLastRow) {
199 index = itemCount - 1;
200 }
201 }
202 break;
203
204 case Qt::Key_Space:
205 if (controlPressed) {
206 m_selectionManager->endAnchoredSelection();
207 m_selectionManager->setSelected(index, 1, KItemListSelectionManager::Toggle);
208 m_selectionManager->beginAnchoredSelection(index);
209 }
210
211 default:
212 break;
213 }
214
215 if (m_selectionManager->currentItem() != index) {
216 if (controlPressed) {
217 m_selectionManager->endAnchoredSelection();
218 }
219
220 m_selectionManager->setCurrentItem(index);
221
222 if (!shiftOrControlPressed || m_selectionBehavior == SingleSelection) {
223 m_selectionManager->clearSelection();
224 m_selectionManager->setSelected(index, 1);
225 }
226
227 if (!shiftPressed) {
228 m_selectionManager->beginAnchoredSelection(index);
229 }
230 }
231 return true;
232 }
233
234 bool KItemListController::inputMethodEvent(QInputMethodEvent* event)
235 {
236 Q_UNUSED(event);
237 return false;
238 }
239
240 bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform)
241 {
242 if (!m_view) {
243 return false;
244 }
245
246 m_pressedMousePos = transform.map(event->pos());
247 m_pressedIndex = m_view->itemAt(m_pressedMousePos);
248
249 if (m_view->isAboveExpansionToggle(m_pressedIndex, m_pressedMousePos)) {
250 return true;
251 }
252
253 const bool shiftPressed = event->modifiers() & Qt::ShiftModifier;
254 const bool controlPressed = event->modifiers() & Qt::ControlModifier;
255 const bool shiftOrControlPressed = shiftPressed || controlPressed;
256
257 if (!shiftOrControlPressed || m_selectionBehavior == SingleSelection) {
258 m_selectionManager->clearSelection();
259 }
260
261 if (!shiftPressed) {
262 // Finish the anchored selection before the current index is changed
263 m_selectionManager->endAnchoredSelection();
264 }
265
266 if (m_pressedIndex >= 0) {
267 m_selectionManager->setCurrentItem(m_pressedIndex);
268
269 switch (m_selectionBehavior) {
270 case NoSelection:
271 break;
272
273 case SingleSelection:
274 m_selectionManager->setSelected(m_pressedIndex);
275 break;
276
277 case MultiSelection:
278 if (controlPressed) {
279 m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Toggle);
280 m_selectionManager->beginAnchoredSelection(m_pressedIndex);
281 } else if (!shiftPressed || !m_selectionManager->isAnchoredSelectionActive()) {
282 // Select the pressed item and start a new anchored selection
283 m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Select);
284 m_selectionManager->beginAnchoredSelection(m_pressedIndex);
285 }
286 break;
287
288 default:
289 Q_ASSERT(false);
290 break;
291 }
292
293 return true;
294 } else {
295 KItemListRubberBand* rubberBand = m_view->rubberBand();
296 QPointF startPos = m_pressedMousePos;
297 if (m_view->scrollOrientation() == Qt::Vertical) {
298 startPos.ry() += m_view->offset();
299 if (m_view->itemSize().width() < 0) {
300 // Use a special rubberband for views that have only one column and
301 // expand the rubberband to use the whole width of the view.
302 startPos.setX(0);
303 }
304 } else {
305 startPos.rx() += m_view->offset();
306 }
307
308 m_oldSelection = m_selectionManager->selectedItems();
309 rubberBand->setStartPosition(startPos);
310 rubberBand->setEndPosition(startPos);
311 rubberBand->setActive(true);
312 connect(rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandChanged()));
313 }
314
315 return false;
316 }
317
318 bool KItemListController::mouseMoveEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform)
319 {
320 if (!m_view) {
321 return false;
322 }
323
324 if (m_pressedIndex >= 0) {
325 // Check whether a dragging should be started
326 if (!m_dragging) {
327 const QPointF pos = transform.map(event->pos());
328 const qreal minDragDiff = 4;
329 m_dragging = qAbs(pos.x() - m_pressedMousePos.x()) >= minDragDiff ||
330 qAbs(pos.y() - m_pressedMousePos.y()) >= minDragDiff;
331 if (m_dragging) {
332 startDragging();
333 }
334 }
335 } else {
336 KItemListRubberBand* rubberBand = m_view->rubberBand();
337 if (rubberBand->isActive()) {
338 QPointF endPos = transform.map(event->pos());
339 if (m_view->scrollOrientation() == Qt::Vertical) {
340 endPos.ry() += m_view->offset();
341 if (m_view->itemSize().width() < 0) {
342 // Use a special rubberband for views that have only one column and
343 // expand the rubberband to use the whole width of the view.
344 endPos.setX(m_view->size().width());
345 }
346 } else {
347 endPos.rx() += m_view->offset();
348 }
349 rubberBand->setEndPosition(endPos);
350 }
351 }
352
353 return false;
354 }
355
356 bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform)
357 {
358 if (!m_view) {
359 return false;
360 }
361
362 KItemListRubberBand* rubberBand = m_view->rubberBand();
363 if (rubberBand->isActive()) {
364 disconnect(rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandChanged()));
365 rubberBand->setActive(false);
366 m_oldSelection.clear();
367 } else {
368 const QPointF pos = transform.map(event->pos());
369 const int index = m_view->itemAt(pos);
370 const bool shiftOrControlPressed = event->modifiers() & Qt::ShiftModifier ||
371 event->modifiers() & Qt::ControlModifier;
372
373 if (index >= 0 && index == m_pressedIndex) {
374 // The release event is done above the same item as the press event
375 bool emitItemClicked = true;
376 if (event->button() & Qt::LeftButton) {
377 if (m_view->isAboveExpansionToggle(index, pos)) {
378 emit itemExpansionToggleClicked(index);
379 emitItemClicked = false;
380 } else if (shiftOrControlPressed) {
381 // The mouse click should only update the selection, not trigger the item
382 emitItemClicked = false;
383 }
384 }
385
386 if (emitItemClicked) {
387 emit itemClicked(index, event->button());
388 }
389 } else if (!shiftOrControlPressed) {
390 m_selectionManager->clearSelection();
391 }
392 }
393
394 m_dragging = false;
395 m_pressedMousePos = QPointF();
396 m_pressedIndex = -1;
397 return false;
398 }
399
400 bool KItemListController::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform)
401 {
402 Q_UNUSED(event);
403 Q_UNUSED(transform);
404 return false;
405 }
406
407 bool KItemListController::dragEnterEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform)
408 {
409 Q_UNUSED(event);
410 Q_UNUSED(transform);
411 return false;
412 }
413
414 bool KItemListController::dragLeaveEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform)
415 {
416 Q_UNUSED(event);
417 Q_UNUSED(transform);
418 return false;
419 }
420
421 bool KItemListController::dragMoveEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform)
422 {
423 Q_UNUSED(event);
424 Q_UNUSED(transform);
425 return false;
426 }
427
428 bool KItemListController::dropEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform)
429 {
430 Q_UNUSED(event);
431 Q_UNUSED(transform);
432
433 m_dragging = false;
434 return false;
435 }
436
437 bool KItemListController::hoverEnterEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform)
438 {
439 Q_UNUSED(event);
440 Q_UNUSED(transform);
441 return false;
442 }
443
444 bool KItemListController::hoverMoveEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform)
445 {
446 // The implementation assumes that only one item can get hovered no matter
447 // whether they overlap or not.
448
449 Q_UNUSED(transform);
450 if (!m_model || !m_view) {
451 return false;
452 }
453
454 // Search the previously hovered item that might get unhovered
455 KItemListWidget* unhoveredWidget = 0;
456 foreach (KItemListWidget* widget, m_view->visibleItemListWidgets()) {
457 if (widget->isHovered()) {
458 unhoveredWidget = widget;
459 break;
460 }
461 }
462
463 // Search the currently hovered item
464 KItemListWidget* hoveredWidget = 0;
465 foreach (KItemListWidget* widget, m_view->visibleItemListWidgets()) {
466 const QPointF mappedPos = widget->mapFromItem(m_view, event->pos());
467
468 const bool hovered = widget->contains(mappedPos) &&
469 !widget->expansionToggleRect().contains(mappedPos) &&
470 !widget->selectionToggleRect().contains(mappedPos);
471 if (hovered) {
472 hoveredWidget = widget;
473 break;
474 }
475 }
476
477 if (unhoveredWidget != hoveredWidget) {
478 if (unhoveredWidget) {
479 unhoveredWidget->setHovered(false);
480 emit itemUnhovered(unhoveredWidget->index());
481 }
482
483 if (hoveredWidget) {
484 hoveredWidget->setHovered(true);
485 emit itemHovered(hoveredWidget->index());
486 }
487 }
488
489 return false;
490 }
491
492 bool KItemListController::hoverLeaveEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform)
493 {
494 Q_UNUSED(event);
495 Q_UNUSED(transform);
496
497 if (!m_model || !m_view) {
498 return false;
499 }
500
501 foreach (KItemListWidget* widget, m_view->visibleItemListWidgets()) {
502 if (widget->isHovered()) {
503 widget->setHovered(false);
504 emit itemUnhovered(widget->index());
505 }
506 }
507 return false;
508 }
509
510 bool KItemListController::wheelEvent(QGraphicsSceneWheelEvent* event, const QTransform& transform)
511 {
512 Q_UNUSED(event);
513 Q_UNUSED(transform);
514 return false;
515 }
516
517 bool KItemListController::resizeEvent(QGraphicsSceneResizeEvent* event, const QTransform& transform)
518 {
519 Q_UNUSED(event);
520 Q_UNUSED(transform);
521 return false;
522 }
523
524 bool KItemListController::processEvent(QEvent* event, const QTransform& transform)
525 {
526 if (!event) {
527 return false;
528 }
529
530 switch (event->type()) {
531 case QEvent::KeyPress:
532 return keyPressEvent(static_cast<QKeyEvent*>(event));
533 case QEvent::InputMethod:
534 return inputMethodEvent(static_cast<QInputMethodEvent*>(event));
535 case QEvent::GraphicsSceneMousePress:
536 return mousePressEvent(static_cast<QGraphicsSceneMouseEvent*>(event), QTransform());
537 case QEvent::GraphicsSceneMouseMove:
538 return mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent*>(event), QTransform());
539 case QEvent::GraphicsSceneMouseRelease:
540 return mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent*>(event), QTransform());
541 case QEvent::GraphicsSceneWheel:
542 return wheelEvent(static_cast<QGraphicsSceneWheelEvent*>(event), QTransform());
543 case QEvent::GraphicsSceneDragEnter:
544 return dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent*>(event), QTransform());
545 case QEvent::GraphicsSceneDragLeave:
546 return dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent*>(event), QTransform());
547 case QEvent::GraphicsSceneDragMove:
548 return dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent*>(event), QTransform());
549 case QEvent::GraphicsSceneDrop:
550 return dropEvent(static_cast<QGraphicsSceneDragDropEvent*>(event), QTransform());
551 case QEvent::GraphicsSceneHoverEnter:
552 return hoverEnterEvent(static_cast<QGraphicsSceneHoverEvent*>(event), QTransform());
553 case QEvent::GraphicsSceneHoverMove:
554 return hoverMoveEvent(static_cast<QGraphicsSceneHoverEvent*>(event), QTransform());
555 case QEvent::GraphicsSceneHoverLeave:
556 return hoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent*>(event), QTransform());
557 case QEvent::GraphicsSceneResize:
558 return resizeEvent(static_cast<QGraphicsSceneResizeEvent*>(event), transform);
559 default:
560 break;
561 }
562
563 return false;
564 }
565
566 void KItemListController::slotViewOffsetChanged(qreal current, qreal previous)
567 {
568 if (!m_view) {
569 return;
570 }
571
572 KItemListRubberBand* rubberBand = m_view->rubberBand();
573 if (rubberBand->isActive()) {
574 const qreal diff = current - previous;
575 // TODO: Ideally just QCursor::pos() should be used as
576 // new end-position but it seems there is no easy way
577 // to have something like QWidget::mapFromGlobal() for QGraphicsWidget
578 // (... or I just missed an easy way to do the mapping)
579 QPointF endPos = rubberBand->endPosition();
580 if (m_view->scrollOrientation() == Qt::Vertical) {
581 endPos.ry() += diff;
582 } else {
583 endPos.rx() += diff;
584 }
585
586 rubberBand->setEndPosition(endPos);
587 }
588 }
589
590 void KItemListController::slotRubberBandChanged()
591 {
592 if (!m_view || !m_model || m_model->count() <= 0) {
593 return;
594 }
595
596 const KItemListRubberBand* rubberBand = m_view->rubberBand();
597 const QPointF startPos = rubberBand->startPosition();
598 const QPointF endPos = rubberBand->endPosition();
599 QRectF rubberBandRect = QRectF(startPos, endPos).normalized();
600
601 const bool scrollVertical = (m_view->scrollOrientation() == Qt::Vertical);
602 if (scrollVertical) {
603 rubberBandRect.translate(0, -m_view->offset());
604 } else {
605 rubberBandRect.translate(-m_view->offset(), 0);
606 }
607
608 if (!m_oldSelection.isEmpty()) {
609 // Clear the old selection that was available before the rubberband has
610 // been activated in case if no Shift- or Control-key are pressed
611 const bool shiftOrControlPressed = QApplication::keyboardModifiers() & Qt::ShiftModifier ||
612 QApplication::keyboardModifiers() & Qt::ControlModifier;
613 if (!shiftOrControlPressed) {
614 m_oldSelection.clear();
615 }
616 }
617
618 QSet<int> selectedItems;
619
620 // Select all visible items that intersect with the rubberband
621 foreach (const KItemListWidget* widget, m_view->visibleItemListWidgets()) {
622 const int index = widget->index();
623
624 const QRectF widgetRect = m_view->itemBoundingRect(index);
625 if (widgetRect.intersects(rubberBandRect)) {
626 const QRectF iconRect = widget->iconBoundingRect().translated(widgetRect.topLeft());
627 const QRectF textRect = widget->textBoundingRect().translated(widgetRect.topLeft());
628 if (iconRect.intersects(rubberBandRect) || textRect.intersects(rubberBandRect)) {
629 selectedItems.insert(index);
630 }
631 }
632 }
633
634 // Select all invisible items that intersect with the rubberband. Instead of
635 // iterating all items only the area which might be touched by the rubberband
636 // will be checked.
637 const bool increaseIndex = scrollVertical ?
638 startPos.y() > endPos.y(): startPos.x() > endPos.x();
639
640 int index = increaseIndex ? m_view->lastVisibleIndex() + 1 : m_view->firstVisibleIndex() - 1;
641 bool selectionFinished = false;
642 do {
643 const QRectF widgetRect = m_view->itemBoundingRect(index);
644 if (widgetRect.intersects(rubberBandRect)) {
645 selectedItems.insert(index);
646 }
647
648 if (increaseIndex) {
649 ++index;
650 selectionFinished = (index >= m_model->count()) ||
651 ( scrollVertical && widgetRect.top() > rubberBandRect.bottom()) ||
652 (!scrollVertical && widgetRect.left() > rubberBandRect.right());
653 } else {
654 --index;
655 selectionFinished = (index < 0) ||
656 ( scrollVertical && widgetRect.bottom() < rubberBandRect.top()) ||
657 (!scrollVertical && widgetRect.right() < rubberBandRect.left());
658 }
659 } while (!selectionFinished);
660
661 m_selectionManager->setSelectedItems(selectedItems + m_oldSelection);
662 }
663
664 QPixmap KItemListController::createDragPixmap(const QSet<int>& indexes) const
665 {
666 if (!m_model || !m_view) {
667 return QPixmap();
668 }
669
670 // TODO: The current hack assumes a property "iconPixmap" in the model. The method
671 // will get an interface of KFileItemList later.
672 QSetIterator<int> it(indexes);
673 while (it.hasNext()) {
674 const int index = it.next();
675 // TODO: Only one item is considered currently
676 QPixmap pixmap = m_model->data(index).value("iconPixmap").value<QPixmap>();
677 if (pixmap.isNull()) {
678 KIcon icon(m_model->data(index).value("iconName").toString());
679 const QSizeF size = m_view->itemSize();
680 pixmap = icon.pixmap(size.toSize());
681 }
682 return pixmap;
683 }
684
685 return QPixmap();
686 }
687
688 QMimeData* KItemListController::createMimeData(const QSet<int>& indexes) const
689 {
690 if (!m_model) {
691 return 0;
692 }
693
694 QMimeData* data = new QMimeData();
695
696 // TODO: Check KDirModel::mimeData() for a good reference implementation
697 KUrl::List urls;
698 QSetIterator<int> it(indexes);
699 while (it.hasNext()) {
700 const int index = it.next();
701 // TODO: Big hack to use KFileItemModel here. Remove after moving mimeData()
702 // into KFileItemModel.
703 KFileItemModel* model = qobject_cast<KFileItemModel*>(m_model);
704 Q_ASSERT(model);
705 const KUrl url = model->fileItem(index).url();
706 urls.append(url);
707 }
708
709 urls.populateMimeData(data);
710
711 return data;
712 }
713
714 void KItemListController::startDragging()
715 {
716 // The created drag object will be owned and deleted
717 // by QApplication::activeWindow().
718 QDrag* drag = new QDrag(QApplication::activeWindow());
719
720 const QSet<int> selectedItems = m_selectionManager->selectedItems();
721
722 const QPixmap pixmap = createDragPixmap(selectedItems);
723 drag->setPixmap(pixmap);
724
725 QMimeData* data = createMimeData(selectedItems);
726 drag->setMimeData(data);
727
728 drag->exec(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction, Qt::IgnoreAction);
729 }
730
731 #include "kitemlistcontroller.moc"