From 51cf77faca7e5a6d2129a5861dd5978464df3237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 11 Oct 2014 23:38:27 +0200 Subject: [PATCH] Added drop support for copying/moving files in the folders view --- YACReaderLibrary/comics_view.cpp | 15 +---- YACReaderLibrary/comics_view.h | 2 +- YACReaderLibrary/db/treemodel.cpp | 2 +- YACReaderLibrary/db/treemodel.h | 8 +-- YACReaderLibrary/library_window.cpp | 70 +++++++++++++++++++-- YACReaderLibrary/library_window.h | 7 ++- common/comic.cpp | 11 ++++ common/comic.h | 1 + custom_widgets/yacreader_treeview.cpp | 87 ++++++++++++++++++++++++++- custom_widgets/yacreader_treeview.h | 24 ++++++-- 10 files changed, 195 insertions(+), 32 deletions(-) diff --git a/YACReaderLibrary/comics_view.cpp b/YACReaderLibrary/comics_view.cpp index 4f1a77f7..8803594e 100644 --- a/YACReaderLibrary/comics_view.cpp +++ b/YACReaderLibrary/comics_view.cpp @@ -39,26 +39,15 @@ QLOG_DEBUG() << "drop" << event->dropAction(); if(event->dropAction() == Qt::CopyAction) { QLOG_DEBUG() << "copy"; - emit copyComicsToCurrentFolder(filterInvalidComicFiles(event->mimeData()->urls())); + emit copyComicsToCurrentFolder(Comic::filterInvalidComicFiles(event->mimeData()->urls())); } else if(event->dropAction() & Qt::MoveAction) { QLOG_DEBUG() << "move"; - emit moveComicsToCurrentFolder(filterInvalidComicFiles(event->mimeData()->urls())); + emit moveComicsToCurrentFolder(Comic::filterInvalidComicFiles(event->mimeData()->urls())); } if(accepted) event->acceptProposedAction(); } - -QList ComicsView::filterInvalidComicFiles(const QList &list) -{ - QList validComicFiles; - foreach (QUrl url, list) { - if(Comic::fileIsComic(url)) - validComicFiles << url.toLocalFile(); - } - - return validComicFiles; -} diff --git a/YACReaderLibrary/comics_view.h b/YACReaderLibrary/comics_view.h index d2c6754a..e920c572 100644 --- a/YACReaderLibrary/comics_view.h +++ b/YACReaderLibrary/comics_view.h @@ -49,7 +49,7 @@ protected: void dropEvent(QDropEvent *event); private: - QList filterInvalidComicFiles(const QList & list); + }; #endif // COMICS_VIEW_H diff --git a/YACReaderLibrary/db/treemodel.cpp b/YACReaderLibrary/db/treemodel.cpp index 219eaa0e..fda51b4b 100644 --- a/YACReaderLibrary/db/treemodel.cpp +++ b/YACReaderLibrary/db/treemodel.cpp @@ -179,7 +179,7 @@ Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const if (!index.isValid()) return 0; - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled; } //! [4] diff --git a/YACReaderLibrary/db/treemodel.h b/YACReaderLibrary/db/treemodel.h index d36dab40..f288f8bc 100644 --- a/YACReaderLibrary/db/treemodel.h +++ b/YACReaderLibrary/db/treemodel.h @@ -75,7 +75,7 @@ public: void setupModelData(QString path); QString getDatabase(); - //Métodos de conveniencia + //Métodos de conveniencia QString getFolderPath(const QModelIndex &folder); void setFilter(QString filter, bool includeComics); @@ -99,11 +99,11 @@ private: void setupFilteredModelData( QSqlQuery &sqlquery, TreeItem *parent); void setupFilteredModelData(); - TreeItem *rootItem; //el árbol - QMap items; //relación entre folders + TreeItem *rootItem; //el árbol + QMap items; //relación entre folders TreeItem *rootBeforeFilter; - QMap filteredItems; //relación entre folders + QMap filteredItems; //relación entre folders QString _databasePath; diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 89384cdc..fb134107 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -184,7 +184,7 @@ void LibraryWindow::doLayout() //SIDEBAR-------------------------------------------------------------------- //--------------------------------------------------------------------------- - sideBar = new YACReaderSideBar; + sideBar = new YACReaderSideBar; foldersView = sideBar->foldersView; selectedLibrary = sideBar->selectedLibrary; @@ -935,7 +935,7 @@ void LibraryWindow::createConnections() connect(libraryCreator,SIGNAL(updated()),this,SLOT(reloadCurrentLibrary())); connect(libraryCreator,SIGNAL(created()),this,SLOT(openLastCreated())); connect(libraryCreator,SIGNAL(updatedCurrentFolder()), this, SLOT(showRootWidget())); - connect(libraryCreator,SIGNAL(updatedCurrentFolder()), this, SLOT(reloadCovers())); + connect(libraryCreator,SIGNAL(updatedCurrentFolder()), this, SLOT(reloadAfterCopyMove())); connect(libraryCreator,SIGNAL(comicAdded(QString,QString)),importWidget,SLOT(newComic(QString,QString))); //libraryCreator errors connect(libraryCreator,SIGNAL(failedCreatingDB(QString)),this,SLOT(manageCreatingError(QString))); @@ -973,6 +973,10 @@ void LibraryWindow::createConnections() connect(foldersView, SIGNAL(clicked(QModelIndex)), this, SLOT(loadCovers(QModelIndex))); connect(foldersView, SIGNAL(clicked(QModelIndex)), this, SLOT(updateHistory(QModelIndex))); + //drops in folders view + connect(foldersView, SIGNAL(copyComicsToFolder(QList,QModelIndex)), this, SLOT(copyAndImportComicsToFolder(QList,QModelIndex))); + connect(foldersView, SIGNAL(moveComicsToFolder(QList,QModelIndex)), this, SLOT(moveAndImportComicsToFolder(QList,QModelIndex))); + //actions connect(createLibraryAction,SIGNAL(triggered()),this,SLOT(createLibrary())); connect(exportLibraryAction,SIGNAL(triggered()),exportLibraryDialog,SLOT(show())); @@ -1259,6 +1263,8 @@ void LibraryWindow::copyAndImportComicsToCurrentFolder(const QList &com { QString destFolderPath = currentFolderPath(); + copyMoveIndexDestination = getCurrentFolderIndex(); + QProgressDialog * progressDialog = newProgressDialog(tr("Copying comics..."),comics.size()); ComicFilesManager * comicFilesManager = new ComicFilesManager(); @@ -1271,6 +1277,8 @@ void LibraryWindow::moveAndImportComicsToCurrentFolder(const QList &com { QString destFolderPath = currentFolderPath(); + copyMoveIndexDestination = getCurrentFolderIndex(); + QProgressDialog * progressDialog = newProgressDialog(tr("Moving comics..."),comics.size()); ComicFilesManager * comicFilesManager = new ComicFilesManager(); @@ -1279,6 +1287,44 @@ void LibraryWindow::moveAndImportComicsToCurrentFolder(const QList &com processComicFiles(comicFilesManager, progressDialog); } +void LibraryWindow::copyAndImportComicsToFolder(const QList &comics, const QModelIndex &miFolder) +{ + if(miFolder.isValid()) + { + QString destFolderPath = QDir::cleanPath(currentPath()+foldersModel->getFolderPath(miFolder)); + + copyMoveIndexDestination = miFolder; + + QLOG_DEBUG() << "Coping to " << destFolderPath; + + QProgressDialog * progressDialog = newProgressDialog(tr("Copying comics..."),comics.size()); + + ComicFilesManager * comicFilesManager = new ComicFilesManager(); + comicFilesManager->copyComicsTo(comics,destFolderPath); + + processComicFiles(comicFilesManager, progressDialog); + } +} + +void LibraryWindow::moveAndImportComicsToFolder(const QList &comics, const QModelIndex &miFolder) +{ + if(miFolder.isValid()) + { + QString destFolderPath = QDir::cleanPath(currentPath()+foldersModel->getFolderPath(miFolder)); + + copyMoveIndexDestination = miFolder; + + QLOG_DEBUG() << "Moving to " << destFolderPath; + + QProgressDialog * progressDialog = newProgressDialog(tr("Moving comics..."),comics.size()); + + ComicFilesManager * comicFilesManager = new ComicFilesManager(); + comicFilesManager->moveComicsTo(comics,destFolderPath); + + processComicFiles(comicFilesManager, progressDialog); + } +} + void LibraryWindow::processComicFiles(ComicFilesManager * comicFilesManager, QProgressDialog * progressDialog) { connect(comicFilesManager,SIGNAL(progress(int)), progressDialog, SLOT(setValue(int))); @@ -1290,7 +1336,7 @@ void LibraryWindow::processComicFiles(ComicFilesManager * comicFilesManager, QPr comicFilesManager->moveToThread(thread); connect(thread, SIGNAL(started()), comicFilesManager, SLOT(process())); - connect(comicFilesManager, SIGNAL(success()), this, SLOT(updateCurrentFolder())); + connect(comicFilesManager, SIGNAL(success()), this, SLOT(updateCopyMoveFolderDestination())); connect(comicFilesManager, SIGNAL(finished()), thread, SLOT(quit())); connect(comicFilesManager, SIGNAL(finished()), comicFilesManager, SLOT(deleteLater())); connect(comicFilesManager, SIGNAL(finished()), progressDialog, SLOT(close())); @@ -1301,7 +1347,7 @@ void LibraryWindow::processComicFiles(ComicFilesManager * comicFilesManager, QPr thread->start(); } -void LibraryWindow::updateCurrentFolder() +void LibraryWindow::updateCopyMoveFolderDestination() { importWidget->setUpdateLook(); showImportingWidget(); @@ -1309,7 +1355,7 @@ void LibraryWindow::updateCurrentFolder() QString currentLibrary = selectedLibrary->currentText(); QString path = libraries.getPath(currentLibrary); _lastAdded = currentLibrary; - libraryCreator->updateFolder(QDir::cleanPath(path),QDir::cleanPath(path+"/.yacreaderlibrary"),currentFolderPath()); + libraryCreator->updateFolder(QDir::cleanPath(path),QDir::cleanPath(path+"/.yacreaderlibrary"),QDir::cleanPath(currentPath()+foldersModel->getFolderPath(copyMoveIndexDestination))); libraryCreator->start(); } @@ -1322,6 +1368,20 @@ QProgressDialog *LibraryWindow::newProgressDialog(const QString &label, int maxV return progressDialog; } +void LibraryWindow::reloadAfterCopyMove() +{ + if(getCurrentFolderIndex() == copyMoveIndexDestination) + reloadCovers(); +} + +QModelIndex LibraryWindow::getCurrentFolderIndex() +{ + if(foldersView->selectionModel()->selectedRows().length()>0) + return foldersView->currentIndex(); + else + return QModelIndex(); +} + void LibraryWindow::selectSubfolder(const QModelIndex &mi, int child) { QModelIndex dest = foldersModel->index(child,0,mi); diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index db644e8d..cd472eb1 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -201,6 +201,7 @@ private: //QModelIndex _rootIndex; //QModelIndex _rootIndexCV; + QModelIndex copyMoveIndexDestination; quint64 _comicIdEdited; @@ -324,9 +325,13 @@ public slots: void loadCoversFromCurrentModel(); void copyAndImportComicsToCurrentFolder(const QList & comics); void moveAndImportComicsToCurrentFolder(const QList &comics); + void copyAndImportComicsToFolder(const QList & comics, const QModelIndex & miFolder); + void moveAndImportComicsToFolder(const QList & comics, const QModelIndex & miFolder); void processComicFiles(ComicFilesManager * comicFilesManager, QProgressDialog * progressDialog); - void updateCurrentFolder(); //imports new comics from the current folder + void updateCopyMoveFolderDestination(); //imports new comics from the current folder QProgressDialog * newProgressDialog(const QString & label, int maxValue); + void reloadAfterCopyMove(); + QModelIndex getCurrentFolderIndex(); }; #endif diff --git a/common/comic.cpp b/common/comic.cpp index 96775a61..e06adb95 100644 --- a/common/comic.cpp +++ b/common/comic.cpp @@ -189,6 +189,17 @@ bool Comic::fileIsComic(QUrl &path) return literalComicExtensions.contains(info.suffix()); } +QList Comic::filterInvalidComicFiles(const QList &list) +{ + QList validComicFiles; + foreach (QUrl url, list) { + if(Comic::fileIsComic(url)) + validComicFiles << url.toLocalFile(); + } + + return validComicFiles; +} + //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// diff --git a/common/comic.h b/common/comic.h index 63180ae1..f4a96942 100644 --- a/common/comic.h +++ b/common/comic.h @@ -85,6 +85,7 @@ class ComicDB; inline static QStringList getSupportedImageLiteralFormats() { return literalImageExtensions;} static bool fileIsComic(QUrl & path); + static QList filterInvalidComicFiles(const QList & list); public slots: void loadFinished(); diff --git a/custom_widgets/yacreader_treeview.cpp b/custom_widgets/yacreader_treeview.cpp index 8b60c330..03d28878 100644 --- a/custom_widgets/yacreader_treeview.cpp +++ b/custom_widgets/yacreader_treeview.cpp @@ -2,12 +2,21 @@ #include "treeitem.h" #include "treemodel.h" -#include -#include +#include "comic.h" + +#include "QsLog.h" YACReaderTreeView::YACReaderTreeView(QWidget *parent) : QTreeView(parent) { + setAcceptDrops(true); + setDragDropMode(QAbstractItemView::DropOnly); + setItemsExpandable(true); + + //setDragEnabled(true); + /*viewport()->setAcceptDrops(true); + setDropIndicatorShown(true);*/ + setContextMenuPolicy(Qt::ActionsContextMenu); setContextMenuPolicy(Qt::ActionsContextMenu); header()->hide(); @@ -49,6 +58,80 @@ YACReaderTreeView::YACReaderTreeView(QWidget *parent) : ); #endif + +} + +void YACReaderTreeView::expandCurrent() +{ + QModelIndex index = indexAt(expandPos); + if(index.isValid()) + expand(index); +} + +void YACReaderTreeView::dragEnterEvent(QDragEnterEvent *event) +{ + QTreeView::dragEnterEvent(event); + + QList urlList; + + if (event->mimeData()->hasUrls()) + { + urlList = event->mimeData()->urls(); + foreach (QUrl url, urlList) + { + if(Comic::fileIsComic(url)) + { + event->acceptProposedAction(); + return; + } + } + } +} + +void YACReaderTreeView::dragMoveEvent(QDragMoveEvent *event) +{ + QTreeView::dragMoveEvent(event); + event->acceptProposedAction(); + + //fix for drop auto expand + QModelIndex lastExpanded = indexAt(expandPos); + QModelIndex underMouse = indexAt(event->pos()); + if( underMouse.isValid() && (underMouse != lastExpanded)) { + expandPos = event->pos(); + connect(&expandTimer,SIGNAL(timeout()),this,SLOT(expandCurrent())); + expandTimer.start(750); + } + //TODO force mouse hover decoration, why the event loop is not working here? + if(!t.isActive()) + { + t.setSingleShot(true); + t.setInterval(50); + t.start(); + repaint(); + } + +} + +void YACReaderTreeView::dropEvent(QDropEvent *event) +{ + QTreeView::dropEvent(event); + + bool accepted = false; + QLOG_DEBUG() << "drop on tree" << event->dropAction(); + if(event->dropAction() == Qt::CopyAction) + { + QLOG_DEBUG() << "copy - tree"; + emit copyComicsToFolder(Comic::filterInvalidComicFiles(event->mimeData()->urls()),indexAt(event->pos())); + + } + else if(event->dropAction() & Qt::MoveAction) + { + QLOG_DEBUG() << "move - tree"; + emit moveComicsToFolder(Comic::filterInvalidComicFiles(event->mimeData()->urls()),indexAt(event->pos())); + } + + if(accepted) + event->acceptProposedAction(); } diff --git a/custom_widgets/yacreader_treeview.h b/custom_widgets/yacreader_treeview.h index bb71448d..e0c48cd1 100644 --- a/custom_widgets/yacreader_treeview.h +++ b/custom_widgets/yacreader_treeview.h @@ -1,8 +1,7 @@ #ifndef YACREADER_TREEVIEW_H #define YACREADER_TREEVIEW_H -#include -#include +#include class YACReaderTreeView : public QTreeView { @@ -11,9 +10,24 @@ public: explicit YACReaderTreeView(QWidget *parent = 0); signals: - -public slots: - + //Drops + void copyComicsToFolder(QList,QModelIndex); + void moveComicsToFolder(QList,QModelIndex); + +protected slots: + //fix for drop auto expand + void expandCurrent(); + +protected: + //Drop to import + void dragEnterEvent(QDragEnterEvent *event); + void dragMoveEvent(QDragMoveEvent *event); + void dropEvent(QDropEvent *event); + + //fix for drop auto expand + QTimer expandTimer; + QTimer t; + QPoint expandPos; }; class YACReaderTreeViewItemDeletegate: public QStyledItemDelegate