diff options
author | Arno <am@disconnect.de> | 2014-04-10 16:14:32 +0200 |
---|---|---|
committer | Arno <am@disconnect.de> | 2014-04-10 16:14:32 +0200 |
commit | b0d671fede5adfadad2b465fb4c8ae50b40516f3 (patch) | |
tree | 0215645b3be6eea7dd11c72c987222eddc0a0faa /archiveview.cpp | |
parent | 9f314ad26720a925e8e7a7f1a9f61330f3fd29c1 (diff) | |
download | SheMov-b0d671fede5adfadad2b465fb4c8ae50b40516f3.tar.gz SheMov-b0d671fede5adfadad2b465fb4c8ae50b40516f3.tar.bz2 SheMov-b0d671fede5adfadad2b465fb4c8ae50b40516f3.zip |
Implement Drag and Drop in Movie Archive
Well, this was actually a bit of a drag. You have read the docs very
carefully to get it right. For one, don't construct the drag object in
mousePressEvent if you also want a double click, otherwise you end up
with very weird behavior.
Same goes for the receiving end. Differentiate between dragEnterEvent
and dragMoveEvent, otherwise you'll only be able to drop items if you
hit the right row on entering.
There are some artefacts during the drag, but I guess that's a Qt bug.
Didn't bother to look into it.
Diffstat (limited to 'archiveview.cpp')
-rw-r--r-- | archiveview.cpp | 104 |
1 files changed, 103 insertions, 1 deletions
diff --git a/archiveview.cpp b/archiveview.cpp index f3656f7..c59130c 100644 --- a/archiveview.cpp +++ b/archiveview.cpp @@ -24,6 +24,12 @@ #include <QStandardItemModel> #include <QFormLayout> #include <QToolBar> +#include <QMouseEvent> +#include <QDrag> +#include <QMimeData> +#include <QDropEvent> +#include <QApplication> +#include <QDataStream> #include "archiveview.h" #include "archivecontroller.h" @@ -152,6 +158,7 @@ ArchiveView::ArchiveView(QWidget *parent) : QWidget(parent) { mainLayout->addWidget(mTreeSplitter); setLayout(mainLayout); + initController(); } @@ -267,7 +274,10 @@ void ArchiveView::initController(){ SmGlobals::instance()->setArchiveController(mController); } -ArchiveTree::ArchiveTree(QWidget *parent) : SmTreeView(parent) {} +ArchiveTree::ArchiveTree(QWidget *parent) : SmTreeView(parent) { + setAcceptDrops(true); + +} void ArchiveTree::setModel(ArchiveProxy *model){ mProxy = model; @@ -440,6 +450,53 @@ void ArchiveTree::newPart(){ } } +void ArchiveTree::dragEnterEvent(QDragEnterEvent *e){ + if(e->mimeData()->hasFormat("application/x-shemov-file")){ + e->acceptProposedAction(); + }else{ + e->ignore(); + } +} + +void ArchiveTree::dragMoveEvent(QDragMoveEvent *e){ + QModelIndex idx = indexAt(e->pos()); + if(idx.isValid()){ + int flags = idx.flags(); + if(flags & Qt::ItemIsDropEnabled){ + e->acceptProposedAction(); + return; + } + } + e->ignore(); + return; +} + +void ArchiveTree::dropEvent(QDropEvent *e){ + QDataStream stream(e->mimeData()->data("application/x-shemov-file")); + int size; + stream >> size; + QString question = QString(tr("Really move %1 items?")).arg(QString::number(size)); + int retval = QMessageBox::question(this, tr("Question"), question); + if(retval == QMessageBox::Yes){ + QModelIndex dropIdx = indexAt(e->pos()); + if(dropIdx.isValid()){ + int newPartId = dropIdx.data(ArchiveModel::SeriesPartIdRole).toInt(); + ArchiveController *c = SmGlobals::instance()->archiveController(); + QStringList md5Sums; + for(int i = 0; i < size; ++i){ + QVariant md5; + stream >> md5; + md5Sums << md5.toString(); + } + c->moveFilesToSeriespart(md5Sums, newPartId); + c->archiveFiles()->expandAll(); + e->accept(); + return; + } + } + e->ignore(); +} + void ArchiveTree::impossible(const QString msg){ QMessageBox::critical(this, tr("Error"), msg); } @@ -454,6 +511,51 @@ QModelIndex ArchiveTree::firstSelected(){ ArchiveFiles::ArchiveFiles(const QString &headerSettings, QWidget *parent) : SmTreeView(headerSettings, parent){ setEditTriggers(QAbstractItemView::NoEditTriggers); + setDragEnabled(true); +} + +void ArchiveFiles::mousePressEvent(QMouseEvent *e){ + if(e->button() == Qt::LeftButton){ + mDragStartPos = e->pos(); + } + return SmTreeView::mousePressEvent(e); +} + +void ArchiveFiles::mouseMoveEvent(QMouseEvent *e){ + if(!(e->buttons() & Qt::LeftButton)){ + return; + } + if((e->pos() - mDragStartPos).manhattanLength() < qApp->startDragDistance()){ + return; + } + + QModelIndexList sel = selectionModel()->selectedRows(); + if(sel.isEmpty()){ + return; + } + + QString files("<ul ul style=\"margin-left: -25; margin-top: 10px; margin-right: 10px; margin-bottom: 10px\">"); + QByteArray dataBuf; + QDataStream stream(&dataBuf, QIODevice::WriteOnly); + stream << sel.size(); + foreach(QModelIndex i, sel){ + files.append("<li>"); + files.append(i.data(ArchiveFilesModel::FilenameRole).toString()); + stream << i.data(ArchiveFilesModel::Md5SumRole); + files.append("</li>"); + } + files.append("</ul>"); + + QLabel dragLabel(files); + QPixmap dragPixmap(dragLabel.size()); + dragLabel.render(&dragPixmap); + + QDrag *drag = new QDrag(this); + QMimeData *mimeData = new QMimeData; + mimeData->setData("application/x-shemov-file", dataBuf); + drag->setMimeData(mimeData); + drag->setPixmap(dragPixmap); + drag->exec(Qt::MoveAction | Qt::CopyAction); } ArchiveProxy::ArchiveProxy(QObject *parent) : QSortFilterProxyModel(parent) {} |