Added support for dropping folders to import them. TODO update the foldersView properly (now all the tree model is reloaded).

This commit is contained in:
Luis Ángel San Martín 2014-10-14 23:24:27 +02:00
parent 5e355f85bf
commit 46e4cfceb9
13 changed files with 223 additions and 93 deletions

View File

@ -5,30 +5,61 @@
#include <QsLog.h>
#include "comic.h"
ComicFilesManager::ComicFilesManager(QObject *parent) :
QObject(parent), canceled(false)
{
}
void ComicFilesManager::copyComicsTo(const QList<QString> &sourceComics, const QString &folderDest)
void ComicFilesManager::copyComicsTo(const QList<QPair<QString,QString> > &sourceComics, const QString &folderDest)
{
comics = sourceComics;
folder = folderDest;
move = false;
}
void ComicFilesManager::moveComicsTo(const QList<QString> &sourceComics, const QString &folderDest)
void ComicFilesManager::moveComicsTo(const QList<QPair<QString, QString> > &sourceComics, const QString &folderDest)
{
comics = sourceComics;
folder = folderDest;
move = true;
}
QList<QPair<QString, QString> > ComicFilesManager::getDroppedFiles(const QList<QUrl> &urls)
{
QList<QPair<QString,QString> > dropedFiles;
QString currentPath;
foreach(QUrl url, urls)
{
currentPath = url.toLocalFile();
if(Comic::fileIsComic(currentPath))
dropedFiles << QPair<QString, QString>(currentPath,"/");
else
{
QFileInfo info(currentPath);
if(info.isDir())
{
foreach(QString comicPath, Comic::findValidComicFilesInFolder(info.absoluteFilePath()))
{
QFileInfo comicInfo(comicPath);
QString path = comicInfo.absolutePath();
dropedFiles << QPair<QString, QString>(comicPath, path.remove(info.absolutePath()));
}
}
}
}
return dropedFiles;
}
void ComicFilesManager::process()
{
int i=0;
bool successProcesingFiles = false;
foreach (QString source, comics) {
QPair<QString, QString> source;
foreach (source, comics) {
if(canceled)
{
@ -39,12 +70,17 @@ void ComicFilesManager::process()
return; //TODO rollback?
}
QFileInfo info(source);
if(QFile::copy(source, QDir::cleanPath(folder+'/'+info.fileName())))
QFileInfo info(source.first);
QString destPath = QDir::cleanPath(folder+'/'+source.second);
QLOG_DEBUG() << "crear : " << destPath;
QDir().mkpath(destPath);
if(QFile::copy(source.first, QDir::cleanPath(destPath+'/'+info.fileName())))
{
successProcesingFiles = true;
if(move)
QFile::remove(source);
{
QFile::remove(source.first); //TODO: remove the whole path....
}
}
i++;

View File

@ -9,9 +9,9 @@ class ComicFilesManager : public QObject
Q_OBJECT
public:
explicit ComicFilesManager(QObject *parent = 0);
void copyComicsTo(const QList<QString> & sourceComics, const QString & folderDest);
void moveComicsTo(const QList<QString> & comics, const QString & folderDest);
void copyComicsTo(const QList<QPair<QString,QString> > & sourceComics, const QString & folderDest);
void moveComicsTo(const QList<QPair<QString,QString> > & comics, const QString & folderDest);
static QList<QPair<QString, QString> > getDroppedFiles(const QList<QUrl> & urls);
signals:
void currentComic(QString);
void progress(int);
@ -24,7 +24,7 @@ public slots:
protected:
bool move;
bool canceled;
QList<QString> comics;
QList<QPair<QString,QString> > comics;
QString folder;
};

View File

@ -1,5 +1,6 @@
#include "comics_view.h"
#include "comic.h"
#include "comic_files_manager.h"
#include "QsLog.h"
@ -21,9 +22,12 @@ void ComicsView::dragEnterEvent(QDragEnterEvent *event)
if (event->mimeData()->hasUrls())
{
urlList = event->mimeData()->urls();
QString currentPath;
foreach (QUrl url, urlList)
{
if(Comic::fileIsComic(url))
//comics or folders are accepted, folders' content is validate in dropEvent (avoid any lag before droping)
currentPath = url.toLocalFile();
if(Comic::fileIsComic(currentPath) || QFileInfo(currentPath).isDir())
{
event->acceptProposedAction();
return;
@ -34,20 +38,26 @@ void ComicsView::dragEnterEvent(QDragEnterEvent *event)
void ComicsView::dropEvent(QDropEvent *event)
{
bool accepted = false;
QLOG_DEBUG() << "drop" << event->dropAction();
QLOG_DEBUG() << "drop" << event->dropAction();
bool validAction = event->dropAction() == Qt::CopyAction || event->dropAction() & Qt::MoveAction;
if(validAction)
{
QList<QPair<QString, QString> > droppedFiles = ComicFilesManager::getDroppedFiles(event->mimeData()->urls());
if(event->dropAction() == Qt::CopyAction)
{
QLOG_DEBUG() << "copy";
emit copyComicsToCurrentFolder(Comic::filterInvalidComicFiles(event->mimeData()->urls()));
QLOG_DEBUG() << "copy :" << droppedFiles;
emit copyComicsToCurrentFolder(droppedFiles);
}
else if(event->dropAction() & Qt::MoveAction)
{
QLOG_DEBUG() << "move";
emit moveComicsToCurrentFolder(Comic::filterInvalidComicFiles(event->mimeData()->urls()));
QLOG_DEBUG() << "move :" << droppedFiles;
emit moveComicsToCurrentFolder(droppedFiles);
}
if(accepted)
event->acceptProposedAction();
}
}

View File

@ -35,8 +35,8 @@ signals:
void comicRated(int,QModelIndex);
//Drops
void copyComicsToCurrentFolder(QList<QString>);
void moveComicsToCurrentFolder(QList<QString>);
void copyComicsToCurrentFolder(QList<QPair<QString, QString> >);
void moveComicsToCurrentFolder(QList<QPair<QString, QString> >);
public slots:
virtual void setShowMarks(bool show) = 0;

View File

@ -544,3 +544,8 @@ QStringList TreeModel::getSubfoldersNames(const QModelIndex &mi)
qSort(result.begin(),result.end(),naturalSortLessThanCI);
return result;
}
void TreeModel::fetchMore(const QModelIndex &parent)
{
}

View File

@ -87,6 +87,8 @@ public:
QStringList getSubfoldersNames(const QModelIndex & mi);
void fetchMore(const QModelIndex & parent);
enum Columns {
Name = 0,
Path = 1,

View File

@ -38,7 +38,7 @@ using namespace std;
LibraryCreator::LibraryCreator()
:creation(false), partialUpdate(false)
{
_nameFilter << "*.cbr" << "*.cbz" << "*.rar" << "*.zip" << "*.tar" << "*.pdf" << "*.7z" << "*.cb7" << "*.arj" << "*.cbt";
_nameFilter << Comic::comicExtensions;
}
void LibraryCreator::createLibrary(const QString &source, const QString &target)
@ -66,11 +66,18 @@ void LibraryCreator::updateFolder(const QString &source, const QString &target,
if(relativeFolderPath.startsWith("/"))
relativeFolderPath = relativeFolderPath.remove(0,1);//remove firts '/'
QStringList folders = relativeFolderPath.split('/');
QStringList folders;
if(!relativeFolderPath.isEmpty()) //updating root
folders = relativeFolderPath.split('/');
QLOG_DEBUG() << "folders found in relative path : " << folders << "-" << relativeFolderPath;
QSqlDatabase db = DataBaseManagement::loadDatabase(target);
foreach (QString folderName, folders) {
if(folderName.isEmpty())
break;
qulonglong parentId = _currentPathFolders.last().id;
_currentPathFolders.append(DBHelper::loadFolder(folderName, parentId, db));
QLOG_DEBUG() << "Folder appended : " << _currentPathFolders.last().id << " " << _currentPathFolders.last().name << " with parent" << _currentPathFolders.last().parentId;

View File

@ -392,8 +392,8 @@ void LibraryWindow::disconnectComicsViewConnections(ComicsView * widget)
disconnect(widget,SIGNAL(selected(unsigned int)),this,SLOT(openComic()));
disconnect(widget,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(openComic()));
disconnect(selectAllComicsAction,SIGNAL(triggered()),widget,SLOT(selectAll()));
disconnect(comicsView, SIGNAL(copyComicsToCurrentFolder(QList<QString>)), this, SLOT(copyAndImportComicsToCurrentFolder(QList<QString>)));
disconnect(comicsView, SIGNAL(moveComicsToCurrentFolder(QList<QString>)), this, SLOT(moveAndImportComicsToCurrentFolder(QList<QString>)));
disconnect(comicsView, SIGNAL(copyComicsToCurrentFolder(QList<QPair<QString, QString> >)), this, SLOT(copyAndImportComicsToCurrentFolder(QList<QPair<QString, QString> >)));
disconnect(comicsView, SIGNAL(moveComicsToCurrentFolder(QList<QPair<QString, QString> >)), this, SLOT(moveAndImportComicsToCurrentFolder(QList<QPair<QString, QString> >)));
}
void LibraryWindow::doComicsViewConnections()
@ -404,8 +404,8 @@ void LibraryWindow::doComicsViewConnections()
connect(comicsView,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(openComic()));
connect(selectAllComicsAction,SIGNAL(triggered()),comicsView,SLOT(selectAll()));
//Drops
connect(comicsView, SIGNAL(copyComicsToCurrentFolder(QList<QString>)), this, SLOT(copyAndImportComicsToCurrentFolder(QList<QString>)));
connect(comicsView, SIGNAL(moveComicsToCurrentFolder(QList<QString>)), this, SLOT(moveAndImportComicsToCurrentFolder(QList<QString>)));
connect(comicsView, SIGNAL(copyComicsToCurrentFolder(QList<QPair<QString, QString> >)), this, SLOT(copyAndImportComicsToCurrentFolder(QList<QPair<QString, QString> >)));
connect(comicsView, SIGNAL(moveComicsToCurrentFolder(QList<QPair<QString, QString> >)), this, SLOT(moveAndImportComicsToCurrentFolder(QList<QPair<QString, QString> >)));
}
void LibraryWindow::createActions()
@ -993,8 +993,8 @@ void LibraryWindow::createConnections()
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)));
connect(foldersView, SIGNAL(copyComicsToFolder(QList<QPair<QString,QString> >,QModelIndex)), this, SLOT(copyAndImportComicsToFolder(QList<QPair<QString,QString> >,QModelIndex)));
connect(foldersView, SIGNAL(moveComicsToFolder(QList<QPair<QString,QString> >,QModelIndex)), this, SLOT(moveAndImportComicsToFolder(QList<QPair<QString,QString> >,QModelIndex)));
//actions
connect(createLibraryAction,SIGNAL(triggered()),this,SLOT(createLibrary()));
@ -1282,8 +1282,11 @@ void LibraryWindow::loadCoversFromCurrentModel()
}
}
void LibraryWindow::copyAndImportComicsToCurrentFolder(const QList<QString> &comics)
void LibraryWindow::copyAndImportComicsToCurrentFolder(const QList<QPair<QString, QString> > &comics)
{
QLOG_DEBUG() << "-copyAndImportComicsToCurrentFolder-";
if(comics.size()>0)
{
QString destFolderPath = currentFolderPath();
updateDestination = getCurrentFolderIndex();
@ -1294,10 +1297,14 @@ void LibraryWindow::copyAndImportComicsToCurrentFolder(const QList<QString> &com
comicFilesManager->copyComicsTo(comics,destFolderPath);
processComicFiles(comicFilesManager, progressDialog);
}
}
void LibraryWindow::moveAndImportComicsToCurrentFolder(const QList<QString> &comics)
void LibraryWindow::moveAndImportComicsToCurrentFolder(const QList<QPair<QString,QString> > &comics)
{
QLOG_DEBUG() << "-moveAndImportComicsToCurrentFolder-";
if(comics.size()>0)
{
QString destFolderPath = currentFolderPath();
updateDestination = getCurrentFolderIndex();
@ -1308,11 +1315,13 @@ void LibraryWindow::moveAndImportComicsToCurrentFolder(const QList<QString> &com
comicFilesManager->moveComicsTo(comics,destFolderPath);
processComicFiles(comicFilesManager, progressDialog);
}
}
void LibraryWindow::copyAndImportComicsToFolder(const QList<QString> &comics, const QModelIndex &miFolder)
void LibraryWindow::copyAndImportComicsToFolder(const QList<QPair<QString,QString> > &comics, const QModelIndex &miFolder)
{
if(miFolder.isValid())
QLOG_DEBUG() << "-copyAndImportComicsToFolder-";
if(comics.size()>0)
{
QString destFolderPath = QDir::cleanPath(currentPath()+foldersModel->getFolderPath(miFolder));
@ -1329,9 +1338,10 @@ void LibraryWindow::copyAndImportComicsToFolder(const QList<QString> &comics, co
}
}
void LibraryWindow::moveAndImportComicsToFolder(const QList<QString> &comics, const QModelIndex &miFolder)
void LibraryWindow::moveAndImportComicsToFolder(const QList<QPair<QString, QString> > &comics, const QModelIndex &miFolder)
{
if(miFolder.isValid())
QLOG_DEBUG() << "-moveAndImportComicsToFolder-";
if(comics.size()>0)
{
QString destFolderPath = QDir::cleanPath(currentPath()+foldersModel->getFolderPath(miFolder));
@ -1415,6 +1425,9 @@ void LibraryWindow::reloadAfterCopyMove()
if(getCurrentFolderIndex() == updateDestination)
reloadCovers();
//TODO do not reload the whole model, just the current folder...
foldersModel->setupModelData(QDir::cleanPath(libraries.getPath(selectedLibrary->currentText())+"/.yacreaderlibrary"));
enableNeededActions();
}

View File

@ -326,10 +326,10 @@ public slots:
void toggleComicsView();
void checkSearchNumResults(int numResults);
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 copyAndImportComicsToCurrentFolder(const QList<QPair<QString,QString> > & comics);
void moveAndImportComicsToCurrentFolder(const QList<QPair<QString, QString> > &comics);
void copyAndImportComicsToFolder(const QList<QPair<QString,QString> > & comics, const QModelIndex & miFolder);
void moveAndImportComicsToFolder(const QList<QPair<QString,QString> > & comics, const QModelIndex & miFolder);
void processComicFiles(ComicFilesManager * comicFilesManager, QProgressDialog * progressDialog);
void updateCopyMoveFolderDestination(); //imports new comics from the current folder
void updateCurrentFolder();

View File

@ -13,11 +13,13 @@
#include "compressed_archive.h"
#include "comic_db.h"
QStringList Comic::imageExtensions = QStringList() << "*.jpg" << "*.jpeg" << "*.png" << "*.gif" << "*.tiff" << "*.tif" << "*.bmp";
QStringList Comic::literalImageExtensions = QStringList() << "jpg" << "jpeg" << "png" << "gif" << "tiff" << "tif" << "bmp";
#include "QsLog.h"
QStringList Comic::comicExtensions = QStringList() << "*.cbr" << "*.cbz" << "*.rar" << "*.zip" << "*.tar" << "*.pdf" << "*.7z" << "*.cb7" << "*.arj" << "*.cbt";
QStringList Comic::literalComicExtensions = QStringList() << "cbr" << "cbz" << "rar" << "zip" << "tar" << "pdf" << "7z" << "cb7" << "arj" << "cbt";
const QStringList Comic::imageExtensions = QStringList() << "*.jpg" << "*.jpeg" << "*.png" << "*.gif" << "*.tiff" << "*.tif" << "*.bmp";
const QStringList Comic::literalImageExtensions = QStringList() << "jpg" << "jpeg" << "png" << "gif" << "tiff" << "tif" << "bmp";
const QStringList Comic::comicExtensions = QStringList() << "*.cbr" << "*.cbz" << "*.rar" << "*.zip" << "*.tar" << "*.pdf" << "*.7z" << "*.cb7" << "*.arj" << "*.cbt";
const QStringList Comic::literalComicExtensions = QStringList() << "cbr" << "cbz" << "rar" << "zip" << "tar" << "pdf" << "7z" << "cb7" << "arj" << "cbt";
//-----------------------------------------------------------------------------
Comic::Comic()
@ -183,18 +185,52 @@ bool Comic::pageIsLoaded(int page)
return _loadedPages[page];
}
bool Comic::fileIsComic(QUrl &path)
bool Comic::fileIsComic(const QString &path)
{
QFileInfo info(path.toLocalFile());
QFileInfo info(path);
return literalComicExtensions.contains(info.suffix());
}
QList<QString> Comic::filterInvalidComicFiles(const QList<QUrl> &list)
QList<QString> Comic::findValidComicFiles(const QList<QUrl> &list)
{
QLOG_DEBUG() << "-findValidComicFiles-";
QList<QString> validComicFiles;
QString currentPath;
foreach (QUrl url, list) {
if(Comic::fileIsComic(url))
validComicFiles << url.toLocalFile();
currentPath = url.toLocalFile();
if(Comic::fileIsComic(currentPath))
validComicFiles << currentPath;
else if(QFileInfo(currentPath).isDir())
{
validComicFiles << findValidComicFilesInFolder(currentPath);
}
}
QLOG_DEBUG() << "-" << validComicFiles << "-";
return validComicFiles;
}
QList<QString> Comic::findValidComicFilesInFolder(const QString &path)
{
QLOG_DEBUG() << "-findValidComicFilesInFolder-" << path;
if(!QFileInfo(path).isDir())
return QList<QString>();
QList<QString> validComicFiles;
QDir folder(path);
folder.setNameFilters(Comic::comicExtensions);
folder.setFilter(QDir::AllDirs|QDir::Files|QDir::NoDotAndDotDot);
QFileInfoList folderContent = folder.entryInfoList();
QString currentPath;
foreach (QFileInfo info, folderContent) {
currentPath = info.absoluteFilePath();
if(info.isDir())
validComicFiles << findValidComicFilesInFolder(currentPath); //find comics recursively
else if(Comic::fileIsComic(currentPath))
{
validComicFiles << currentPath;
}
}
return validComicFiles;

View File

@ -49,12 +49,13 @@ class ComicDB;
bool _isPDF;
static QStringList imageExtensions;
static QStringList literalImageExtensions;
static QStringList comicExtensions;
static QStringList literalComicExtensions;
public:
static const QStringList imageExtensions;
static const QStringList literalImageExtensions;
static const QStringList comicExtensions;
static const QStringList literalComicExtensions;
Bookmarks * bm;
//Constructors
@ -84,9 +85,9 @@ class ComicDB;
inline static QStringList getSupportedImageFormats() { return imageExtensions;}
inline static QStringList getSupportedImageLiteralFormats() { return literalImageExtensions;}
static bool fileIsComic(QUrl & path);
static QList<QString> filterInvalidComicFiles(const QList<QUrl> & list);
static bool fileIsComic(const QString &path);
static QList<QString> findValidComicFiles(const QList<QUrl> & list);
static QList<QString> findValidComicFilesInFolder(const QString &path);
public slots:
void loadFinished();
void setBookmark();

View File

@ -3,6 +3,7 @@
#include "treemodel.h"
#include "comic.h"
#include "comic_files_manager.h"
#include "QsLog.h"
@ -77,9 +78,12 @@ void YACReaderTreeView::dragEnterEvent(QDragEnterEvent *event)
if (event->mimeData()->hasUrls())
{
urlList = event->mimeData()->urls();
QString currentPath;
foreach (QUrl url, urlList)
{
if(Comic::fileIsComic(url))
//comics or folders are accepted, folders' content is validate in dropEvent (avoid any lag before droping)
currentPath = url.toLocalFile();
if(Comic::fileIsComic(currentPath) || QFileInfo(currentPath).isDir())
{
event->acceptProposedAction();
return;
@ -88,20 +92,25 @@ void YACReaderTreeView::dragEnterEvent(QDragEnterEvent *event)
}
}
void YACReaderTreeView::dragLeaveEvent(QDragLeaveEvent *event)
{
Q_UNUSED(event)
}
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)) {
if( underMouse.isValid()) {
expandPos = event->pos();
connect(&expandTimer,SIGNAL(timeout()),this,SLOT(expandCurrent()));
expandTimer.start(750);
expandTimer.setSingleShot(true);
expandTimer.start(500);
}
//TODO force mouse hover decoration, why the event loop is not working here?
//force mouse hover decoration, TODO why the event loop is not working here?
if(!t.isActive())
{
t.setSingleShot(true);
@ -114,24 +123,33 @@ void YACReaderTreeView::dragMoveEvent(QDragMoveEvent *event)
void YACReaderTreeView::dropEvent(QDropEvent *event)
{
t.stop();
QTreeView::dropEvent(event);
bool accepted = false;
QLOG_DEBUG() << "drop on tree" << event->dropAction();
bool validAction = event->dropAction() == Qt::CopyAction || event->dropAction() & Qt::MoveAction;
if(validAction)
{
QList<QPair<QString, QString> > droppedFiles = ComicFilesManager::getDroppedFiles(event->mimeData()->urls());
QModelIndex destinationIndex = indexAt(event->pos());
if(event->dropAction() == Qt::CopyAction)
{
QLOG_DEBUG() << "copy - tree";
emit copyComicsToFolder(Comic::filterInvalidComicFiles(event->mimeData()->urls()),indexAt(event->pos()));
QLOG_DEBUG() << "copy - tree :" << droppedFiles;
emit copyComicsToFolder(droppedFiles, destinationIndex);
}
else if(event->dropAction() & Qt::MoveAction)
{
QLOG_DEBUG() << "move - tree";
emit moveComicsToFolder(Comic::filterInvalidComicFiles(event->mimeData()->urls()),indexAt(event->pos()));
QLOG_DEBUG() << "move - tree :" << droppedFiles;
emit moveComicsToFolder(droppedFiles, destinationIndex);
}
if(accepted)
event->acceptProposedAction();
}
}

View File

@ -11,8 +11,8 @@ public:
signals:
//Drops
void copyComicsToFolder(QList<QString>,QModelIndex);
void moveComicsToFolder(QList<QString>,QModelIndex);
void copyComicsToFolder(QList<QPair<QString,QString> >,QModelIndex);
void moveComicsToFolder(QList<QPair<QString,QString> >,QModelIndex);
protected slots:
//fix for drop auto expand
@ -21,9 +21,11 @@ protected slots:
protected:
//Drop to import
void dragEnterEvent(QDragEnterEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
//fix for drop auto expand
QTimer expandTimer;
QTimer t;