added comic vine pagination and sorting volumes by column

This commit is contained in:
Luis Ángel San Martín 2013-11-17 17:53:02 +01:00
parent e3ddde47b3
commit afc787be7b
21 changed files with 301 additions and 42 deletions

View File

@ -17,7 +17,9 @@ HEADERS += \
comic_vine/sort_volume_comics.h \
comic_vine/model/local_comic_list_model.h \
comic_vine/model/volume_comics_model.h \
comic_vine/scraper_scroll_label.h
comic_vine/scraper_scroll_label.h \
comic_vine/scraper_results_paginator.h \
comic_vine/scraper_selector.h
SOURCES += \
comic_vine/comic_vine_dialog.cpp \
@ -37,4 +39,6 @@ SOURCES += \
comic_vine/sort_volume_comics.cpp \
comic_vine/model/local_comic_list_model.cpp \
comic_vine/model/volume_comics_model.cpp \
comic_vine/scraper_scroll_label.cpp
comic_vine/scraper_scroll_label.cpp \
comic_vine/scraper_results_paginator.cpp \
comic_vine/scraper_selector.cpp

View File

@ -19,7 +19,9 @@ static const QString CV_SERIES_DETAIL = CV_WEB_ADDRESS + "/volume/4050-%1/?api_k
//gets info for comics in a volume id %1
static const QString CV_COMICS_INFO = CV_WEB_ADDRESS + "/issues/?api_key=" + CV_API_KEY +
"&format=json&field_list=name,issue_number,id,image&filter=volume:%1";//offset??
"&format=json&field_list=name,issue_number,id,image&filter=volume:%1&offset=%2";//offset??
//"http://www.comicvine.com/api/issues/?api_key=46680bebb358f1de690a5a365e15d325f9649f91&format=json&field_list=name,issue_number,id,image&filter=volume:%1&page=%2
//gets id for comic number %2 in a volume id %1
static const QString CV_COMIC_ID = CV_WEB_ADDRESS + "/issues/?api_key=" + CV_API_KEY +
@ -99,9 +101,9 @@ void ComicVineClient::getSeriesCover(const QString & url)
}
//CV_COMIC_IDS
void ComicVineClient::getVolumeComicsInfo(const QString & idVolume)
void ComicVineClient::getVolumeComicsInfo(const QString & idVolume, int page)
{
HttpWorker * search = new HttpWorker(CV_COMICS_INFO.arg(idVolume));
HttpWorker * search = new HttpWorker(CV_COMICS_INFO.arg(idVolume).arg((page-1)*100)); //page on works for search, using offset instead
connect(search,SIGNAL(dataReady(const QByteArray &)),this,SLOT(processVolumeComicsInfo(const QByteArray &)));
connect(search,SIGNAL(timeout()),this,SIGNAL(timeOut())); //TODO
connect(search,SIGNAL(finished()),search,SLOT(deleteLater()));

View File

@ -24,7 +24,7 @@ public slots:
void search(const QString & query, int page = 1);
void getSeriesDetail(const QString & id);
void getSeriesCover(const QString & url);
void getVolumeComicsInfo(const QString & idVolume);
void getVolumeComicsInfo(const QString & idVolume, int page=1);
QByteArray getComicDetail(const QString & id, bool &outError, bool &outTimeout);
void getComicCover(const QString & url);

View File

@ -106,6 +106,10 @@ void ComicVineDialog::doConnections()
connect(backButton,SIGNAL(clicked()),this,SLOT(goBack()));
connect(searchButton,SIGNAL(clicked()),this,SLOT(search()));
connect(skipButton,SIGNAL(clicked()),this,SLOT(goToNextComic()));
connect(selectVolumeWidget,SIGNAL(loadPage(QString,int)),this,SLOT(searchVolume(QString,int)));
connect(selectComicWidget,SIGNAL(loadPage(QString,int)),this,SLOT(getVolumeComicsInfo(QString,int)));
}
void ComicVineDialog::goNext()
@ -141,18 +145,9 @@ void ComicVineDialog::goNext()
}
}
else if (content->currentWidget() == selectVolumeWidget) {
showLoading(tr("Retrieving volume info..."));
currentVolumeId = selectVolumeWidget->getSelectedVolumeId();
getVolumeComicsInfo(currentVolumeId);
status = GettingVolumeComics;
ComicVineClient * comicVineClient = new ComicVineClient;
if(mode == Volume)
connect(comicVineClient,SIGNAL(volumeComicsInfo(QString)),this,SLOT(showSortVolumeComics(QString)));
else
connect(comicVineClient,SIGNAL(volumeComicsInfo(QString)),this,SLOT(showSelectComic(QString)));
connect(comicVineClient,SIGNAL(timeOut()),this,SLOT(queryTimeOut()));
connect(comicVineClient,SIGNAL(finished()),comicVineClient,SLOT(deleteLater()));
comicVineClient->getVolumeComicsInfo(selectVolumeWidget->getSelectedVolumeId());
} else if (content->currentWidget() == sortVolumeComicsWidget) {
showLoading();
@ -328,7 +323,7 @@ void ComicVineDialog::showSearchVolume()
void ComicVineDialog::showSelectVolume(const QString & json)
{
showSelectVolume();
selectVolumeWidget->load(json);
selectVolumeWidget->load(json,currentVolumeSearchString);
}
void ComicVineDialog::showSelectVolume()
@ -349,7 +344,7 @@ void ComicVineDialog::showSelectComic(const QString &json)
status = SelectingComic;
content->setCurrentWidget(selectComicWidget);
selectComicWidget->load(json);
selectComicWidget->load(json,currentVolumeId);
backButton->setVisible(true);
nextButton->setVisible(true);
@ -662,17 +657,40 @@ void ComicVineDialog::search()
}
}
void ComicVineDialog::searchVolume(const QString &v)
void ComicVineDialog::searchVolume(const QString &v, int page)
{
showLoading(tr("Looking for volume..."));
currentVolumeSearchString = v;
ComicVineClient * comicVineClient = new ComicVineClient;
connect(comicVineClient,SIGNAL(searchResult(QString)),this,SLOT(debugClientResults(QString)));
connect(comicVineClient,SIGNAL(timeOut()),this,SLOT(queryTimeOut()));
connect(comicVineClient,SIGNAL(finished()),comicVineClient,SLOT(deleteLater()));
comicVineClient->search(v);
comicVineClient->search(v,page);
status = SearchingVolume;
}
void ComicVineDialog::getVolumeComicsInfo(const QString &vID, int page)
{
showLoading(tr("Retrieving volume info..."));
status = GettingVolumeComics;
ComicVineClient * comicVineClient = new ComicVineClient;
if(mode == Volume)
connect(comicVineClient,SIGNAL(volumeComicsInfo(QString)),this,SLOT(showSortVolumeComics(QString)));
else
connect(comicVineClient,SIGNAL(volumeComicsInfo(QString)),this,SLOT(showSelectComic(QString)));
connect(comicVineClient,SIGNAL(timeOut()),this,SLOT(queryTimeOut()));
connect(comicVineClient,SIGNAL(finished()),comicVineClient,SLOT(deleteLater()));
QLOG_TRACE() << vID;
comicVineClient->getVolumeComicsInfo(vID,page);
}
void ComicVineDialog::launchSearchVolume()
{
showLoading(tr("Looking for volume..."));

View File

@ -47,7 +47,8 @@ protected slots:
void showSearchVolume();
void showLoading(const QString & message = "");
void search();
void searchVolume(const QString & v);
void searchVolume(const QString & v, int page = 1);
void getVolumeComicsInfo(const QString &vID, int page = 1);
void launchSearchVolume();
void launchSearchComic();
void showSelectVolume(const QString & json);
@ -121,6 +122,9 @@ private:
SelectVolume * selectVolumeWidget;
SelectComic * selectComicWidget;
SortVolumeComics * sortVolumeComicsWidget;
QString currentVolumeSearchString;
QString currentVolumeId;
};
#endif // COMIC_VINE_DIALOG_H

