code refactoring for adding support to multiple "comics views"

two "comics views" added, classic (flow+table_view) and grid (based on qml/qtquick)
TODO: the views are only interchangeable in compilation time, some more work is needed for doing it in run time.
fixed reloadCovers
This commit is contained in:
Luis Ángel San Martín 2014-07-06 14:50:28 +02:00
parent 692a924954
commit 664dac3401
24 changed files with 1473 additions and 279 deletions

View File

@ -113,6 +113,9 @@ HEADERS += comic_flow.h \
../common/http_worker.h \
yacreader_libraries.h \
../common/exit_check.h \
comics_view.h \
classic_comics_view.h
SOURCES += comic_flow.cpp \
create_library_dialog.cpp \
@ -156,6 +159,9 @@ SOURCES += comic_flow.cpp \
../common/yacreader_global.cpp \
yacreader_libraries.cpp \
../common/exit_check.cpp \
comics_view.cpp \
classic_comics_view.cpp
include(./server/server.pri)
@ -186,6 +192,16 @@ TRANSLATIONS = yacreaderlibrary_es.ts \
isEqual(QT_MAJOR_VERSION, 5) {
Release:DESTDIR = ../release5
Debug:DESTDIR = ../debug5
#QML/GridView
QT += quick qml
HEADERS += grid_comics_view.h
SOURCES += grid_comics_view.cpp
RESOURCES += qml.qrc
} else {
Release:DESTDIR = ../release
Debug:DESTDIR = ../debug

View File

@ -0,0 +1,233 @@
#include "classic_comics_view.h"
#include "yacreader_table_view.h"
#include "comic_flow_widget.h"
#include "QsLog.h"
ClassicComicsView::ClassicComicsView(QWidget *parent)
:ComicsView(parent)
{
QHBoxLayout * layout = new QHBoxLayout;
settings = new QSettings(YACReader::getSettingsPath()+"/YACReaderLibrary.ini",QSettings::IniFormat); //TODO unificar la creación del fichero de config con el servidor
settings->beginGroup("libraryConfig");
//FLOW-----------------------------------------------------------------------
//---------------------------------------------------------------------------
if(QGLFormat::hasOpenGL() && (settings->value(USE_OPEN_GL).toBool() == true))
comicFlow = new ComicFlowWidgetGL(0);
else
comicFlow = new ComicFlowWidgetSW(0);
comicFlow->updateConfig(settings);
comicFlow->setFocusPolicy(Qt::StrongFocus);
comicFlow->setShowMarks(true);
setFocusProxy(comicFlow);
comicFlow->setFocus(Qt::OtherFocusReason);
comicFlow->setContextMenuPolicy(Qt::ActionsContextMenu);
//TODO!!! set actions....
//comicFlow->addAction(toggleFullScreenAction);
//comicFlow->addAction(openComicAction);
//END FLOW----
//layout-----------------------------------------------
sVertical = new QSplitter(Qt::Vertical); //spliter derecha
sVertical->addWidget(comicFlow);
comics = new QWidget;
QVBoxLayout * comicsLayout = new QVBoxLayout;
comicsLayout->setSpacing(0);
comicsLayout->setContentsMargins(0,0,0,0);
//TODO ComicsView:(set toolbar) comicsLayout->addWidget(editInfoToolBar);
tableView = new YACReaderTableView;
tableView->verticalHeader()->hide();
comicsLayout->addWidget(tableView);
comics->setLayout(comicsLayout);
sVertical->addWidget(comics);
//config--------------------------------------------------
if(settings->contains(COMICS_VIEW_HEADERS))
tableView->horizontalHeader()->restoreState(settings->value(COMICS_VIEW_HEADERS).toByteArray());
//connections---------------------------------------------
connect(tableView, SIGNAL(clicked(QModelIndex)), this, SLOT(centerComicFlow(QModelIndex)));
connect(comicFlow, SIGNAL(centerIndexChanged(int)), this, SLOT(updateTableView(int)));
connect(tableView, SIGNAL(comicRated(int,QModelIndex)), this, SIGNAL(comicRated(int,QModelIndex)));
connect(comicFlow, SIGNAL(selected(uint)), this, SIGNAL(selected(uint)));
connect(tableView->horizontalHeader(), SIGNAL(sectionMoved(int,int,int)), this, SLOT(saveTableHeadersStatus()));
layout->addWidget(sVertical);
setLayout(layout);
layout->setMargin(0);
}
void ClassicComicsView::setToolBar(QToolBar *toolBar)
{
static_cast<QVBoxLayout *>(comics->layout())->insertWidget(0,toolBar);
}
void ClassicComicsView::setModel(TableModel *model)
{
ComicsView::setModel(model);
if(model == NULL)
{
comicFlow->clear();
}
else
{
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), this, SLOT(applyModelChanges(QModelIndex,QModelIndex,QVector<int>)));
connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(removeItemsFromFlow(QModelIndex,int,int)));
tableView->setModel(model);
tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
#if QT_VERSION >= 0x050000
tableView->horizontalHeader()->setSectionsMovable(true);
#else
tableView->horizontalHeader()->setMovable(true);
#endif
//TODO parametrizar la configuración de las columnas
for(int i = 0;i<tableView->horizontalHeader()->count();i++)
tableView->horizontalHeader()->hideSection(i);
tableView->horizontalHeader()->showSection(TableModel::Number);
tableView->horizontalHeader()->showSection(TableModel::Title);
tableView->horizontalHeader()->showSection(TableModel::FileName);
tableView->horizontalHeader()->showSection(TableModel::NumPages);
tableView->horizontalHeader()->showSection(TableModel::Hash); //Size is part of the Hash...TODO add Columns::Size to Columns
tableView->horizontalHeader()->showSection(TableModel::ReadColumn);
tableView->horizontalHeader()->showSection(TableModel::CurrentPage);
tableView->horizontalHeader()->showSection(TableModel::Rating);
//debido a un bug, qt4 no es capaz de ajustar el ancho teniendo en cuenta todas la filas (no sólo las visibles)
//así que se ecala la primera vez y después se deja el control al usuario.
//if(!settings->contains(COMICS_VIEW_HEADERS))
tableView->resizeColumnsToContents();
tableView->horizontalHeader()->setStretchLastSection(true);
QStringList paths = model->getPaths(model->getCurrentPath());//TODO ComicsView: get currentpath from somewhere currentPath());
comicFlow->setImagePaths(paths);
comicFlow->setMarks(model->getReadList());
comicFlow->setFocus(Qt::OtherFocusReason);
}
if(settings->contains(COMICS_VIEW_HEADERS))
tableView->horizontalHeader()->restoreState(settings->value(COMICS_VIEW_HEADERS).toByteArray());
}
void ClassicComicsView::setCurrentIndex(const QModelIndex &index)
{
tableView->setCurrentIndex(index);
//TODO ComicsView: scroll comicFlow to index
}
QModelIndex ClassicComicsView::currentIndex()
{
return tableView->currentIndex();
}
QItemSelectionModel *ClassicComicsView::selectionModel()
{
return tableView->selectionModel();
}
void ClassicComicsView::scrollTo(const QModelIndex & mi, QAbstractItemView::ScrollHint hint)
{
comicFlow->setCenterIndex(mi.row());
}
void ClassicComicsView::toFullScreen()
{
comicFlow->hide();
comicFlow->setCenterIndex(comicFlow->centerIndex());
comics->hide();
//showFullScreen() //parent windows
comicFlow->show();
comicFlow->setFocus(Qt::OtherFocusReason);
}
void ClassicComicsView::toNormal()
{
comicFlow->hide();
comicFlow->setCenterIndex(comicFlow->centerIndex());
comicFlow->render();
comics->show();
comicFlow->show();
}
void ClassicComicsView::updateConfig(QSettings *settings)
{
comicFlow->updateConfig(settings);
}
void ClassicComicsView::setItemActions(const QList<QAction *> &actions)
{
tableView->addActions(actions);
}
void ClassicComicsView::setViewActions(const QList<QAction *> &actions)
{
comicFlow->addActions(actions);
}
void ClassicComicsView::setShowMarks(bool show)
{
comicFlow->setShowMarks(show);
}
void ClassicComicsView::centerComicFlow(const QModelIndex & mi)
{
comicFlow->showSlide(mi.row());
comicFlow->setFocus(Qt::OtherFocusReason);
}
void ClassicComicsView::updateTableView(int i)
{
QModelIndex mi = model->index(i,2);
tableView->setCurrentIndex(mi);
tableView->scrollTo(mi,QAbstractItemView::EnsureVisible);
}
void ClassicComicsView::saveTableHeadersStatus()
{
settings->setValue(COMICS_VIEW_HEADERS,tableView->horizontalHeader()->saveState());
}
void ClassicComicsView::applyModelChanges(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
Q_UNUSED(topLeft);
Q_UNUSED(bottomRight);
if(roles.contains(TableModel::ReadColumnRole))
{
comicFlow->setMarks(model->getReadList());
comicFlow->updateMarks();
}
}
void ClassicComicsView::removeItemsFromFlow(const QModelIndex &parent, int from, int to)
{
Q_UNUSED(parent);
for(int i = from; i<=to; i++)
comicFlow->remove(i);
}
void ClassicComicsView::closeEvent(QCloseEvent *event)
{
saveTableHeadersStatus();
ComicsView::closeEvent(event);
}

