new class for controlling navigation in LibraryWindow (NavigationController), code refactoring

This commit is contained in:
Luis Ángel San Martín 2014-11-19 15:05:09 +01:00
parent b8ba1e5b70
commit 7c800011b3
18 changed files with 598 additions and 276 deletions

View File

@ -126,7 +126,8 @@ HEADERS += comic_flow.h \
yacreader_folders_view.h \ yacreader_folders_view.h \
yacreader_reading_lists_view.h \ yacreader_reading_lists_view.h \
add_label_dialog.h \ add_label_dialog.h \
yacreader_history_controller.h yacreader_history_controller.h \
yacreader_navigation_controller.h
SOURCES += comic_flow.cpp \ SOURCES += comic_flow.cpp \
@ -181,7 +182,8 @@ SOURCES += comic_flow.cpp \
yacreader_folders_view.cpp \ yacreader_folders_view.cpp \
yacreader_reading_lists_view.cpp \ yacreader_reading_lists_view.cpp \
add_label_dialog.cpp \ add_label_dialog.cpp \
yacreader_history_controller.cpp yacreader_history_controller.cpp \
yacreader_navigation_controller.cpp
include(./server/server.pri) include(./server/server.pri)

View File

@ -12,17 +12,19 @@ ComicFilesManager::ComicFilesManager(QObject *parent) :
{ {
} }
void ComicFilesManager::copyComicsTo(const QList<QPair<QString,QString> > &sourceComics, const QString &folderDest) void ComicFilesManager::copyComicsTo(const QList<QPair<QString,QString> > &sourceComics, const QString &folderDest, const QModelIndex & dest)
{ {
comics = sourceComics; comics = sourceComics;
folder = folderDest; folder = folderDest;
folderDestinationModelIndex = dest;
move = false; move = false;
} }
void ComicFilesManager::moveComicsTo(const QList<QPair<QString, QString> > &sourceComics, const QString &folderDest) void ComicFilesManager::moveComicsTo(const QList<QPair<QString, QString> > &sourceComics, const QString &folderDest, const QModelIndex &dest)
{ {
comics = sourceComics; comics = sourceComics;
folder = folderDest; folder = folderDest;
folderDestinationModelIndex = dest;
move = true; move = true;
} }
@ -34,17 +36,24 @@ QList<QPair<QString, QString> > ComicFilesManager::getDroppedFiles(const QList<Q
foreach(QUrl url, urls) foreach(QUrl url, urls)
{ {
currentPath = url.toLocalFile(); currentPath = url.toLocalFile();
if(currentPath.endsWith('/'))
currentPath = currentPath.remove(currentPath.length()-1,1); //QTBUG-35896 QUrl.toLocalFile inconsistency.
if(Comic::fileIsComic(currentPath)) if(Comic::fileIsComic(currentPath))
dropedFiles << QPair<QString, QString>(currentPath,"/"); dropedFiles << QPair<QString, QString>(currentPath,"/");
else else
{ {
QLOG_DEBUG() << "XXXXXXXXXXXX :" << currentPath;
QFileInfo info(currentPath); QFileInfo info(currentPath);
if(info.isDir()) if(info.isDir())
{ {
QLOG_DEBUG() << "origin path prior to absoluteFilePath : " << info.absolutePath();
foreach(QString comicPath, Comic::findValidComicFilesInFolder(info.absoluteFilePath())) foreach(QString comicPath, Comic::findValidComicFilesInFolder(info.absoluteFilePath()))
{ {
QFileInfo comicInfo(comicPath); QFileInfo comicInfo(comicPath);
QString path = comicInfo.absolutePath(); QString path = comicInfo.absolutePath();
QLOG_DEBUG() << "comic path : " << comicPath;
QLOG_DEBUG() << "full comic path : " << path;
QLOG_DEBUG() << "origin path : " << info.absolutePath();
dropedFiles << QPair<QString, QString>(comicPath, path.remove(info.absolutePath())); dropedFiles << QPair<QString, QString>(comicPath, path.remove(info.absolutePath()));
} }
} }
@ -64,7 +73,7 @@ void ComicFilesManager::process()
if(canceled) if(canceled)
{ {
if(successProcesingFiles) if(successProcesingFiles)
emit success(); emit success(folderDestinationModelIndex);
emit finished(); emit finished();
return; //TODO rollback? return; //TODO rollback?
@ -88,7 +97,7 @@ void ComicFilesManager::process()
} }
if(successProcesingFiles) if(successProcesingFiles)
emit success(); emit success(folderDestinationModelIndex);
emit finished(); emit finished();
} }

View File

@ -4,6 +4,7 @@
#include <QObject> #include <QObject>
#include <QList> #include <QList>
#include <QPair> #include <QPair>
#include <QModelIndex>
//this class is intended to work in background, just use moveToThread and process to start working //this class is intended to work in background, just use moveToThread and process to start working
@ -12,14 +13,14 @@ class ComicFilesManager : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit ComicFilesManager(QObject *parent = 0); explicit ComicFilesManager(QObject *parent = 0);
void copyComicsTo(const QList<QPair<QString,QString> > & sourceComics, const QString & folderDest); void copyComicsTo(const QList<QPair<QString,QString> > & sourceComics, const QString & folderDest, const QModelIndex &dest);
void moveComicsTo(const QList<QPair<QString,QString> > & comics, const QString & folderDest); void moveComicsTo(const QList<QPair<QString,QString> > & comics, const QString & folderDest, const QModelIndex &dest);
static QList<QPair<QString, QString> > getDroppedFiles(const QList<QUrl> & urls); static QList<QPair<QString, QString> > getDroppedFiles(const QList<QUrl> & urls);
signals: signals:
void currentComic(QString); void currentComic(QString);
void progress(int); void progress(int);
void finished(); void finished();
void success(); //at least one comics has been copied or moved void success(QModelIndex); //at least one comics has been copied or moved
public slots: public slots:
void process(); void process();
void cancel(); void cancel();
@ -29,6 +30,7 @@ protected:
bool canceled; bool canceled;
QList<QPair<QString,QString> > comics; QList<QPair<QString,QString> > comics;
QString folder; QString folder;
QModelIndex folderDestinationModelIndex;
}; };

View File

@ -99,7 +99,7 @@ void drawMacOSXFinishedFolderIcon()
#define ROOT 1 #define ROOT 1
FolderModel::FolderModel(QObject *parent) FolderModel::FolderModel(QObject *parent)
: QAbstractItemModel(parent),rootItem(0),rootBeforeFilter(0),filterEnabled(false),includeComics(false) : QAbstractItemModel(parent),rootItem(0)
{ {
connect(this,SIGNAL(beforeReset()),this,SIGNAL(modelAboutToBeReset())); connect(this,SIGNAL(beforeReset()),this,SIGNAL(modelAboutToBeReset()));
connect(this,SIGNAL(reset()),this,SIGNAL(modelReset())); connect(this,SIGNAL(reset()),this,SIGNAL(modelReset()));
@ -107,7 +107,7 @@ FolderModel::FolderModel(QObject *parent)
//! [0] //! [0]
FolderModel::FolderModel( QSqlQuery &sqlquery, QObject *parent) FolderModel::FolderModel( QSqlQuery &sqlquery, QObject *parent)
: QAbstractItemModel(parent),rootItem(0),rootBeforeFilter(0),filterEnabled(false),includeComics(false) : QAbstractItemModel(parent),rootItem(0)
{ {
//lo m<>s probable es que el nodo ra<72>z no necesite tener informaci<63>n //lo m<>s probable es que el nodo ra<72>z no necesite tener informaci<63>n
QList<QVariant> rootData; QList<QVariant> rootData;
@ -234,6 +234,7 @@ QModelIndex FolderModel::parent(const QModelIndex &index) const
} }
//! [7] //! [7]
/*
QModelIndex FolderModel::indexFromItem(FolderItem * item,int column) QModelIndex FolderModel::indexFromItem(FolderItem * item,int column)
{ {
//if(item->parent() != 0) //if(item->parent() != 0)
@ -241,7 +242,7 @@ QModelIndex FolderModel::indexFromItem(FolderItem * item,int column)
//else //else
// return index(item->row(),0,QModelIndex()); // return index(item->row(),0,QModelIndex());
return createIndex(item->row(), column, item); return createIndex(item->row(), column, item);
} }*/
//! [8] //! [8]
@ -265,9 +266,9 @@ void FolderModel::setupModelData(QString path)
beginResetModel(); beginResetModel();
if(rootItem != 0) if(rootItem != 0)
delete rootItem; //TODO comprobar que se libera bien la memoria delete rootItem; //TODO comprobar que se libera bien la memoria
filterEnabled = false;
rootItem = 0; rootItem = 0;
rootBeforeFilter = 0;
//inicializar el nodo ra<72>z //inicializar el nodo ra<72>z
QList<QVariant> rootData; QList<QVariant> rootData;
rootData << "root"; //id 0, padre 0, title "root" (el id, y el id del padre van a ir en la clase TreeItem) rootData << "root"; //id 0, padre 0, title "root" (el id, y el id del padre van a ir en la clase TreeItem)
@ -323,6 +324,7 @@ void FolderModel::setupModelData(QSqlQuery &sqlquery, FolderItem *parent)
void FolderModel::updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent) void FolderModel::updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent)
{ {
while (sqlquery.next()) { while (sqlquery.next()) {
QLOG_DEBUG () << "habia next";
QList<QVariant> data; QList<QVariant> data;
QSqlRecord record = sqlquery.record(); QSqlRecord record = sqlquery.record();
@ -342,160 +344,6 @@ void FolderModel::updateFolderModelData(QSqlQuery &sqlquery, FolderItem *parent)
} }
} }
void FolderModel::setupFilteredModelData()
{
beginResetModel();
//TODO hay que liberar memoria de anteriores filtrados
//inicializar el nodo ra<72>z
if(rootBeforeFilter == 0)
rootBeforeFilter = rootItem;
else
delete rootItem;//los resultados de la b<>squeda anterior deben ser borrados
QList<QVariant> rootData;
rootData << "root"; //id 1, padre 1, title "root" (el id, y el id del padre van a ir en la clase TreeItem)
rootItem = new FolderItem(rootData);
rootItem->id = ROOT;
rootItem->parentItem = 0;
//cargar la base de datos
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
//crear la consulta
{
QSqlQuery selectQuery(db); //TODO check
if(!includeComics)
{
selectQuery.prepare("select * from folder where id <> 1 and upper(name) like upper(:filter) order by parentId,name ");
selectQuery.bindValue(":filter", "%%"+filter+"%%");
}
else
{
switch(modifier)
{
case YACReader::NoModifiers:
selectQuery.prepare("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed "
"FROM folder f LEFT JOIN comic c ON (f.id = c.parentId) "
"WHERE f.id <> 1 AND ((UPPER(c.fileName) like UPPER(:filter)) OR (UPPER(f.name) like UPPER(:filter2))) ORDER BY f.parentId,f.name");
selectQuery.bindValue(":filter", "%%"+filter+"%%");
selectQuery.bindValue(":filter2", "%%"+filter+"%%");
break;
case YACReader::OnlyRead:
selectQuery.prepare("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed "
"FROM folder f LEFT JOIN (comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id)) ON (f.id = c.parentId) "
"WHERE f.id <> 1 AND ((UPPER(c.fileName) like UPPER(:filter)) OR (UPPER(f.name) like UPPER(:filter2))) AND ci.read = 1 ORDER BY f.parentId,f.name;");
selectQuery.bindValue(":filter", "%%"+filter+"%%");
selectQuery.bindValue(":filter2", "%%"+filter+"%%");
break;
case YACReader::OnlyUnread:
selectQuery.prepare("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed "
"FROM folder f LEFT JOIN (comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id)) ON (f.id = c.parentId) "
"WHERE f.id <> 1 AND ((UPPER(c.fileName) like UPPER(:filter)) OR (UPPER(f.name) like UPPER(:filter2))) AND ci.read = 0 ORDER BY f.parentId,f.name;");
selectQuery.bindValue(":filter", "%%"+filter+"%%");
selectQuery.bindValue(":filter2", "%%"+filter+"%%");
break;
default:
QLOG_ERROR() << "not implemented";
break;
}
}
selectQuery.exec();
setupFilteredModelData(selectQuery,rootItem);
}
//selectQuery.finish();
db.close();
QSqlDatabase::removeDatabase(_databasePath);
endResetModel();
}
void FolderModel::setupFilteredModelData(QSqlQuery &sqlquery, FolderItem *parent)
{
//64 bits para la primary key, es decir la misma precisi<73>n que soporta sqlit 2^64
filteredItems.clear();
//se a<>ade el nodo 0 al modelo que representa el arbol de elementos que cumplen con el filtro
filteredItems.insert(parent->id,parent);
while (sqlquery.next()) { //se procesan todos los folders que cumplen con el filtro
//datos de la base de datos
QList<QVariant> data;
QSqlRecord record = sqlquery.record();
data << record.value("name").toString();
data << record.value("path").toString();
data << record.value("finished").toBool();
data << record.value("completed").toBool();
FolderItem * item = new FolderItem(data);
item->id = sqlquery.value(0).toULongLong();
//id del padre
quint64 parentId = record.value("parentId").toULongLong();
//se a<>ade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones
if(!filteredItems.contains(item->id))
filteredItems.insert(item->id,item);
//es necesario conocer las coordenadas de origen para poder realizar scroll autom<6F>tico en la vista
item->originalItem = items.value(item->id);
//si el padre ya existe en el modelo, el item se a<>ade como hijo
if(filteredItems.contains(parentId))
filteredItems.value(parentId)->appendChild(item);
else//si el padre a<>n no se ha a<>adido, hay que a<>adirlo a <20>l y todos los padres hasta el nodo ra<72>z
{
//comprobamos con esta variable si el <20>ltimo de los padres (antes del nodo ra<72>z) ya exist<73>a en el modelo
bool parentPreviousInserted = false;
//mientras no se alcance el nodo ra<72>z se procesan todos los padres (de abajo a arriba)
while(parentId != ROOT )
{
//el padre no estaba en el modelo filtrado, as<61> que se rescata del modelo original
FolderItem * parentItem = items.value(parentId);
//se debe crear un nuevo nodo (para no compartir los hijos con el nodo original)
FolderItem * newparentItem = new FolderItem(parentItem->getData()); //padre que se a<>adir<69> a la estructura de directorios filtrados
newparentItem->id = parentId;
newparentItem->originalItem = parentItem;
//si el modelo contiene al padre, se a<>ade el item actual como hijo
if(filteredItems.contains(parentId))
{
filteredItems.value(parentId)->appendChild(item);
parentPreviousInserted = true;
}
//sino se registra el nodo para poder encontrarlo con posterioridad y se a<>ade el item actual como hijo
else
{
newparentItem->appendChild(item);
filteredItems.insert(newparentItem->id,newparentItem);
parentPreviousInserted = false;
}
//variables de control del bucle, se avanza hacia el nodo padre
item = newparentItem;
parentId = parentItem->parentItem->id;
}
//si el nodo es hijo de 1 y no hab<61>a sido previamente insertado como hijo, se a<>ade como tal
if(!parentPreviousInserted)
filteredItems.value(ROOT)->appendChild(item);
}
}
}
QString FolderModel::getDatabase() QString FolderModel::getDatabase()
{ {
return _databasePath; return _databasePath;
@ -508,15 +356,7 @@ QString FolderModel::getFolderPath(const QModelIndex &folder)
return static_cast<FolderItem*>(folder.internalPointer())->data(FolderModel::Path).toString(); return static_cast<FolderItem*>(folder.internalPointer())->data(FolderModel::Path).toString();
} }
void FolderModel::setFilter(const YACReader::SearchModifiers modifier, QString filter, bool includeComics) /*
{
this->filter = filter;
this->includeComics = includeComics;
this->modifier = modifier;
filterEnabled = true;
setupFilteredModelData();
}
void FolderModel::resetFilter() void FolderModel::resetFilter()
{ {
beginResetModel(); beginResetModel();
@ -535,7 +375,7 @@ void FolderModel::resetFilter()
endResetModel(); endResetModel();
} }*/
void FolderModel::updateFolderCompletedStatus(const QModelIndexList &list, bool status) void FolderModel::updateFolderCompletedStatus(const QModelIndexList &list, bool status)
{ {
@ -609,9 +449,12 @@ void FolderModel::fetchMoreFromDB(const QModelIndex &parent)
item = rootItem; item = rootItem;
//Remove all children //Remove all children
beginRemoveRows(parent, 0, item->childCount()); if(item->childCount() > 0)
{
beginRemoveRows(parent, 0, item->childCount()-1);
item->clearChildren(); item->clearChildren();
endRemoveRows(); endRemoveRows();
}
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
@ -622,26 +465,38 @@ void FolderModel::fetchMoreFromDB(const QModelIndex &parent)
selectQuery.prepare("select * from folder where id <> 1 and parentId = :parentId order by parentId,name"); selectQuery.prepare("select * from folder where id <> 1 and parentId = :parentId order by parentId,name");
items << item; items << item;
bool firstLevelUpdate = false; bool firstLevelUpdated = false;
while(items.size() > 0) while(items.size() > 0)
{ {
nextLevelItems.clear(); nextLevelItems.clear();
foreach(FolderItem * item, items) foreach(FolderItem * item, items)
{ {
QLOG_DEBUG() << "ID " << item->id;
selectQuery.bindValue(":parentId", item->id); selectQuery.bindValue(":parentId", item->id);
selectQuery.exec(); selectQuery.exec();
//Reload all children
if(!firstLevelUpdate) if(!firstLevelUpdated)
{ {
beginInsertRows(parent, 0, selectQuery.numRowsAffected()); //NO size support
firstLevelUpdate = true; int numResults = 0;
while(selectQuery.next())
numResults++;
if(!selectQuery.seek(-1))
selectQuery.exec();
//END no size support
beginInsertRows(parent, 0, numResults-1);
} }
updateFolderModelData(selectQuery,item); updateFolderModelData(selectQuery,item);
if(!firstLevelUpdate) if(!firstLevelUpdated)
{
endInsertRows(); endInsertRows();
firstLevelUpdated = true;
}
nextLevelItems << item->children(); nextLevelItems << item->children();
@ -651,6 +506,9 @@ void FolderModel::fetchMoreFromDB(const QModelIndex &parent)
items = nextLevelItems; items = nextLevelItems;
} }
QLOG_DEBUG() << "item->childCount()-1" << item->childCount()-1;
db.close(); db.close();
QSqlDatabase::removeDatabase(_databasePath); QSqlDatabase::removeDatabase(_databasePath);
} }
@ -713,3 +571,208 @@ void FolderModel::deleteFolder(const QModelIndex &mi)
endRemoveRows(); endRemoveRows();
} }
//PROXY
FolderModelProxy::FolderModelProxy(QObject *parent)
:QSortFilterProxyModel(parent),rootItem(0),filterEnabled(false),filter(""),includeComics(true)
{
}
FolderModelProxy::~FolderModelProxy()
{
}
bool FolderModelProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
if(!filterEnabled)
return true;
FolderItem * parent = static_cast<FolderItem *>(source_parent.internalPointer());
if(parent == 0)
parent = static_cast<FolderModel *>(sourceModel())->rootItem;
FolderItem * item = parent->children().at(source_row);
return filteredItems.contains(item->id);
}
void FolderModelProxy::setFilter(const YACReader::SearchModifiers modifier, QString filter, bool includeComics)
{
clear();
this->filter = filter;
this->includeComics = includeComics;
this->modifier = modifier;
filterEnabled = true;
setupFilteredModelData();
}
void FolderModelProxy::setupFilteredModelData()
{
beginResetModel();
//TODO hay que liberar memoria de anteriores filtrados
//inicializar el nodo ra<72>z
if(rootItem != 0)
delete rootItem; //TODO comprobar que se libera bien la memoria
rootItem = 0;
//inicializar el nodo ra<72>z
QList<QVariant> rootData;
rootData << "root";
rootItem = new FolderItem(rootData);
rootItem->id = ROOT;
rootItem->parentItem = 0;
FolderModel * model = static_cast<FolderModel *>(sourceModel());
//cargar la base de datos
QSqlDatabase db = DataBaseManagement::loadDatabase(model->_databasePath);
//crear la consulta
{
QSqlQuery selectQuery(db); //TODO check
if(!includeComics)
{
selectQuery.prepare("select * from folder where id <> 1 and upper(name) like upper(:filter) order by parentId,name ");
selectQuery.bindValue(":filter", "%%"+filter+"%%");
}
else
{
switch(modifier)
{
case YACReader::NoModifiers:
selectQuery.prepare("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed "
"FROM folder f LEFT JOIN comic c ON (f.id = c.parentId) "
"WHERE f.id <> 1 AND ((UPPER(c.fileName) like UPPER(:filter)) OR (UPPER(f.name) like UPPER(:filter2))) ORDER BY f.parentId,f.name");
selectQuery.bindValue(":filter", "%%"+filter+"%%");
selectQuery.bindValue(":filter2", "%%"+filter+"%%");
break;
case YACReader::OnlyRead:
selectQuery.prepare("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed "
"FROM folder f LEFT JOIN (comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id)) ON (f.id = c.parentId) "
"WHERE f.id <> 1 AND ((UPPER(c.fileName) like UPPER(:filter)) OR (UPPER(f.name) like UPPER(:filter2))) AND ci.read = 1 ORDER BY f.parentId,f.name;");
selectQuery.bindValue(":filter", "%%"+filter+"%%");
selectQuery.bindValue(":filter2", "%%"+filter+"%%");
break;
case YACReader::OnlyUnread:
selectQuery.prepare("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed "
"FROM folder f LEFT JOIN (comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id)) ON (f.id = c.parentId) "
"WHERE f.id <> 1 AND ((UPPER(c.fileName) like UPPER(:filter)) OR (UPPER(f.name) like UPPER(:filter2))) AND ci.read = 0 ORDER BY f.parentId,f.name;");
selectQuery.bindValue(":filter", "%%"+filter+"%%");
selectQuery.bindValue(":filter2", "%%"+filter+"%%");
break;
default:
QLOG_ERROR() << "not implemented";
break;
}
}
selectQuery.exec();
setupFilteredModelData(selectQuery,rootItem);
}
//selectQuery.finish();
db.close();
QSqlDatabase::removeDatabase(model->_databasePath);
endResetModel();
}
void FolderModelProxy::clear()
{
filterEnabled = false;
filteredItems.clear();
QSortFilterProxyModel::clear();
}
void FolderModelProxy::setupFilteredModelData(QSqlQuery &sqlquery, FolderItem *parent)
{
FolderModel * model = static_cast<FolderModel *>(sourceModel());
//64 bits para la primary key, es decir la misma precisi<73>n que soporta sqlit 2^64
filteredItems.clear();
//se a<>ade el nodo 0 al modelo que representa el arbol de elementos que cumplen con el filtro
filteredItems.insert(parent->id,parent);
while (sqlquery.next()) { //se procesan todos los folders que cumplen con el filtro
//datos de la base de datos
QList<QVariant> data;
QSqlRecord record = sqlquery.record();
data << record.value("name").toString();
data << record.value("path").toString();
data << record.value("finished").toBool();
data << record.value("completed").toBool();
FolderItem * item = new FolderItem(data);
item->id = sqlquery.value(0).toULongLong();
//id del padre
quint64 parentId = record.value("parentId").toULongLong();
//se a<>ade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones
if(!filteredItems.contains(item->id))
filteredItems.insert(item->id,item);
//es necesario conocer las coordenadas de origen para poder realizar scroll autom<6F>tico en la vista
item->originalItem = model->items.value(item->id);
//si el padre ya existe en el modelo, el item se a<>ade como hijo
if(filteredItems.contains(parentId))
filteredItems.value(parentId)->appendChild(item);
else//si el padre a<>n no se ha a<>adido, hay que a<>adirlo a <20>l y todos los padres hasta el nodo ra<72>z
{
//comprobamos con esta variable si el <20>ltimo de los padres (antes del nodo ra<72>z) ya exist<73>a en el modelo
bool parentPreviousInserted = false;
//mientras no se alcance el nodo ra<72>z se procesan todos los padres (de abajo a arriba)
while(parentId != ROOT )
{
//el padre no estaba en el modelo filtrado, as<61> que se rescata del modelo original
FolderItem * parentItem = model->items.value(parentId);
//se debe crear un nuevo nodo (para no compartir los hijos con el nodo original)
FolderItem * newparentItem = new FolderItem(parentItem->getData()); //padre que se a<>adir<69> a la estructura de directorios filtrados
newparentItem->id = parentId;
newparentItem->originalItem = parentItem;
//si el modelo contiene al padre, se a<>ade el item actual como hijo
if(filteredItems.contains(parentId))
{
filteredItems.value(parentId)->appendChild(item);
parentPreviousInserted = true;
}
//sino se registra el nodo para poder encontrarlo con posterioridad y se a<>ade el item actual como hijo
else
{
newparentItem->appendChild(item);
filteredItems.insert(newparentItem->id,newparentItem);
parentPreviousInserted = false;
}
//variables de control del bucle, se avanza hacia el nodo padre
item = newparentItem;
parentId = parentItem->parentItem->id;
}
//si el nodo es hijo de 1 y no hab<61>a sido previamente insertado como hijo, se a<>ade como tal
if(!parentPreviousInserted)
filteredItems.value(ROOT)->appendChild(item);
}
}
}

