Skip to content

Commit 7d5baf7

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

6 files changed

Lines changed: 172 additions & 57 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: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,47 @@ 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+
bRet = m_pDatabase->MoveNode(item.id, nParentId);
287+
if(!bRet) return false;
288+
bRet = MoveTree(ip->item, ipParent->item.id);
289+
return bRet;
290+
}
291+
292+
// TODO: not test!!!
293+
bool CFavoriteModel::Copy(QModelIndex index, QModelIndex parentIndex)
294+
{
295+
bool bRet = true;
296+
if(!index.isValid()) return false;
297+
tree* ip = GetTree(index);
298+
if(!ip) return false;
299+
tree* ipParent = GetTree(parentIndex);
300+
if(!ipParent || ipParent->item.isFavorite()) return false;
301+
int nParentId = ipParent->item.id;
302+
auto& item = ip->item;
303+
if(item.isFavorite())
304+
bRet = AddFavorite(item.szFile, item.szName, item.GetIcon(),
305+
item.szDescription, nParentId);
306+
else {
307+
bRet = m_pDatabase->AddNode(item.szName, nParentId);
308+
if(!bRet) return false;
309+
bRet = AddTree(item, nParentId);
310+
}
311+
return bRet;
312+
}
313+
273314
CFavoriteDatabase::Item CFavoriteModel::GetFavorite(const QString &szFile)
274315
{
275316
CFavoriteDatabase::Item item;

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: 112 additions & 53 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,110 @@ 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+
565+
CFavoriteDatabase::Item item
566+
= m_pModel->data(idxParent, CFavoriteModel::RoleItem)
567+
.value<CFavoriteDatabase::Item>();
568+
if(0 < item.id && item.isFolder())
539569
{
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{
555570
foreach(auto i, pData->m_Items)
556571
{
557-
pModel->appendRow(NewItem(i));
558-
if(event->dropAction() == Qt::MoveAction)
559-
pModel->removeRow(i.row(), i.parent());
572+
if (event->dropAction() == Qt::MoveAction)
573+
bRet = m_pModel->Move(i, idxParent);
574+
else if (event->dropAction() == Qt::CopyAction)
575+
bRet = m_pModel->Copy(i, idxParent);
576+
if(!bRet) break;
560577
}
578+
} else {
579+
qWarning(log) << "Don't group node. the id:" << item.id
580+
<< " Folder:" << item.isFolder();
561581
}
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;
582+
583+
if(bRet)
584+
event->accept();
585+
else
586+
event->ignore();
575587
}
576588

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

584624
void CFavoriteView::mouseMoveEvent(QMouseEvent *event)
@@ -591,21 +631,40 @@ void CFavoriteView::mouseMoveEvent(QMouseEvent *event)
591631
< QApplication::startDragDistance())
592632
break;
593633
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);
598634

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

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

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)