View File

@ -0,0 +1,49 @@
#ifndef CLASSIC_COMICS_VIEW_H
#define CLASSIC_COMICS_VIEW_H
#include "comics_view.h"
#include <QModelIndex>
#include <QModelIndexList>
class YACReaderTableView;
class QSplitter;
class ComicFlowWidget;
class QToolBar;
class TableModel;
class ClassicComicsView : public ComicsView
{
Q_OBJECT
public:
ClassicComicsView(QWidget *parent = 0);
void setToolBar(QToolBar * toolBar);
void setModel(TableModel *model);
void setCurrentIndex(const QModelIndex &index);
QModelIndex currentIndex();
QItemSelectionModel * selectionModel();
void scrollTo(const QModelIndex & mi, QAbstractItemView::ScrollHint hint );
void toFullScreen();
void toNormal();
void updateConfig(QSettings * settings);
void setItemActions(const QList<QAction *> & actions);
void setViewActions(const QList<QAction *> & actions);
public slots:
void centerComicFlow(const QModelIndex & mi);
void updateTableView(int i);
void saveTableHeadersStatus();
void applyModelChanges(const QModelIndex & topLeft,const QModelIndex & bottomRight,const QVector<int> & roles);
void removeItemsFromFlow(const QModelIndex & parent, int from, int to);
//ComicsView
void setShowMarks(bool show);
private:
YACReaderTableView * tableView;
QWidget *comics;
QSplitter * sVertical;
ComicFlowWidget * comicFlow;
QSettings * settings;
void closeEvent ( QCloseEvent * event );
};
#endif // CLASSIC_COMICS_VIEW_H

View File

@ -0,0 +1,11 @@
#include "comics_view.h"
ComicsView::ComicsView(QWidget *parent) :
QWidget(parent),model(NULL)
{
}
void ComicsView::setModel(TableModel *m)
{
model = m;
}

View File

@ -0,0 +1,46 @@
#ifndef COMICS_VIEW_H
#define COMICS_VIEW_H
#include <QWidget>
#include "tablemodel.h"
#include <QAbstractItemView>
#include <QSettings>
#include <QModelIndex>
#include <QModelIndexList>
class YACReaderTableView;
class QSplitter;
class ComicFlowWidget;
class QToolBar;
class TableModel;
class ComicsView : public QWidget
{
Q_OBJECT
public:
explicit ComicsView(QWidget *parent = 0);
virtual void setToolBar(QToolBar * toolBar) = 0;
virtual void setModel(TableModel *model);
virtual void setCurrentIndex(const QModelIndex &index) = 0;
virtual QModelIndex currentIndex() = 0;
virtual QItemSelectionModel * selectionModel() = 0;
virtual void scrollTo(const QModelIndex & mi, QAbstractItemView::ScrollHint hint ) = 0;
virtual void toFullScreen() = 0;
virtual void toNormal() = 0;
virtual void updateConfig(QSettings * settings) = 0;
//Actions for tableviews
virtual void setItemActions(const QList<QAction *> & actions) = 0;
//actions for visual-oriented views
virtual void setViewActions(const QList<QAction *> & actions) = 0;
//virtual selectItem(int index) = 0;
signals:
void selected(unsigned int);
void comicRated(int,QModelIndex);
public slots:
virtual void setShowMarks(bool show) = 0;
protected:
TableModel * model;
};
#endif // COMICS_VIEW_H

View File