View File

@ -4,7 +4,7 @@
#include <QDebug>
ResponseParser::ResponseParser(QObject *parent) :
QObject(parent),error(false),numResults(-1)
QObject(parent),error(false),numResults(-1),currentPage(-1),totalPages(-1)
{
}
@ -18,6 +18,16 @@ qint32 ResponseParser::getNumResults()
return numResults;
}
qint32 ResponseParser::getCurrentPage()
{
return currentPage;
}
qint32 ResponseParser::getTotalPages()
{
return totalPages;
}
void ResponseParser::loadJSONResponse(const QString &response)
{
QScriptEngine engine;
@ -36,5 +46,16 @@ void ResponseParser::loadJSONResponse(const QString &response)
numResults = sc.property("number_of_total_results").toString().toInt();// sc.property("number_of_total_results").toInt32();
else
qDebug() << sc.property("oops").toString();
int limit = sc.property("limit").toInt32();
int offset = sc.property("offset").toInt32();
int total = sc.property("number_of_total_results").toInt32();
if(limit > 0)
{
totalPages = (total / limit) + (total%limit>0?1:0);
currentPage = (offset / limit) + 1;
}
else
totalPages = currentPage = 1;
}
}

View File

@ -10,6 +10,8 @@ public:
explicit ResponseParser(QObject *parent = 0);
bool responseError();
qint32 getNumResults();
qint32 getCurrentPage();
qint32 getTotalPages();
signals:
public slots:
@ -18,6 +20,8 @@ public slots:
protected:
bool error;
qint32 numResults;
qint32 currentPage;
qint32 totalPages;
};
#endif // RESPONSE_PARSER_H