View File

@ -42,6 +42,7 @@
#define TREEMODEL_H #define TREEMODEL_H
#include <QAbstractItemModel> #include <QAbstractItemModel>
#include <QSortFilterProxyModel>
#include <QModelIndex> #include <QModelIndex>
#include <QVariant> #include <QVariant>
#include <QSqlQuery> #include <QSqlQuery>
@ -51,10 +52,37 @@
class FolderItem; class FolderItem;
//! [0] class FolderModelProxy : public QSortFilterProxyModel
class FolderModel : public QAbstractItemModel
{ {
Q_OBJECT Q_OBJECT
public:
explicit FolderModelProxy(QObject *parent = 0);
~FolderModelProxy();
void setFilter(const YACReader::SearchModifiers modifier, QString filter, bool includeComics);
void setupFilteredModelData( QSqlQuery &sqlquery, FolderItem *parent);
void setupFilteredModelData();
void clear();
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
protected:
FolderItem *rootItem;
QMap<unsigned long long int, FolderItem *> filteredItems; //relación entre folders
bool includeComics;
QString filter;
bool filterEnabled;
YACReader::SearchModifiers modifier;
};
class FolderModel : public QAbstractItemModel
{
Q_OBJECT
friend class FolderModelProxy;
public: public:
FolderModel(QObject *parent = 0); FolderModel(QObject *parent = 0);
@ -76,10 +104,10 @@ public:
void setupModelData(QString path); void setupModelData(QString path);
QString getDatabase(); QString getDatabase();
QString getFolderPath(const QModelIndex &folder); QString getFolderPath(const QModelIndex &folder);
QModelIndex indexFromItem(FolderItem * item, int column); //QModelIndex indexFromItem(FolderItem * item, int column);
void setFilter(const YACReader::SearchModifiers modifier, QString filter, bool includeComics);
void resetFilter();
bool isFilterEnabled(){return filterEnabled;}; //bool isFilterEnabled(){return filterEnabled;};
void updateFolderCompletedStatus(const QModelIndexList & list, bool status); void updateFolderCompletedStatus(const QModelIndexList & list, bool status);
void updateFolderFinishedStatus(const QModelIndexList & list, bool status); void updateFolderFinishedStatus(const QModelIndexList & list, bool status);
@ -103,22 +131,12 @@ public slots:
private: private:
void setupModelData( QSqlQuery &sqlquery, FolderItem *parent); void setupModelData( QSqlQuery &sqlquery, FolderItem *parent);
void updateFolderModelData( QSqlQuery &sqlquery, FolderItem *parent); void updateFolderModelData( QSqlQuery &sqlquery, FolderItem *parent);
void setupFilteredModelData( QSqlQuery &sqlquery, FolderItem *parent);
void setupFilteredModelData();
FolderItem *rootItem; //el árbol FolderItem *rootItem; //el árbol
QMap<unsigned long long int, FolderItem *> items; //relación entre folders QMap<unsigned long long int, FolderItem *> items; //relación entre folders
FolderItem *rootBeforeFilter;
QMap<unsigned long long int, FolderItem *> filteredItems; //relación entre folders
QString _databasePath; QString _databasePath;
bool includeComics;
QString filter;
bool filterEnabled;
YACReader::SearchModifiers modifier;
signals: signals:
void beforeReset(); void beforeReset();
void reset(); void reset();

View File

@ -53,9 +53,10 @@ void LibraryCreator::updateLibrary(const QString &source, const QString &target)
processLibrary(source, target); processLibrary(source, target);
} }
void LibraryCreator::updateFolder(const QString &source, const QString &target, const QString &sourceFolder) void LibraryCreator::updateFolder(const QString &source, const QString &target, const QString &sourceFolder, const QModelIndex & dest)
{ {
partialUpdate = true; partialUpdate = true;
folderDestinationModelIndex = dest;
_currentPathFolders.clear(); _currentPathFolders.clear();
_currentPathFolders.append(Folder(1,1,"root","/")); _currentPathFolders.append(Folder(1,1,"root","/"));
@ -198,7 +199,10 @@ void LibraryCreator::run()
} }
//msleep(100);//TODO try to solve the problem with the udpate dialog (ya no se usa más...) //msleep(100);//TODO try to solve the problem with the udpate dialog (ya no se usa más...)
if(partialUpdate) if(partialUpdate)
emit updatedCurrentFolder(); {
emit updatedCurrentFolder(folderDestinationModelIndex);
emit finished();
}
else else
emit finished(); emit finished();
creation = false; creation = false;

