-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfiletreewidget.cpp
More file actions
107 lines (94 loc) · 3 KB
/
filetreewidget.cpp
File metadata and controls
107 lines (94 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "filetreewidget.h"
#include "mainwindow.h"
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDragLeaveEvent>
#include <QDropEvent>
#include <QItemSelectionModel>
FileTreeWidget::FileTreeWidget(QWidget* parent)
: QTreeWidget(parent)
{
setDragEnabled(true);
setAcceptDrops(true);
setDropIndicatorShown(true);
setDragDropMode(QAbstractItemView::DragDrop);
setDefaultDropAction(Qt::MoveAction);
setSelectionMode(QAbstractItemView::SingleSelection);
}
QTreeWidgetItem* FileTreeWidget::targetGroupItemForPos(const QPoint& viewportPos) const
{
QTreeWidgetItem* target = itemAt(viewportPos);
if (!target) return nullptr;
if (target->data(0, ITEM_KIND_ROLE).toInt() == ITEM_GROUP) return target;
return target->parent();
}
QString FileTreeWidget::targetGroupForPos(const QPoint& viewportPos) const
{
QTreeWidgetItem* g = targetGroupItemForPos(viewportPos);
return g ? g->text(0) : QString(); // empty == root
}
bool FileTreeWidget::isAcceptableDrop(const QPoint& viewportPos) const
{
if (!m_dragSource) return false;
if (m_dragSource->data(0, ITEM_KIND_ROLE).toInt() != ITEM_NOTE) return false;
QString srcGroup = m_dragSource->parent() ? m_dragSource->parent()->text(0) : QString();
QString dstGroup = targetGroupForPos(viewportPos);
if (dstGroup == srcGroup) return false; // empty == root
return true;
}
void FileTreeWidget::dragEnterEvent(QDragEnterEvent* event)
{
if (event->source() != this) { event->ignore(); return; }
QList<QTreeWidgetItem*> sel = selectedItems();
m_dragSource = sel.isEmpty() ? nullptr : sel.first();
if (!m_dragSource || m_dragSource->data(0, ITEM_KIND_ROLE).toInt() != ITEM_NOTE)
{
event->ignore();
return;
}
event->acceptProposedAction();
}
void FileTreeWidget::dragMoveEvent(QDragMoveEvent* event)
{
if (event->source() == this && isAcceptableDrop(event->pos()))
{
QTreeWidgetItem* g = targetGroupItemForPos(event->pos());
if (g)
{
setCurrentItem(g);
}
else
{
// root target: actively clear current/selection so no group looks highlighted
selectionModel()->clearCurrentIndex();
clearSelection();
}
event->acceptProposedAction();
}
else
{
event->ignore();
}
}
void FileTreeWidget::dragLeaveEvent(QDragLeaveEvent* event)
{
// restore selection to the original source so the visual state is consistent
// if the user drops outside the viewport
if (m_dragSource) setCurrentItem(m_dragSource);
m_dragSource = nullptr;
QTreeWidget::dragLeaveEvent(event);
}
void FileTreeWidget::dropEvent(QDropEvent* event)
{
if (!isAcceptableDrop(event->pos()))
{
event->ignore();
return;
}
QTreeWidgetItem* src = m_dragSource;
QString dstGroup = targetGroupForPos(event->pos());
m_dragSource = nullptr;
event->setDropAction(Qt::IgnoreAction);
event->accept();
emit noteDropped(src, dstGroup);
}