mirror of
https://github.com/YACReader/yacreader
synced 2025-06-04 01:28:55 -04:00
added new view for empty folders in YACReaderLibrary that shows a list with all the subfolders
TODO ?use a special case for the root folder?
This commit is contained in:
parent
9f53ae6efc
commit
1b2f33d0c6
@ -117,7 +117,8 @@ HEADERS += comic_flow.h \
|
|||||||
yacreader_libraries.h \
|
yacreader_libraries.h \
|
||||||
../common/exit_check.h \
|
../common/exit_check.h \
|
||||||
comics_view.h \
|
comics_view.h \
|
||||||
classic_comics_view.h
|
classic_comics_view.h \
|
||||||
|
empty_folder_widget.h
|
||||||
|
|
||||||
|
|
||||||
SOURCES += comic_flow.cpp \
|
SOURCES += comic_flow.cpp \
|
||||||
@ -163,7 +164,8 @@ SOURCES += comic_flow.cpp \
|
|||||||
yacreader_libraries.cpp \
|
yacreader_libraries.cpp \
|
||||||
../common/exit_check.cpp \
|
../common/exit_check.cpp \
|
||||||
comics_view.cpp \
|
comics_view.cpp \
|
||||||
classic_comics_view.cpp
|
classic_comics_view.cpp \
|
||||||
|
empty_folder_widget.cpp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -304,7 +304,9 @@ void TableModel::setupModelData(unsigned long long int folderId,const QString &
|
|||||||
db.close();
|
db.close();
|
||||||
QSqlDatabase::removeDatabase(_databasePath);
|
QSqlDatabase::removeDatabase(_databasePath);
|
||||||
endResetModel();
|
endResetModel();
|
||||||
//f.close();
|
|
||||||
|
if(_data.length()==0)
|
||||||
|
emit isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TableModel::getComicPath(QModelIndex mi)
|
QString TableModel::getComicPath(QModelIndex mi)
|
||||||
|
@ -113,6 +113,7 @@ private:
|
|||||||
signals:
|
signals:
|
||||||
void beforeReset();
|
void beforeReset();
|
||||||
void reset();
|
void reset();
|
||||||
|
void isEmpty();
|
||||||
};
|
};
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include "data_base_management.h"
|
#include "data_base_management.h"
|
||||||
#include "folder.h"
|
#include "folder.h"
|
||||||
#include "db_helper.h"
|
#include "db_helper.h"
|
||||||
|
#include "qnaturalsorting.h"
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
#include <QFileIconProvider>
|
#include <QFileIconProvider>
|
||||||
@ -106,7 +107,7 @@ TreeModel::TreeModel(QObject *parent)
|
|||||||
TreeModel::TreeModel( QSqlQuery &sqlquery, QObject *parent)
|
TreeModel::TreeModel( QSqlQuery &sqlquery, QObject *parent)
|
||||||
: QAbstractItemModel(parent),rootItem(0),rootBeforeFilter(0),filterEnabled(false),includeComics(false)
|
: QAbstractItemModel(parent),rootItem(0),rootBeforeFilter(0),filterEnabled(false),includeComics(false)
|
||||||
{
|
{
|
||||||
//lo más probable es que el nodo raíz no necesite tener información
|
//lo m<EFBFBD>s probable es que el nodo ra<72>z no necesite tener informaci<63>n
|
||||||
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)
|
||||||
rootItem = new TreeItem(rootData);
|
rootItem = new TreeItem(rootData);
|
||||||
@ -265,7 +266,7 @@ void TreeModel::setupModelData(QString path)
|
|||||||
filterEnabled = false;
|
filterEnabled = false;
|
||||||
rootItem = 0;
|
rootItem = 0;
|
||||||
rootBeforeFilter = 0;
|
rootBeforeFilter = 0;
|
||||||
//inicializar el nodo raíz
|
//inicializar el nodo ra<EFBFBD>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)
|
||||||
rootItem = new TreeItem(rootData);
|
rootItem = new TreeItem(rootData);
|
||||||
@ -291,10 +292,10 @@ void TreeModel::setupModelData(QString path)
|
|||||||
|
|
||||||
void TreeModel::setupModelData(QSqlQuery &sqlquery, TreeItem *parent)
|
void TreeModel::setupModelData(QSqlQuery &sqlquery, TreeItem *parent)
|
||||||
{
|
{
|
||||||
//64 bits para la primary key, es decir la misma precisión que soporta sqlit 2^64
|
//64 bits para la primary key, es decir la misma precisi<EFBFBD>n que soporta sqlit 2^64
|
||||||
//el diccionario permitirá encontrar cualquier nodo del árbol rápidamente, de forma que añadir un hijo a un padre sea O(1)
|
//el diccionario permitir<EFBFBD> encontrar cualquier nodo del <20>rbol r<>pidamente, de forma que a<>adir un hijo a un padre sea O(1)
|
||||||
items.clear();
|
items.clear();
|
||||||
//se añade el nodo 0
|
//se a<EFBFBD>ade el nodo 0
|
||||||
items.insert(parent->id,parent);
|
items.insert(parent->id,parent);
|
||||||
|
|
||||||
while (sqlquery.next()) {
|
while (sqlquery.next()) {
|
||||||
@ -308,11 +309,11 @@ void TreeModel::setupModelData(QSqlQuery &sqlquery, TreeItem *parent)
|
|||||||
TreeItem * item = new TreeItem(data);
|
TreeItem * item = new TreeItem(data);
|
||||||
|
|
||||||
item->id = record.value("id").toULongLong();
|
item->id = record.value("id").toULongLong();
|
||||||
//la inserción de hijos se hace de forma ordenada
|
//la inserci<EFBFBD>n de hijos se hace de forma ordenada
|
||||||
TreeItem * parent = items.value(record.value("parentId").toULongLong());
|
TreeItem * parent = items.value(record.value("parentId").toULongLong());
|
||||||
if(parent !=0) //TODO if parent==0 the parent of item was removed from the DB and delete on cascade didn't work, ERROR.
|
if(parent !=0) //TODO if parent==0 the parent of item was removed from the DB and delete on cascade didn't work, ERROR.
|
||||||
parent->appendChild(item);
|
parent->appendChild(item);
|
||||||
//se añade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones
|
//se a<EFBFBD>ade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones
|
||||||
items.insert(item->id,item);
|
items.insert(item->id,item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -323,12 +324,12 @@ void TreeModel::setupFilteredModelData()
|
|||||||
|
|
||||||
//TODO hay que liberar memoria de anteriores filtrados
|
//TODO hay que liberar memoria de anteriores filtrados
|
||||||
|
|
||||||
//inicializar el nodo raíz
|
//inicializar el nodo ra<EFBFBD>z
|
||||||
|
|
||||||
if(rootBeforeFilter == 0)
|
if(rootBeforeFilter == 0)
|
||||||
rootBeforeFilter = rootItem;
|
rootBeforeFilter = rootItem;
|
||||||
else
|
else
|
||||||
delete rootItem;//los resultados de la búsqueda anterior deben ser borrados
|
delete rootItem;//los resultados de la b<EFBFBD>squeda anterior deben ser borrados
|
||||||
|
|
||||||
QList<QVariant> rootData;
|
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)
|
rootData << "root"; //id 1, padre 1, title "root" (el id, y el id del padre van a ir en la clase TreeItem)
|
||||||
@ -365,10 +366,10 @@ void TreeModel::setupFilteredModelData()
|
|||||||
|
|
||||||
void TreeModel::setupFilteredModelData(QSqlQuery &sqlquery, TreeItem *parent)
|
void TreeModel::setupFilteredModelData(QSqlQuery &sqlquery, TreeItem *parent)
|
||||||
{
|
{
|
||||||
//64 bits para la primary key, es decir la misma precisión que soporta sqlit 2^64
|
//64 bits para la primary key, es decir la misma precisi<EFBFBD>n que soporta sqlit 2^64
|
||||||
filteredItems.clear();
|
filteredItems.clear();
|
||||||
|
|
||||||
//se añade el nodo 0 al modelo que representa el arbol de elementos que cumplen con el filtro
|
//se a<EFBFBD>ade el nodo 0 al modelo que representa el arbol de elementos que cumplen con el filtro
|
||||||
filteredItems.insert(parent->id,parent);
|
filteredItems.insert(parent->id,parent);
|
||||||
|
|
||||||
while (sqlquery.next()) { //se procesan todos los folders que cumplen con el filtro
|
while (sqlquery.next()) { //se procesan todos los folders que cumplen con el filtro
|
||||||
@ -387,39 +388,39 @@ void TreeModel::setupFilteredModelData(QSqlQuery &sqlquery, TreeItem *parent)
|
|||||||
//id del padre
|
//id del padre
|
||||||
quint64 parentId = record.value("parentId").toULongLong();
|
quint64 parentId = record.value("parentId").toULongLong();
|
||||||
|
|
||||||
//se añade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones
|
//se a<EFBFBD>ade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones
|
||||||
if(!filteredItems.contains(item->id))
|
if(!filteredItems.contains(item->id))
|
||||||
filteredItems.insert(item->id,item);
|
filteredItems.insert(item->id,item);
|
||||||
|
|
||||||
//es necesario conocer las coordenadas de origen para poder realizar scroll automático en la vista
|
//es necesario conocer las coordenadas de origen para poder realizar scroll autom<EFBFBD>tico en la vista
|
||||||
item->originalItem = items.value(item->id);
|
item->originalItem = items.value(item->id);
|
||||||
|
|
||||||
//si el padre ya existe en el modelo, el item se añade como hijo
|
//si el padre ya existe en el modelo, el item se a<EFBFBD>ade como hijo
|
||||||
if(filteredItems.contains(parentId))
|
if(filteredItems.contains(parentId))
|
||||||
filteredItems.value(parentId)->appendChild(item);
|
filteredItems.value(parentId)->appendChild(item);
|
||||||
else//si el padre aún no se ha añadido, hay que añadirlo a él y todos los padres hasta el nodo raíz
|
else//si el padre a<EFBFBD>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 último de los padres (antes del nodo raíz) ya existía en el modelo
|
//comprobamos con esta variable si el <EFBFBD>ltimo de los padres (antes del nodo ra<72>z) ya exist<73>a en el modelo
|
||||||
bool parentPreviousInserted = false;
|
bool parentPreviousInserted = false;
|
||||||
|
|
||||||
//mientras no se alcance el nodo raíz se procesan todos los padres (de abajo a arriba)
|
//mientras no se alcance el nodo ra<EFBFBD>z se procesan todos los padres (de abajo a arriba)
|
||||||
while(parentId != ROOT )
|
while(parentId != ROOT )
|
||||||
{
|
{
|
||||||
//el padre no estaba en el modelo filtrado, así que se rescata del modelo original
|
//el padre no estaba en el modelo filtrado, as<EFBFBD> que se rescata del modelo original
|
||||||
TreeItem * parentItem = items.value(parentId);
|
TreeItem * parentItem = items.value(parentId);
|
||||||
//se debe crear un nuevo nodo (para no compartir los hijos con el nodo original)
|
//se debe crear un nuevo nodo (para no compartir los hijos con el nodo original)
|
||||||
TreeItem * newparentItem = new TreeItem(parentItem->getData()); //padre que se añadirá a la estructura de directorios filtrados
|
TreeItem * newparentItem = new TreeItem(parentItem->getData()); //padre que se a<EFBFBD>adir<EFBFBD> a la estructura de directorios filtrados
|
||||||
newparentItem->id = parentId;
|
newparentItem->id = parentId;
|
||||||
|
|
||||||
newparentItem->originalItem = parentItem;
|
newparentItem->originalItem = parentItem;
|
||||||
|
|
||||||
//si el modelo contiene al padre, se añade el item actual como hijo
|
//si el modelo contiene al padre, se a<EFBFBD>ade el item actual como hijo
|
||||||
if(filteredItems.contains(parentId))
|
if(filteredItems.contains(parentId))
|
||||||
{
|
{
|
||||||
filteredItems.value(parentId)->appendChild(item);
|
filteredItems.value(parentId)->appendChild(item);
|
||||||
parentPreviousInserted = true;
|
parentPreviousInserted = true;
|
||||||
}
|
}
|
||||||
//sino se registra el nodo para poder encontrarlo con posterioridad y se añade el item actual como hijo
|
//sino se registra el nodo para poder encontrarlo con posterioridad y se a<EFBFBD>ade el item actual como hijo
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newparentItem->appendChild(item);
|
newparentItem->appendChild(item);
|
||||||
@ -432,7 +433,7 @@ void TreeModel::setupFilteredModelData(QSqlQuery &sqlquery, TreeItem *parent)
|
|||||||
parentId = parentItem->parentItem->id;
|
parentId = parentItem->parentItem->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
//si el nodo es hijo de 1 y no había sido previamente insertado como hijo, se añade como tal
|
//si el nodo es hijo de 1 y no hab<EFBFBD>a sido previamente insertado como hijo, se a<>ade como tal
|
||||||
if(!parentPreviousInserted)
|
if(!parentPreviousInserted)
|
||||||
filteredItems.value(ROOT)->appendChild(item);
|
filteredItems.value(ROOT)->appendChild(item);
|
||||||
}
|
}
|
||||||
@ -468,7 +469,7 @@ void TreeModel::resetFilter()
|
|||||||
//items.clear();
|
//items.clear();
|
||||||
filteredItems.clear();
|
filteredItems.clear();
|
||||||
TreeItem * root = rootItem;
|
TreeItem * root = rootItem;
|
||||||
rootItem = rootBeforeFilter; //TODO si no se aplica el filtro previamente, esto invalidaría en modelo
|
rootItem = rootBeforeFilter; //TODO si no se aplica el filtro previamente, esto invalidar<EFBFBD>a en modelo
|
||||||
if(root !=0)
|
if(root !=0)
|
||||||
delete root;
|
delete root;
|
||||||
|
|
||||||
@ -518,3 +519,26 @@ void TreeModel::updateFolderFinishedStatus(const QModelIndexList &list, bool sta
|
|||||||
|
|
||||||
emit dataChanged(index(list.first().row(),TreeModel::Name),index(list.last().row(),TreeModel::Completed));
|
emit dataChanged(index(list.first().row(),TreeModel::Name),index(list.last().row(),TreeModel::Completed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList TreeModel::getSubfoldersNames(const QModelIndex &mi)
|
||||||
|
{
|
||||||
|
QStringList result;
|
||||||
|
qulonglong id = 1;
|
||||||
|
if(mi.isValid()){
|
||||||
|
TreeItem * item = static_cast<TreeItem*>(mi.internalPointer());
|
||||||
|
id = item->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||||
|
db.transaction();
|
||||||
|
|
||||||
|
result = DBHelper::loadSubfoldersNames(id,db);
|
||||||
|
|
||||||
|
db.commit();
|
||||||
|
db.close();
|
||||||
|
QSqlDatabase::removeDatabase(_databasePath);
|
||||||
|
|
||||||
|
//TODO sort result))
|
||||||
|
qSort(result.begin(),result.end(),naturalSortLessThanCI);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -85,6 +85,8 @@ public:
|
|||||||
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);
|
||||||
|
|
||||||
|
QStringList getSubfoldersNames(const QModelIndex & mi);
|
||||||
|
|
||||||
enum Columns {
|
enum Columns {
|
||||||
Name = 0,
|
Name = 0,
|
||||||
Path = 1,
|
Path = 1,
|
||||||
|
@ -671,5 +671,18 @@ ComicInfo DBHelper::loadComicInfo(QString hash, QSqlDatabase & db)
|
|||||||
else
|
else
|
||||||
comicInfo.existOnDb = false;
|
comicInfo.existOnDb = false;
|
||||||
|
|
||||||
return comicInfo;
|
return comicInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QString> DBHelper::loadSubfoldersNames(qulonglong folderId, QSqlDatabase &db)
|
||||||
|
{
|
||||||
|
QList<QString> result;
|
||||||
|
QSqlQuery selectQuery(db);
|
||||||
|
selectQuery.prepare("SELECT name FROM folder WHERE parentId = :parentId AND id <> 1"); //do not select the root folder
|
||||||
|
selectQuery.bindValue(":parentId", folderId);
|
||||||
|
selectQuery.exec();
|
||||||
|
while(selectQuery.next()){
|
||||||
|
result << selectQuery.record().value("name").toString();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@ public:
|
|||||||
static ComicDB loadComic(qulonglong id, QSqlDatabase & db);
|
static ComicDB loadComic(qulonglong id, QSqlDatabase & db);
|
||||||
static ComicDB loadComic(QString cname, QString cpath, QString chash, QSqlDatabase & database);
|
static ComicDB loadComic(QString cname, QString cpath, QString chash, QSqlDatabase & database);
|
||||||
static ComicInfo loadComicInfo(QString hash, QSqlDatabase & db);
|
static ComicInfo loadComicInfo(QString hash, QSqlDatabase & db);
|
||||||
|
static QList<QString> loadSubfoldersNames(qulonglong folderId, QSqlDatabase & db);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
89
YACReaderLibrary/empty_folder_widget.cpp
Normal file
89
YACReaderLibrary/empty_folder_widget.cpp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#include "empty_folder_widget.h"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QListView>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
|
||||||
|
#include <QStringListModel>
|
||||||
|
void testListView(QListView * l)
|
||||||
|
{
|
||||||
|
QStringListModel * slm = new QStringListModel(QStringList() = {"Lorem ipsum", "Hailer skualer", "Mumbaluba X", "Finger layden", "Pacum tactus filer", "Aposum", "En","Lorem ipsum", "Hailer skualer", "Mumbaluba X", "Finger layden", "Pacum tactus filer", "Aposum", "En" });
|
||||||
|
l->setModel(slm);
|
||||||
|
}
|
||||||
|
|
||||||
|
EmptyFolderWidget::EmptyFolderWidget(QWidget *parent) :
|
||||||
|
QWidget(parent),subfoldersModel(new QStringListModel())
|
||||||
|
{
|
||||||
|
QVBoxLayout * layout = new QVBoxLayout;
|
||||||
|
|
||||||
|
iconLabel = new QLabel();
|
||||||
|
iconLabel->setPixmap(QPixmap(":/images/empty_folder.png"));
|
||||||
|
iconLabel->setAlignment(Qt::AlignCenter);
|
||||||
|
|
||||||
|
titleLabel = new QLabel("Subfolders in this folder");
|
||||||
|
titleLabel->setAlignment(Qt::AlignCenter);
|
||||||
|
titleLabel->setStyleSheet("QLabel {color:#CCCCCC; font-size:24px;font-family:Arial;font-weight:bold;}");
|
||||||
|
|
||||||
|
foldersView = new QListView();
|
||||||
|
foldersView->setMinimumWidth(282);
|
||||||
|
foldersView->setWrapping(true);
|
||||||
|
|
||||||
|
foldersView->setStyleSheet("QListView {background-color:transparent; border: none; color:#858585; outline:0; font-size: 18px; font:bold; show-decoration-selected: 0; margin:0}"
|
||||||
|
"QListView::item:selected {background-color: #212121; color:#CCCCCC;}"
|
||||||
|
"QListView::item:hover {background-color:#212121; color:#CCCCCC; }"
|
||||||
|
|
||||||
|
|
||||||
|
"QScrollBar:vertical { border: none; background: #212121; width: 14px; margin: 0 10px 0 0; }"
|
||||||
|
"QScrollBar::handle:vertical { background: #858585; width: 14px; min-height: 20px; }"
|
||||||
|
"QScrollBar::add-line:vertical { border: none; background: #212121; height: 0px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}"
|
||||||
|
|
||||||
|
"QScrollBar::sub-line:vertical { border: none; background: #212121; height: 0px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}"
|
||||||
|
"QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}"
|
||||||
|
"QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}"
|
||||||
|
|
||||||
|
"QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none; }"
|
||||||
|
"QScrollBar:horizontal{height:0px;}"
|
||||||
|
);
|
||||||
|
|
||||||
|
foldersView->setSizePolicy(QSizePolicy ::Expanding , QSizePolicy ::Expanding );
|
||||||
|
testListView(foldersView);
|
||||||
|
|
||||||
|
layout->addSpacing(100);
|
||||||
|
layout->addWidget(iconLabel);
|
||||||
|
layout->addSpacing(30);
|
||||||
|
layout->addWidget(titleLabel);
|
||||||
|
layout->addSpacing(12);
|
||||||
|
layout->addWidget(foldersView,1,Qt::AlignHCenter);
|
||||||
|
layout->addStretch();
|
||||||
|
layout->setMargin(0);
|
||||||
|
layout->setSpacing(0);
|
||||||
|
|
||||||
|
setContentsMargins(0,0,0,0);
|
||||||
|
|
||||||
|
setStyleSheet("QWidget {background:#2A2A2A}");
|
||||||
|
|
||||||
|
setSizePolicy(QSizePolicy ::Expanding , QSizePolicy ::Expanding );
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
connect(foldersView,SIGNAL(clicked(QModelIndex)),this,SLOT(onItemClicked(QModelIndex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmptyFolderWidget::setSubfolders(const QModelIndex &mi, const QStringList &foldersNames)
|
||||||
|
{
|
||||||
|
parent = mi;
|
||||||
|
subfoldersModel->setStringList(foldersNames);
|
||||||
|
foldersView->setModel(subfoldersModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmptyFolderWidget::onItemClicked(const QModelIndex &mi)
|
||||||
|
{
|
||||||
|
emit subfolderSelected(parent,mi.row());
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmptyFolderWidget::paintEvent(QPaintEvent *)
|
||||||
|
{
|
||||||
|
QPainter painter (this);
|
||||||
|
painter.fillRect(0,0,width(),height(),QColor("#2A2A2A"));
|
||||||
|
}
|
32
YACReaderLibrary/empty_folder_widget.h
Normal file
32
YACReaderLibrary/empty_folder_widget.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef EMPTY_FOLDER_WIDGET_H
|
||||||
|
#define EMPTY_FOLDER_WIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QModelIndex>
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
class QListView;
|
||||||
|
class QStringListModel;
|
||||||
|
|
||||||
|
class EmptyFolderWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit EmptyFolderWidget(QWidget *parent = 0);
|
||||||
|
void setSubfolders(const QModelIndex & mi, const QStringList & foldersNames);
|
||||||
|
signals:
|
||||||
|
void subfolderSelected(QModelIndex, int);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onItemClicked(const QModelIndex & mi);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QLabel * iconLabel;
|
||||||
|
QLabel * titleLabel;
|
||||||
|
QListView * foldersView;
|
||||||
|
QModelIndex parent;
|
||||||
|
QStringListModel * subfoldersModel;
|
||||||
|
void paintEvent(QPaintEvent *);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EMPTY_FOLDER_WIDGET_H
|
@ -19,5 +19,6 @@
|
|||||||
<file alias="images/openLibraryIcon.png">../images/openLibraryIcon_osx.png</file>
|
<file alias="images/openLibraryIcon.png">../images/openLibraryIcon_osx.png</file>
|
||||||
<file alias="images/flow_to_grid.gif">../images/flow_to_grid.gif</file>
|
<file alias="images/flow_to_grid.gif">../images/flow_to_grid.gif</file>
|
||||||
<file alias="images/grid_to_flow.gif">../images/grid_to_flow.gif</file>
|
<file alias="images/grid_to_flow.gif">../images/grid_to_flow.gif</file>
|
||||||
|
<file alias="images/empty_folder.png">../images/empty_folder.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -18,5 +18,6 @@
|
|||||||
<file>../images/main_toolbar/grid.png</file>
|
<file>../images/main_toolbar/grid.png</file>
|
||||||
<file>../images/flow_to_grid.gif</file>
|
<file>../images/flow_to_grid.gif</file>
|
||||||
<file>../images/grid_to_flow.gif</file>
|
<file>../images/grid_to_flow.gif</file>
|
||||||
|
<file>../images/empty_folder.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
#include "classic_comics_view.h"
|
#include "classic_comics_view.h"
|
||||||
#include "grid_comics_view.h"
|
#include "grid_comics_view.h"
|
||||||
#include "comics_view_transition.h"
|
#include "comics_view_transition.h"
|
||||||
|
#include "empty_folder_widget.h"
|
||||||
|
|
||||||
#include "QsLog.h"
|
#include "QsLog.h"
|
||||||
|
|
||||||
@ -205,8 +206,11 @@ void LibraryWindow::doLayout()
|
|||||||
doComicsViewConnections();
|
doComicsViewConnections();
|
||||||
|
|
||||||
comicsView->setToolBar(editInfoToolBar);
|
comicsView->setToolBar(editInfoToolBar);
|
||||||
comicsViewStack->addWidget(comicsView);
|
|
||||||
comicsViewStack->addWidget(comicsViewTransition = new ComicsViewTransition());
|
comicsViewStack->addWidget(comicsViewTransition = new ComicsViewTransition());
|
||||||
|
comicsViewStack->addWidget(emptyFolderWidget = new EmptyFolderWidget());
|
||||||
|
comicsViewStack->addWidget(comicsView);
|
||||||
|
|
||||||
|
comicsViewStack->setCurrentWidget(comicsView);
|
||||||
|
|
||||||
fullScreenToolTip = new QLabel(comicsView);
|
fullScreenToolTip = new QLabel(comicsView);
|
||||||
fullScreenToolTip->setText(tr("<font color='white'> press 'F' to close fullscreen mode </font>"));
|
fullScreenToolTip->setText(tr("<font color='white'> press 'F' to close fullscreen mode </font>"));
|
||||||
@ -887,6 +891,8 @@ void LibraryWindow::createConnections()
|
|||||||
|
|
||||||
connect(comicsViewTransition,SIGNAL(transitionFinished()),this,SLOT(showComicsView()));
|
connect(comicsViewTransition,SIGNAL(transitionFinished()),this,SLOT(showComicsView()));
|
||||||
|
|
||||||
|
connect(dmCV,SIGNAL(isEmpty()),this,SLOT(showEmptyFolderView()));
|
||||||
|
connect(emptyFolderWidget,SIGNAL(subfolderSelected(QModelIndex,int)),this,SLOT(selectSubfolder(QModelIndex,int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibraryWindow::loadLibrary(const QString & name)
|
void LibraryWindow::loadLibrary(const QString & name)
|
||||||
@ -1075,8 +1081,20 @@ void LibraryWindow::loadCovers(const QModelIndex & mi)
|
|||||||
QStringList paths = dmCV->getPaths(currentPath());
|
QStringList paths = dmCV->getPaths(currentPath());
|
||||||
checkEmptyFolder(&paths);
|
checkEmptyFolder(&paths);
|
||||||
|
|
||||||
if(paths.size()>0)
|
if(paths.size()>0) {
|
||||||
comicsView->setCurrentIndex(dmCV->index(0,0));
|
comicsView->setCurrentIndex(dmCV->index(0,0));
|
||||||
|
if(comicsViewStack->currentWidget() == emptyFolderWidget)
|
||||||
|
comicsViewStack->setCurrentWidget(comicsView);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
emptyFolderWidget->setSubfolders(mi,dm->getSubfoldersNames(mi));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibraryWindow::selectSubfolder(const QModelIndex &mi, int child)
|
||||||
|
{
|
||||||
|
QModelIndex dest = dm->index(child,0,mi);
|
||||||
|
foldersView->setCurrentIndex(dest);
|
||||||
|
loadCovers(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibraryWindow::checkEmptyFolder(QStringList * paths)
|
void LibraryWindow::checkEmptyFolder(QStringList * paths)
|
||||||
@ -1521,7 +1539,7 @@ void LibraryWindow::switchToComicsView(ComicsView * from, ComicsView * to)
|
|||||||
comicsView->setToolBar(editInfoToolBar);
|
comicsView->setToolBar(editInfoToolBar);
|
||||||
|
|
||||||
comicsViewStack->removeWidget(from);
|
comicsViewStack->removeWidget(from);
|
||||||
comicsViewStack->insertWidget(0,comicsView);
|
comicsViewStack->addWidget(comicsView);
|
||||||
|
|
||||||
delete from;
|
delete from;
|
||||||
|
|
||||||
@ -1530,7 +1548,7 @@ void LibraryWindow::switchToComicsView(ComicsView * from, ComicsView * to)
|
|||||||
|
|
||||||
void LibraryWindow::showComicsViewTransition()
|
void LibraryWindow::showComicsViewTransition()
|
||||||
{
|
{
|
||||||
comicsViewStack->setCurrentIndex(1);
|
comicsViewStack->setCurrentWidget(comicsViewTransition);
|
||||||
comicsViewTransition->startMovie();
|
comicsViewTransition->startMovie();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1556,14 +1574,22 @@ void LibraryWindow::toggleComicsView_delayed()
|
|||||||
|
|
||||||
void LibraryWindow::showComicsView()
|
void LibraryWindow::showComicsView()
|
||||||
{
|
{
|
||||||
comicsViewStack->setCurrentIndex(0);
|
comicsViewStack->setCurrentWidget(comicsView);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibraryWindow::showEmptyFolderView()
|
||||||
|
{
|
||||||
|
comicsViewStack->setCurrentWidget(emptyFolderWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO recover the current comics selection and restore it in the destination
|
//TODO recover the current comics selection and restore it in the destination
|
||||||
void LibraryWindow::toggleComicsView()
|
void LibraryWindow::toggleComicsView()
|
||||||
{
|
{
|
||||||
QTimer::singleShot(0,this,SLOT(showComicsViewTransition()));
|
if(comicsViewStack->currentWidget()!=emptyFolderWidget) {
|
||||||
QTimer::singleShot(32,this,SLOT(toggleComicsView_delayed()));
|
QTimer::singleShot(0,this,SLOT(showComicsViewTransition()));
|
||||||
|
QTimer::singleShot(32,this,SLOT(toggleComicsView_delayed()));
|
||||||
|
} else
|
||||||
|
toggleComicsView_delayed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibraryWindow::asignNumbers()
|
void LibraryWindow::asignNumbers()
|
||||||
|
@ -53,6 +53,8 @@ class ComicsView;
|
|||||||
class ClassicComicsView;
|
class ClassicComicsView;
|
||||||
class GridComicsView;
|
class GridComicsView;
|
||||||
class ComicsViewTransition;
|
class ComicsViewTransition;
|
||||||
|
class EmptyFolderWidget;
|
||||||
|
|
||||||
#include "comic_db.h"
|
#include "comic_db.h"
|
||||||
|
|
||||||
using namespace YACReader;
|
using namespace YACReader;
|
||||||
@ -99,6 +101,7 @@ private:
|
|||||||
GridComicsView * gridComicsView;
|
GridComicsView * gridComicsView;
|
||||||
QStackedWidget * comicsViewStack;
|
QStackedWidget * comicsViewStack;
|
||||||
ComicsViewTransition * comicsViewTransition;
|
ComicsViewTransition * comicsViewTransition;
|
||||||
|
EmptyFolderWidget * emptyFolderWidget;
|
||||||
|
|
||||||
YACReaderTreeView * foldersView;
|
YACReaderTreeView * foldersView;
|
||||||
YACReaderLibraryListWidget * selectedLibrary;
|
YACReaderLibraryListWidget * selectedLibrary;
|
||||||
@ -207,104 +210,107 @@ private:
|
|||||||
void doComicsViewConnections();
|
void doComicsViewConnections();
|
||||||
|
|
||||||
|
|
||||||
//ACTIONS MANAGEMENT
|
//ACTIONS MANAGEMENT
|
||||||
void disableComicsActions(bool disabled);
|
void disableComicsActions(bool disabled);
|
||||||
void disableLibrariesActions(bool disabled);
|
void disableLibrariesActions(bool disabled);
|
||||||
void disableNoUpdatedLibrariesActions(bool disabled);
|
void disableNoUpdatedLibrariesActions(bool disabled);
|
||||||
void disableFoldersActions(bool disabled);
|
void disableFoldersActions(bool disabled);
|
||||||
|
|
||||||
void disableAllActions();
|
void disableAllActions();
|
||||||
//void disableActions();
|
//void disableActions();
|
||||||
//void enableActions();
|
//void enableActions();
|
||||||
//void enableLibraryActions();
|
//void enableLibraryActions();
|
||||||
|
|
||||||
QString currentPath();
|
QString currentPath();
|
||||||
|
|
||||||
//settings
|
//settings
|
||||||
QSettings * settings;
|
QSettings * settings;
|
||||||
|
|
||||||
//navigation backward and forward
|
//navigation backward and forward
|
||||||
int currentFolderNavigation;
|
int currentFolderNavigation;
|
||||||
QList<QModelIndex> history;
|
QList<QModelIndex> history;
|
||||||
|
|
||||||
bool removeError;
|
bool removeError;
|
||||||
|
|
||||||
ComicsViewStatus comicsViewStatus;
|
ComicsViewStatus comicsViewStatus;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void closeEvent ( QCloseEvent * event );
|
virtual void closeEvent ( QCloseEvent * event );
|
||||||
public:
|
public:
|
||||||
LibraryWindow();
|
LibraryWindow();
|
||||||
public slots:
|
|
||||||
void loadLibrary(const QString & path);
|
public slots:
|
||||||
void loadCovers(const QModelIndex & mi);
|
void loadLibrary(const QString & path);
|
||||||
void checkEmptyFolder(QStringList * paths = 0);
|
void loadCovers(const QModelIndex & mi);
|
||||||
void reloadCovers();
|
void selectSubfolder(const QModelIndex & mi, int child);
|
||||||
void openComic();
|
void checkEmptyFolder(QStringList * paths = 0);
|
||||||
void createLibrary();
|
void reloadCovers();
|
||||||
void create(QString source,QString dest, QString name);
|
void openComic();
|
||||||
void showAddLibrary();
|
void createLibrary();
|
||||||
void openLibrary(QString path, QString name);
|
void create(QString source,QString dest, QString name);
|
||||||
void loadLibraries();
|
void showAddLibrary();
|
||||||
void saveLibraries();
|
void openLibrary(QString path, QString name);
|
||||||
void reloadCurrentLibrary();
|
void loadLibraries();
|
||||||
void openLastCreated();
|
void saveLibraries();
|
||||||
void updateLibrary();
|
void reloadCurrentLibrary();
|
||||||
//void deleteLibrary();
|
void openLastCreated();
|
||||||
void openContainingFolder();
|
void updateLibrary();
|
||||||
void setFolderAsNotCompleted();
|
//void deleteLibrary();
|
||||||
void setFolderAsCompleted();
|
void openContainingFolder();
|
||||||
void setFolderAsFinished();
|
void setFolderAsNotCompleted();
|
||||||
void setFolderAsNotFinished();
|
void setFolderAsCompleted();
|
||||||
void openContainingFolderComic();
|
void setFolderAsFinished();
|
||||||
void deleteCurrentLibrary();
|
void setFolderAsNotFinished();
|
||||||
void removeLibrary();
|
void openContainingFolderComic();
|
||||||
void renameLibrary();
|
void deleteCurrentLibrary();
|
||||||
void rename(QString newName);
|
void removeLibrary();
|
||||||
void cancelCreating();
|
void renameLibrary();
|
||||||
void stopLibraryCreator();
|
void rename(QString newName);
|
||||||
void setRootIndex();
|
void cancelCreating();
|
||||||
void toggleFullScreen();
|
void stopLibraryCreator();
|
||||||
void toNormal();
|
void setRootIndex();
|
||||||
void toFullScreen();
|
void toggleFullScreen();
|
||||||
void setFoldersFilter(QString filter);
|
void toNormal();
|
||||||
void showProperties();
|
void toFullScreen();
|
||||||
void exportLibrary(QString destPath);
|
void setFoldersFilter(QString filter);
|
||||||
void importLibrary(QString clc,QString destPath,QString name);
|
void showProperties();
|
||||||
void reloadOptions();
|
void exportLibrary(QString destPath);
|
||||||
void setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus);
|
void importLibrary(QString clc,QString destPath,QString name);
|
||||||
void setCurrentComicReaded();
|
void reloadOptions();
|
||||||
void setCurrentComicUnreaded();
|
void setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus);
|
||||||
void hideComicFlow(bool hide);
|
void setCurrentComicReaded();
|
||||||
void showExportComicsInfo();
|
void setCurrentComicUnreaded();
|
||||||
void showImportComicsInfo();
|
void hideComicFlow(bool hide);
|
||||||
void asignNumbers();
|
void showExportComicsInfo();
|
||||||
void showNoLibrariesWidget();
|
void showImportComicsInfo();
|
||||||
void showRootWidget();
|
void asignNumbers();
|
||||||
void showImportingWidget();
|
void showNoLibrariesWidget();
|
||||||
void manageCreatingError(const QString & error);
|
void showRootWidget();
|
||||||
void manageUpdatingError(const QString & error);
|
void showImportingWidget();
|
||||||
void manageOpeningLibraryError(const QString & error);
|
void manageCreatingError(const QString & error);
|
||||||
QModelIndexList getSelectedComics();
|
void manageUpdatingError(const QString & error);
|
||||||
void deleteComics();
|
void manageOpeningLibraryError(const QString & error);
|
||||||
//void showSocial();
|
QModelIndexList getSelectedComics();
|
||||||
void backward();
|
void deleteComics();
|
||||||
void forward();
|
//void showSocial();
|
||||||
void updateHistory(const QModelIndex & mi);
|
void backward();
|
||||||
void updateFoldersViewConextMenu(const QModelIndex & mi);
|
void forward();
|
||||||
void libraryAlreadyExists(const QString & name);
|
void updateHistory(const QModelIndex & mi);
|
||||||
void importLibraryPackage();
|
void updateFoldersViewConextMenu(const QModelIndex & mi);
|
||||||
void updateComicsView(quint64 libraryId, const ComicDB & comic);
|
void libraryAlreadyExists(const QString & name);
|
||||||
void setCurrentComicOpened();
|
void importLibraryPackage();
|
||||||
void showComicVineScraper();
|
void updateComicsView(quint64 libraryId, const ComicDB & comic);
|
||||||
void setRemoveError();
|
void setCurrentComicOpened();
|
||||||
void checkRemoveError();
|
void showComicVineScraper();
|
||||||
void resetComicRating();
|
void setRemoveError();
|
||||||
void switchToComicsView(ComicsView *from, ComicsView *to);
|
void checkRemoveError();
|
||||||
void showComicsViewTransition();
|
void resetComicRating();
|
||||||
void toggleComicsView_delayed();//used in orther to avoid flickering;
|
void switchToComicsView(ComicsView *from, ComicsView *to);
|
||||||
void showComicsView();
|
void showComicsViewTransition();
|
||||||
void toggleComicsView();
|
void toggleComicsView_delayed();//used in orther to avoid flickering;
|
||||||
|
void showComicsView();
|
||||||
|
void showEmptyFolderView();
|
||||||
|
void toggleComicsView();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
BIN
images/empty_folder.png
Normal file
BIN
images/empty_folder.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
Loading…
x
Reference in New Issue
Block a user