@ -46,6 +46,27 @@ int TableModel::columnCount(const QModelIndex &parent) const
}
//! [2]
QHash<int, QByteArray> TableModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[NumberRole] = "number";
roles[TitleRole] = "title";
roles[FileNameRole] = "file_name";
roles[NumPagesRole] = "num_pages";
roles[IdRole] = "id";
roles[Parent_IdRole] = "parent_id";
roles[PathRole] = "path";
roles[HashRole] = "hash";
roles[ReadColumnRole] = "read_column";
roles[IsBisRole] = "is_bis";
roles[CurrentPageRole] = "current_page";
roles[RatingRole] = "rating";
roles[HasBeenOpenedRole] = "has_been_opened";
roles[CoverPathRole] = "cover_path";
return roles;
}
//! [3]
QVariant TableModel::data(const QModelIndex &index, int role) const
{
@ -84,10 +105,28 @@ QVariant TableModel::data(const QModelIndex &index, int role) const
//TODO check here if any view is asking for TableModel::Roles
//these roles will be used from QML/GridView
TableItem *item = static_cast<TableItem*>(index.internalPointer());
if (role == NumberRole)
return item->data(Number);
else if (role == TitleRole)
return item->data(Title).isNull()?item->data(FileName):item->data(Title);
else if (role == RatingRole)
return item->data(Rating);
else if (role == CoverPathRole)
return "file:///"+_databasePath+"/covers/"+item->data(Hash).toString()+".jpg";
else if (role == NumPagesRole)
return item->data(NumPages);
else if (role == CurrentPageRole)
return item->data(CurrentPage);
else if (role == ReadColumnRole)
return item->data(ReadColumn).toBool();
else if (role == HasBeenOpenedRole)
return item->data(TableModel::HasBeenOpened);
if (role != Qt::DisplayRole)
return QVariant();
TableItem *item = static_cast<TableItem*>(index.internalPointer());
if(index.column() == TableModel::Hash)
return QString::number(item->data(index.column()).toString().right(item->data(index.column()).toString().length()-40).toInt()/1024.0/1024.0,'f',2)+"Mb";
if(index.column() == TableModel::ReadColumn)
@ -467,7 +506,7 @@ QVector<YACReaderComicReadStatus> TableModel::setComicsRead(QList<QModelIndex> l
db.close();
QSqlDatabase::removeDatabase(_databasePath);
emit dataChanged(index(list.first().row(),TableModel::ReadColumn),index(list.last().row(),TableModel::CurrentPage+1));
emit dataChanged(index(list.first().row(),TableModel::ReadColumn),index(list.last().row(),TableModel::HasBeenOpened),QVector<int>() = {ReadColumnRole,CurrentPageRole,HasBeenOpenedRole});
return getReadList();
}
@ -553,10 +592,10 @@ void TableModel::remove(ComicDB * comic, int row)
endRemoveRows();
}
ComicDB TableModel::getComic(int row)
/*ComicDB TableModel::getComic(int row)
{
return getComic(index(row,0));
}
}*/
void TableModel::remove(int row)
{
@ -581,7 +620,7 @@ void TableModel::reload(const ComicDB & comic)
row++;
}
if(found)
emit dataChanged(index(row,TableModel::CurrentPage),index(row,TableModel::CurrentPage));
emit dataChanged(index(row,ReadColumn),index(row,HasBeenOpened), QVector<int>() = {ReadColumnRole,CurrentPageRole,HasBeenOpenedRole});
}
void TableModel::resetComicRating(const QModelIndex &mi)
@ -600,27 +639,6 @@ void TableModel::resetComicRating(const QModelIndex &mi)
QSqlDatabase::removeDatabase(_databasePath);
}
QHash<int, QByteArray> TableModel::roleNames()
{
QHash<int, QByteArray> roles;
roles[NumberRole] = "number";
roles[TitleRole] = "title";
roles[FileNameRole] = "file_name";
roles[NumPagesRole] = "num_pages";
roles[IdRole] = "id";
roles[Parent_IdRole] = "parent_id";
roles[PathRole] = "path";
roles[HashRole] = "hash";
roles[ReadColumnRole] = "read";
roles[IsBisRole] = "is_bis";
roles[CurrentPageRole] = "current_page";
roles[RatingRole] = "rating";
roles[HasBeenOpenedRole] = "has_been_opened";
roles[CoverPathRole] = "cover_path";
return roles;
}
void TableModel::updateRating(int rating, QModelIndex mi)
{

View File

@ -39,8 +39,9 @@ public:
//Métodos de conveniencia
QStringList getPaths(const QString & _source);
QString getComicPath(QModelIndex mi);
QString getCurrentPath(){return QString(_databasePath).remove("/.yacreaderlibrary");};
ComicDB getComic(const QModelIndex & mi); //--> para la edición
ComicDB getComic(int row);
//ComicDB getComic(int row);
QVector<YACReaderComicReadStatus> getReadList();
QVector<YACReaderComicReadStatus> setAllComicsRead(YACReaderComicReadStatus readStatus);
QList<ComicDB> getComics(QList<QModelIndex> list); //--> recupera la información común a los comics seleccionados
@ -56,7 +57,7 @@ public:
void reload(const ComicDB & comic);
void resetComicRating(const QModelIndex & mi);
QHash<int, QByteArray> roleNames();
QHash<int, QByteArray> roleNames() const;
enum Columns {
Number = 0,
@ -98,6 +99,8 @@ public slots:
void finishTransaction();
void updateRating(int rating, QModelIndex mi);
protected:
private:
void setupModelData( QSqlQuery &sqlquery);
ComicDB _getComic(const QModelIndex & mi);

View File

@ -253,6 +253,7 @@ void DBHelper::update(ComicInfo * comicInfo, QSqlDatabase & db)
updateComicInfo.bindValue(":notes",comicInfo->notes);
bool read = comicInfo->read || comicInfo->currentPage == comicInfo->numPages.toInt(); //if current page is the las page, the comic is read(completed)
comicInfo->read = read;
updateComicInfo.bindValue(":read", read?1:0);
updateComicInfo.bindValue(":id", comicInfo->id);
updateComicInfo.bindValue(":edited", comicInfo->edited?1:0);

View File

@ -0,0 +1,200 @@
#include "grid_comics_view.h"
#include <QtWidgets>
#include <QtQuick>
#include "QsLog.h"
GridComicsView::GridComicsView(QWidget *parent) :
ComicsView(parent),_selectionModel(NULL)
{
qmlRegisterType<TableModel>("comicModel",1,0,"TableModel");
view = new QQuickView();
container = QWidget::createWindowContainer(view, this);
container->setMinimumSize(200, 200);
container->setFocusPolicy(Qt::TabFocus);
view->setSource(QUrl("qrc:/qml/GridComicsView.qml"));
setShowMarks(true);//TODO save this in settings
QVBoxLayout * l = new QVBoxLayout;
l->addWidget(container);
this->setLayout(l);
setContentsMargins(0,0,0,0);
l->setContentsMargins(0,0,0,0);
QLOG_INFO() << "GridComicsView";
}
GridComicsView::~GridComicsView()
{
delete view;
}
void GridComicsView::setToolBar(QToolBar *toolBar)
{
QLOG_INFO() << "setToolBar";
static_cast<QVBoxLayout *>(this->layout())->insertWidget(1,toolBar);
}
void GridComicsView::setModel(TableModel *model)
{
QLOG_INFO() << "setModel";
QQmlContext *ctxt = view->rootContext();
//there is only one mothel in the system
ComicsView::setModel(model);
if(this->model != NULL)
{
QLOG_INFO() << "xxx";
if(_selectionModel != NULL)
delete _selectionModel;
_selectionModel = new QItemSelectionModel(this->model);
ctxt->setContextProperty("comicsList", this->model);
ctxt->setContextProperty("comicsSelection", _selectionModel);
ctxt->setContextProperty("comicsSelectionHelper", this);
ctxt->setContextProperty("dummyValue", true);
}
#ifdef Q_OS_MAC
ctxt->setContextProperty("backgroundColor", "#FAFAFA");
ctxt->setContextProperty("cellColor", "#EDEDED");
ctxt->setContextProperty("selectedColor", "#DDDDDD");
ctxt->setContextProperty("titleColor", "#121212");
ctxt->setContextProperty("textColor", "#636363");
ctxt->setContextProperty("dropShadow",true);
#else
ctxt->setContextProperty("backgroundColor", "#2A2A2A");
ctxt->setContextProperty("cellColor", "#212121");
ctxt->setContextProperty("selectedColor", "#121212");
ctxt->setContextProperty("titleColor", "#E6E6E6");
ctxt->setContextProperty("textColor", "#E6E6E6");
ctxt->setContextProperty("dropShadow",false);
#endif
}
void GridComicsView::setCurrentIndex(const QModelIndex &index)
{
QLOG_INFO() << "setCurrentIndex";
}
QModelIndex GridComicsView::currentIndex()
{
QLOG_INFO() << "currentIndex";
QModelIndexList indexes = _selectionModel->selectedRows();
if(indexes.length()>0)
return indexes[0];
this->selectIndex(0);
return _selectionModel->selectedRows()[0];
}
QItemSelectionModel *GridComicsView::selectionModel()
{
QLOG_INFO() << "selectionModel";
QModelIndexList indexes = _selectionModel->selectedRows();
if(indexes.length()==0)
this->selectIndex(0);
return _selectionModel;
}
void GridComicsView::scrollTo(const QModelIndex &mi, QAbstractItemView::ScrollHint hint)
{
QLOG_INFO() << "scrollTo";
}
void GridComicsView::toFullScreen()
{
QLOG_INFO() << "toFullScreen";
}
void GridComicsView::toNormal()
{
QLOG_INFO() << "toNormal";
}
void GridComicsView::updateConfig(QSettings *settings)
{
QLOG_INFO() << "updateConfig";
}
void GridComicsView::setItemActions(const QList<QAction *> &actions)
{
QLOG_INFO() << "setItemActions";
}
void GridComicsView::setViewActions(const QList<QAction *> &actions)
{
//TODO generate QML Menu from actions
QLOG_INFO() << "setViewActions";
this->addActions(actions);
}
QSize GridComicsView::sizeHint()
{
QLOG_INFO() << "sizeHint";
return QSize(1280,768);
}
//helper
void GridComicsView::selectIndex(int index)
{
QLOG_INFO() << "selectIndex" << index;
if(_selectionModel != NULL && model!=NULL)
_selectionModel->select(model->index(index,0),QItemSelectionModel::Select | QItemSelectionModel::Rows);
}
bool GridComicsView::isSelectedIndex(int index)
{
if(_selectionModel != NULL && model!=NULL)
{
QModelIndex mi = model->index(index,0);
return _selectionModel->isSelected(mi);
}
return false;
}
void GridComicsView::clear()
{
QLOG_INFO() << "clear";
if(_selectionModel != NULL)
{
_selectionModel->clear();
QQmlContext *ctxt = view->rootContext();
ctxt->setContextProperty("dummyValue", true);
}
//model->forceClear();
}
void GridComicsView::selectedItem(int index)
{
emit doubleClicked(model->index(index,0));
}
void GridComicsView::setShowMarks(bool show)
{
QLOG_INFO() << "setShowMarks";
QQmlContext *ctxt = view->rootContext();
ctxt->setContextProperty("show_marks", show);
}
void GridComicsView::closeEvent(QCloseEvent *event)
{
QLOG_INFO() << "closeEvent";
QObject *object = view->rootObject();
QMetaObject::invokeMethod(object, "exit");
container->close();
view->close();
event->accept();
ComicsView::closeEvent(event);
}

View File

@ -0,0 +1,58 @@
#ifndef GRID_COMICS_VIEW_H
#define GRID_COMICS_VIEW_H
#include "comics_view.h"
#include <QModelIndex>
class QAbstractListModel;
class QItemSelectionModel;
class QQuickView;
class QQuickView;
class GridComicsView : public ComicsView
{
Q_OBJECT
public:
explicit GridComicsView(QWidget *parent = 0);
virtual ~GridComicsView();
void setToolBar(QToolBar * toolBar);
void setModel(TableModel *model);
void setCurrentIndex(const QModelIndex &index);
QModelIndex currentIndex();
QItemSelectionModel * selectionModel();
void scrollTo(const QModelIndex & mi, QAbstractItemView::ScrollHint hint );
void toFullScreen();
void toNormal();
void updateConfig(QSettings * settings);
void setItemActions(const QList<QAction *> & actions);
void setViewActions(const QList<QAction *> & actions);
QSize sizeHint();
signals:
signals:
void comicRated(int,QModelIndex);
void doubleClicked(QModelIndex);
public slots:
//selection helper
void selectIndex(int index);
bool isSelectedIndex(int index);
void clear();
//double clicked item
void selectedItem(int index);
//ComicsView
void setShowMarks(bool show);
private:
QItemSelectionModel * _selectionModel;
QQuickView *view;
QWidget *container;
bool dummy;
void closeEvent ( QCloseEvent * event );
};
#endif // GRID_COMICS_VIEW_H

View File

@ -60,6 +60,9 @@
#include "comic_vine_dialog.h"
//#include "yacreader_social_dialog.h"
#include "classic_comics_view.h"
#include "grid_comics_view.h"
#include "QsLog.h"
#ifdef Q_OS_WIN
@ -118,10 +121,9 @@ void LibraryWindow::setupUI()
else
//if(settings->value(USE_OPEN_GL).toBool() == false)
showMaximized();
if(settings->contains(COMICS_VIEW_HEADERS))
comicView->horizontalHeader()->restoreState(settings->value(COMICS_VIEW_HEADERS).toByteArray());
/*if(settings->contains(COMICS_VIEW_HEADERS_GEOMETRY))
comicView->horizontalHeader()->restoreGeometry(settings->value(COMICS_VIEW_HEADERS_GEOMETRY).toByteArray());*/
comicsView->horizontalHeader()->restoreGeometry(settings->value(COMICS_VIEW_HEADERS_GEOMETRY).toByteArray());*/
/*socialDialog = new YACReaderSocialDialog(this);
socialDialog->setHidden(true);*/
@ -131,7 +133,7 @@ void LibraryWindow::doLayout()
{
//LAYOUT ELEMENTS------------------------------------------------------------
//---------------------------------------------------------------------------
sVertical = new QSplitter(Qt::Vertical); //spliter derecha
QSplitter * sHorizontal = new QSplitter(Qt::Horizontal); //spliter principal
#ifdef Q_OS_MAC
sHorizontal->setStyleSheet("QSplitter::handle{image:none;background-color:#B8B8B8;} QSplitter::handle:vertical {height:1px;}");
@ -142,12 +144,15 @@ void LibraryWindow::doLayout()
//TOOLBARS-------------------------------------------------------------------
//---------------------------------------------------------------------------
editInfoToolBar = new QToolBar();
editInfoToolBar->setStyleSheet("QToolBar {border: none;}");
#ifdef Q_OS_MAC
libraryToolBar = addToolBar(tr("Library"));
#else
libraryToolBar = new YACReaderMainToolBar(this);
#endif
//FLOW-----------------------------------------------------------------------
//---------------------------------------------------------------------------
if(QGLFormat::hasOpenGL() && !settings->contains(USE_OPEN_GL))
@ -163,29 +168,6 @@ void LibraryWindow::doLayout()
delete flowSelDialog;
}
if(QGLFormat::hasOpenGL() && (settings->value(USE_OPEN_GL).toBool() == true))
comicFlow = new ComicFlowWidgetGL(0);
else
comicFlow = new ComicFlowWidgetSW(0);
comicFlow->updateConfig(settings);
comicFlow->setFocusPolicy(Qt::StrongFocus);
comicFlow->setShowMarks(true);
setFocusProxy(comicFlow);
fullScreenToolTip = new QLabel(comicFlow);
fullScreenToolTip->setText(tr("<font color='white'> press 'F' to close fullscreen mode </font>"));
fullScreenToolTip->setPalette(QPalette(QColor(0,0,0)));
fullScreenToolTip->setFont(QFont("courier new",15,234));
fullScreenToolTip->setAutoFillBackground(true);
fullScreenToolTip->hide();
fullScreenToolTip->adjustSize();
comicFlow->setFocus(Qt::OtherFocusReason);
comicFlow->addAction(toggleFullScreenAction);
comicFlow->addAction(openComicAction);
//SIDEBAR-----------------------------------------------------------------------
//---------------------------------------------------------------------------
sideBar = new YACReaderSideBar;
@ -207,25 +189,23 @@ void LibraryWindow::doLayout()
foldersTitle->addAction(colapseAllNodesAction);
//FINAL LAYOUT-------------------------------------------------------------
sVertical->addWidget(comicFlow);
comics = new QWidget;
QVBoxLayout * comicsLayout = new QVBoxLayout;
comicsLayout->setSpacing(0);
comicsLayout->setContentsMargins(0,0,0,0);
comicsLayout->addWidget(editInfoToolBar);
editInfoToolBar->setStyleSheet("QToolBar {border: none;}");
comicsView = new ClassicComicsView();
comicsView->setToolBar(editInfoToolBar);
fullScreenToolTip = new QLabel(comicsView);
fullScreenToolTip->setText(tr("<font color='white'> press 'F' to close fullscreen mode </font>"));
fullScreenToolTip->setPalette(QPalette(QColor(0,0,0)));
fullScreenToolTip->setFont(QFont("courier new",15,234));
fullScreenToolTip->setAutoFillBackground(true);
fullScreenToolTip->hide();
fullScreenToolTip->adjustSize();
comicView = new YACReaderTableView;
comicView->verticalHeader()->hide();
comicsLayout->addWidget(comicView);
comics->setLayout(comicsLayout);
sVertical->addWidget(comics);
sHorizontal->addWidget(sideBar);
#ifndef Q_OS_MAC
QVBoxLayout * rightLayout = new QVBoxLayout;
rightLayout->addWidget(libraryToolBar);
rightLayout->addWidget(sVertical);
rightLayout->addWidget(comicsView);
rightLayout->setMargin(0);
rightLayout->setSpacing(0);
@ -257,10 +237,7 @@ void LibraryWindow::doLayout()
connect(noLibrariesWidget,SIGNAL(createNewLibrary()),this,SLOT(createLibrary()));
connect(noLibrariesWidget,SIGNAL(addExistingLibrary()),this,SLOT(showAddLibrary()));
comicFlow->addAction(toggleFullScreenAction);
comicFlow->addAction(openComicAction);
comicFlow->setContextMenuPolicy(Qt::ActionsContextMenu);
//collapsible disabled in macosx (only temporaly)
#ifdef Q_OS_MAC
@ -640,22 +617,43 @@ void LibraryWindow::createToolBars()
void LibraryWindow::createMenus()
{
comicView->addAction(openContainingFolderComicAction);
YACReader::addSperator(comicView);
QList<QAction *> itemActions;
itemActions << openContainingFolderComicAction
<< YACReader::createSeparator()
<< resetComicRatingAction
<< YACReader::createSeparator()
<< editSelectedComicsAction
<< getInfoAction
<< asignOrderActions
<< YACReader::createSeparator()
<< setAsReadAction
<< setAsNonReadAction
<< YACReader::createSeparator()
<< deleteComicsAction;
comicView->addAction(resetComicRatingAction);
YACReader::addSperator(comicView);
QList<QAction *> viewActions;
viewActions << openComicAction
<< YACReader::createSeparator()
<< openContainingFolderComicAction
<< YACReader::createSeparator()
<< resetComicRatingAction
<< YACReader::createSeparator()
<< editSelectedComicsAction
<< getInfoAction
<< asignOrderActions
<< YACReader::createSeparator()
<< selectAllComicsAction
<< YACReader::createSeparator()
<< setAsReadAction
<< setAsNonReadAction
<< showHideMarksAction
<< YACReader::createSeparator()
<< deleteComicsAction
<< YACReader::createSeparator()
<< toggleFullScreenAction;
comicView->addAction(editSelectedComicsAction);
comicView->addAction(getInfoAction);
comicView->addAction(asignOrderActions);
YACReader::addSperator(comicView);
comicView->addAction(setAsReadAction);
comicView->addAction(setAsNonReadAction);
YACReader::addSperator(comicView);
comicView->addAction(deleteComicsAction);
comicsView->setItemActions(itemActions);
comicsView->setViewActions(viewActions);
foldersView->addAction(openContainingFolderAction);
YACReader::addSperator(foldersView);
@ -679,6 +677,9 @@ void LibraryWindow::createMenus()
selectedLibrary->addAction(exportLibraryAction);
selectedLibrary->addAction(importLibraryAction);
//MacOSX app menus
#ifdef Q_OS_MACX
QMenuBar * menu = this->menuBar();
@ -776,9 +777,8 @@ void LibraryWindow::createConnections()
connect(foldersView, SIGNAL(clicked(QModelIndex)), this, SLOT(loadCovers(QModelIndex)));
connect(foldersView, SIGNAL(clicked(QModelIndex)), this, SLOT(updateHistory(QModelIndex)));
connect(comicView, SIGNAL(clicked(QModelIndex)), this, SLOT(centerComicFlow(QModelIndex)));
connect(comicFlow, SIGNAL(centerIndexChanged(int)), this, SLOT(updateComicView(int)));
connect(comicView, SIGNAL(comicRated(int,QModelIndex)), dmCV, SLOT(updateRating(int,QModelIndex)));
connect(comicsView, SIGNAL(comicRated(int,QModelIndex)), dmCV, SLOT(updateRating(int,QModelIndex)));
connect(showHideMarksAction,SIGNAL(toggled(bool)),comicsView,SLOT(setShowMarks(bool)));
//actions
connect(createLibraryAction,SIGNAL(triggered()),this,SLOT(createLibrary()));
@ -791,7 +791,6 @@ void LibraryWindow::createConnections()
//connect(setAllAsReadAction,SIGNAL(triggered()),this,SLOT(setComicsReaded()));
//connect(setAllAsNonReadAction,SIGNAL(triggered()),this,SLOT(setComicsUnreaded()));
connect(showHideMarksAction,SIGNAL(toggled(bool)),comicFlow,SLOT(setShowMarks(bool)));
//comicsInfoManagement
connect(exportComicsInfo,SIGNAL(triggered()),this,SLOT(showExportComicsInfo()));
@ -819,8 +818,8 @@ void LibraryWindow::createConnections()
#endif
connect(optionsDialog, SIGNAL(optionsChanged()),this,SLOT(reloadOptions()));
//ComicFlow
connect(comicFlow,SIGNAL(selected(unsigned int)),this,SLOT(openComic()));
connect(comicView,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(openComic()));
connect(comicsView,SIGNAL(selected(unsigned int)),this,SLOT(openComic()));
connect(comicsView,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(openComic()));
//Folders filter
//connect(clearFoldersFilter,SIGNAL(clicked()),foldersFilter,SLOT(clear()));
connect(foldersFilter,SIGNAL(textChanged(QString)),this,SLOT(setFoldersFilter(QString)));
@ -838,7 +837,7 @@ void LibraryWindow::createConnections()
//connect(dm,SIGNAL(directoryLoaded(QString)),foldersView,SLOT(expandAll()));
//connect(dm,SIGNAL(directoryLoaded(QString)),this,SLOT(updateFoldersView(QString)));
//Comicts edition
connect(selectAllComicsAction,SIGNAL(triggered()),comicView,SLOT(selectAll()));
connect(selectAllComicsAction,SIGNAL(triggered()),comicsView,SLOT(selectAll()));
connect(editSelectedComicsAction,SIGNAL(triggered()),this,SLOT(showProperties()));
connect(asignOrderActions,SIGNAL(triggered()),this,SLOT(asignNumbers()));
@ -875,16 +874,14 @@ void LibraryWindow::loadLibrary(const QString & name)
int ret = QMessageBox::question(this,tr("Update needed"),tr("This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now?"),QMessageBox::Yes,QMessageBox::No);
if(ret == QMessageBox::Yes)
{
//TODO update to new version
updated = DataBaseManagement::updateToCurrentVersion(path+"/library.ydb");
if(!updated)
QMessageBox::critical(this,tr("Update failed"), tr("The current library can't be udpated. Check for write write permissions on: ") + path+"/library.ydb");
}
else
{
comicView->setModel(NULL);
comicsView->setModel(NULL);
foldersView->setModel(NULL);
comicFlow->clear();
disableAllActions();//TODO comprobar que se deben deshabilitar
//será posible renombrar y borrar estas bibliotecas
renameLibraryAction->setEnabled(true);
@ -935,9 +932,8 @@ void LibraryWindow::loadLibrary(const QString & name)
if(ret == QMessageBox::Yes)
QDesktopServices::openUrl(QUrl("http://www.yacreader.com"));
comicView->setModel(NULL);
comicsView->setModel(NULL);
foldersView->setModel(NULL);
comicFlow->clear();
disableAllActions();//TODO comprobar que se deben deshabilitar
//será posible renombrar y borrar estas bibliotecas
renameLibraryAction->setEnabled(true);
@ -946,9 +942,8 @@ void LibraryWindow::loadLibrary(const QString & name)
}
else
{
comicView->setModel(NULL);
comicsView->setModel(NULL);
foldersView->setModel(NULL);
comicFlow->clear();
disableAllActions();//TODO comprobar que se deben deshabilitar
//si la librería no existe en disco, se ofrece al usuario la posibiliad de eliminarla
@ -1035,45 +1030,15 @@ void LibraryWindow::loadCovers(const QModelIndex & mi)
column = mi.column();
}
//comicView->setModel(NULL);
//comicsView->setModel(NULL);
dmCV->setupModelData(folderId,dm->getDatabase());
comicView->setModel(dmCV);
comicView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
#if QT_VERSION >= 0x050000
comicView->horizontalHeader()->setSectionsMovable(true);
#else
comicView->horizontalHeader()->setMovable(true);
#endif
//TODO parametrizar la configuración de las columnas
for(int i = 0;i<comicView->horizontalHeader()->count();i++)
comicView->horizontalHeader()->hideSection(i);
comicView->horizontalHeader()->showSection(0);
comicView->horizontalHeader()->showSection(1);
comicView->horizontalHeader()->showSection(2);
comicView->horizontalHeader()->showSection(3);
comicView->horizontalHeader()->showSection(7);
comicView->horizontalHeader()->showSection(8);
comicView->horizontalHeader()->showSection(10);
comicView->horizontalHeader()->showSection(11);
//debido a un bug, qt4 no es capaz de ajustar el ancho teniendo en cuenta todas la filas (no sólo las visibles)
//así que se ecala la primera vez y después se deja el control al usuario.
//if(!settings->contains(COMICS_VIEW_HEADERS))
comicView->resizeColumnsToContents();
comicView->horizontalHeader()->setStretchLastSection(true);
comicsView->setModel(dmCV);
QStringList paths = dmCV->getPaths(currentPath());
comicFlow->setImagePaths(paths);
comicFlow->setMarks(dmCV->getReadList());
comicFlow->setFocus(Qt::OtherFocusReason);
checkEmptyFolder(&paths);
if(paths.size()>0)
comicView->setCurrentIndex(dmCV->index(0,0));
comicsView->setCurrentIndex(dmCV->index(0,0));
}
void LibraryWindow::checkEmptyFolder(QStringList * paths)
@ -1098,33 +1063,22 @@ void LibraryWindow::checkEmptyFolder(QStringList * paths)
void LibraryWindow::reloadCovers()
{
if(foldersView->selectionModel()->selectedRows().length()>0)
loadCovers(foldersView->currentIndex());
else
loadCovers(QModelIndex());
QLOG_INFO() << "reloaded covers at row : " << foldersView->currentIndex().row();
QModelIndex mi = dmCV->getIndexFromId(_comicIdEdited);
comicView->scrollTo(mi,QAbstractItemView::PositionAtCenter);
comicView->setCurrentIndex(mi);
comicsView->scrollTo(mi,QAbstractItemView::PositionAtCenter);
comicsView->setCurrentIndex(mi);
//centerComicFlow(mi);
comicFlow->setCenterIndex(mi.row());
}
void LibraryWindow::centerComicFlow(const QModelIndex & mi)
{
comicFlow->showSlide(mi.row());
comicFlow->setFocus(Qt::OtherFocusReason);
}
void LibraryWindow::updateComicView(int i)
{
QModelIndex mi = dmCV->index(i,2);
comicView->setCurrentIndex(mi);
comicView->scrollTo(mi,QAbstractItemView::EnsureVisible);
}
void LibraryWindow::openComic()
{
if(!importedCovers)
{
ComicDB comic = dmCV->getComic(comicView->currentIndex());
ComicDB comic = dmCV->getComic(comicsView->currentIndex());
QString path = currentPath();
QList<ComicDB> siblings = dmCV->getAllComics();
@ -1159,42 +1113,24 @@ void LibraryWindow::openComic()
}
}
void LibraryWindow::setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus)
{
comicFlow->setMarks(dmCV->setComicsRead(getSelectedComics(),readStatus));
comicFlow->updateMarks();
void LibraryWindow::setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus) {
dmCV->setComicsRead(getSelectedComics(),readStatus);
}
void LibraryWindow::setCurrentComicReaded()
{
void LibraryWindow::setCurrentComicReaded() {
this->setCurrentComicsStatusReaded(YACReader::Read);
}
void LibraryWindow::setCurrentComicOpened()
{
//TODO: remove?
}
void LibraryWindow::setComicsReaded()
{
comicFlow->setMarks(dmCV->setAllComicsRead(YACReader::Read));
comicFlow->updateMarks();
}
void LibraryWindow::setCurrentComicUnreaded()
{
void LibraryWindow::setCurrentComicUnreaded() {
this->setCurrentComicsStatusReaded(YACReader::Unread);
}
void LibraryWindow::setComicsUnreaded()
{
comicFlow->setMarks(dmCV->setAllComicsRead(YACReader::Unread));
comicFlow->updateMarks();
}
void LibraryWindow::createLibrary()
{
void LibraryWindow::createLibrary() {
createLibraryDialog->show(libraries);
}
@ -1211,8 +1147,7 @@ void LibraryWindow::create(QString source, QString dest, QString name)
}
void LibraryWindow::reloadCurrentLibrary()
{
void LibraryWindow::reloadCurrentLibrary() {
loadLibrary(selectedLibrary->currentText());
}
@ -1268,24 +1203,8 @@ void LibraryWindow::loadLibraries()
}
void LibraryWindow::saveLibraries()
{
void LibraryWindow::saveLibraries() {
libraries.save();
/*QFile f(QCoreApplication::applicationDirPath()+"/libraries.yacr");
if(!f.open(QIODevice::WriteOnly))
{
QMessageBox::critical(NULL,tr("Saving libraries file...."),tr("There was a problem saving YACReaderLibrary libraries file. Please, check if you have enough permissions in the YACReader root folder."));
}
else
{
QTextStream txtS(&f);
for(QMap<QString,QString>::iterator i = libraries.begin();i!=libraries.end();i++)
{
txtS << i.key() << "\n";
txtS << i.value() << "\n";
}
}*/
}
void LibraryWindow::updateLibrary()
@ -1313,9 +1232,9 @@ void LibraryWindow::deleteCurrentLibrary()
d.rmdir(path);
if(libraries.isEmpty())//no more libraries avaliable.
{
comicView->setModel(NULL);
comicsView->setModel(NULL);
foldersView->setModel(NULL);
comicFlow->clear();
disableAllActions();
showNoLibrariesWidget();
}
@ -1335,9 +1254,9 @@ void LibraryWindow::removeLibrary()
//selectedLibrary->setCurrentIndex(0);
if(libraries.isEmpty())//no more libraries avaliable.
{
comicView->setModel(NULL);
comicsView->setModel(NULL);
foldersView->setModel(NULL);
comicFlow->clear();
disableAllActions();
showNoLibrariesWidget();
}
@ -1408,11 +1327,10 @@ void LibraryWindow::setRootIndex()
}
else
{
comicView->setModel(NULL);
comicFlow->clear();
comicsView->setModel(NULL);
}
foldersView->clearSelection();
foldersView->selectionModel()->clear();
}
setFolderAsNotCompletedAction->setVisible(false);
@ -1432,17 +1350,12 @@ void LibraryWindow::toFullScreen()
{
fromMaximized = this->isMaximized();
comicFlow->hide();
//comicFlow->setSlideSize(slideSizeF);
comicFlow->setCenterIndex(comicFlow->centerIndex());
comics->hide();
sideBar->hide();
libraryToolBar->hide();
showFullScreen();
comicsView->toFullScreen();
comicFlow->show();
comicFlow->setFocus(Qt::OtherFocusReason);
showFullScreen();
fullScreenToolTip->move((width()-fullScreenToolTip->width())/2,0);
fullScreenToolTip->adjustSize();
@ -1452,14 +1365,10 @@ void LibraryWindow::toFullScreen()
void LibraryWindow::toNormal()
{
fullScreenToolTip->hide();
comicFlow->hide();
//comicFlow->setSlideSize(slideSizeW);
comicFlow->setCenterIndex(comicFlow->centerIndex());
comicFlow->render();
comics->show();
sideBar->show();
comicFlow->show();
comicsView->toNormal();
if(fromMaximized)
showMaximized();
@ -1580,7 +1489,7 @@ void LibraryWindow::asignNumbers()
void LibraryWindow::openContainingFolderComic()
{
QModelIndex modelIndex = comicView->currentIndex();
QModelIndex modelIndex = comicsView->currentIndex();
QFileInfo file = QDir::cleanPath(currentPath() + dmCV->getComicPath(modelIndex));
#ifdef Q_OS_LINUX
QString path = file.absolutePath();
@ -1656,7 +1565,7 @@ void LibraryWindow::importLibrary(QString clc,QString destPath,QString name)
void LibraryWindow::reloadOptions()
{
//comicFlow->setFlowType(flowType);
comicFlow->updateConfig(settings);
comicsView->updateConfig(settings);
}
QString LibraryWindow::currentPath()
@ -1664,8 +1573,11 @@ QString LibraryWindow::currentPath()
return libraries.getPath(selectedLibrary->currentText());
}
//TODO ComicsView: some actions in the comics toolbar can be relative to a certain view
//show/hide actions on show/hide widget
void LibraryWindow::hideComicFlow(bool hide)
{
/*
if(hide)
{
QList<int> sizes;
@ -1682,7 +1594,7 @@ void LibraryWindow::hideComicFlow(bool hide)
sizes.append(total/3);
sVertical->setSizes(sizes);
}
*/
}
void LibraryWindow::showExportComicsInfo()
@ -1696,13 +1608,17 @@ void LibraryWindow::showImportComicsInfo()
importComicsInfoDialog->dest = currentPath() + "/.yacreaderlibrary/library.ydb";
importComicsInfoDialog->show();
}
#include "startup.h"
extern Startup * s;
void LibraryWindow::closeEvent ( QCloseEvent * event )
{
s->stop();
settings->setValue(MAIN_WINDOW_GEOMETRY, saveGeometry());
settings->setValue(COMICS_VIEW_HEADERS,comicView->horizontalHeader()->saveState());
comicsView->close();
QApplication::instance()->processEvents();
event->accept();
//settings->setValue(COMICS_VIEW_HEADERS_GEOMETRY,comicView->horizontalHeader()->saveGeometry());
QMainWindow::closeEvent(event);
}
void LibraryWindow::showNoLibrariesWidget()
@ -1751,15 +1667,16 @@ bool lessThanModelIndexRow(const QModelIndex & m1, const QModelIndex & m2)
QModelIndexList LibraryWindow::getSelectedComics()
{
//se fuerza a que haya almenos una fila seleccionada TODO comprobar se se puede forzar a la tabla a que lo haga automáticamente
QModelIndexList selection = comicView->selectionModel()->selectedRows();
//avoid selection.count()==0 forcing selection in comicsView
QModelIndexList selection = comicsView->selectionModel()->selectedRows();
QLOG_INFO() << "selection count " << selection.length();
qSort(selection.begin(),selection.end(),lessThanModelIndexRow);
if(selection.count()==0)
/*if(selection.count()==0)
{
comicView->selectRow(comicFlow->centerIndex());
selection = comicView->selectionModel()->selectedRows();
}
comicsView->selectRow(comicFlow->centerIndex());
selection = comicsView->selectionModel()->selectedRows();
}*/
return selection;
}
@ -1779,18 +1696,20 @@ void LibraryWindow::deleteComics()
foreach(ComicDB comic, comics)
{
paths.append(libraryPath + comic.path);
QLOG_INFO() << comic.path;
QLOG_INFO() << comic.id;
QLOG_INFO() << comic.parentId;
}
ComicsRemover * remover = new ComicsRemover(indexList,paths);
//comicView->showDeleteProgress();
//comicsView->showDeleteProgress();
dmCV->startTransaction();
connect(remover, SIGNAL(remove(int)), dmCV, SLOT(remove(int)));
connect(remover, SIGNAL(remove(int)), comicFlow, SLOT(remove(int)));
connect(remover,SIGNAL(removeError()),this,SLOT(setRemoveError()));
connect(remover, SIGNAL(finished()), dmCV, SLOT(finishTransaction()));
//connect(remover, SIGNAL(finished()), comicView, SLOT(hideDeleteProgress()));
//connect(remover, SIGNAL(finished()), comicsView, SLOT(hideDeleteProgress()));
connect(remover, SIGNAL(finished()),this,SLOT(checkEmptyFolder()));
connect(remover, SIGNAL(finished()),this,SLOT(checkRemoveError()));
connect(remover, SIGNAL(finished()), remover, SLOT(deleteLater()));
@ -1895,9 +1814,7 @@ void LibraryWindow::importLibraryPackage()
void LibraryWindow::updateComicsView(quint64 libraryId, const ComicDB & comic)
{
//TODO comprobar la biblioteca....
if(libraryId == selectedLibrary->currentIndex())
{
if(libraryId == selectedLibrary->currentIndex()) {
dmCV->reload(comic);
comicFlow->setMarks(dmCV->getReadList());
}
}

View File

@ -27,7 +27,6 @@ class HelpAboutDialog;
class RenameLibraryDialog;
class PropertiesDialog;
class PackageManager;
class ComicFlowWidget;
class QCheckBox;
class QPushButton;
class TableModel;
@ -50,6 +49,7 @@ class YACReaderLibraryListWidget;
class YACReaderTreeView;
class YACReaderMainToolBar;
class ComicVineDialog;
class ComicsView;
#include "comic_db.h"
using namespace YACReader;
@ -59,7 +59,7 @@ class LibraryWindow : public QMainWindow
Q_OBJECT
private:
YACReaderSideBar * sideBar;
QSplitter * sVertical;
CreateLibraryDialog * createLibraryDialog;
ExportLibraryDialog * exportLibraryDialog;
ImportLibraryDialog * importLibraryDialog;
@ -80,7 +80,6 @@ private:
//YACReaderSortComics * proxySort;
PackageManager * packageManager;
ComicFlowWidget * comicFlow;
QSize slideSizeW;
QSize slideSizeF;
//search filter
@ -91,8 +90,8 @@ private:
QPushButton * clearFoldersFilter;
QCheckBox * includeComicsCheckBox;
//-------------
QWidget *comics;
YACReaderTableView * comicView;
ComicsView * comicsView;
YACReaderTreeView * foldersView;
YACReaderLibraryListWidget * selectedLibrary;
TreeModel * dm;
@ -224,8 +223,6 @@ public:
void loadCovers(const QModelIndex & mi);
void checkEmptyFolder(QStringList * paths = 0);
void reloadCovers();
void centerComicFlow(const QModelIndex & mi);
void updateComicView(int i);
void openComic();
void createLibrary();
void create(QString source,QString dest, QString name);
@ -261,8 +258,6 @@ public:
void setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus);
void setCurrentComicReaded();
void setCurrentComicUnreaded();
void setComicsReaded();
void setComicsUnreaded();
void hideComicFlow(bool hide);
void showExportComicsInfo();
void showImportComicsInfo();

View File

@ -213,9 +213,12 @@ int main( int argc, char ** argv )
YACReader::exitCheck(ret);
//server shutdown
//shutdown
s->stop();
delete s;
localServer->close();
delete localServer;
delete mw;
QsLogging::Logger::destroyInstance();

View File

@ -0,0 +1,288 @@
import QtQuick 2.3
import QtQuick.Controls 1.0
import QtQuick.Controls 1.1
import QtGraphicalEffects 1.0
import comicModel 1.0
Rectangle {
id: main
color: backgroundColor
width: parent.width
height: parent.height
anchors.margins: 0
function selectAll(from,to)
{
for(var i = from+1;i<to;i++)
{
comicsSelectionHelper.selectIndex(i);
}
}
Component {
id: appDelegate
Rectangle
{
id: cell
width: grid.cellWidth
height: grid.cellHeight
color: backgroundColor
MouseArea {
anchors.fill: parent
onClicked: {
comicsSelectionHelper.clear();
comicsSelectionHelper.selectIndex(grid.currentIndex);
}
}
Rectangle {
id: realCell
width: 156; height: 287
color: ((dummyValue || !dummyValue) && comicsSelectionHelper.isSelectedIndex(index)) || grid.currentIndex === index?selectedColor:cellColor;
anchors.horizontalCenter: parent.horizontalCenter
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onDoubleClicked: {
comicsSelectionHelper.clear();
comicsSelectionHelper.selectIndex(index);
grid.currentIndex = index;
comicsSelectionHelper.selectedItem(index);
}
onClicked: {
//grid.currentIndex = index
//comicsSelection.setCurrentIndex(index,0x0002)
var ci = grid.currentIndex;
if(mouse.button == Qt.RightButton || !(mouse.modifiers & Qt.ControlModifier || mouse.modifiers & Qt.ShiftModifier))
{
comicsSelectionHelper.clear();
}
if(mouse.button == Qt.RightButton)
myContextMenu.popup();
if(mouse.modifiers & Qt.ShiftModifier)
if(index < ci)
selectAll(index,ci);
else if (index > ci)
selectAll(ci,index);
mouse.accepted = true;
comicsSelectionHelper.selectIndex(index)
grid.currentIndex = index;
}
}
Menu {
id: myContextMenu
MenuItem { text: "Open containing folder..."; onTriggered: display.setRandomName() }
MenuSeparator{}
MenuItem { text: "Reset comic rating"; onTriggered: model1.removeRows(index, 1) }
MenuSeparator{}
MenuItem { text: "Edit"; onTriggered: model1.removeRows(index, 1) }
MenuItem { text: "Download tags from Comic Vine"; onTriggered: model1.removeRows(index, 1) }
MenuItem { text: "Asign current order to comics"; onTriggered: model1.removeRows(index, 1) }
MenuSeparator{}
MenuItem { text: "Set as read"; onTriggered: model1.removeRows(index, 1) }
MenuItem { text: "Set as unread"; onTriggered: model1.removeRows(index, 1) }
MenuSeparator{}
MenuItem { text: "Delete selected comics"; onTriggered: model1.removeRows(index, 1) }
//MenuItem { text: "Show details"; onTriggered: cell.state = 'Details';
}
}
DropShadow {
anchors.fill: source
horizontalOffset: 0
verticalOffset: 0
radius: 3
samples: 24
color: "#40000000"
transparentBorder: true;
source: realCell;
enabled: dropShadow;
visible: dropShadow;
}
/**/
//cover
Image {
id: coverElement
width: 148
height: 224
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 4}
source: cover_path
fillMode: Image.PreserveAspectCrop
//smooth: true
mipmap: true
//antialiasing: true
asynchronous : true
cache: false //TODO clear cache only when it is neede
}
//mark
Image {
id: mark
width: 23
height: 23
source: read_column&&show_marks?"tick.png":has_been_opened&&show_marks?"reading.png":""
anchors {right: coverElement.right; top: coverElement.top; topMargin: 11; rightMargin: 11}
asynchronous : true
}
//title
Text {
anchors { top: realCell.top; left: realCell.left; leftMargin: 4; rightMargin: 4; topMargin: 234; }
width: 148
maximumLineCount: 2
wrapMode: Text.WordWrap
text: title
elide: Text.ElideRight
color: titleColor
clip: true
font.letterSpacing: 0.5
}
//number
Text {
anchors {bottom: realCell.bottom; left: realCell.left; margins: 4}
text: number?"<b>#</b>"+number:""
color: textColor
font.letterSpacing: 0.5
}
//page icon
Image {
id: pageImage
anchors {bottom: realCell.bottom; right: realCell.right; bottomMargin: 5; rightMargin: 4; leftMargin: 4}
source: "page.png"
}
//numPages
Text {
id: pages
anchors {bottom: realCell.bottom; right: pageImage.left; margins: 4}
text: has_been_opened?current_page+"/"+num_pages:num_pages
color: textColor
font.letterSpacing: 0.5
}
//rating icon
Image {
id: ratingImage
anchors {bottom: realCell.bottom; right: pageImage.left; bottomMargin: 5; rightMargin: Math.floor(pages.width)+12}
source: "star.png"
}
//comic rating
Text {
id: comicRating
anchors {bottom: realCell.bottom; right: ratingImage.left; margins: 4}
text: rating>0?rating:"-"
color: textColor
}
}
}
YACReaderScrollView{
id: scrollView
anchors.fill: parent
anchors.margins: 0
GridView {
id:grid
anchors.fill: parent
cellHeight: 295
highlight: appHighlight
focus: true
model: comicsList
delegate: appDelegate
anchors.topMargin: 20
anchors.bottomMargin: 20
anchors.leftMargin: 10
anchors.rightMargin: 10
pixelAligned: true
//flickDeceleration: -2000
snapMode: GridView.SnapToRow
currentIndex: 0
cacheBuffer: 0
function numCellsPerRow() {
return Math.floor(width / 190);
}
onWidthChanged: {
var numCells = numCellsPerRow();
var rest = width % 190;
if(numCells > 0)
{
cellWidth = Math.floor(width / numCells) ;
//console.log("numCells=",numCells,"rest=",rest,"cellWidth=",cellWidth,"width=",width);
}
}
}
focus: true
Keys.onPressed: {
if (event.modifiers & Qt.ControlModifier || event.modifiers & Qt.ShiftModifier)
return;
var numCells = grid.numCellsPerRow();
var ci
if (event.key === Qt.Key_Right) {
ci = Math.min(grid.currentIndex+1,grid.count);
}
else if (event.key === Qt.Key_Left) {
ci = Math.max(0,grid.currentIndex-1);
}
else if (event.key === Qt.Key_Up) {
ci = Math.max(0,grid.currentIndex-numCells);
}
else if (event.key === Qt.Key_Down) {
ci = Math.min(grid.currentIndex+numCells,grid.count);
}
event.accepted = true;
//var ci = grid.currentIndex;
grid.currentIndex = -1
comicsSelectionHelper.clear();
comicsSelectionHelper.selectIndex(ci);
grid.currentIndex = ci;
}
//}
/*MouseArea {
anchors.fill: parent
onClicked: {
clicked.accepted = false;
console.log("xx");
}
onWheel: {
var newValue = Math.max(0,scrollView.flickableItem.contentY - wheel.angleDelta.y)
scrollView.flickableItem.contentY = newValue
}
}*/
/*ScrollBar {
flickable: grid;
}
PerformanceMeter {
anchors {top: parent.top; left: parent.left; margins: 4}
id: performanceMeter
width: 128
height: 64
enabled: (dummyValue || !dummyValue)
}*/
}
}

View File

@ -0,0 +1,336 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Private 1.0
import QtQuick.Controls.Styles 1.1
/*!
\qmltype ScrollView
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup views
\brief Provides a scrolling view within another Item.
A ScrollView can be used either to replace a \l Flickable or decorate an
existing \l Flickable. Depending on the platform, it will add scroll bars and
a content frame.
Only one Item can be a direct child of the ScrollView and the child is implicitly anchored
to fill the scroll view.
Example:
\code
ScrollView {
Image { source: "largeImage.png" }
}
\endcode
In the previous example the Image item will implicitly get scroll behavior as if it was
used within a \l Flickable. The width and height of the child item will be used to
define the size of the content area.
Example:
\code
ScrollView {
ListView {
...
}
}
\endcode
In this case the content size of the ScrollView will simply mirror that of its contained
\l flickableItem.
You can create a custom appearance for a ScrollView by
assigning a \l {QtQuick.Controls.Styles::ScrollViewStyle}{ScrollViewStyle}.
*/
FocusScope {
id: root
implicitWidth: 240
implicitHeight: 150
/*!
This property tells the ScrollView if it should render
a frame around its content.
The default value is \c false.
*/
property bool frameVisible: false
/*!
This property controls if there should be a highlight
around the frame when the ScrollView has input focus.
The default value is \c false.
\note This property is only applicable on some platforms, such
as Mac OS.
*/
property bool highlightOnFocus: false
/*!
\qmlproperty Item ScrollView::viewport
The viewport determines the current "window" on the contentItem.
In other words, it clips it and the size of the viewport tells you
how much of the content area is visible.
*/
property alias viewport: viewportItem
/*!
\qmlproperty Item ScrollView::flickableItem
The flickableItem of the ScrollView. If the contentItem provided
to the ScrollView is a Flickable, it will be the \l contentItem.
*/
readonly property alias flickableItem: internal.flickableItem
/*!
The contentItem of the ScrollView. This is set by the user.
Note that the definition of contentItem is somewhat different to that
of a Flickable, where the contentItem is implicitly created.
*/
default property Item contentItem
/*! \internal */
property Item __scroller: scroller
/*! \internal */
property alias __wheelAreaScrollSpeed: wheelArea.scrollSpeed
/*! \internal */
property int __scrollBarTopMargin: 0
/*! \internal */
property int __viewTopMargin: 0
/*! \internal */
property alias __horizontalScrollBar: scroller.horizontalScrollBar
/*! \internal */
property alias __verticalScrollBar: scroller.verticalScrollBar
/*! \qmlproperty Component ScrollView::style
The style Component for this control.
\sa {Qt Quick Controls Styles QML Types}
*/
property Component style: Qt.createComponent(Settings.style + "/ScrollViewStyle.qml", root)
/*! \internal */
property Style __style: styleLoader.item
activeFocusOnTab: true
onContentItemChanged: {
//console.log("onContentItemChanged");
if (contentItem.hasOwnProperty("contentY") && // Check if flickable
contentItem.hasOwnProperty("contentHeight")) {
internal.flickableItem = contentItem // "Use content if it is a flickable
internal.flickableItem.parent = viewportItem
} else {
internal.flickableItem = flickableComponent.createObject(viewportItem)
contentItem.parent = internal.flickableItem.contentItem
}
internal.flickableItem.anchors.fill = viewportItem
if (!Settings.hasTouchScreen)
internal.flickableItem.interactive = false
}
children: Item {
id: internal
property Flickable flickableItem
Loader {
id: styleLoader
sourceComponent: style
onStatusChanged: {
if (status === Loader.Error)
console.error("Failed to load Style for", root)
}
property alias __control: root
}
Binding {
target: flickableItem
property: "contentHeight"
when: contentItem !== flickableItem
value: contentItem ? contentItem.height : 0
}
Binding {
target: flickableItem
when: contentItem !== flickableItem
property: "contentWidth"
value: contentItem ? contentItem.width : 0
}
Connections {
target: flickableItem
onContentYChanged: {
//console.log("onContentYChanged2");
scroller.blockUpdates = true
scroller.verticalScrollBar.value = flickableItem.contentY
scroller.blockUpdates = false
}
onContentXChanged: {
//console.log("onContentXChanged2");
scroller.blockUpdates = true
scroller.horizontalScrollBar.value = flickableItem.contentX
scroller.blockUpdates = false
}
}
anchors.fill: parent
Component {
id: flickableComponent
Flickable {}
}
WheelArea {
id: wheelArea
parent: flickableItem
// ### Note this is needed due to broken mousewheel behavior in Flickable.
anchors.fill: parent
property int stepSize: 295
property int acceleration: 40
property int flickThreshold: Settings.dragThreshold
property real speedThreshold: 3
property real ignored: 0.001 // ## flick() does not work with 0 yVelocity
property int maxFlick: 400
property bool horizontalRecursionGuard: false
property bool verticalRecursionGuard: false
horizontalMinimumValue: flickableItem ? flickableItem.originX : 0
horizontalMaximumValue: flickableItem ? flickableItem.originX + flickableItem.contentWidth - viewport.width : 0
verticalMinimumValue: flickableItem ? flickableItem.originY : 0
verticalMaximumValue: flickableItem ? flickableItem.originY + flickableItem.contentHeight - viewport.height + __viewTopMargin : 0
Connections {
target: flickableItem
onContentYChanged: {
//console.log("onContentYChanged");
wheelArea.verticalRecursionGuard = true
wheelArea.verticalValue = flickableItem.contentY
wheelArea.verticalRecursionGuard = false
}
onContentXChanged: {
//console.log("onContentXChanged");
wheelArea.horizontalRecursionGuard = true
wheelArea.horizontalValue = flickableItem.contentX
wheelArea.horizontalRecursionGuard = false
}
}
onVerticalValueChanged: {
if (!verticalRecursionGuard) {
//console.log(verticalDelta);
if (flickableItem.contentY < flickThreshold && verticalDelta > speedThreshold) {
flickableItem.flick(ignored, Math.min(maxFlick, acceleration * verticalDelta))
} else if (flickableItem.contentY > flickableItem.contentHeight
- flickThreshold - viewport.height && verticalDelta < -speedThreshold) {
flickableItem.flick(ignored, Math.max(-maxFlick, acceleration * verticalDelta))
} else {
var absDelta = Math.abs(verticalDelta);
if(verticalDelta < 0)
flickableItem.contentY = verticalValue + Math.min(98,0.93*absDelta+4.5);
else
flickableItem.contentY = verticalValue - Math.min(98,0.93*absDelta+4.5);
}
//TODO: snap to row
}
}
onHorizontalValueChanged: {
if (!horizontalRecursionGuard)
flickableItem.contentX = horizontalValue
}
}
ScrollViewHelper {
id: scroller
anchors.fill: parent
active: wheelArea.active
property bool outerFrame: !frameVisible || !(__style ? __style.__externalScrollBars : 0)
property int scrollBarSpacing: outerFrame ? 0 : (__style ? __style.__scrollBarSpacing : 0)
property int verticalScrollbarOffset: verticalScrollBar.visible && !verticalScrollBar.isTransient ?
verticalScrollBar.width + scrollBarSpacing : 0
property int horizontalScrollbarOffset: horizontalScrollBar.visible && !horizontalScrollBar.isTransient ?
horizontalScrollBar.height + scrollBarSpacing : 0
Loader {
id: frameLoader
sourceComponent: __style ? __style.frame : null
anchors.fill: parent
anchors.rightMargin: scroller.outerFrame ? 0 : scroller.verticalScrollbarOffset
anchors.bottomMargin: scroller.outerFrame ? 0 : scroller.horizontalScrollbarOffset
}
Item {
id: viewportItem
anchors.fill: frameLoader
anchors.topMargin: frameVisible ? __style.padding.top : 0
anchors.leftMargin: frameVisible ? __style.padding.left : 0
anchors.rightMargin: (frameVisible ? __style.padding.right : 0) + (scroller.outerFrame ? scroller.verticalScrollbarOffset : 0)
anchors.bottomMargin: (frameVisible ? __style.padding.bottom : 0) + (scroller.outerFrame ? scroller.horizontalScrollbarOffset : 0)
clip: true
}
}
FocusFrame { visible: highlightOnFocus && root.activeFocus }
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

View File

@ -67,7 +67,12 @@ void Startup::start() {
void Startup::stop() {
qDebug("ServiceHelper: Service has been stopped");
// QCoreApplication destroys all objects that have been created in start().
if(listener!=nullptr)
{
listener->close();
delete listener;
listener = nullptr;
}
}

View File

@ -67,6 +67,11 @@ bool YACReaderLocalServer::isRunning()
return false;
}
void YACReaderLocalServer::close()
{
localServer->close();
}
YACReaderClientConnectionWorker::YACReaderClientConnectionWorker( QLocalSocket *cc)
:QThread(),clientConnection(cc)

View File

@ -21,6 +21,7 @@ public slots:
bool isListening();
void sendResponse();
static bool isRunning();
void close();
private:
//void run();
QLocalServer * localServer;

View File

@ -19,3 +19,11 @@ void YACReader::addSperator(QWidget *w)
separator->setSeparator(true);
w->addAction(separator);
}
QAction * YACReader::createSeparator()
{
QAction * a = new QAction(0);
a->setSeparator(true);
return a;
}

View File

@ -96,6 +96,7 @@ namespace YACReader
QString getSettingsPath();
void addSperator(QWidget * w);
QAction * createSeparator();
}
#endif