View File

@ -0,0 +1,75 @@
#include "scraper_results_paginator.h"
#include "response_parser.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QToolButton>
#include <QtScript>
ScraperResultsPaginator::ScraperResultsPaginator(QWidget *parent) :
QWidget(parent),customLabel("items")
{
QHBoxLayout * pagesButtonsLayout = new QHBoxLayout;
QString labelStylesheet = "QLabel {color:white; font-size:12px;font-family:Arial;}";
nextPage = new QToolButton;
nextPage->setStyleSheet("QToolButton {border:none;}");
QPixmap np(":/images/comic_vine/nextPage.png");
nextPage->setIconSize(np.size());
nextPage->setIcon(np);
previousPage = new QToolButton;
previousPage->setStyleSheet("QToolButton {border:none;}");
QPixmap pp(":/images/comic_vine/previousPage.png");
previousPage->setIconSize(pp.size());
previousPage->setIcon(pp);
connect(nextPage,SIGNAL(clicked()),this,SIGNAL(loadNextPage()));
connect(previousPage,SIGNAL(clicked()),this,SIGNAL(loadPreviousPage()));
numElements = new QLabel(tr("Number of volumes found : %1"));
numElements->setStyleSheet(labelStylesheet);
numPages = new QLabel(tr("page %1 of %2"));
numPages->setStyleSheet(labelStylesheet);
pagesButtonsLayout->addSpacing(15);
pagesButtonsLayout->addWidget(numElements);
pagesButtonsLayout->addStretch();
pagesButtonsLayout->addWidget(numPages);
pagesButtonsLayout->addWidget(previousPage);
pagesButtonsLayout->addWidget(nextPage);
setContentsMargins(0,0,0,0);
pagesButtonsLayout->setContentsMargins(0,0,0,0);
setLayout(pagesButtonsLayout);
}
void ScraperResultsPaginator::update(const QString &json)
{
ResponseParser rp;
rp.loadJSONResponse(json);
currentPage = rp.getCurrentPage();
numElements->setText(tr("Number of %1 found : %2").arg(customLabel).arg(rp.getNumResults()));
numPages->setText(tr("page %1 of %2").arg(currentPage).arg(rp.getTotalPages()));
previousPage->setDisabled(currentPage == 1);
nextPage->setDisabled(currentPage == rp.getTotalPages());
numPages->setHidden(rp.getTotalPages()==1);
previousPage->setHidden(rp.getTotalPages()==1);
nextPage->setHidden(rp.getTotalPages()==1);
}
int ScraperResultsPaginator::getCurrentPage()
{
return currentPage;
}
void ScraperResultsPaginator::setCustomLabel(const QString &label)
{
customLabel = label;
}

View File

