Added drop support for copying/moving files in the folders view

This commit is contained in:
Luis Ángel San Martín 2014-10-11 23:38:27 +02:00
parent 8d4a3b0e84
commit 51cf77faca
10 changed files with 195 additions and 32 deletions

View File

@ -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<QString> ComicsView::filterInvalidComicFiles(const QList<QUrl> &list)
{
QList<QString> validComicFiles;
foreach (QUrl url, list) {
if(Comic::fileIsComic(url))
validComicFiles << url.toLocalFile();
}
return validComicFiles;
}

View File

@ -49,7 +49,7 @@ protected:
void dropEvent(QDropEvent *event);
private:
QList<QString> filterInvalidComicFiles(const QList<QUrl> & list);
};
#endif // COMICS_VIEW_H

View File

@ -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]

View File

@ -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<unsigned long long int, TreeItem *> items; //relación entre folders
TreeItem *rootItem; //el árbol
QMap<unsigned long long int, TreeItem *> items; //relación entre folders
TreeItem *rootBeforeFilter;
QMap<unsigned long long int, TreeItem *> filteredItems; //relación entre folders
QMap<unsigned long long int, TreeItem *> filteredItems; //relación entre folders
QString _databasePath;

View File

@ -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<QString>,QModelIndex)), this, SLOT(copyAndImportComicsToFolder(QList<QString>,QModelIndex)));
connect(foldersView, SIGNAL(moveComicsToFolder(QList<QString>,QModelIndex)), this, SLOT(moveAndImportComicsToFolder(QList<QString>,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<QString> &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<QString> &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<QString> &com
processComicFiles(comicFilesManager, progressDialog);
}
void LibraryWindow::copyAndImportComicsToFolder(const QList<QString> &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<QString> &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);

View File

@ -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<QString> & comics);
void moveAndImportComicsToCurrentFolder(const QList<QString> &comics);
void copyAndImportComicsToFolder(const QList<QString> & comics, const QModelIndex & miFolder);
void moveAndImportComicsToFolder(const QList<QString> & 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

View File

@ -189,6 +189,17 @@ bool Comic::fileIsComic(QUrl &path)
return literalComicExtensions.contains(info.suffix());
}
QList<QString> Comic::filterInvalidComicFiles(const QList<QUrl> &list)
{
QList<QString> validComicFiles;
foreach (QUrl url, list) {
if(Comic::fileIsComic(url))
validComicFiles << url.toLocalFile();
}
return validComicFiles;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

View File

@ -85,6 +85,7 @@ class ComicDB;
inline static QStringList getSupportedImageLiteralFormats() { return literalImageExtensions;}
static bool fileIsComic(QUrl & path);
static QList<QString> filterInvalidComicFiles(const QList<QUrl> & list);
public slots:
void loadFinished();

View File

@ -2,12 +2,21 @@
#include "treeitem.h"
#include "treemodel.h"
#include <QHeaderView>
#include <QPainter>
#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<QUrl> 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();
}

View File

@ -1,8 +1,7 @@
#ifndef YACREADER_TREEVIEW_H
#define YACREADER_TREEVIEW_H
#include <QTreeView>
#include <QStyledItemDelegate>
#include <QtWidgets>
class YACReaderTreeView : public QTreeView
{
@ -11,9 +10,24 @@ public:
explicit YACReaderTreeView(QWidget *parent = 0);
signals:
//Drops
void copyComicsToFolder(QList<QString>,QModelIndex);
void moveComicsToFolder(QList<QString>,QModelIndex);
public slots:
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