diff options
-rw-r--r-- | archivecontroller.cpp | 7 | ||||
-rw-r--r-- | archivecontroller.h | 1 | ||||
-rw-r--r-- | archivemodel.cpp | 23 | ||||
-rw-r--r-- | archivemodel.h | 3 | ||||
-rw-r--r-- | archiveview.cpp | 104 | ||||
-rw-r--r-- | archiveview.h | 14 |
6 files changed, 150 insertions, 2 deletions
diff --git a/archivecontroller.cpp b/archivecontroller.cpp index a7d0501..5638119 100644 --- a/archivecontroller.cpp +++ b/archivecontroller.cpp @@ -232,6 +232,13 @@ void ArchiveController::readConfig(){ mGenreIcon = SmGlobals::instance()->iconFor("genre"); } +void ArchiveController::moveFilesToSeriespart(const QStringList &md5Sums, int newSeriesPart){ + foreach(QString md5, md5Sums){ + mArchiveFilesModel->updateSeriesPartForFile(md5, newSeriesPart); + } + mArchiveFilesModel->refresh(); +} + void ArchiveController::treeSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected){ Q_UNUSED(selected); Q_UNUSED(deselected); diff --git a/archivecontroller.h b/archivecontroller.h index e7593e1..fb02383 100644 --- a/archivecontroller.h +++ b/archivecontroller.h @@ -56,6 +56,7 @@ class ArchiveController : public QObject { void addActionForTree(QAction *a); void addCovers(); void readConfig(); + void moveFilesToSeriespart(const QStringList &md5Sums, int newSeriesPart); private slots: void fileDoubleClicked(const QModelIndex &idx); diff --git a/archivemodel.cpp b/archivemodel.cpp index 5369ff7..578ff5c 100644 --- a/archivemodel.cpp +++ b/archivemodel.cpp @@ -62,6 +62,19 @@ ArchiveModel::~ArchiveModel(){ } } +Qt::ItemFlags ArchiveModel::flags(const QModelIndex &index) const{ + SmTreeItem *item = itemAt(index); + Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + if(item->data(Type).toInt() == ArchiveModel::SeriesPartNode){ + retval |= Qt::ItemIsDropEnabled; + } + return retval; +} + +Qt::DropActions ArchiveModel::supportedDragActions() const{ + return Qt::MoveAction; +} + const QStringList ArchiveModel::availableOrders() const { QStringList retval = mAvailableOrders.keys(); qSort(retval); @@ -896,7 +909,7 @@ Qt::ItemFlags ArchiveFilesModel::flags(const QModelIndex &index) const{ return Qt::ItemIsEnabled; } } - return SmTreeModel::flags(index); + return (Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); } int ArchiveFilesModel::nextDvd() const{ @@ -982,6 +995,14 @@ QStringList ArchiveFilesModel::filesForSeriespart(int seriesPartId) const{ return retval; } +void ArchiveFilesModel::updateSeriesPartForFile(const QString &md5sum, int newSeriesPart){ + QSqlQuery q(mDb); + q.prepare("UPDATE files SET iseriespart_id = :id WHERE cmd5sum = :md5"); + q.bindValue(":id", newSeriesPart); + q.bindValue(":md5", md5sum); + q.exec(); +} + void ArchiveFilesModel::refresh(){ populate(mSeriesPartIds); } diff --git a/archivemodel.h b/archivemodel.h index a9a11eb..20f878c 100644 --- a/archivemodel.h +++ b/archivemodel.h @@ -31,6 +31,8 @@ class ArchiveModel : public SmTreeModel { enum NodeType { SeriesNode = 1, SeriesPartNode = 2, GenreNode = 4, ActorNode = 8, AllNodes = 15 }; explicit ArchiveModel(const QStringList &headers, QObject *parent = 0); virtual ~ArchiveModel(); + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual Qt::DropActions supportedDragActions() const; const QStringList availableOrders() const; const QHash<QString, int> availableOrdersHash() const { return mAvailableOrders; } virtual QVariant data(const QModelIndex &index, int role) const; @@ -103,6 +105,7 @@ class ArchiveFilesModel : public SmTreeModel { bool isMovie(const QModelIndex &idx) const; void populate(const QSet<int> &seriesPartIds); QStringList filesForSeriespart(int seriesPartId) const; + void updateSeriesPartForFile(const QString &md5sum, int newSeriesPart); public slots: void refresh(); 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) {} diff --git a/archiveview.h b/archiveview.h index f1b9029..dbe0e8f 100644 --- a/archiveview.h +++ b/archiveview.h @@ -33,6 +33,8 @@ class QCompleter; class QStandardItemModel; class QSpinBox; class QToolBar; +class QMouseEvent; +class QDragEnterEvent; class ArchiveView : public QWidget { Q_OBJECT @@ -96,6 +98,11 @@ class ArchiveTree : public SmTreeView { void deleteFromTree(); void newPart(); + protected: + virtual void dragEnterEvent(QDragEnterEvent *e); + virtual void dragMoveEvent(QDragMoveEvent *e); + virtual void dropEvent(QDropEvent *e); + private: void impossible(const QString msg = tr("Unable to perform function!")); QModelIndex firstSelected(); @@ -106,6 +113,13 @@ class ArchiveTree : public SmTreeView { class ArchiveFiles : public SmTreeView { public: explicit ArchiveFiles(const QString &headerSettings = "afilesheaders", QWidget *parent = 0); + + protected: + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseMoveEvent(QMouseEvent *e); + + private: + QPoint mDragStartPos; }; class ArchiveProxy : public QSortFilterProxyModel { |