@ -0,0 +1,34 @@
#ifndef SCRAPER_RESULTS_PAGINATOR_H
#define SCRAPER_RESULTS_PAGINATOR_H
#include <QWidget>
class QToolButton;
class QLabel;
class ScraperResultsPaginator : public QWidget
{
Q_OBJECT
public:
explicit ScraperResultsPaginator(QWidget *parent = 0);
void update(const QString & json);
int getCurrentPage();
void setCustomLabel(const QString & label);
signals:
void loadNextPage();
void loadPreviousPage();
public slots:
private:
QToolButton * nextPage;
QToolButton * previousPage;
QLabel * numElements;
QLabel * numPages;
int currentPage;
QString customLabel;
};
#endif // SCRAPER_RESULTS_PAGINATOR_H

View File

@ -0,0 +1,25 @@
#include "scraper_selector.h"
ScraperSelector::ScraperSelector(QWidget *parent) :
QWidget(parent)
{
paginator = new ScraperResultsPaginator;
connect(paginator,SIGNAL(loadNextPage()),this,SLOT(loadNextPage()));
connect(paginator,SIGNAL(loadPreviousPage()),this,SLOT(loadPreviousPage()));
}
void ScraperSelector::load(const QString &json, const QString &searchString)
{
currentSearchString = searchString;
paginator->update(json);
}
void ScraperSelector::loadNextPage()
{
emit loadPage(currentSearchString,paginator->getCurrentPage()+1);
}
void ScraperSelector::loadPreviousPage()
{
emit loadPage(currentSearchString,paginator->getCurrentPage()-1);
}

View File

@ -0,0 +1,28 @@
#ifndef SCRAPER_SELECTOR_H
#define SCRAPER_SELECTOR_H
#include <QWidget>
#include "scraper_results_paginator.h"
class ScraperSelector : public QWidget
{
Q_OBJECT
public:
explicit ScraperSelector(QWidget *parent = 0);
virtual void load(const QString & json, const QString & searchString);
public slots:
signals:
void loadPage(QString,int);
private slots:
void loadNextPage();
void loadPreviousPage();
protected:
QString currentSearchString;
ScraperResultsPaginator * paginator;
};
#endif // SCRAPER_SELECTOR_H

View File

@ -10,6 +10,8 @@ ScraperTableView::ScraperTableView(QWidget *parent) :
"QTableView::item:selected {outline: 0px; background-color: #555555; }"
"QHeaderView::section:horizontal {background-color:#292929; border-bottom:1px solid #1F1F1F; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #292929, stop: 1 #1F1F1F); border-left:none; border-top:none; padding:4px; color:#ebebeb;}"
"QHeaderView::section:vertical {border-bottom: 1px solid #DFDFDF;border-top: 1px solid #FEFEFE;}"
"QHeaderView::down-arrow {image: url(':/images/comic_vine/downArrow.png');}"
"QHeaderView::up-arrow {image: url(':/images/comic_vine/upArrow.png');}"
"QScrollBar:vertical { border: none; background: #2B2B2B; width: 3px; margin: 0; }"
"QScrollBar:horizontal { border: none; background: #2B2B2B; height: 3px; margin: 0; }"
"QScrollBar::handle:vertical { background: #DDDDDD; width: 7px; min-height: 20px; }"

View File

@ -10,7 +10,7 @@
#include <QtScript>
SelectComic::SelectComic(QWidget *parent)
:QWidget(parent),model(0)
:ScraperSelector(parent),model(0)
{
QString labelStylesheet = "QLabel {color:white; font-size:12px;font-family:Arial;}";
@ -20,8 +20,11 @@ SelectComic::SelectComic(QWidget *parent)
QVBoxLayout * l = new QVBoxLayout;
QWidget * leftWidget = new QWidget;
QVBoxLayout * left = new QVBoxLayout;
QVBoxLayout * right = new QVBoxLayout;
QHBoxLayout * content = new QHBoxLayout;
right->setContentsMargins(0,0,0,0);
//widgets
cover = new QLabel();
cover->setScaledContents(true);
@ -34,6 +37,8 @@ SelectComic::SelectComic(QWidget *parent)
//connections
connect(tableComics,SIGNAL(clicked(QModelIndex)),this,SLOT(loadComicInfo(QModelIndex)));
paginator->setCustomLabel(tr("comics"));
left->addWidget(cover);
left->addWidget(detailLabel,1);
left->addStretch();
@ -42,8 +47,11 @@ SelectComic::SelectComic(QWidget *parent)
left->setContentsMargins(0,0,0,0);
leftWidget->setContentsMargins(0,0,0,0);
right->addWidget(tableComics,0,Qt::AlignRight|Qt::AlignTop);
right->addWidget(paginator);
content->addWidget(leftWidget);
content->addWidget(tableComics,0,Qt::AlignRight|Qt::AlignTop);
content->addLayout(right);
l->addSpacing(15);
l->addWidget(label);
@ -56,7 +64,7 @@ SelectComic::SelectComic(QWidget *parent)
setContentsMargins(0,0,0,0);
}
void SelectComic::load(const QString &json)
void SelectComic::load(const QString &json, const QString & searchString)
{
VolumeComicsModel * tempM = new VolumeComicsModel();
tempM->load(json);
@ -76,6 +84,8 @@ void SelectComic::load(const QString &json)
}
tableComics->resizeColumnToContents(0);
ScraperSelector::load(json,searchString);
}
SelectComic::~SelectComic() {}

View File

@ -1,7 +1,7 @@
#ifndef SELECT_COMIC_H
#define SELECT_COMIC_H
#include <QWidget>
#include "scraper_selector.h"
class QLabel;
class VolumeComicsModel;
@ -10,12 +10,12 @@ class QModelIndex;
class ScraperScrollLabel;
class ScraperTableView;
class SelectComic : public QWidget
class SelectComic : public ScraperSelector
{
Q_OBJECT
public:
SelectComic(QWidget * parent = 0);
void load(const QString & json);
void load(const QString & json, const QString & searchString);
virtual ~SelectComic();
public slots:

View File

@ -8,6 +8,7 @@
#include <QScrollArea>
#include <QDesktopServices>
#include <QHeaderView>
#include <QToolButton>
#include "scraper_tableview.h"
@ -17,9 +18,14 @@
#include "comic_vine_client.h"
#include "scraper_scroll_label.h"
#include "response_parser.h"
#include "scraper_results_paginator.h"
SelectVolume::SelectVolume(QWidget *parent)
:QWidget(parent),model(0)
:ScraperSelector(parent),model(0)
{
proxyModel = new QSortFilterProxyModel;
QString labelStylesheet = "QLabel {color:white; font-size:12px;font-family:Arial;}";
QLabel * label = new QLabel(tr("Please, select the right series for your comic."));
@ -28,8 +34,11 @@ SelectVolume::SelectVolume(QWidget *parent)
QVBoxLayout * l = new QVBoxLayout;
QWidget * leftWidget = new QWidget;
QVBoxLayout * left = new QVBoxLayout;
QVBoxLayout * right = new QVBoxLayout;
QHBoxLayout * content = new QHBoxLayout;
right->setContentsMargins(0,0,0,0);
//widgets
cover = new QLabel();
cover->setScaledContents(true);
@ -39,9 +48,15 @@ SelectVolume::SelectVolume(QWidget *parent)
detailLabel = new ScraperScrollLabel(this);
tableVolumes = new ScraperTableView(this);
tableVolumes->setSortingEnabled(true);
tableVolumes->horizontalHeader()->setSectionsClickable(true);
//tableVolumes->horizontalHeader()->setSortIndicatorShown(false);
connect(tableVolumes->horizontalHeader(),SIGNAL(sectionClicked(int)), tableVolumes, SLOT(sortByColumn(int)));
//connections
connect(tableVolumes,SIGNAL(clicked(QModelIndex)),this,SLOT(loadVolumeInfo(QModelIndex)));
paginator->setCustomLabel(tr("volumes"));
left->addWidget(cover);
left->addWidget(detailLabel,1);
left->addStretch();
@ -50,8 +65,11 @@ SelectVolume::SelectVolume(QWidget *parent)
left->setContentsMargins(0,0,0,0);
leftWidget->setContentsMargins(0,0,0,0);
right->addWidget(tableVolumes,0,Qt::AlignRight|Qt::AlignTop);
right->addWidget(paginator);
content->addWidget(leftWidget);
content->addWidget(tableVolumes,0,Qt::AlignRight|Qt::AlignTop);
content->addLayout(right);
l->addSpacing(15);
l->addWidget(label);
@ -64,12 +82,15 @@ SelectVolume::SelectVolume(QWidget *parent)
setContentsMargins(0,0,0,0);
}
void SelectVolume::load(const QString & json)
void SelectVolume::load(const QString & json, const QString & searchString)
{
VolumesModel * tempM = new VolumesModel();
tempM->load(json);
tableVolumes->setModel(tempM);
//tableVolumes->setModel(tempM);
proxyModel->setSourceModel( tempM );
tableVolumes->setModel(proxyModel);
tableVolumes->sortByColumn(0,Qt::AscendingOrder);
tableVolumes->resizeColumnsToContents();
tableVolumes->setFixedSize(619,341);
@ -82,16 +103,19 @@ void SelectVolume::load(const QString & json)
if(model->rowCount()>0)
{
tableVolumes->selectRow(0);
loadVolumeInfo(model->index(0,0));
loadVolumeInfo(proxyModel->index(0,0));
}
tableVolumes->setColumnWidth(0,350);
ScraperSelector::load(json,searchString);
}
SelectVolume::~SelectVolume() {}
void SelectVolume::loadVolumeInfo(const QModelIndex & mi)
void SelectVolume::loadVolumeInfo(const QModelIndex & omi)
{
QModelIndex mi = proxyModel->mapToSource(omi);
QString coverURL = model->getCoverURL(mi);
QString id = model->getVolumeId(mi);
@ -146,16 +170,17 @@ void SelectVolume::setDescription(const QString & jsonDetail)
QString SelectVolume::getSelectedVolumeId()
{
return model->getVolumeId(tableVolumes->currentIndex());
return model->getVolumeId(proxyModel->mapToSource(tableVolumes->currentIndex()));
}
int SelectVolume::getSelectedVolumeNumIssues()
{
return model->getNumIssues(tableVolumes->currentIndex());
return model->getNumIssues(proxyModel->mapToSource(tableVolumes->currentIndex()));
}
QString SelectVolume::getSelectedVolumePublisher()
{
return model->getPublisher(tableVolumes->currentIndex());
return model->getPublisher(proxyModel->mapToSource(tableVolumes->currentIndex()));
}

View File

@ -1,21 +1,23 @@
#ifndef SELECT_VOLUME_H
#define SELECT_VOLUME_H
#include <QWidget>
#include "scraper_selector.h"
class QLabel;
class VolumesModel;
class QModelIndex;
class QToolButton;
class QSortFilterProxyModel;
class ScraperScrollLabel;
class ScraperTableView;
class SelectVolume : public QWidget
class SelectVolume : public ScraperSelector
{
Q_OBJECT
public:
SelectVolume(QWidget * parent = 0);
void load(const QString & json);
void load(const QString & json, const QString & searchString);
virtual ~SelectVolume();
public slots:
@ -31,6 +33,7 @@ private:
ScraperScrollLabel * detailLabel;
ScraperTableView * tableVolumes;
VolumesModel * model;
QSortFilterProxyModel * proxyModel;
};
#endif // SELECT_VOLUME_H

View File

@ -79,7 +79,7 @@
<file>../images/main_toolbar/divider.png</file>
<file>../images/collapsed_branch_osx.png</file>
<file>../images/expanded_branch_osx.png</file>
<file>../images/folder_macosx.png</file>
<file>../images/folder_macosx.png</file>
<file>../images/libraryIconSelected.png</file>
<file>../images/libraryOptions.png</file>
<file>../images/branch-open.png</file>
@ -94,6 +94,10 @@
<file>../images/comic_vine/radioUnchecked.png</file>
<file>../images/comic_vine/rowDown.png</file>
<file>../images/comic_vine/rowUp.png</file>
<file>../images/comic_vine/previousPage.png</file>
<file>../images/comic_vine/nextPage.png</file>
<file>../images/comic_vine/downArrow.png</file>
<file>../images/comic_vine/upArrow.png</file>
<file>../images/find_folder.png</file>
<!--<file>../images/busy_background.png</file>-->
</qresource>

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B