View File

@ -13,6 +13,7 @@
#include <QMutex> #include <QMutex>
#include <QThread> #include <QThread>
#include <QSqlDatabase> #include <QSqlDatabase>
#include <QModelIndex>
#include "folder.h" #include "folder.h"
#include "comic_db.h" #include "comic_db.h"
@ -25,7 +26,7 @@
LibraryCreator(); LibraryCreator();
void createLibrary(const QString & source, const QString & target); void createLibrary(const QString & source, const QString & target);
void updateLibrary(const QString & source, const QString & target); void updateLibrary(const QString & source, const QString & target);
void updateFolder(const QString & source, const QString & target, const QString & folder); void updateFolder(const QString & source, const QString & target, const QString & folder, const QModelIndex &dest);
void stop(); void stop();
private: private:
@ -52,6 +53,7 @@
//LibraryCreator está en modo creación si creation == true; //LibraryCreator está en modo creación si creation == true;
bool creation; bool creation;
bool partialUpdate; bool partialUpdate;
QModelIndex folderDestinationModelIndex;
signals: signals:
void finished(); void finished();
@ -62,7 +64,7 @@
void created(); void created();
void failedCreatingDB(QString); void failedCreatingDB(QString);
void failedOpeningDB(QString); void failedOpeningDB(QString);
void updatedCurrentFolder(); void updatedCurrentFolder(QModelIndex);
}; };
class ThumbnailCreator : public QObject class ThumbnailCreator : public QObject

