Skip to content

Commit 8d33347

Browse files
committed
App: add drag and drop in favorite
1 parent 55cdcd1 commit 8d33347

6 files changed

Lines changed: 184 additions & 58 deletions

File tree

App/Client/Favorite/FavoriteMimeData.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,13 @@
55
CFavoriteMimeData::CFavoriteMimeData(QObject *parent) : QMimeData()
66
{
77
}
8+
9+
bool CFavoriteMimeData::hasFormat(const QString &mimetype) const
10+
{
11+
return MIME_TYPE_RABBITREMOTECONTROL_APP_FAVORITE == mimetype;
12+
}
13+
14+
QStringList CFavoriteMimeData::formats() const
15+
{
16+
return QStringList() << MIME_TYPE_RABBITREMOTECONTROL_APP_FAVORITE;
17+
}

App/Client/Favorite/FavoriteMimeData.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44
#include <QMimeData>
55
#include <QModelIndexList>
66

7+
#define MIME_TYPE_RABBITREMOTECONTROL_APP_FAVORITE "rabbit/remotecontrol/App/Favorite"
78
class CFavoriteMimeData : public QMimeData
89
{
910
Q_OBJECT
1011

1112
public:
1213
CFavoriteMimeData(QObject *parent = nullptr);
1314
QModelIndexList m_Items;
15+
16+
virtual bool hasFormat(const QString &mimetype) const override;
17+
virtual QStringList formats() const override;
1418
};

App/Client/Favorite/FavoriteModel.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,52 @@ bool CFavoriteModel::UpdateFavorite(
270270
return true;
271271
}
272272

273+
bool CFavoriteModel::Move(QModelIndex index, QModelIndex parentIndex)
274+
{
275+
if(!index.isValid()) return false;
276+
tree* ip = GetTree(index);
277+
if(!ip) return false;
278+
tree* ipParent = GetTree(parentIndex);
279+
if(!ipParent || ipParent->item.isFavorite()) return false;
280+
int nParentId = ipParent->item.id;
281+
auto& item = ip->item;
282+
bool bRet = false;
283+
if(item.isFavorite())
284+
bRet = m_pDatabase->Move(item.id, nParentId);
285+
else {
286+
if(item.id != nParentId)
287+
bRet = m_pDatabase->MoveNode(item.id, nParentId);
288+
else
289+
qWarning(log) << "The same node:" << item.id;
290+
}
291+
if(bRet)
292+
bRet = MoveTree(ip->item, ipParent->item.id);
293+
return bRet;
294+
}
295+
296+
// TODO: not test!!!
297+
bool CFavoriteModel::Copy(QModelIndex index, QModelIndex parentIndex)
298+
{
299+
bool bRet = false;
300+
if(!index.isValid()) return false;
301+
tree* ip = GetTree(index);
302+
if(!ip) return false;
303+
tree* ipParent = GetTree(parentIndex);
304+
if(!ipParent || ipParent->item.isFavorite()) return false;
305+
int nParentId = ipParent->item.id;
306+
auto& item = ip->item;
307+
if(item.isFavorite())
308+
bRet = AddFavorite(item.szFile, item.szName, item.GetIcon(),
309+
item.szDescription, nParentId);
310+
else {
311+
if(item.id != nParentId)
312+
bRet = m_pDatabase->AddNode(item.szName, nParentId);
313+
if(bRet)
314+
bRet = AddTree(item, nParentId);
315+
}
316+
return bRet;
317+
}
318+
273319
CFavoriteDatabase::Item CFavoriteModel::GetFavorite(const QString &szFile)
274320
{
275321
CFavoriteDatabase::Item item;
@@ -424,6 +470,9 @@ bool CFavoriteModel::MoveTree(const CFavoriteDatabase::Item &item, int newParent
424470
if(parentId == newParentId)
425471
return true;
426472

473+
if(item.isFolder() && item.id == newParentId)
474+
return true;
475+
427476
tree* parent = GetTree(parentId);
428477
if(!parent) return false;
429478

App/Client/Favorite/FavoriteModel.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class CFavoriteModel : public QAbstractItemModel
2626
CFavoriteDatabase::Item GetFavorite(const QString& szFile);
2727
void Refresh();
2828

29+
bool Move(QModelIndex index, QModelIndex parentIndex);
30+
bool Copy(QModelIndex index, QModelIndex parentIndex);
2931
enum RoleType {
3032
RoleFile = Qt::UserRole,
3133
RoleNodeType,

App/Client/Favorite/FavoriteView.cpp

Lines changed: 116 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,14 @@ void CFavoriteView::setupTreeView(QLayout *layout)
185185
return;
186186
layout->addWidget(m_pTreeView);
187187

188+
//m_pTreeView->installEventFilter(this);
189+
m_pTreeView->viewport()->installEventFilter(this);
188190
m_pTreeView->setAcceptDrops(true);
191+
m_pTreeView->setDragEnabled(true);
192+
m_pTreeView->setDragDropMode(QTreeView::InternalMove);
193+
m_pTreeView->setDefaultDropAction(Qt::MoveAction);
194+
m_pTreeView->setDropIndicatorShown(true);
195+
189196
m_pTreeView->setUniformRowHeights(true);
190197
m_pTreeView->setHeaderHidden(true);
191198

@@ -508,77 +515,113 @@ void CFavoriteView::slotExport()
508515

509516
void CFavoriteView::dragEnterEvent(QDragEnterEvent *event)
510517
{
511-
qDebug(log) << "dragEnterEvent";
518+
qDebug(log) << Q_FUNC_INFO;
512519
const CFavoriteMimeData* pData =
513520
qobject_cast<const CFavoriteMimeData*>(event->mimeData());
514521
if (pData)
515522
{
516523
qDebug(log) << "dragEnterEvent acceptProposedAction";
517524
event->acceptProposedAction();
518-
}
525+
/*
526+
// 设置拖拽时的光标
527+
if (event->proposedAction() == Qt::MoveAction) {
528+
setCursor(Qt::DragMoveCursor);
529+
} else {
530+
setCursor(Qt::DragCopyCursor);
531+
}//*/
532+
} else
533+
event->ignore();
519534
}
520535

521536
void CFavoriteView::dragMoveEvent(QDragMoveEvent *event)
522537
{
538+
qDebug(log) << Q_FUNC_INFO;
539+
const CFavoriteMimeData* pData =
540+
qobject_cast<const CFavoriteMimeData*>(event->mimeData());
541+
if (!pData)
542+
{
543+
event->ignore();
544+
return;
545+
}
523546
}
524547

525548
void CFavoriteView::dropEvent(QDropEvent *event)
526549
{
527-
qDebug(log) << "dropEvent";
550+
qDebug(log) << Q_FUNC_INFO << "drop action:" << event->dropAction();
551+
528552
const CFavoriteMimeData *pData = qobject_cast<const CFavoriteMimeData*>(event->mimeData());
529-
if(!pData) return;
530-
/*
531-
QStandardItemModel* pModel = dynamic_cast<QStandardItemModel*>(model());
532-
if(!pModel) return;
553+
if(!pData || pData->m_Items.isEmpty() || !m_pTreeView || !m_pModel) {
554+
event->ignore();
555+
return;
556+
}
557+
558+
bool bRet = false;
533559
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
534-
auto index = indexAt(event->position().toPoint());
560+
auto idxParent = m_pTreeView->indexAt(event->position().toPoint());
535561
#else
536-
auto index = indexAt(event->pos());
562+
auto idxParent = m_pTreeView->indexAt(event->pos());
537563
#endif
538-
if(index.isValid())
564+
CFavoriteDatabase::Item item
565+
= m_pModel->data(idxParent, CFavoriteModel::RoleItem)
566+
.value<CFavoriteDatabase::Item>();
567+
if(0 < item.id && item.isFolder())
539568
{
540-
auto item = pModel->itemFromIndex(index);
541-
if(item->data().isNull())
542-
{
543-
foreach(auto i, pData->m_Items)
544-
{
545-
qDebug(log) << "dropEvent:" << item->text();
546-
547-
auto newItem = NewItem(i);
548-
item->appendRow(newItem);
549-
if(event->dropAction() == Qt::MoveAction)
550-
pModel->removeRow(i.row(), i.parent());
551-
}
552-
} else
553-
qWarning(log) << "Don't group node. the data:" << item->data();
554-
}else{
555569
foreach(auto i, pData->m_Items)
556570
{
557-
pModel->appendRow(NewItem(i));
558-
if(event->dropAction() == Qt::MoveAction)
559-
pModel->removeRow(i.row(), i.parent());
571+
if(i == idxParent) {
572+
qWarning(log) << "Don't drag, the same node.";
573+
break;
574+
}
575+
if (event->dropAction() == Qt::MoveAction)
576+
bRet = m_pModel->Move(i, idxParent);
577+
else if (event->dropAction() == Qt::CopyAction)
578+
bRet = m_pModel->Copy(i, idxParent);
579+
if(!bRet) break;
560580
}
581+
} else {
582+
qWarning(log) << "Don't group node. the id:" << item.id
583+
<< " Folder:" << item.isFolder();
561584
}
562-
//*/
563-
event->accept();
564-
}
565-
/*
566-
QStandardItem* CFavoriteView::NewItem(const QModelIndex &index)
567-
{
568-
QStandardItemModel* pModel = dynamic_cast<QStandardItemModel*>(model());
569-
if(!pModel) return nullptr;
570-
auto item = pModel->itemFromIndex(index);
571-
if(!item) return nullptr;
572-
auto ri = new QStandardItem(item->text());
573-
ri->setData(item->data());
574-
return ri;
585+
586+
if(bRet)
587+
event->accept();
588+
else
589+
event->ignore();
575590
}
576591

577592
void CFavoriteView::mousePressEvent(QMouseEvent *event)
578593
{
579-
if (event->button() == Qt::LeftButton)
580-
m_DragStartPosition = event->pos();
581-
QTreeView::mousePressEvent(event);
594+
qDebug(log) << "mousePressEvent";
595+
if (m_pTreeView && m_pTreeView->selectionModel()
596+
&& event->button() == Qt::LeftButton) {
597+
// 获取选中的索引
598+
QModelIndexList indexes = m_pTreeView->selectionModel()->selectedIndexes();
599+
if (!indexes.isEmpty()) {
600+
QDrag *drag = new QDrag(this);
601+
do {
602+
if(!drag) break;
603+
m_DragStartPosition = event->pos();
604+
CFavoriteMimeData *pData = new CFavoriteMimeData();
605+
pData->m_Items = indexes;
606+
drag->setMimeData(pData);
607+
Qt::DropAction dropAction = Qt::MoveAction;
608+
/*
609+
if(event->modifiers() & Qt::ControlModifier) {
610+
dropAction = Qt::CopyAction;
611+
// 设置拖拽时的光标
612+
// QIcon icon = QIcon::fromTheme("edit-copy");
613+
// QSize size(16, 16);
614+
// if(!icon.availableSizes().isEmpty())
615+
// size = icon.availableSizes().at(0);
616+
// drag->setDragCursor(icon.pixmap(size), Qt::MoveAction);
617+
}//*/
618+
drag->exec(dropAction);
619+
} while(0);
620+
if(drag)
621+
delete drag;
622+
}
623+
}
624+
QWidget::mousePressEvent(event);
582625
}
583626

584627
void CFavoriteView::mouseMoveEvent(QMouseEvent *event)
@@ -591,21 +634,40 @@ void CFavoriteView::mouseMoveEvent(QMouseEvent *event)
591634
< QApplication::startDragDistance())
592635
break;
593636
qDebug(log) << "mouseMoveEvent drag";
594-
QDrag *drag = new QDrag(this);
595-
CFavoriteMimeData *pData = new CFavoriteMimeData();
596-
pData->m_Items = this->selectionModel()->selectedIndexes();
597-
drag->setMimeData(pData);
598637

599-
Qt::DropAction dropAction = Qt::MoveAction;
600-
if(event->modifiers() & Qt::ControlModifier)
601-
dropAction = Qt::CopyAction;
602-
drag->exec(dropAction);
603638
} while (false);
604639

605-
QTreeView::mouseMoveEvent(event);
640+
QWidget::mouseMoveEvent(event);
606641
}
607-
//*/
642+
608643
bool CFavoriteView::eventFilter(QObject *watched, QEvent *event)
609644
{
645+
// 处理 treeview 的事件
646+
if (watched == m_pTreeView->viewport()) { // 处理 viewport 的事件
647+
qDebug(log) << Q_FUNC_INFO << "Viewport event:" << event->type();
648+
649+
switch (event->type()) {
650+
case QEvent::DragEnter:
651+
dragEnterEvent(static_cast<QDragEnterEvent*>(event));
652+
return true;
653+
case QEvent::DragMove:
654+
dragMoveEvent(static_cast<QDragMoveEvent*>(event));
655+
return true;
656+
case QEvent::Drop:
657+
dropEvent(static_cast<QDropEvent*>(event));
658+
return true;
659+
case QEvent::MouseButtonPress:
660+
mousePressEvent(static_cast<QMouseEvent*>(event));
661+
// 不返回true,让 viewport 也处理
662+
break;
663+
case QEvent::MouseMove:
664+
mouseMoveEvent(static_cast<QMouseEvent*>(event));
665+
// 不返回true,让 viewport 也处理
666+
break;
667+
default:
668+
break;
669+
}
670+
}
671+
610672
return QWidget::eventFilter(watched, event);
611673
}

App/Client/Favorite/FavoriteView.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,20 @@ public Q_SLOTS:
3535
const QString& szName = QString(),
3636
const QString& szDescription = QString(),
3737
const QIcon& icon = QIcon());
38-
virtual bool eventFilter(QObject *watched, QEvent *event) override;
3938

4039
Q_SIGNALS:
4140
void sigStart(const QString &szFile, bool bOpenSettings);
4241
void sigFavorite();
4342

44-
// QWidget interface
4543
protected:
44+
virtual bool eventFilter(QObject *watched, QEvent *event) override;
4645
virtual void dragEnterEvent(QDragEnterEvent *event) override;
4746
virtual void dragMoveEvent(QDragMoveEvent *event) override;
4847
virtual void dropEvent(QDropEvent *event) override;
49-
/*
48+
5049
virtual void mousePressEvent(QMouseEvent *event) override;
5150
virtual void mouseMoveEvent(QMouseEvent *event) override;
52-
*/
51+
5352
private slots:
5453
void slotFavrtieClicked(const QModelIndex &index);
5554
void slotFavortiedoubleClicked(const QModelIndex &index);

0 commit comments

Comments
 (0)