┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kitemviews/kitemlistcontroller.cpp169
-rw-r--r--src/kitemviews/kitemlistcontroller.h24
-rw-r--r--src/kitemviews/kitemlistview.cpp6
-rw-r--r--src/kitemviews/kitemlistview.h1
4 files changed, 161 insertions, 39 deletions
diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp
index beb5b5c0a..15aab28d5 100644
--- a/src/kitemviews/kitemlistcontroller.cpp
+++ b/src/kitemviews/kitemlistcontroller.cpp
@@ -26,19 +26,28 @@
#include "kitemlistrubberband_p.h"
#include "kitemlistselectionmanager.h"
+// TODO: Remove after moving mimeData() and createDropPixmap() into
+// KFileItemModel/KFileItemListView
+#include "kfileitemmodel.h"
+#include <KIcon>
+
#include <QApplication>
+#include <QDrag>
#include <QEvent>
#include <QGraphicsSceneEvent>
+#include <QMimeData>
#include <KDebug>
KItemListController::KItemListController(QObject* parent) :
QObject(parent),
+ m_dragging(false),
m_selectionBehavior(NoSelection),
m_model(0),
m_view(0),
m_selectionManager(new KItemListSelectionManager(this)),
m_pressedIndex(-1),
+ m_pressedMousePos(),
m_oldSelection()
{
}
@@ -234,10 +243,10 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const
return false;
}
- const QPointF pos = transform.map(event->pos());
- m_pressedIndex = m_view->itemAt(pos);
+ m_pressedMousePos = transform.map(event->pos());
+ m_pressedIndex = m_view->itemAt(m_pressedMousePos);
- if (m_view->isAboveExpansionToggle(m_pressedIndex, pos)) {
+ if (m_view->isAboveExpansionToggle(m_pressedIndex, m_pressedMousePos)) {
return true;
}
@@ -284,7 +293,7 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const
return true;
} else {
KItemListRubberBand* rubberBand = m_view->rubberBand();
- QPointF startPos = pos;
+ QPointF startPos = m_pressedMousePos;
if (m_view->scrollOrientation() == Qt::Vertical) {
startPos.ry() += m_view->offset();
if (m_view->itemSize().width() < 0) {
@@ -312,20 +321,33 @@ bool KItemListController::mouseMoveEvent(QGraphicsSceneMouseEvent* event, const
return false;
}
- KItemListRubberBand* rubberBand = m_view->rubberBand();
- if (rubberBand->isActive()) {
- QPointF endPos = transform.map(event->pos());
- if (m_view->scrollOrientation() == Qt::Vertical) {
- endPos.ry() += m_view->offset();
- if (m_view->itemSize().width() < 0) {
- // Use a special rubberband for views that have only one column and
- // expand the rubberband to use the whole width of the view.
- endPos.setX(m_view->size().width());
+ if (m_pressedIndex >= 0) {
+ // Check whether a dragging should be started
+ if (!m_dragging) {
+ const QPointF pos = transform.map(event->pos());
+ const qreal minDragDiff = 4;
+ m_dragging = qAbs(pos.x() - m_pressedMousePos.x()) >= minDragDiff ||
+ qAbs(pos.y() - m_pressedMousePos.y()) >= minDragDiff;
+ if (m_dragging) {
+ startDragging();
}
- } else {
- endPos.rx() += m_view->offset();
}
- rubberBand->setEndPosition(endPos);
+ } else {
+ KItemListRubberBand* rubberBand = m_view->rubberBand();
+ if (rubberBand->isActive()) {
+ QPointF endPos = transform.map(event->pos());
+ if (m_view->scrollOrientation() == Qt::Vertical) {
+ endPos.ry() += m_view->offset();
+ if (m_view->itemSize().width() < 0) {
+ // Use a special rubberband for views that have only one column and
+ // expand the rubberband to use the whole width of the view.
+ endPos.setX(m_view->size().width());
+ }
+ } else {
+ endPos.rx() += m_view->offset();
+ }
+ rubberBand->setEndPosition(endPos);
+ }
}
return false;
@@ -342,35 +364,35 @@ bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, con
disconnect(rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandChanged()));
rubberBand->setActive(false);
m_oldSelection.clear();
- m_pressedIndex = -1;
- return false;
- }
-
- const QPointF pos = transform.map(event->pos());
- const int index = m_view->itemAt(pos);
- const bool shiftOrControlPressed = event->modifiers() & Qt::ShiftModifier || event->modifiers() & Qt::ControlModifier;
+ } else {
+ const QPointF pos = transform.map(event->pos());
+ const int index = m_view->itemAt(pos);
+ const bool shiftOrControlPressed = event->modifiers() & Qt::ShiftModifier ||
+ event->modifiers() & Qt::ControlModifier;
- if (index >= 0 && index == m_pressedIndex) {
- // The release event is done above the same item as the press event
- bool emitItemClicked = true;
- if (event->button() & Qt::LeftButton) {
- if (m_view->isAboveExpansionToggle(index, pos)) {
- emit itemExpansionToggleClicked(index);
- emitItemClicked = false;
- }
- else if (shiftOrControlPressed) {
- // The mouse click should only update the selection, not trigger the item
- emitItemClicked = false;
+ if (index >= 0 && index == m_pressedIndex) {
+ // The release event is done above the same item as the press event
+ bool emitItemClicked = true;
+ if (event->button() & Qt::LeftButton) {
+ if (m_view->isAboveExpansionToggle(index, pos)) {
+ emit itemExpansionToggleClicked(index);
+ emitItemClicked = false;
+ } else if (shiftOrControlPressed) {
+ // The mouse click should only update the selection, not trigger the item
+ emitItemClicked = false;
+ }
}
- }
- if (emitItemClicked) {
- emit itemClicked(index, event->button());
+ if (emitItemClicked) {
+ emit itemClicked(index, event->button());
+ }
+ } else if (!shiftOrControlPressed) {
+ m_selectionManager->clearSelection();
}
- } else if (!shiftOrControlPressed) {
- m_selectionManager->clearSelection();
}
+ m_dragging = false;
+ m_pressedMousePos = QPointF();
m_pressedIndex = -1;
return false;
}
@@ -407,6 +429,8 @@ bool KItemListController::dropEvent(QGraphicsSceneDragDropEvent* event, const QT
{
Q_UNUSED(event);
Q_UNUSED(transform);
+
+ m_dragging = false;
return false;
}
@@ -637,4 +661,71 @@ void KItemListController::slotRubberBandChanged()
m_selectionManager->setSelectedItems(selectedItems + m_oldSelection);
}
+QPixmap KItemListController::createDragPixmap(const QSet<int>& indexes) const
+{
+ if (!m_model || !m_view) {
+ return QPixmap();
+ }
+
+ // TODO: The current hack assumes a property "iconPixmap" in the model. The method
+ // will get an interface of KFileItemList later.
+ QSetIterator<int> it(indexes);
+ while (it.hasNext()) {
+ const int index = it.next();
+ // TODO: Only one item is considered currently
+ QPixmap pixmap = m_model->data(index).value("iconPixmap").value<QPixmap>();
+ if (pixmap.isNull()) {
+ KIcon icon(m_model->data(index).value("iconName").toString());
+ const QSizeF size = m_view->itemSize();
+ pixmap = icon.pixmap(size.toSize());
+ }
+ return pixmap;
+ }
+
+ return QPixmap();
+}
+
+QMimeData* KItemListController::createMimeData(const QSet<int>& indexes) const
+{
+ if (!m_model) {
+ return 0;
+ }
+
+ QMimeData* data = new QMimeData();
+
+ // TODO: Check KDirModel::mimeData() for a good reference implementation
+ KUrl::List urls;
+ QSetIterator<int> it(indexes);
+ while (it.hasNext()) {
+ const int index = it.next();
+ // TODO: Big hack to use KFileItemModel here. Remove after moving mimeData()
+ // into KFileItemModel.
+ KFileItemModel* model = qobject_cast<KFileItemModel*>(m_model);
+ Q_ASSERT(model);
+ const KUrl url = model->fileItem(index).url();
+ urls.append(url);
+ }
+
+ urls.populateMimeData(data);
+
+ return data;
+}
+
+void KItemListController::startDragging()
+{
+ // The created drag object will be owned and deleted
+ // by QApplication::activeWindow().
+ QDrag* drag = new QDrag(QApplication::activeWindow());
+
+ const QSet<int> selectedItems = m_selectionManager->selectedItems();
+
+ const QPixmap pixmap = createDragPixmap(selectedItems);
+ drag->setPixmap(pixmap);
+
+ QMimeData* data = createMimeData(selectedItems);
+ drag->setMimeData(data);
+
+ drag->exec(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction, Qt::IgnoreAction);
+}
+
#include "kitemlistcontroller.moc"
diff --git a/src/kitemviews/kitemlistcontroller.h b/src/kitemviews/kitemlistcontroller.h
index 90850bae1..b56087ce1 100644
--- a/src/kitemviews/kitemlistcontroller.h
+++ b/src/kitemviews/kitemlistcontroller.h
@@ -26,6 +26,8 @@
#include <libdolphin_export.h>
#include <QObject>
+#include <QPixmap>
+#include <QPointF>
#include <QSet>
class KItemModelBase;
@@ -39,6 +41,7 @@ class QGraphicsSceneWheelEvent;
class QHideEvent;
class QInputMethodEvent;
class QKeyEvent;
+class QMimeData;
class QShowEvent;
class QTransform;
@@ -130,11 +133,32 @@ private slots:
void slotRubberBandChanged();
private:
+ /**
+ * @return Pixmap that is used for a drag operation based on the
+ * items given by \a indexes.
+ * TODO: Will be moved to KItemListView later
+ */
+ QPixmap createDragPixmap(const QSet<int>& indexes) const;
+
+ /**
+ * @return MIME-data for the items given by \a indexes.
+ * TODO: Will be moved to KItemListView or KItemModelBase/KFileItemModel later.
+ */
+ QMimeData* createMimeData(const QSet<int>& indexes) const;
+
+ /**
+ * Creates a QDrag object to start a drag-operation.
+ */
+ void startDragging();
+
+private:
+ bool m_dragging;
SelectionBehavior m_selectionBehavior;
KItemModelBase* m_model;
KItemListView* m_view;
KItemListSelectionManager* m_selectionManager;
int m_pressedIndex;
+ QPointF m_pressedMousePos;
/**
* When starting a rubberband selection during a Shift- or Control-key has been
diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp
index 9189cbda3..4bf7159d6 100644
--- a/src/kitemviews/kitemlistview.cpp
+++ b/src/kitemviews/kitemlistview.cpp
@@ -66,6 +66,7 @@ KItemListView::KItemListView(QGraphicsWidget* parent) :
m_mousePos()
{
setAcceptHoverEvents(true);
+ setAcceptDrops(true);
m_sizeHintResolver = new KItemListSizeHintResolver(this);
@@ -459,6 +460,11 @@ void KItemListView::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
QGraphicsWidget::mouseMoveEvent(event);
}
+void KItemListView::dragEnterEvent(QGraphicsSceneDragDropEvent* event)
+{
+ event->setAccepted(true);
+}
+
QList<KItemListWidget*> KItemListView::visibleItemListWidgets() const
{
return m_visibleItems.values();
diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h
index 3f877d236..2a07dbb23 100644
--- a/src/kitemviews/kitemlistview.h
+++ b/src/kitemviews/kitemlistview.h
@@ -183,6 +183,7 @@ protected:
virtual bool event(QEvent* event);
virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
+ virtual void dragEnterEvent(QGraphicsSceneDragDropEvent* event);
QList<KItemListWidget*> visibleItemListWidgets() const;