View File

@ -90,7 +90,7 @@
#endif #endif
LibraryWindow::LibraryWindow() LibraryWindow::LibraryWindow()
:QMainWindow(),fullscreen(false),fetching(false),previousFilter(""),removeError(false) :QMainWindow(),fullscreen(false),fetching(false),previousFilter(""),removeError(false),status(LibraryWindow::Normal)
{ {
setupUI(); setupUI();
loadLibraries(); loadLibraries();
@ -104,6 +104,8 @@ LibraryWindow::LibraryWindow()
showRootWidget(); showRootWidget();
selectedLibrary->setCurrentIndex(0); selectedLibrary->setCurrentIndex(0);
} }
navigationController = new YACReaderNavigationController(this);
} }
void LibraryWindow::setupUI() void LibraryWindow::setupUI()
@ -406,12 +408,14 @@ void LibraryWindow::doModels()
{ {
//folders //folders
foldersModel = new FolderModel(); foldersModel = new FolderModel();
foldersModelProxy = new FolderModelProxy();
//foldersModelProxy->setSourceModel(foldersModel);
//comics //comics
comicsModel = new ComicModel(); comicsModel = new ComicModel();
//lists //lists
listsModel = new ReadingListModel(); listsModel = new ReadingListModel();
setSearchFilter(YACReader::NoModifiers, ""); //clear search filter //setSearchFilter(YACReader::NoModifiers, ""); //clear search filter
} }
void LibraryWindow::disconnectComicsViewConnections(ComicsView * widget) void LibraryWindow::disconnectComicsViewConnections(ComicsView * widget)
@ -1025,9 +1029,7 @@ void LibraryWindow::createConnections()
//-- //--
connect(historyController,SIGNAL(enabledBackward(bool)),backAction,SLOT(setEnabled(bool))); connect(historyController,SIGNAL(enabledBackward(bool)),backAction,SLOT(setEnabled(bool)));
connect(historyController,SIGNAL(enabledForward(bool)),forwardAction,SLOT(setEnabled(bool))); connect(historyController,SIGNAL(enabledForward(bool)),forwardAction,SLOT(setEnabled(bool)));
connect(historyController,SIGNAL(modelIndexSelected(QModelIndex)),this,SLOT(loadCovers(QModelIndex))); //connect(foldersView, SIGNAL(clicked(QModelIndex)), historyController, SLOT(updateHistory(QModelIndex)));
connect(historyController,SIGNAL(modelIndexSelected(QModelIndex)),foldersView,SLOT(setCurrentIndex(QModelIndex)));
connect(foldersView, SIGNAL(clicked(QModelIndex)), historyController, SLOT(updateHistory(QModelIndex)));
//libraryCreator connections //libraryCreator connections
connect(createLibraryDialog,SIGNAL(createLibrary(QString,QString,QString)),this,SLOT(create(QString,QString,QString))); connect(createLibraryDialog,SIGNAL(createLibrary(QString,QString,QString)),this,SLOT(create(QString,QString,QString)));
@ -1039,8 +1041,8 @@ void LibraryWindow::createConnections()
connect(libraryCreator,SIGNAL(finished()),this,SLOT(showRootWidget())); connect(libraryCreator,SIGNAL(finished()),this,SLOT(showRootWidget()));
connect(libraryCreator,SIGNAL(updated()),this,SLOT(reloadCurrentLibrary())); connect(libraryCreator,SIGNAL(updated()),this,SLOT(reloadCurrentLibrary()));
connect(libraryCreator,SIGNAL(created()),this,SLOT(openLastCreated())); connect(libraryCreator,SIGNAL(created()),this,SLOT(openLastCreated()));
connect(libraryCreator,SIGNAL(updatedCurrentFolder()), this, SLOT(showRootWidget())); //connect(libraryCreator,SIGNAL(updatedCurrentFolder()), this, SLOT(showRootWidget()));
connect(libraryCreator,SIGNAL(updatedCurrentFolder()), this, SLOT(reloadAfterCopyMove())); connect(libraryCreator,SIGNAL(updatedCurrentFolder(QModelIndex)), this, SLOT(reloadAfterCopyMove(QModelIndex)));
connect(libraryCreator,SIGNAL(comicAdded(QString,QString)),importWidget,SLOT(newComic(QString,QString))); connect(libraryCreator,SIGNAL(comicAdded(QString,QString)),importWidget,SLOT(newComic(QString,QString)));
//libraryCreator errors //libraryCreator errors
connect(libraryCreator,SIGNAL(failedCreatingDB(QString)),this,SLOT(manageCreatingError(QString))); connect(libraryCreator,SIGNAL(failedCreatingDB(QString)),this,SLOT(manageCreatingError(QString)));
@ -1074,8 +1076,8 @@ void LibraryWindow::createConnections()
connect(renameLibraryDialog,SIGNAL(renameLibrary(QString)),this,SLOT(rename(QString))); connect(renameLibraryDialog,SIGNAL(renameLibrary(QString)),this,SLOT(rename(QString)));
//navigations between view modes (tree,list and flow) //navigations between view modes (tree,list and flow)
connect(foldersView, SIGNAL(pressed(QModelIndex)), this, SLOT(updateFoldersViewConextMenu(QModelIndex))); //TODO connect(foldersView, SIGNAL(pressed(QModelIndex)), this, SLOT(updateFoldersViewConextMenu(QModelIndex)));
connect(foldersView, SIGNAL(clicked(QModelIndex)), this, SLOT(loadCovers(QModelIndex))); //connect(foldersView, SIGNAL(clicked(QModelIndex)), this, SLOT(loadCovers(QModelIndex)));
//drops in folders view //drops in folders view
connect(foldersView, SIGNAL(copyComicsToFolder(QList<QPair<QString,QString> >,QModelIndex)), this, SLOT(copyAndImportComicsToFolder(QList<QPair<QString,QString> >,QModelIndex))); connect(foldersView, SIGNAL(copyComicsToFolder(QList<QPair<QString,QString> >,QModelIndex)), this, SLOT(copyAndImportComicsToFolder(QList<QPair<QString,QString> >,QModelIndex)));
@ -1155,9 +1157,9 @@ void LibraryWindow::createConnections()
connect(comicsViewTransition,SIGNAL(transitionFinished()),this,SLOT(showComicsView())); connect(comicsViewTransition,SIGNAL(transitionFinished()),this,SLOT(showComicsView()));
connect(comicsModel,SIGNAL(isEmpty()),this,SLOT(showEmptyFolderView())); //connect(comicsModel,SIGNAL(isEmpty()),this,SLOT(showEmptyFolderView()));
connect(comicsModel,SIGNAL(searchNumResults(int)),this,SLOT(checkSearchNumResults(int))); //connect(comicsModel,SIGNAL(searchNumResults(int)),this,SLOT(checkSearchNumResults(int)));
connect(emptyFolderWidget,SIGNAL(subfolderSelected(QModelIndex,int)),this,SLOT(selectSubfolder(QModelIndex,int))); //connect(emptyFolderWidget,SIGNAL(subfolderSelected(QModelIndex,int)),this,SLOT(selectSubfolder(QModelIndex,int)));
//Drops //Drops
connect(emptyFolderWidget, SIGNAL(copyComicsToCurrentFolder(QList<QPair<QString, QString> >)), this, SLOT(copyAndImportComicsToCurrentFolder(QList<QPair<QString, QString> >))); connect(emptyFolderWidget, SIGNAL(copyComicsToCurrentFolder(QList<QPair<QString, QString> >)), this, SLOT(copyAndImportComicsToCurrentFolder(QList<QPair<QString, QString> >)));
connect(emptyFolderWidget, SIGNAL(moveComicsToCurrentFolder(QList<QPair<QString, QString> >)), this, SLOT(moveAndImportComicsToCurrentFolder(QList<QPair<QString, QString> >))); connect(emptyFolderWidget, SIGNAL(moveComicsToCurrentFolder(QList<QPair<QString, QString> >)), this, SLOT(moveAndImportComicsToCurrentFolder(QList<QPair<QString, QString> >)));
@ -1166,7 +1168,7 @@ void LibraryWindow::createConnections()
//update folders (partial updates) //update folders (partial updates)
connect(updateCurrentFolderAction,SIGNAL(triggered()), this, SLOT(updateCurrentFolder())); connect(updateCurrentFolderAction,SIGNAL(triggered()), this, SLOT(updateCurrentFolder()));
connect(updateFolderAction,SIGNAL(triggered()), this, SLOT(updateTreeFolder())); connect(updateFolderAction,SIGNAL(triggered()), this, SLOT(updateCurrentFolder()));
//lists //lists
connect(addReadingListAction,SIGNAL(triggered()),this,SLOT(addNewReadingList())); connect(addReadingListAction,SIGNAL(triggered()),this,SLOT(addNewReadingList()));
@ -1212,10 +1214,9 @@ void LibraryWindow::loadLibrary(const QString & name)
if(comparation == 0 || updated) //en caso de que la versión se igual que la actual if(comparation == 0 || updated) //en caso de que la versión se igual que la actual
{ {
index = 0;
foldersModel->setupModelData(path); foldersModel->setupModelData(path);
foldersView->setModel(foldersModel); foldersModelProxy->setSourceModel(foldersModel);
foldersView->setModel(foldersModelProxy);
listsModel->setupReadingListsData(path); listsModel->setupReadingListsData(path);
listsView->setModel(listsModel); listsView->setModel(listsModel);
@ -1342,6 +1343,7 @@ void LibraryWindow::loadCovers(const QModelIndex & mi)
//cambiado de orden, ya que al llamar a foldersFilter->clear() se invalidan los model index //cambiado de orden, ya que al llamar a foldersFilter->clear() se invalidan los model index
/*
if(searchEdit->text()!="") if(searchEdit->text()!="")
{ {
//setFoldersFilter(""); //setFoldersFilter("");
@ -1357,6 +1359,7 @@ void LibraryWindow::loadCovers(const QModelIndex & mi)
index = static_cast<FolderItem *>(mi.internalPointer()); index = static_cast<FolderItem *>(mi.internalPointer());
column = mi.column(); column = mi.column();
} }
*/
//comicsView->setModel(NULL); //comicsView->setModel(NULL);
comicsModel->setupModelData(folderId,foldersModel->getDatabase()); comicsModel->setupModelData(folderId,foldersModel->getDatabase());
@ -1391,12 +1394,12 @@ void LibraryWindow::copyAndImportComicsToCurrentFolder(const QList<QPair<QString
{ {
QString destFolderPath = currentFolderPath(); QString destFolderPath = currentFolderPath();
updateDestination = getCurrentFolderIndex(); QModelIndex folderDestination = getCurrentFolderIndex();
QProgressDialog * progressDialog = newProgressDialog(tr("Copying comics..."),comics.size()); QProgressDialog * progressDialog = newProgressDialog(tr("Copying comics..."),comics.size());
ComicFilesManager * comicFilesManager = new ComicFilesManager(); ComicFilesManager * comicFilesManager = new ComicFilesManager();
comicFilesManager->copyComicsTo(comics,destFolderPath); comicFilesManager->copyComicsTo(comics,destFolderPath,folderDestination);
processComicFiles(comicFilesManager, progressDialog); processComicFiles(comicFilesManager, progressDialog);
} }
@ -1409,12 +1412,12 @@ void LibraryWindow::moveAndImportComicsToCurrentFolder(const QList<QPair<QString
{ {
QString destFolderPath = currentFolderPath(); QString destFolderPath = currentFolderPath();
updateDestination = getCurrentFolderIndex(); QModelIndex folderDestination = getCurrentFolderIndex();
QProgressDialog * progressDialog = newProgressDialog(tr("Moving comics..."),comics.size()); QProgressDialog * progressDialog = newProgressDialog(tr("Moving comics..."),comics.size());
ComicFilesManager * comicFilesManager = new ComicFilesManager(); ComicFilesManager * comicFilesManager = new ComicFilesManager();
comicFilesManager->moveComicsTo(comics,destFolderPath); comicFilesManager->moveComicsTo(comics,destFolderPath,folderDestination);
processComicFiles(comicFilesManager, progressDialog); processComicFiles(comicFilesManager, progressDialog);
} }
@ -1425,16 +1428,16 @@ void LibraryWindow::copyAndImportComicsToFolder(const QList<QPair<QString,QStrin
QLOG_DEBUG() << "-copyAndImportComicsToFolder-"; QLOG_DEBUG() << "-copyAndImportComicsToFolder-";
if(comics.size()>0) if(comics.size()>0)
{ {
QString destFolderPath = QDir::cleanPath(currentPath()+foldersModel->getFolderPath(miFolder)); QModelIndex folderDestination = foldersModelProxy->mapToSource(miFolder);
updateDestination = miFolder; QString destFolderPath = QDir::cleanPath(currentPath()+foldersModel->getFolderPath(folderDestination));
QLOG_DEBUG() << "Coping to " << destFolderPath; QLOG_DEBUG() << "Coping to " << destFolderPath;
QProgressDialog * progressDialog = newProgressDialog(tr("Copying comics..."),comics.size()); QProgressDialog * progressDialog = newProgressDialog(tr("Copying comics..."),comics.size());
ComicFilesManager * comicFilesManager = new ComicFilesManager(); ComicFilesManager * comicFilesManager = new ComicFilesManager();
comicFilesManager->copyComicsTo(comics,destFolderPath); comicFilesManager->copyComicsTo(comics,destFolderPath,folderDestination);
processComicFiles(comicFilesManager, progressDialog); processComicFiles(comicFilesManager, progressDialog);
} }
@ -1445,16 +1448,16 @@ void LibraryWindow::moveAndImportComicsToFolder(const QList<QPair<QString, QStri
QLOG_DEBUG() << "-moveAndImportComicsToFolder-"; QLOG_DEBUG() << "-moveAndImportComicsToFolder-";
if(comics.size()>0) if(comics.size()>0)
{ {
QString destFolderPath = QDir::cleanPath(currentPath()+foldersModel->getFolderPath(miFolder)); QModelIndex folderDestination = foldersModelProxy->mapToSource(miFolder);
updateDestination = miFolder; QString destFolderPath = QDir::cleanPath(currentPath()+foldersModel->getFolderPath(folderDestination));
QLOG_DEBUG() << "Moving to " << destFolderPath; QLOG_DEBUG() << "Moving to " << destFolderPath;
QProgressDialog * progressDialog = newProgressDialog(tr("Moving comics..."),comics.size()); QProgressDialog * progressDialog = newProgressDialog(tr("Moving comics..."),comics.size());
ComicFilesManager * comicFilesManager = new ComicFilesManager(); ComicFilesManager * comicFilesManager = new ComicFilesManager();
comicFilesManager->moveComicsTo(comics,destFolderPath); comicFilesManager->moveComicsTo(comics,destFolderPath,folderDestination);
processComicFiles(comicFilesManager, progressDialog); processComicFiles(comicFilesManager, progressDialog);
} }
@ -1473,7 +1476,7 @@ void LibraryWindow::processComicFiles(ComicFilesManager * comicFilesManager, QPr
connect(progressDialog, SIGNAL(canceled()), comicFilesManager, SLOT(cancel()), Qt::DirectConnection); connect(progressDialog, SIGNAL(canceled()), comicFilesManager, SLOT(cancel()), Qt::DirectConnection);
connect(thread, SIGNAL(started()), comicFilesManager, SLOT(process())); connect(thread, SIGNAL(started()), comicFilesManager, SLOT(process()));
connect(comicFilesManager, SIGNAL(success()), this, SLOT(updateCopyMoveFolderDestination())); connect(comicFilesManager, SIGNAL(success(QModelIndex)), this, SLOT(updateCopyMoveFolderDestination(QModelIndex)));
connect(comicFilesManager, SIGNAL(finished()), thread, SLOT(quit())); connect(comicFilesManager, SIGNAL(finished()), thread, SLOT(quit()));
connect(comicFilesManager, SIGNAL(finished()), comicFilesManager, SLOT(deleteLater())); connect(comicFilesManager, SIGNAL(finished()), comicFilesManager, SLOT(deleteLater()));
connect(comicFilesManager, SIGNAL(finished()), progressDialog, SLOT(close())); connect(comicFilesManager, SIGNAL(finished()), progressDialog, SLOT(close()));
@ -1484,9 +1487,9 @@ void LibraryWindow::processComicFiles(ComicFilesManager * comicFilesManager, QPr
thread->start(); thread->start();
} }
void LibraryWindow::updateCopyMoveFolderDestination() void LibraryWindow::updateCopyMoveFolderDestination(const QModelIndex & mi)
{ {
updateFolder(updateDestination); updateFolder(mi);
} }
void LibraryWindow::updateCurrentFolder() void LibraryWindow::updateCurrentFolder()
@ -1494,15 +1497,9 @@ void LibraryWindow::updateCurrentFolder()
updateFolder(getCurrentFolderIndex()); updateFolder(getCurrentFolderIndex());
} }
void LibraryWindow::updateTreeFolder()
{
updateFolder(foldersView->currentIndex());
}
void LibraryWindow::updateFolder(const QModelIndex & miFolder) void LibraryWindow::updateFolder(const QModelIndex & miFolder)
{ {
QLOG_DEBUG() << "UPDATE FOLDER!!!!"; QLOG_DEBUG() << "UPDATE FOLDER!!!!";
updateDestination = miFolder;
importWidget->setUpdateLook(); importWidget->setUpdateLook();
showImportingWidget(); showImportingWidget();
@ -1510,7 +1507,7 @@ void LibraryWindow::updateFolder(const QModelIndex & miFolder)
QString currentLibrary = selectedLibrary->currentText(); QString currentLibrary = selectedLibrary->currentText();
QString path = libraries.getPath(currentLibrary); QString path = libraries.getPath(currentLibrary);
_lastAdded = currentLibrary; _lastAdded = currentLibrary;
libraryCreator->updateFolder(QDir::cleanPath(path),QDir::cleanPath(path+"/.yacreaderlibrary"),QDir::cleanPath(currentPath()+foldersModel->getFolderPath(miFolder))); libraryCreator->updateFolder(QDir::cleanPath(path),QDir::cleanPath(path+"/.yacreaderlibrary"),QDir::cleanPath(currentPath()+foldersModel->getFolderPath(miFolder)),miFolder);
libraryCreator->start(); libraryCreator->start();
} }
@ -1523,12 +1520,12 @@ QProgressDialog *LibraryWindow::newProgressDialog(const QString &label, int maxV
return progressDialog; return progressDialog;
} }
void LibraryWindow::reloadAfterCopyMove() void LibraryWindow::reloadAfterCopyMove(const QModelIndex & mi)
{ {
if(getCurrentFolderIndex() == updateDestination) if(getCurrentFolderIndex() == mi)
reloadCovers(); reloadCovers();
foldersModel->fetchMoreFromDB(updateDestination); foldersModel->fetchMoreFromDB(mi);
enableNeededActions(); enableNeededActions();
} }
@ -1536,7 +1533,7 @@ void LibraryWindow::reloadAfterCopyMove()
QModelIndex LibraryWindow::getCurrentFolderIndex() QModelIndex LibraryWindow::getCurrentFolderIndex()
{ {
if(foldersView->selectionModel()->selectedRows().length()>0) if(foldersView->selectionModel()->selectedRows().length()>0)
return foldersView->currentIndex(); return foldersModelProxy->mapToSource(foldersView->currentIndex());
else else
return QModelIndex(); return QModelIndex();
} }
@ -1742,10 +1739,10 @@ void LibraryWindow::reloadCovers()
} }
if(foldersView->selectionModel()->selectedRows().length()>0) if(foldersView->selectionModel()->selectedRows().length()>0)
loadCovers(foldersView->currentIndex()); loadCovers(foldersModelProxy->mapToSource(foldersView->currentIndex()));
else else
loadCovers(QModelIndex()); loadCovers(QModelIndex());
QLOG_INFO() << "reloaded covers at row : " << foldersView->currentIndex().row(); QLOG_INFO() << "reloaded covers at row : " << foldersModelProxy->mapToSource(foldersView->currentIndex()).row();
QModelIndex mi = comicsModel->getIndexFromId(_comicIdEdited); QModelIndex mi = comicsModel->getIndexFromId(_comicIdEdited);
if(mi.isValid()) if(mi.isValid())
{ {
@ -1972,7 +1969,7 @@ void LibraryWindow::rename(QString newName) //TODO replace
libraries.save(); libraries.save();
renameLibraryDialog->close(); renameLibraryDialog->close();
#ifndef Q_OS_MAC #ifndef Q_OS_MAC
if(!foldersView->currentIndex().isValid()) if(!foldersModelProxy->mapToSource(foldersView->currentIndex()).isValid())
libraryToolBar->setCurrentFolderName(selectedLibrary->currentText()); libraryToolBar->setCurrentFolderName(selectedLibrary->currentText());
#endif #endif
} }
@ -2066,11 +2063,18 @@ void LibraryWindow::toNormal()
void LibraryWindow::setSearchFilter(const YACReader::SearchModifiers modifier, QString filter) void LibraryWindow::setSearchFilter(const YACReader::SearchModifiers modifier, QString filter)
{ {
if(filter.isEmpty() && foldersModel->isFilterEnabled()) /*
if(filter.isEmpty())
{ {
foldersModel->resetFilter(); QLOG_DEBUG() << "clearing filter";
foldersModelProxy->clear();
comicsView->enableFilterMode(false); comicsView->enableFilterMode(false);
//foldersView->collapseAll(); foldersView->collapseAll();
//TODO scroll to folder after clearing the filter
//1. histoy last index
//2. scrollto
//3. setCurrentIndex
if(index != 0) if(index != 0)
{ {
QModelIndex mi = foldersModel->indexFromItem(index,column); QModelIndex mi = foldersModel->indexFromItem(index,column);
@ -2081,20 +2085,31 @@ void LibraryWindow::setSearchFilter(const YACReader::SearchModifiers modifier, Q
} }
reloadCovers(); reloadCovers();
} }*/
else
{
if(!filter.isEmpty()) if(!filter.isEmpty())
{ {
foldersModel->setFilter(modifier, filter, true);//includeComicsCheckBox->isChecked()); status = LibraryWindow::Searching;
foldersModelProxy->setFilter(modifier, filter, true);//includeComicsCheckBox->isChecked());
comicsModel->setupModelData(modifier, filter, foldersModel->getDatabase()); comicsModel->setupModelData(modifier, filter, foldersModel->getDatabase());
comicsView->enableFilterMode(true); comicsView->enableFilterMode(true);
foldersView->expandAll(); foldersView->expandAll();
//loadCoversFromCurrentModel(); }
else if(status == LibraryWindow::Searching)
{//if no searching, then ignore this
clearSearchFilter();
navigationController->loadPreviousStatus();
} }
} }
void LibraryWindow::clearSearchFilter()
{
foldersModelProxy->clear();
comicsView->enableFilterMode(false);
foldersView->collapseAll();
status = LibraryWindow::Normal;
} }
void LibraryWindow::showProperties() void LibraryWindow::showProperties()
{ {
QModelIndexList indexList = getSelectedComics(); QModelIndexList indexList = getSelectedComics();
@ -2301,7 +2316,7 @@ QFileInfo file = QDir::cleanPath(currentPath() + comicsModel->getComicPath(model
void LibraryWindow::openContainingFolder() void LibraryWindow::openContainingFolder()
{ {
QModelIndex modelIndex = foldersView->currentIndex(); QModelIndex modelIndex = foldersModelProxy->mapToSource(foldersView->currentIndex());
QString path; QString path;
if(modelIndex.isValid()) if(modelIndex.isValid())
path = QDir::cleanPath(currentPath() + foldersModel->getFolderPath(modelIndex)); path = QDir::cleanPath(currentPath() + foldersModel->getFolderPath(modelIndex));
@ -2360,7 +2375,7 @@ QString LibraryWindow::currentFolderPath()
QString path; QString path;
if(foldersView->selectionModel()->selectedRows().length()>0) if(foldersView->selectionModel()->selectedRows().length()>0)
path = foldersModel->getFolderPath(foldersView->currentIndex()); path = foldersModel->getFolderPath(foldersModelProxy->mapToSource(foldersView->currentIndex()));
else else
path = foldersModel->getFolderPath(QModelIndex()); path = foldersModel->getFolderPath(QModelIndex());

View File

@ -6,7 +6,9 @@
#include <QModelIndex> #include <QModelIndex>
#include <QFileInfo> #include <QFileInfo>
#include "yacreader_global.h" #include "yacreader_global.h"
#include <yacreader_libraries.h> #include "yacreader_libraries.h"
#include "yacreader_navigation_controller.h"
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
#include "yacreader_macosx_toolbar.h" #include "yacreader_macosx_toolbar.h"
@ -35,8 +37,8 @@ class QCheckBox;
class QPushButton; class QPushButton;
class ComicModel; class ComicModel;
class QSplitter; class QSplitter;
class FolderItem;
class FolderModel; class FolderModel;
class FolderModelProxy;
class QItemSelectionModel; class QItemSelectionModel;
class QString; class QString;
class QLabel; class QLabel;
@ -72,6 +74,8 @@ using namespace YACReader;
class LibraryWindow : public QMainWindow class LibraryWindow : public QMainWindow
{ {
friend class YACReaderNavigationController;
Q_OBJECT Q_OBJECT
private: private:
YACReaderSideBar * sideBar; YACReaderSideBar * sideBar;
@ -105,12 +109,13 @@ private:
#else #else
YACReaderSearchLineEdit * searchEdit; YACReaderSearchLineEdit * searchEdit;
#endif #endif
FolderItem * index; //index al que hay que hacer scroll despu<70>s de pulsar sobre un folder filtrado
int column;
QString previousFilter; QString previousFilter;
QCheckBox * includeComicsCheckBox; QCheckBox * includeComicsCheckBox;
//------------- //-------------
YACReaderNavigationController * navigationController;
ComicsView * comicsView; ComicsView * comicsView;
ClassicComicsView * classicComicsView; ClassicComicsView * classicComicsView;
GridComicsView * gridComicsView; GridComicsView * gridComicsView;
@ -123,6 +128,7 @@ private:
YACReaderReadingListsView * listsView; YACReaderReadingListsView * listsView;
YACReaderLibraryListWidget * selectedLibrary; YACReaderLibraryListWidget * selectedLibrary;
FolderModel * foldersModel; FolderModel * foldersModel;
FolderModelProxy * foldersModelProxy;
ComicModel * comicsModel; ComicModel * comicsModel;
ReadingListModel * listsModel; ReadingListModel * listsModel;
//QStringList paths; //QStringList paths;
@ -231,10 +237,18 @@ private:
//QModelIndex _rootIndex; //QModelIndex _rootIndex;
//QModelIndex _rootIndexCV; //QModelIndex _rootIndexCV;
QModelIndex updateDestination; //QModelIndex updateDestination;
quint64 _comicIdEdited; quint64 _comicIdEdited;
enum NavigationStatus
{
Normal, //
Searching
};
NavigationStatus status;
void setupUI(); void setupUI();
void createActions(); void createActions();
void createToolBars(); void createToolBars();
@ -311,6 +325,7 @@ public slots:
void toNormal(); void toNormal();
void toFullScreen(); void toFullScreen();
void setSearchFilter(const YACReader::SearchModifiers modifier, QString filter); void setSearchFilter(const YACReader::SearchModifiers modifier, QString filter);
void clearSearchFilter();
void showProperties(); void showProperties();
void exportLibrary(QString destPath); void exportLibrary(QString destPath);
void importLibrary(QString clc,QString destPath,QString name); void importLibrary(QString clc,QString destPath,QString name);
@ -354,12 +369,11 @@ public slots:
void copyAndImportComicsToFolder(const QList<QPair<QString,QString> > & comics, const QModelIndex & miFolder); void copyAndImportComicsToFolder(const QList<QPair<QString,QString> > & comics, const QModelIndex & miFolder);
void moveAndImportComicsToFolder(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 processComicFiles(ComicFilesManager * comicFilesManager, QProgressDialog * progressDialog);
void updateCopyMoveFolderDestination(); //imports new comics from the current folder void updateCopyMoveFolderDestination(const QModelIndex & mi); //imports new comics from the current folder
void updateCurrentFolder(); void updateCurrentFolder();
void updateTreeFolder();
void updateFolder(const QModelIndex & miFolder); void updateFolder(const QModelIndex & miFolder);
QProgressDialog * newProgressDialog(const QString & label, int maxValue); QProgressDialog * newProgressDialog(const QString & label, int maxValue);
void reloadAfterCopyMove(); void reloadAfterCopyMove(const QModelIndex &mi);
QModelIndex getCurrentFolderIndex(); QModelIndex getCurrentFolderIndex();
void enableNeededActions(); void enableNeededActions();
void addFolderToCurrentIndex(); void addFolderToCurrentIndex();

View File

@ -87,6 +87,7 @@ YACReaderFoldersViewItemDeletegate::YACReaderFoldersViewItemDeletegate(QObject *
void YACReaderFoldersViewItemDeletegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const void YACReaderFoldersViewItemDeletegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{ {
/*
FolderItem * item = static_cast<FolderItem *>(index.internalPointer()); FolderItem * item = static_cast<FolderItem *>(index.internalPointer());
if(!item->data(FolderModel::Completed).toBool()) if(!item->data(FolderModel::Completed).toBool())
@ -101,6 +102,6 @@ void YACReaderFoldersViewItemDeletegate::paint(QPainter *painter, const QStyleOp
painter->drawRect(0,option.rect.y(),2,option.rect.height()); painter->drawRect(0,option.rect.y(),2,option.rect.height());
painter->restore(); painter->restore();
} }
*/
QStyledItemDelegate::paint(painter, option, index); QStyledItemDelegate::paint(painter, option, index);
} }

View File

@ -64,3 +64,13 @@ void YACReaderHistoryController::updateHistory(const QModelIndex &mi)
emit(enabledForward(false)); emit(enabledForward(false));
} }
QModelIndex YACReaderHistoryController::lastIndex()
{
return history.last();
}
QModelIndex YACReaderHistoryController::currentIndex()
{
return history.at(currentFolderNavigation);
}

View File

@ -21,6 +21,8 @@ public slots:
void backward(); void backward();
void forward(); void forward();
void updateHistory(const QModelIndex & mi); void updateHistory(const QModelIndex & mi);
QModelIndex lastIndex();
QModelIndex currentIndex();
protected: protected:
int currentFolderNavigation; int currentFolderNavigation;

View File

@ -0,0 +1,125 @@
#include "yacreader_navigation_controller.h"
#include <QModelIndex>
#include "library_window.h"
#include "yacreader_folders_view.h"
#include "yacreader_reading_lists_view.h"
#include "folder_item.h"
#include "yacreader_history_controller.h"
#include "comic_model.h"
#include "folder_model.h"
#include "comics_view.h"
#include "empty_folder_widget.h"
YACReaderNavigationController::YACReaderNavigationController(LibraryWindow *parent) :
QObject(parent),libraryWindow(parent)
{
setupConnections();
}
void YACReaderNavigationController::selectedFolder(const QModelIndex &mi)
{
//A proxy is used
QModelIndex modelIndex = libraryWindow->foldersModelProxy->mapToSource(mi);
//update history
libraryWindow->historyController->updateHistory(modelIndex);
if(libraryWindow->status == LibraryWindow::Searching)
{
//when a folder is selected the search mode has to be reset
libraryWindow->searchEdit->clearText();
libraryWindow->clearSearchFilter();
libraryWindow->foldersView->scrollTo(mi,QAbstractItemView::PositionAtTop);
libraryWindow->foldersView->setCurrentIndex(mi);
}
loadFolderInfo(modelIndex);
}
void YACReaderNavigationController::loadFolderInfo(const QModelIndex &modelIndex)
{
//Get FolderItem
qulonglong folderId = folderModelIndexToID(modelIndex);
//check comics in folder with id = folderId
libraryWindow->comicsModel->setupModelData(folderId,libraryWindow->foldersModel->getDatabase());
libraryWindow->comicsView->setModel(libraryWindow->comicsModel);
//configure views
if(libraryWindow->comicsModel->rowCount() > 0)
{
//updateView
libraryWindow->showComicsView();
}
else{
//showEmptyFolder
QStringList subfolders;
subfolders = libraryWindow->foldersModel->getSubfoldersNames(modelIndex);
libraryWindow->emptyFolderWidget->setSubfolders(modelIndex,subfolders);
libraryWindow->showEmptyFolderView();
}
}
void YACReaderNavigationController::selectedList(const QModelIndex &mi)
{
}
void YACReaderNavigationController::selectedIndexFromHistory(const QModelIndex &sourceMI)
{
//TODO NO searching allowed, just disable backward/forward actions in searching mode
if(libraryWindow->status == LibraryWindow::Searching)
{
//when a folder is selected the search mode has to be reset
libraryWindow->searchEdit->clearText();
libraryWindow->clearSearchFilter();
}
//TODO more info about mi is needed (folder, lists...)
QModelIndex mi = libraryWindow->foldersModelProxy->mapFromSource(sourceMI);
libraryWindow->foldersView->scrollTo(mi,QAbstractItemView::PositionAtTop);
libraryWindow->foldersView->setCurrentIndex(mi);
loadFolderInfo(sourceMI);
}
void YACReaderNavigationController::selectSubfolder(const QModelIndex &sourceMIParent, int child)
{
QModelIndex dest = libraryWindow->foldersModel->index(child,0,sourceMIParent);
libraryWindow->foldersView->setCurrentIndex(libraryWindow->foldersModelProxy->mapFromSource(dest));
libraryWindow->historyController->updateHistory(dest);
loadFolderInfo(dest);
}
void YACReaderNavigationController::loadPreviousStatus()
{
QModelIndex sourceMI = libraryWindow->historyController->currentIndex();
QModelIndex mi = libraryWindow->foldersModelProxy->mapFromSource(sourceMI);
libraryWindow->foldersView->scrollTo(mi,QAbstractItemView::PositionAtTop);
libraryWindow->foldersView->setCurrentIndex(mi);
loadFolderInfo(sourceMI);
}
void YACReaderNavigationController::setupConnections()
{
connect(libraryWindow->foldersView,SIGNAL(clicked(QModelIndex)),this,SLOT(selectedFolder(QModelIndex)));
connect(libraryWindow->listsView,SIGNAL(clicked(QModelIndex)),this,SLOT(selectedList(QModelIndex)));
connect(libraryWindow->historyController,SIGNAL(modelIndexSelected(QModelIndex)),this,SLOT(selectedIndexFromHistory(QModelIndex)));
connect(libraryWindow->emptyFolderWidget,SIGNAL(subfolderSelected(QModelIndex,int)),this,SLOT(selectSubfolder(QModelIndex,int)));
}
qulonglong YACReaderNavigationController::folderModelIndexToID(const QModelIndex &mi)
{
if(!mi.isValid())
return 1;
FolderItem * folderItem = static_cast<FolderItem *>(mi.internalPointer());
if(folderItem != 0)
return folderItem->id;
return 1;
}

View File

@ -0,0 +1,40 @@
#ifndef YACREADER_NAVIGATION_CONTROLLER_H
#define YACREADER_NAVIGATION_CONTROLLER_H
#include <QObject>
class LibraryWindow;
class YACReaderNavigationController : public QObject
{
Q_OBJECT
public:
explicit YACReaderNavigationController(LibraryWindow * parent);
signals:
public slots:
//info origins
//folders view
void selectedFolder(const QModelIndex & mi);
//reading lists
void selectedList(const QModelIndex & mi);
//history navigation
void selectedIndexFromHistory(const QModelIndex & mi);
//empty subfolder
void selectSubfolder(const QModelIndex &sourceMI, int child);
void loadFolderInfo(const QModelIndex & modelIndex);
void loadPreviousStatus();
private:
void setupConnections();
LibraryWindow * libraryWindow;
//convenience methods
qulonglong folderModelIndexToID(const QModelIndex & mi);
};
#endif // YACREADER_NAVIGATION_CONTROLLER_H

View File

@ -17,6 +17,7 @@ public:
public slots: public slots:
QString text(); QString text();
void clear(); void clear();
void clearText(); //no signal emited
void setDisabled(bool disabled); void setDisabled(bool disabled);
void setEnabled(bool enabled); void setEnabled(bool enabled);

View File

@ -342,6 +342,12 @@ void YACReaderMacOSXSearchLineEdit::clear()
emit filterChanged(YACReader::NoModifiers, ""); emit filterChanged(YACReader::NoModifiers, "");
} }
void YACReaderMacOSXSearchLineEdit::clearText()
{
//TODO be sure that this will not generate any event....
[((NSTextField *)nstextfield) setStringValue:@""];
}
void YACReaderMacOSXSearchLineEdit::setDisabled(bool disabled) void YACReaderMacOSXSearchLineEdit::setDisabled(bool disabled)
{ {
[((NSTextField *)nstextfield) setEnabled:!disabled]; [((NSTextField *)nstextfield) setEnabled:!disabled];

View File

@ -70,6 +70,13 @@ YACReaderSearchLineEdit::YACReaderSearchLineEdit(QWidget *parent)
connect(this,SIGNAL(textChanged(QString)),this,SLOT(processText(QString))); connect(this,SIGNAL(textChanged(QString)),this,SLOT(processText(QString)));
} }
void YACReaderSearchLineEdit::clearText()
{
disconnect(this,SIGNAL(textChanged(QString)),this,SLOT(processText(QString)));
clear();
connect(this,SIGNAL(textChanged(QString)),this,SLOT(processText(QString)));
}
//modifiers are not returned //modifiers are not returned
const QString YACReaderSearchLineEdit::text() const QString YACReaderSearchLineEdit::text()
{ {

View File

@ -15,6 +15,7 @@ class YACReaderSearchLineEdit : public QLineEdit
public: public:
YACReaderSearchLineEdit(QWidget *parent = 0); YACReaderSearchLineEdit(QWidget *parent = 0);
void clearText(); //no signal emited;
const QString text(); const QString text();
protected: protected: