mirror of
https://github.com/YACReader/yacreader
synced 2026-04-02 02:42:43 -04:00
added yacreader flow optimization, flow animation stops if everything is done
This commit is contained in:
BIN
YACReaderLibrary/YACReaderLibrary.icns
Normal file
BIN
YACReaderLibrary/YACReaderLibrary.icns
Normal file
Binary file not shown.
191
YACReaderLibrary/YACReaderLibrary.pro
Normal file
191
YACReaderLibrary/YACReaderLibrary.pro
Normal file
@ -0,0 +1,191 @@
|
||||
######################################################################
|
||||
# Automatically generated by qmake (2.01a) dom 12. oct 20:47:48 2008
|
||||
######################################################################
|
||||
|
||||
TEMPLATE = app
|
||||
TARGET = YACReaderLibrary
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += .
|
||||
INCLUDEPATH += ../common \
|
||||
./server \
|
||||
./db \
|
||||
../custom_widgets \
|
||||
./comic_vine \
|
||||
./comic_vine/model
|
||||
|
||||
DEFINES += SERVER_RELEASE NOMINMAX
|
||||
|
||||
win32 {
|
||||
|
||||
LIBS += -L../dependencies/poppler/lib -loleaut32 -lole32
|
||||
|
||||
isEqual(QT_MAJOR_VERSION, 5) {
|
||||
LIBS += -lpoppler-qt5
|
||||
INCLUDEPATH += ../dependencies/poppler/include/qt5
|
||||
}
|
||||
else {
|
||||
LIBS += -lpoppler-qt4
|
||||
INCLUDEPATH += ../dependencies/poppler/include/qt4
|
||||
}
|
||||
|
||||
QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL
|
||||
QMAKE_LFLAGS_RELEASE += /LTCG
|
||||
CONFIG -= embed_manifest_exe
|
||||
}
|
||||
|
||||
unix:!macx{
|
||||
|
||||
isEqual(QT_MAJOR_VERSION, 5) {
|
||||
INCLUDEPATH += /usr/include/poppler/qt5
|
||||
LIBS += -L/usr/lib -lpoppler-qt5
|
||||
}
|
||||
else {
|
||||
INCLUDEPATH += /usr/include/poppler/qt4
|
||||
LIBS += -L/usr/lib -lpoppler-qt4
|
||||
}
|
||||
LIBS += -lGLU
|
||||
}
|
||||
|
||||
macx{
|
||||
#INCLUDEPATH += "/Volumes/Mac OS X Lion/usr/X11/include"
|
||||
#isEqual(QT_MAJOR_VERSION, 5) {
|
||||
#INCLUDEPATH += /usr/local/include/poppler/qt5
|
||||
#LIBS += -L/usr/local/lib -lpoppler-qt5
|
||||
#}
|
||||
#else {
|
||||
#INCLUDEPATH += /usr/local/include/poppler/qt4
|
||||
#LIBS += -L/usr/local/lib -lpoppler-qt4
|
||||
#}
|
||||
#QT += macextras
|
||||
|
||||
LIBS += -framework Foundation -framework ApplicationServices
|
||||
|
||||
OBJECTIVE_SOURCES += $$PWD/../common/pdf_comic.mm
|
||||
HEADERS += $$PWD/../common/pdf_comic.h
|
||||
CONFIG += objective_c
|
||||
|
||||
}
|
||||
|
||||
#CONFIG += release
|
||||
CONFIG -= flat
|
||||
QT += sql network opengl script
|
||||
|
||||
# Input
|
||||
HEADERS += comic_flow.h \
|
||||
create_library_dialog.h \
|
||||
library_creator.h \
|
||||
library_window.h \
|
||||
add_library_dialog.h \
|
||||
rename_library_dialog.h \
|
||||
properties_dialog.h \
|
||||
options_dialog.h \
|
||||
export_library_dialog.h \
|
||||
import_library_dialog.h \
|
||||
package_manager.h \
|
||||
bundle_creator.h \
|
||||
export_comics_info_dialog.h \
|
||||
import_comics_info_dialog.h \
|
||||
server_config_dialog.h \
|
||||
comic_flow_widget.h \
|
||||
db_helper.h \
|
||||
./db/data_base_management.h \
|
||||
./db/treeitem.h \
|
||||
./db/treemodel.h \
|
||||
./db/tablemodel.h \
|
||||
./db/tableitem.h \
|
||||
../common/comic_db.h \
|
||||
../common/folder.h \
|
||||
../common/library_item.h \
|
||||
../common/comic.h \
|
||||
../common/bookmarks.h \
|
||||
../common/pictureflow.h \
|
||||
../common/custom_widgets.h \
|
||||
../common/qnaturalsorting.h \
|
||||
../common/yacreader_flow_gl.h \
|
||||
../common/yacreader_global.h \
|
||||
../common/onstart_flow_selection_dialog.h \
|
||||
no_libraries_widget.h \
|
||||
import_widget.h \
|
||||
yacreader_local_server.h \
|
||||
yacreader_main_toolbar.h \
|
||||
comics_remover.h \
|
||||
../common/http_worker.h \
|
||||
yacreader_libraries.h \
|
||||
../common/exit_check.h \
|
||||
|
||||
SOURCES += comic_flow.cpp \
|
||||
create_library_dialog.cpp \
|
||||
library_creator.cpp \
|
||||
library_window.cpp \
|
||||
main.cpp \
|
||||
add_library_dialog.cpp \
|
||||
rename_library_dialog.cpp \
|
||||
properties_dialog.cpp \
|
||||
options_dialog.cpp \
|
||||
export_library_dialog.cpp \
|
||||
import_library_dialog.cpp \
|
||||
package_manager.cpp \
|
||||
bundle_creator.cpp \
|
||||
export_comics_info_dialog.cpp \
|
||||
import_comics_info_dialog.cpp \
|
||||
server_config_dialog.cpp \
|
||||
comic_flow_widget.cpp \
|
||||
db_helper.cpp \
|
||||
./db/data_base_management.cpp \
|
||||
./db/treeitem.cpp \
|
||||
./db/treemodel.cpp \
|
||||
./db/tablemodel.cpp \
|
||||
./db/tableitem.cpp \
|
||||
../common/comic_db.cpp \
|
||||
../common/folder.cpp \
|
||||
../common/library_item.cpp \
|
||||
../common/comic.cpp \
|
||||
../common/bookmarks.cpp \
|
||||
../common/pictureflow.cpp \
|
||||
../common/custom_widgets.cpp \
|
||||
../common/qnaturalsorting.cpp \
|
||||
../common/yacreader_flow_gl.cpp \
|
||||
../common/onstart_flow_selection_dialog.cpp \
|
||||
no_libraries_widget.cpp \
|
||||
import_widget.cpp \
|
||||
yacreader_local_server.cpp \
|
||||
yacreader_main_toolbar.cpp \
|
||||
comics_remover.cpp \
|
||||
../common/http_worker.cpp \
|
||||
../common/yacreader_global.cpp \
|
||||
yacreader_libraries.cpp \
|
||||
../common/exit_check.cpp \
|
||||
|
||||
|
||||
include(./server/server.pri)
|
||||
include(../custom_widgets/custom_widgets_yacreaderlibrary.pri)
|
||||
include(../compressed_archive/wrapper.pri)
|
||||
include(./comic_vine/comic_vine.pri)
|
||||
include(../QsLog/QsLog.pri)
|
||||
|
||||
RESOURCES += images.qrc files.qrc
|
||||
win32:RESOURCES += images_win.qrc
|
||||
unix:!macx:RESOURCES += images_win.qrc
|
||||
macx:RESOURCES += images_osx.qrc
|
||||
|
||||
RC_FILE = icon.rc
|
||||
|
||||
macx {
|
||||
ICON = YACReaderLibrary.icns
|
||||
}
|
||||
|
||||
TRANSLATIONS = yacreaderlibrary_es.ts \
|
||||
yacreaderlibrary_ru.ts \
|
||||
yacreaderlibrary_pt.ts \
|
||||
yacreaderlibrary_fr.ts \
|
||||
yacreaderlibrary_nl.ts \
|
||||
yacreaderlibrary_tr.ts \
|
||||
yacreaderlibrary_source.ts
|
||||
|
||||
isEqual(QT_MAJOR_VERSION, 5) {
|
||||
Release:DESTDIR = ../release5
|
||||
Debug:DESTDIR = ../debug5
|
||||
} else {
|
||||
Release:DESTDIR = ../release
|
||||
Debug:DESTDIR = ../debug
|
||||
}
|
||||
124
YACReaderLibrary/add_library_dialog.cpp
Normal file
124
YACReaderLibrary/add_library_dialog.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
#include "add_library_dialog.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QFileDialog>
|
||||
#include <QGridLayout>
|
||||
|
||||
|
||||
AddLibraryDialog::AddLibraryDialog(QWidget * parent)
|
||||
:QDialog(parent)
|
||||
{
|
||||
setupUI();
|
||||
}
|
||||
|
||||
void AddLibraryDialog::setupUI()
|
||||
{
|
||||
textLabel = new QLabel(tr("Comics folder : "));
|
||||
path = new QLineEdit;
|
||||
textLabel->setBuddy(path);
|
||||
connect(path,SIGNAL(textChanged(QString)),this,SLOT(pathSetted(QString)));
|
||||
|
||||
nameLabel = new QLabel(tr("Library Name : "));
|
||||
nameEdit = new QLineEdit;
|
||||
nameLabel->setBuddy(nameEdit);
|
||||
connect(nameEdit,SIGNAL(textChanged(QString)),this,SLOT(nameSetted(QString)));
|
||||
|
||||
accept = new QPushButton(tr("Add"));
|
||||
accept->setDisabled(true);
|
||||
connect(accept,SIGNAL(clicked()),this,SLOT(add()));
|
||||
|
||||
cancel = new QPushButton(tr("Cancel"));
|
||||
connect(cancel,SIGNAL(clicked()),this,SLOT(close()));
|
||||
|
||||
find = new QPushButton(QIcon(":/images/find_folder.png"),"");
|
||||
connect(find,SIGNAL(clicked()),this,SLOT(findPath()));
|
||||
|
||||
QGridLayout * content = new QGridLayout;
|
||||
|
||||
content->addWidget(nameLabel,0,0);
|
||||
content->addWidget(nameEdit,0,1);
|
||||
|
||||
content->addWidget(textLabel,1,0);
|
||||
content->addWidget(path,1,1);
|
||||
content->addWidget(find,1,2);
|
||||
content->setColumnStretch(2,0);
|
||||
|
||||
QHBoxLayout *bottomLayout = new QHBoxLayout;
|
||||
bottomLayout->addStretch();
|
||||
bottomLayout->addWidget(accept);
|
||||
bottomLayout->addWidget(cancel);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(content);
|
||||
mainLayout->addStretch();
|
||||
mainLayout->addLayout(bottomLayout);
|
||||
|
||||
QHBoxLayout * imgMainLayout = new QHBoxLayout;
|
||||
QLabel * imgLabel = new QLabel(this);
|
||||
QPixmap p(":/images/openLibrary.png");
|
||||
imgLabel->setPixmap(p);
|
||||
imgMainLayout->addWidget(imgLabel);//,0,Qt::AlignTop);
|
||||
imgMainLayout->addLayout(mainLayout);
|
||||
|
||||
setLayout(imgMainLayout);
|
||||
|
||||
setModal(true);
|
||||
setWindowTitle(tr("Add an existing library"));
|
||||
}
|
||||
|
||||
void AddLibraryDialog::add()
|
||||
{
|
||||
//accept->setEnabled(false);
|
||||
emit(addLibrary(QDir::cleanPath(path->text()),nameEdit->text()));
|
||||
}
|
||||
|
||||
void AddLibraryDialog::nameSetted(const QString & text)
|
||||
{
|
||||
if(!text.isEmpty())
|
||||
{
|
||||
if(!path->text().isEmpty())
|
||||
{
|
||||
QFileInfo fi(path->text());
|
||||
if(fi.isDir())
|
||||
accept->setEnabled(true);
|
||||
else
|
||||
accept->setEnabled(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
accept->setEnabled(false);
|
||||
}
|
||||
|
||||
void AddLibraryDialog::pathSetted(const QString & text)
|
||||
{
|
||||
QFileInfo fi(text);
|
||||
if(fi.isDir())
|
||||
{
|
||||
if(!nameEdit->text().isEmpty())
|
||||
accept->setEnabled(true);
|
||||
}
|
||||
else
|
||||
accept->setEnabled(false);
|
||||
}
|
||||
|
||||
void AddLibraryDialog::findPath()
|
||||
{
|
||||
QString s = QFileDialog::getExistingDirectory(0,"Comics directory",".");
|
||||
if(!s.isEmpty())
|
||||
{
|
||||
path->setText(s);
|
||||
if(!nameEdit->text().isEmpty())
|
||||
accept->setEnabled(true);
|
||||
}
|
||||
else
|
||||
accept->setEnabled(false);
|
||||
}
|
||||
|
||||
void AddLibraryDialog::close()
|
||||
{
|
||||
path->clear();
|
||||
nameEdit->clear();
|
||||
accept->setEnabled(false);
|
||||
QDialog::close();
|
||||
}
|
||||
35
YACReaderLibrary/add_library_dialog.h
Normal file
35
YACReaderLibrary/add_library_dialog.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef __ADD_LIBRARY_DIALOG_H
|
||||
#define __ADD_LIBRARY_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QThread>
|
||||
|
||||
class AddLibraryDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AddLibraryDialog(QWidget * parent = 0);
|
||||
private:
|
||||
QLabel * nameLabel;
|
||||
QLabel * textLabel;
|
||||
QLineEdit * path;
|
||||
QLineEdit * nameEdit;
|
||||
QPushButton * find;
|
||||
QPushButton * accept;
|
||||
QPushButton * cancel;
|
||||
void setupUI();
|
||||
public slots:
|
||||
void add();
|
||||
void findPath();
|
||||
void close();
|
||||
void nameSetted(const QString & text);
|
||||
void pathSetted(const QString & text);
|
||||
signals:
|
||||
void addLibrary(QString target, QString name);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
13
YACReaderLibrary/bundle_creator.cpp
Normal file
13
YACReaderLibrary/bundle_creator.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "bundle_creator.h"
|
||||
|
||||
|
||||
BundleCreator::BundleCreator(void)
|
||||
:QObject()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
BundleCreator::~BundleCreator(void)
|
||||
{
|
||||
}
|
||||
14
YACReaderLibrary/bundle_creator.h
Normal file
14
YACReaderLibrary/bundle_creator.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef __BUNDLE_CREATOR_H
|
||||
#define __BUNDLE_CREATOR_H
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class BundleCreator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
BundleCreator(void);
|
||||
~BundleCreator(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
238
YACReaderLibrary/comic_flow.cpp
Normal file
238
YACReaderLibrary/comic_flow.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
#include "comic_flow.h"
|
||||
#include "qnaturalsorting.h"
|
||||
|
||||
#include "yacreader_global.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <QMutex>
|
||||
#include <QImageReader>
|
||||
#include <QTimer>
|
||||
|
||||
ComicFlow::ComicFlow(QWidget* parent,FlowType flowType)
|
||||
:YACReaderFlow(parent,flowType)
|
||||
{
|
||||
updateTimer = new QTimer;
|
||||
connect(updateTimer, SIGNAL(timeout()), this, SLOT(updateImageData()));
|
||||
|
||||
worker = new ImageLoader;
|
||||
connect(this, SIGNAL(centerIndexChanged(int)), this, SLOT(preload()));
|
||||
connect(this, SIGNAL(centerIndexChangedSilent(int)), this, SLOT(preload()));
|
||||
|
||||
setReflectionEffect(PlainReflection);
|
||||
}
|
||||
|
||||
ComicFlow::~ComicFlow()
|
||||
{
|
||||
delete worker;
|
||||
delete updateTimer;
|
||||
}
|
||||
|
||||
void ComicFlow::setImagePaths(const QStringList& paths)
|
||||
{
|
||||
clear();
|
||||
|
||||
//imagePath = path;
|
||||
imageFiles = paths;
|
||||
imagesLoaded.clear();
|
||||
imagesLoaded.fill(false,imageFiles.size());
|
||||
numImagesLoaded = 0;
|
||||
|
||||
imagesSetted.clear();
|
||||
imagesSetted.fill(false,imageFiles.size());
|
||||
|
||||
// populate with empty images
|
||||
QImage img; //TODO remove
|
||||
QString s;
|
||||
for(int i = 0; i < (int)imageFiles.size(); i++)
|
||||
{
|
||||
addSlide(img);
|
||||
s = imageFiles.at(i);
|
||||
s.remove(s.size()-4,4);
|
||||
if(QFileInfo(s+".r").exists())
|
||||
markSlide(i);
|
||||
}
|
||||
|
||||
setCenterIndex(0);
|
||||
worker->reset();
|
||||
preload();
|
||||
}
|
||||
|
||||
void ComicFlow::preload()
|
||||
{
|
||||
if(numImagesLoaded < imagesLoaded.size())
|
||||
updateTimer->start(30); //TODO comprobar rendimiento, originalmente era 70
|
||||
}
|
||||
|
||||
void ComicFlow::updateImageData()
|
||||
{
|
||||
// can't do anything, wait for the next possibility
|
||||
if(worker->busy())
|
||||
return;
|
||||
|
||||
// set image of last one
|
||||
int idx = worker->index();
|
||||
if( idx >= 0 && !worker->result().isNull())
|
||||
{
|
||||
if(!imagesSetted[idx])
|
||||
{
|
||||
setSlide(idx, worker->result());
|
||||
imagesSetted[idx] = true;
|
||||
numImagesLoaded++;
|
||||
imagesLoaded[idx]=true;
|
||||
}
|
||||
}
|
||||
|
||||
// try to load only few images on the left and right side
|
||||
// i.e. all visible ones plus some extra
|
||||
#define COUNT 8
|
||||
int indexes[2*COUNT+1];
|
||||
int center = centerIndex();
|
||||
indexes[0] = center;
|
||||
for(int j = 0; j < COUNT; j++)
|
||||
{
|
||||
indexes[j*2+1] = center+j+1;
|
||||
indexes[j*2+2] = center-j-1;
|
||||
}
|
||||
for(int c = 0; c < 2*COUNT+1; c++)
|
||||
{
|
||||
int i = indexes[c];
|
||||
if((i >= 0) && (i < slideCount()))
|
||||
if(!imagesLoaded[i])//slide(i).isNull())
|
||||
{
|
||||
// schedule thumbnail generation
|
||||
QString fname = imageFiles[i];
|
||||
|
||||
|
||||
worker->generate(i, fname, slideSize());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// no need to generate anything? stop polling...
|
||||
updateTimer->stop();
|
||||
}
|
||||
|
||||
void ComicFlow::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
PictureFlow::keyPressEvent(event);
|
||||
}
|
||||
|
||||
void ComicFlow::wheelEvent(QWheelEvent * event)
|
||||
{
|
||||
if(event->delta()<0)
|
||||
showNext();
|
||||
else
|
||||
showPrevious();
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void ComicFlow::removeSlide(int cover)
|
||||
{
|
||||
worker->lock();
|
||||
|
||||
worker->reset();
|
||||
|
||||
imageFiles.removeAt(cover);
|
||||
if(imagesLoaded[cover])
|
||||
numImagesLoaded--;
|
||||
imagesLoaded.remove(cover);
|
||||
imagesSetted.remove(cover);
|
||||
|
||||
YACReaderFlow::removeSlide(cover);
|
||||
worker->unlock();
|
||||
|
||||
preload();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//ImageLoader
|
||||
//-----------------------------------------------------------------------------
|
||||
static QImage loadImage(const QString& fileName)
|
||||
{
|
||||
QImage image;
|
||||
bool result = image.load(fileName);
|
||||
|
||||
if(!result)
|
||||
return QImage();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
ImageLoader::ImageLoader():
|
||||
QThread(), restart(false), working(false), idx(-1)
|
||||
{
|
||||
}
|
||||
|
||||
ImageLoader::~ImageLoader()
|
||||
{
|
||||
mutex.lock();
|
||||
condition.wakeOne();
|
||||
mutex.unlock();
|
||||
wait();
|
||||
}
|
||||
|
||||
bool ImageLoader::busy() const
|
||||
{
|
||||
return isRunning() ? working : false;
|
||||
}
|
||||
|
||||
void ImageLoader::generate(int index, const QString& fileName, QSize size)
|
||||
{
|
||||
mutex.lock();
|
||||
this->idx = index;
|
||||
this->fileName = fileName;
|
||||
this->size = size;
|
||||
this->img = QImage();
|
||||
mutex.unlock();
|
||||
|
||||
if (!isRunning())
|
||||
start();
|
||||
else
|
||||
{
|
||||
// already running, wake up whenever ready
|
||||
restart = true;
|
||||
condition.wakeOne();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageLoader::lock()
|
||||
{
|
||||
mutex.lock();
|
||||
}
|
||||
|
||||
void ImageLoader::unlock()
|
||||
{
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void ImageLoader::run()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
// copy necessary data
|
||||
mutex.lock();
|
||||
this->working = true;
|
||||
QString fileName = this->fileName;
|
||||
mutex.unlock();
|
||||
|
||||
QImage image = loadImage(fileName);
|
||||
|
||||
// let everyone knows it is ready
|
||||
mutex.lock();
|
||||
this->working = false;
|
||||
this->img = image;
|
||||
mutex.unlock();
|
||||
|
||||
// put to sleep
|
||||
mutex.lock();
|
||||
if (!this->restart)
|
||||
condition.wait(&mutex);
|
||||
restart = false;
|
||||
mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
QImage ImageLoader::result()
|
||||
{
|
||||
return img;
|
||||
}
|
||||
77
YACReaderLibrary/comic_flow.h
Normal file
77
YACReaderLibrary/comic_flow.h
Normal file
@ -0,0 +1,77 @@
|
||||
#ifndef __COMICFLOW_H
|
||||
#define __COMICFLOW_H
|
||||
|
||||
#include "yacreader_flow.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QImage>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include <QString>
|
||||
#include <QWheelEvent>
|
||||
|
||||
class ImageLoader;
|
||||
class ComicFlow : public YACReaderFlow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ComicFlow(QWidget* parent = 0,FlowType flowType = CoverFlowLike);
|
||||
virtual ~ComicFlow();
|
||||
|
||||
void setImagePaths(const QStringList& paths);
|
||||
//bool eventFilter(QObject *target, QEvent *event);
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void removeSlide(int cover);
|
||||
|
||||
private slots:
|
||||
void preload();
|
||||
void updateImageData();
|
||||
|
||||
private:
|
||||
//QString imagePath;
|
||||
QStringList imageFiles;
|
||||
QVector<bool> imagesLoaded;
|
||||
QVector<bool> imagesSetted;
|
||||
int numImagesLoaded;
|
||||
QTimer* updateTimer;
|
||||
ImageLoader* worker;
|
||||
virtual void wheelEvent(QWheelEvent * event);
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Source code of ImageLoader class was modified from http://code.google.com/p/photoflow/
|
||||
//------------------------------------------------------------------------------
|
||||
class ImageLoader : public QThread
|
||||
{
|
||||
public:
|
||||
ImageLoader();
|
||||
~ImageLoader();
|
||||
// returns FALSE if worker is still busy and can't take the task
|
||||
bool busy() const;
|
||||
void generate(int index, const QString& fileName, QSize size);
|
||||
void reset(){idx = -1;};
|
||||
int index() const { return idx; };
|
||||
void lock();
|
||||
void unlock();
|
||||
QImage result();
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
private:
|
||||
QMutex mutex;
|
||||
QWaitCondition condition;
|
||||
|
||||
bool restart;
|
||||
bool working;
|
||||
int idx;
|
||||
QString fileName;
|
||||
QSize size;
|
||||
QImage img;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
345
YACReaderLibrary/comic_flow_widget.cpp
Normal file
345
YACReaderLibrary/comic_flow_widget.cpp
Normal file
@ -0,0 +1,345 @@
|
||||
#include "comic_flow_widget.h"
|
||||
|
||||
ComicFlowWidget::ComicFlowWidget(QWidget * parent)
|
||||
:QWidget(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ComicFlowWidgetSW::ComicFlowWidgetSW(QWidget * parent)
|
||||
:ComicFlowWidget(parent)
|
||||
{
|
||||
flow = new ComicFlow(parent);
|
||||
|
||||
connect(flow,SIGNAL(centerIndexChanged(int)),this,SIGNAL(centerIndexChanged(int)));
|
||||
connect(flow,SIGNAL(selected(unsigned int)),this,SIGNAL(selected(unsigned int)));
|
||||
|
||||
QVBoxLayout * l = new QVBoxLayout;
|
||||
l->addWidget(flow);
|
||||
setLayout(l);
|
||||
|
||||
//TODO eleminar "padding"
|
||||
QPalette Pal(palette());
|
||||
// set black background
|
||||
Pal.setColor(QPalette::Background, Qt::black);
|
||||
setAutoFillBackground(true);
|
||||
setPalette(Pal);
|
||||
|
||||
//config
|
||||
QMatrix m;
|
||||
m.rotate(-90);
|
||||
m.scale(-1,1);
|
||||
QImage image(":/images/setRead.png");
|
||||
QImage imageTransformed = image.transformed(m,Qt::SmoothTransformation);
|
||||
setMarkImage(imageTransformed);
|
||||
}
|
||||
|
||||
QSize ComicFlowWidgetSW::minimumSizeHint() const
|
||||
{
|
||||
return flow->minimumSizeHint();
|
||||
}
|
||||
QSize ComicFlowWidgetSW::sizeHint() const
|
||||
{
|
||||
return flow->sizeHint();
|
||||
}
|
||||
|
||||
void ComicFlowWidgetSW::setShowMarks(bool value)
|
||||
{
|
||||
flow->setShowMarks(value);
|
||||
}
|
||||
void ComicFlowWidgetSW::setMarks(QVector<YACReaderComicReadStatus> marks)
|
||||
{
|
||||
flow->setMarks(marks);
|
||||
}
|
||||
void ComicFlowWidgetSW::setMarkImage(QImage & image)
|
||||
{
|
||||
flow->setMarkImage(image);
|
||||
}
|
||||
void ComicFlowWidgetSW::markSlide(int index, YACReaderComicReadStatus status)
|
||||
{
|
||||
flow->markSlide(index,status);
|
||||
}
|
||||
void ComicFlowWidgetSW::unmarkSlide(int index)
|
||||
{
|
||||
flow->unmarkSlide(index);
|
||||
}
|
||||
void ComicFlowWidgetSW::setSlideSize(QSize size)
|
||||
{
|
||||
flow->setSlideSize(size);
|
||||
}
|
||||
void ComicFlowWidgetSW::clear()
|
||||
{
|
||||
flow->clear();
|
||||
}
|
||||
void ComicFlowWidgetSW::setImagePaths(QStringList paths)
|
||||
{
|
||||
flow->setImagePaths(paths);
|
||||
}
|
||||
void ComicFlowWidgetSW::setCenterIndex(int index)
|
||||
{
|
||||
flow->setCenterIndex(index);
|
||||
}
|
||||
void ComicFlowWidgetSW::showSlide(int index)
|
||||
{
|
||||
flow->showSlide(index);
|
||||
}
|
||||
int ComicFlowWidgetSW::centerIndex()
|
||||
{
|
||||
return flow->centerIndex();
|
||||
}
|
||||
void ComicFlowWidgetSW::updateMarks()
|
||||
{
|
||||
flow->updateMarks();
|
||||
}
|
||||
void ComicFlowWidgetSW::setFlowType(FlowType flowType)
|
||||
{
|
||||
flow->setFlowType(flowType);
|
||||
}
|
||||
void ComicFlowWidgetSW::render()
|
||||
{
|
||||
flow->render();
|
||||
}
|
||||
void ComicFlowWidgetSW::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
flow->keyPressEvent(event);
|
||||
}
|
||||
void ComicFlowWidgetSW::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
flow->paintEvent(event);
|
||||
}
|
||||
void ComicFlowWidgetSW::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
flow->mousePressEvent(event);
|
||||
}
|
||||
void ComicFlowWidgetSW::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
flow->resizeEvent(event);
|
||||
}
|
||||
void ComicFlowWidgetSW::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
{
|
||||
flow->mouseDoubleClickEvent(event);
|
||||
}
|
||||
void ComicFlowWidgetSW::updateConfig(QSettings * settings)
|
||||
{
|
||||
switch (settings->value(FLOW_TYPE_SW).toInt())
|
||||
{
|
||||
case CoverFlowLike:
|
||||
flow->setFlowType(CoverFlowLike);
|
||||
return;
|
||||
case Strip:
|
||||
flow->setFlowType(Strip);
|
||||
return;
|
||||
case StripOverlapped:
|
||||
flow->setFlowType(StripOverlapped);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ComicFlowWidgetSW::remove(int cover)
|
||||
{
|
||||
flow->removeSlide(cover);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
///OpenGL ComicFlow
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ComicFlowWidgetGL::ComicFlowWidgetGL(QWidget * parent)
|
||||
:ComicFlowWidget(parent)
|
||||
{
|
||||
flow = new YACReaderComicFlowGL(parent);
|
||||
|
||||
connect(flow,SIGNAL(centerIndexChanged(int)),this,SIGNAL(centerIndexChanged(int)));
|
||||
connect(flow,SIGNAL(selected(unsigned int)),this,SIGNAL(selected(unsigned int)));
|
||||
|
||||
QVBoxLayout * l = new QVBoxLayout;
|
||||
l->addWidget(flow);
|
||||
l->setContentsMargins(0,0,0,0);
|
||||
setLayout(l);
|
||||
|
||||
//TODO eleminar "padding"
|
||||
QPalette Pal(palette());
|
||||
// set black background
|
||||
Pal.setColor(QPalette::Background, Qt::black);
|
||||
setAutoFillBackground(true);
|
||||
setPalette(Pal);
|
||||
}
|
||||
|
||||
QSize ComicFlowWidgetGL::minimumSizeHint() const
|
||||
{
|
||||
return flow->minimumSizeHint();
|
||||
}
|
||||
QSize ComicFlowWidgetGL::sizeHint() const
|
||||
{
|
||||
return flow->sizeHint();
|
||||
}
|
||||
|
||||
void ComicFlowWidgetGL::setShowMarks(bool value)
|
||||
{
|
||||
flow->setShowMarks(value);
|
||||
}
|
||||
void ComicFlowWidgetGL::setMarks(QVector<YACReaderComicReadStatus> marks)
|
||||
{
|
||||
flow->setMarks(marks);
|
||||
}
|
||||
void ComicFlowWidgetGL::setMarkImage(QImage & image)
|
||||
{
|
||||
flow->setMarkImage(image);
|
||||
}
|
||||
void ComicFlowWidgetGL::markSlide(int index, YACReaderComicReadStatus status)
|
||||
{
|
||||
flow->markSlide(index,status);
|
||||
}
|
||||
void ComicFlowWidgetGL::unmarkSlide(int index)
|
||||
{
|
||||
flow->unmarkSlide(index);
|
||||
}
|
||||
void ComicFlowWidgetGL::setSlideSize(QSize size)
|
||||
{
|
||||
flow->setSlideSize(size);
|
||||
}
|
||||
void ComicFlowWidgetGL::clear()
|
||||
{
|
||||
flow->clear();
|
||||
}
|
||||
void ComicFlowWidgetGL::setImagePaths(QStringList paths)
|
||||
{
|
||||
flow->setImagePaths(paths);
|
||||
}
|
||||
void ComicFlowWidgetGL::setCenterIndex(int index)
|
||||
{
|
||||
flow->setCenterIndex(index);
|
||||
}
|
||||
void ComicFlowWidgetGL::showSlide(int index)
|
||||
{
|
||||
flow->showSlide(index);
|
||||
}
|
||||
int ComicFlowWidgetGL::centerIndex()
|
||||
{
|
||||
return flow->centerIndex();
|
||||
}
|
||||
void ComicFlowWidgetGL::updateMarks()
|
||||
{
|
||||
flow->updateMarks();
|
||||
}
|
||||
void ComicFlowWidgetGL::setFlowType(FlowType flowType)
|
||||
{
|
||||
if(flowType == CoverFlowLike)
|
||||
flow->setPreset(presetYACReaderFlowClassicConfig);
|
||||
else if(flowType == Strip)
|
||||
flow->setPreset(presetYACReaderFlowStripeConfig);
|
||||
else if(flowType == StripOverlapped)
|
||||
flow->setPreset(presetYACReaderFlowOverlappedStripeConfig);
|
||||
else
|
||||
flow->setPreset(defaultYACReaderFlowConfig);
|
||||
}
|
||||
void ComicFlowWidgetGL::render()
|
||||
{
|
||||
flow->render();
|
||||
}
|
||||
void ComicFlowWidgetGL::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
flow->keyPressEvent(event);
|
||||
}
|
||||
void ComicFlowWidgetGL::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
//flow->paintEvent(event);
|
||||
ComicFlowWidget::paintEvent(event);
|
||||
}
|
||||
void ComicFlowWidgetGL::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
flow->mousePressEvent(event);
|
||||
}
|
||||
void ComicFlowWidgetGL::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
flow->resizeGL(event->size().width(),event->size().height());
|
||||
}
|
||||
void ComicFlowWidgetGL::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
{
|
||||
flow->mouseDoubleClickEvent(event);
|
||||
}
|
||||
|
||||
void ComicFlowWidgetGL::updateConfig(QSettings * settings)
|
||||
{
|
||||
Performance performance = medium;
|
||||
|
||||
switch (settings->value(PERFORMANCE).toInt())
|
||||
{
|
||||
case 0:
|
||||
performance = low;
|
||||
break;
|
||||
case 1:
|
||||
performance = medium;
|
||||
break;
|
||||
case 2:
|
||||
performance = high;
|
||||
break;
|
||||
case 3:
|
||||
performance = ultraHigh;
|
||||
break;
|
||||
}
|
||||
|
||||
flow->setPerformance(performance);
|
||||
if(!settings->contains(V_SYNC))
|
||||
flow->useVSync(false);
|
||||
else
|
||||
flow->useVSync(settings->value(V_SYNC).toBool());
|
||||
|
||||
switch (settings->value(FLOW_TYPE_GL).toInt())
|
||||
{
|
||||
case 0:
|
||||
flow->setPreset(presetYACReaderFlowClassicConfig);
|
||||
return;
|
||||
case 1:
|
||||
flow->setPreset(presetYACReaderFlowStripeConfig);
|
||||
return;
|
||||
case 2:
|
||||
flow->setPreset(presetYACReaderFlowOverlappedStripeConfig);
|
||||
return;
|
||||
case 3:
|
||||
flow->setPreset(defaultYACReaderFlowConfig);
|
||||
return;
|
||||
case 4:
|
||||
flow->setPreset(pressetYACReaderFlowDownConfig);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//custom config
|
||||
|
||||
flow->setCF_RX(settings->value(X_ROTATION).toInt());
|
||||
flow->setCF_Y(settings->value(Y_POSITION).toInt());
|
||||
flow->setX_Distance(settings->value(COVER_DISTANCE).toInt());
|
||||
flow->setCenter_Distance(settings->value(CENTRAL_DISTANCE).toInt());
|
||||
flow->setCF_Z(settings->value(ZOOM_LEVEL).toInt());
|
||||
flow->setY_Distance(settings->value(Y_COVER_OFFSET).toInt());
|
||||
flow->setZ_Distance(settings->value(Z_COVER_OFFSET).toInt());
|
||||
flow->setRotation(settings->value(COVER_ROTATION).toInt());
|
||||
flow->setFadeOutDist(settings->value(FADE_OUT_DIST).toInt());
|
||||
flow->setLightStrenght(settings->value(LIGHT_STRENGTH).toInt());
|
||||
flow->setMaxAngle(settings->value(MAX_ANGLE).toInt());
|
||||
|
||||
/* flow->setVisibility(settings->value("visibilityDistance").toInt());
|
||||
flow->setLightStrenght(settings->value("lightStrength").toInt())*/;
|
||||
|
||||
}
|
||||
|
||||
void ComicFlowWidgetGL::remove(int cover)
|
||||
{
|
||||
flow->remove(cover);
|
||||
}
|
||||
|
||||
//void ComicFlowWidgetGL::setCF_RX(int value){ flow->setCF_RX(value);}
|
||||
//void ComicFlowWidgetGL::setCF_RY(int value){ flow->setCF_RY(value);}
|
||||
//void ComicFlowWidgetGL::setCF_RZ(int value){ flow->setCF_RZ(value);}
|
||||
//void ComicFlowWidgetGL::setZoom(int zoom){ flow->setZoom(zoom);}
|
||||
//void ComicFlowWidgetGL::setRotation(int angle){ flow->setRotation(angle);}
|
||||
//void ComicFlowWidgetGL::setX_Distance(int distance){ flow->setX_Distance(distance);}
|
||||
//void ComicFlowWidgetGL::setCenter_Distance(int distance){ flow->setCenter_Distance(distance);}
|
||||
//void ComicFlowWidgetGL::setZ_Distance(int distance){ flow->setZ_Distance(distance);}
|
||||
//void ComicFlowWidgetGL::setCF_Y(int value){ flow->setCF_Y(value);}
|
||||
//void ComicFlowWidgetGL::setY_Distance(int value){ flow->setY_Distance(value);}
|
||||
//void ComicFlowWidgetGL::setPreset(const Preset & p){ flow->setPreset(p);}
|
||||
128
YACReaderLibrary/comic_flow_widget.h
Normal file
128
YACReaderLibrary/comic_flow_widget.h
Normal file
@ -0,0 +1,128 @@
|
||||
#ifndef __COMIC_FLOW_WIDGET_H
|
||||
#define __COMIC_FLOW_WIDGET_H
|
||||
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "pictureflow.h"
|
||||
#include "comic_flow.h"
|
||||
#include "yacreader_flow_gl.h"
|
||||
|
||||
class ComicFlowWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ComicFlowWidget(QWidget * paret = 0);
|
||||
|
||||
public slots:
|
||||
virtual void setShowMarks(bool value) = 0;
|
||||
virtual void setMarks(QVector<YACReaderComicReadStatus> marks) = 0;
|
||||
virtual void setMarkImage(QImage & image) = 0;
|
||||
virtual void markSlide(int index, YACReaderComicReadStatus status) = 0;
|
||||
virtual void unmarkSlide(int index) = 0;
|
||||
virtual void setSlideSize(QSize size) = 0;
|
||||
virtual void clear() = 0;
|
||||
virtual void setImagePaths(QStringList paths) = 0;
|
||||
virtual void setCenterIndex(int index) = 0;
|
||||
virtual void showSlide(int index) = 0;
|
||||
virtual int centerIndex() = 0;
|
||||
virtual void updateMarks() = 0;
|
||||
virtual void setFlowType(FlowType flowType) = 0;
|
||||
virtual void render() = 0;
|
||||
virtual void updateConfig(QSettings * settings) = 0;
|
||||
virtual void remove(int cover) = 0;
|
||||
signals:
|
||||
void centerIndexChanged(int);
|
||||
void selected(unsigned int);
|
||||
};
|
||||
|
||||
|
||||
class ComicFlowWidgetSW : public ComicFlowWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
ComicFlow * flow;
|
||||
public:
|
||||
ComicFlowWidgetSW(QWidget * parent = 0);
|
||||
|
||||
void setShowMarks(bool value);
|
||||
void setMarks(QVector<YACReaderComicReadStatus> marks);
|
||||
void setMarkImage(QImage & image);
|
||||
void markSlide(int index, YACReaderComicReadStatus status);
|
||||
void unmarkSlide(int index);
|
||||
void setSlideSize(QSize size);
|
||||
void clear();
|
||||
void setImagePaths(QStringList paths);
|
||||
void setCenterIndex(int index);
|
||||
void showSlide(int index);
|
||||
int centerIndex();
|
||||
void updateMarks();
|
||||
void setFlowType(FlowType flowType);
|
||||
void render();
|
||||
void updateConfig(QSettings * settings);
|
||||
void remove(int cover);
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
void mouseDoubleClickEvent(QMouseEvent* event);
|
||||
QSize minimumSizeHint() const;
|
||||
QSize sizeHint() const;
|
||||
QSize slideSizeW;
|
||||
QSize slideSizeF;
|
||||
};
|
||||
|
||||
class ComicFlowWidgetGL : public ComicFlowWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
YACReaderComicFlowGL * flow;
|
||||
public:
|
||||
ComicFlowWidgetGL(QWidget * parent = 0);
|
||||
|
||||
void setShowMarks(bool value);
|
||||
void setMarks(QVector<YACReaderComicReadStatus> marks);
|
||||
void setMarkImage(QImage & image);
|
||||
void markSlide(int index, YACReaderComicReadStatus status);
|
||||
void unmarkSlide(int index);
|
||||
void setSlideSize(QSize size);
|
||||
void clear();
|
||||
void setImagePaths(QStringList paths);
|
||||
void setCenterIndex(int index);
|
||||
void showSlide(int index);
|
||||
int centerIndex();
|
||||
void updateMarks();
|
||||
void setFlowType(FlowType flowType);
|
||||
void render();
|
||||
void updateConfig(QSettings * settings);
|
||||
void remove(int cover);
|
||||
//public slots:
|
||||
// void setCF_RX(int value);
|
||||
// //the Y Rotation of the Coverflow
|
||||
// void setCF_RY(int value);
|
||||
// //the Z Rotation of the Coverflow
|
||||
// void setCF_RZ(int value);
|
||||
// //perspective
|
||||
// void setZoom(int zoom);
|
||||
// void setRotation(int angle);
|
||||
// //sets the distance between the covers
|
||||
// void setX_Distance(int distance);
|
||||
// //sets the distance between the centered and the non centered covers
|
||||
// void setCenter_Distance(int distance);
|
||||
// //sets the pushback amount
|
||||
// void setZ_Distance(int distance);
|
||||
// void setCF_Y(int value);
|
||||
// void setY_Distance(int value);
|
||||
// void setPreset(const Preset & p);
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
void mouseDoubleClickEvent(QMouseEvent* event);
|
||||
QSize minimumSizeHint() const;
|
||||
QSize sizeHint() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
44
YACReaderLibrary/comic_vine/comic_vine.pri
Normal file
44
YACReaderLibrary/comic_vine/comic_vine.pri
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
HEADERS += \
|
||||
comic_vine/comic_vine_dialog.h \
|
||||
comic_vine/comic_vine_client.h \
|
||||
comic_vine/scraper_lineedit.h \
|
||||
comic_vine/title_header.h \
|
||||
comic_vine/series_question.h \
|
||||
comic_vine/search_single_comic.h \
|
||||
comic_vine/search_volume.h \
|
||||
comic_vine/select_comic.h \
|
||||
comic_vine/select_volume.h \
|
||||
comic_vine/model/volumes_model.h \
|
||||
comic_vine/model/comics_model.h \
|
||||
comic_vine/model/json_model.h \
|
||||
comic_vine/model/response_parser.h \
|
||||
comic_vine/scraper_tableview.h \
|
||||
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_results_paginator.h \
|
||||
comic_vine/scraper_selector.h
|
||||
|
||||
SOURCES += \
|
||||
comic_vine/comic_vine_dialog.cpp \
|
||||
comic_vine/comic_vine_client.cpp \
|
||||
comic_vine/scraper_lineedit.cpp \
|
||||
comic_vine/title_header.cpp \
|
||||
comic_vine/series_question.cpp \
|
||||
comic_vine/search_single_comic.cpp \
|
||||
comic_vine/search_volume.cpp \
|
||||
comic_vine/select_comic.cpp \
|
||||
comic_vine/select_volume.cpp \
|
||||
comic_vine/model/volumes_model.cpp \
|
||||
comic_vine/model/comics_model.cpp \
|
||||
comic_vine/model/json_model.cpp \
|
||||
comic_vine/model/response_parser.cpp \
|
||||
comic_vine/scraper_tableview.cpp \
|
||||
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_results_paginator.cpp \
|
||||
comic_vine/scraper_selector.cpp
|
||||
164
YACReaderLibrary/comic_vine/comic_vine_client.cpp
Normal file
164
YACReaderLibrary/comic_vine/comic_vine_client.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
#include "comic_vine_client.h"
|
||||
|
||||
//this is the API key used by YACReader to access Comic Vine
|
||||
//please, do not use it in your own software, get one for free at Comic Vine
|
||||
static const QString CV_API_KEY = "46680bebb358f1de690a5a365e15d325f9649f91";
|
||||
|
||||
static const QString CV_WEB_ADDRESS = "http://www.comicvine.com/api";
|
||||
|
||||
//gets any volumen containing any comic matching 'query'
|
||||
static const QString CV_SEARCH = CV_WEB_ADDRESS + "/search/?api_key=" + CV_API_KEY +
|
||||
"&format=json&limit=100&resources=volume"
|
||||
"&field_list=name,start_year,publisher,id,image,count_of_issues,deck"
|
||||
"&sort=name:asc"
|
||||
"&query=%1&page=%2";
|
||||
//http://www.comicvine.com/api/search/?api_key=46680bebb358f1de690a5a365e15d325f9649f91&format=json&limit=100&resources=volume&field_list=name,start_year,publisher,id,image,count_of_issues,deck&query=superman
|
||||
|
||||
//gets the detail for a volume %1
|
||||
static const QString CV_SERIES_DETAIL = CV_WEB_ADDRESS + "/volume/4050-%1/?api_key=" + CV_API_KEY +
|
||||
"&format=json&field_list=name,start_year,publisher,image,count_of_issues,id,description";
|
||||
|
||||
//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"
|
||||
"&sort=cover_date:asc" //sorting by cover_date, because comic vine doesn't use natural sorting (issue_number -> 1 10 11 ... 100 2 20 21....)
|
||||
"&offset=%2";
|
||||
|
||||
//"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 +
|
||||
"&format=json&field_list=name,issue_number,id,image"
|
||||
"&filter=volume:%1,issue_number:%2";
|
||||
//gets comic detail
|
||||
static const QString CV_COMIC_DETAIL = CV_WEB_ADDRESS + "/issue/4000-%1/?api_key=" + CV_API_KEY + "&format=json";
|
||||
//http://www.comicvine.com/api/issue/4000-%1/?api_key=46680bebb358f1de690a5a365e15d325f9649f91&format=json
|
||||
|
||||
//gets comic cover URL
|
||||
static const QString CV_COVER_URL = CV_WEB_ADDRESS + "/issue/4000-%1/?api_key=" + CV_API_KEY + "&format=json&field_list=image";
|
||||
|
||||
//gets comics matching name %1 and number %2
|
||||
//http://comicvine.com/api/issues/?api_key=46680bebb358f1de690a5a365e15d325f9649f91&limit=20&filter=name:super,issue_number:15
|
||||
|
||||
ComicVineClient::ComicVineClient(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//CV_SEARCH
|
||||
void ComicVineClient::search(const QString & query, int page)
|
||||
{
|
||||
HttpWorker * search = new HttpWorker(CV_SEARCH.arg(query).arg(page));
|
||||
connect(search,SIGNAL(dataReady(const QByteArray &)),this,SLOT(proccessVolumesSearchData(const QByteArray &)));
|
||||
connect(search,SIGNAL(timeout()),this,SIGNAL(timeOut()));
|
||||
connect(search,SIGNAL(finished()),search,SLOT(deleteLater()));
|
||||
search->get();
|
||||
}
|
||||
//CV_SEARCH result
|
||||
void ComicVineClient::proccessVolumesSearchData(const QByteArray & data)
|
||||
{
|
||||
QString json(data);
|
||||
emit searchResult(json);
|
||||
emit finished();
|
||||
}
|
||||
|
||||
void ComicVineClient::proccessSeriesDetailData(const QByteArray &data)
|
||||
{
|
||||
QString json(data);
|
||||
emit seriesDetail(json);
|
||||
emit finished();
|
||||
}
|
||||
|
||||
void ComicVineClient::processVolumeComicsInfo(const QByteArray &data)
|
||||
{
|
||||
QString json(data);
|
||||
emit volumeComicsInfo(json);
|
||||
emit finished();
|
||||
}
|
||||
|
||||
void ComicVineClient::proccessComicDetailData(const QByteArray &data)
|
||||
{
|
||||
QString json(data);
|
||||
emit comicDetail(json);
|
||||
emit finished();
|
||||
}
|
||||
|
||||
//CV_SERIES_DETAIL
|
||||
void ComicVineClient::getSeriesDetail(const QString & id)
|
||||
{
|
||||
HttpWorker * search = new HttpWorker(CV_SERIES_DETAIL.arg(id));
|
||||
connect(search,SIGNAL(dataReady(const QByteArray &)),this,SLOT(proccessSeriesDetailData(const QByteArray &)));
|
||||
connect(search,SIGNAL(timeout()),this,SIGNAL(timeOut()));
|
||||
connect(search,SIGNAL(finished()),search,SLOT(deleteLater()));
|
||||
search->get();
|
||||
}
|
||||
|
||||
void ComicVineClient::getSeriesCover(const QString & url)
|
||||
{
|
||||
HttpWorker * search = new HttpWorker(url);
|
||||
connect(search,SIGNAL(dataReady(const QByteArray &)),this,SIGNAL(seriesCover(const QByteArray &)));
|
||||
connect(search,SIGNAL(timeout()),this,SIGNAL(timeOut())); //TODO
|
||||
connect(search,SIGNAL(finished()),search,SLOT(deleteLater()));
|
||||
search->get();
|
||||
}
|
||||
|
||||
//CV_COMIC_IDS
|
||||
void ComicVineClient::getVolumeComicsInfo(const QString & idVolume, int page)
|
||||
{
|
||||
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()));
|
||||
search->get();
|
||||
}
|
||||
|
||||
//CV_COMIC_ID
|
||||
void ComicVineClient::getComicId(const QString & id, int comicNumber)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//CV_COMIC_DETAIL
|
||||
QByteArray ComicVineClient::getComicDetail(const QString & id, bool & outError, bool & outTimeout)
|
||||
{
|
||||
HttpWorker * search = new HttpWorker(CV_COMIC_DETAIL.arg(id));
|
||||
|
||||
//connect(search,SIGNAL(dataReady(const QByteArray &)),this,SLOT(proccessComicDetailData(const QByteArray &)));
|
||||
//connect(search,SIGNAL(timeout()),this,SIGNAL(timeOut()));
|
||||
//connect(search,SIGNAL(finished()),search,SLOT(deleteLater()));
|
||||
search->get();
|
||||
search->wait();
|
||||
outError = !(search->wasValid());
|
||||
outTimeout = search->wasTimeout();
|
||||
QByteArray result = search->getResult();
|
||||
delete search;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//CV_COMIC_DETAIL
|
||||
void ComicVineClient::getComicDetailAsync(const QString & id)
|
||||
{
|
||||
HttpWorker * search = new HttpWorker(CV_COMIC_DETAIL.arg(id));
|
||||
|
||||
connect(search,SIGNAL(dataReady(const QByteArray &)),this,SLOT(proccessComicDetailData(const QByteArray &)));
|
||||
connect(search,SIGNAL(timeout()),this,SIGNAL(timeOut()));
|
||||
connect(search,SIGNAL(finished()),search,SLOT(deleteLater()));
|
||||
search->get();
|
||||
}
|
||||
|
||||
void ComicVineClient::getComicCover(const QString &url)
|
||||
{
|
||||
HttpWorker * search = new HttpWorker(url);
|
||||
connect(search,SIGNAL(dataReady(const QByteArray &)),this,SIGNAL(comicCover(QByteArray)));
|
||||
connect(search,SIGNAL(timeout()),this,SIGNAL(timeOut())); //TODO
|
||||
connect(search,SIGNAL(finished()),search,SLOT(deleteLater()));
|
||||
search->get();
|
||||
}
|
||||
|
||||
//CV_COVER_DETAIL
|
||||
void ComicVineClient::getCoverURL(const QString & id)
|
||||
{
|
||||
|
||||
}
|
||||
41
YACReaderLibrary/comic_vine/comic_vine_client.h
Normal file
41
YACReaderLibrary/comic_vine/comic_vine_client.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef COMIC_VINE_CLIENT_H
|
||||
#define COMIC_VINE_CLIENT_H
|
||||
|
||||
#include "http_worker.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class ComicVineClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ComicVineClient(QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
void searchResult(QString);
|
||||
void seriesDetail(QString);//JSON
|
||||
void comicDetail(QString);//JSON
|
||||
void seriesCover(const QByteArray &);
|
||||
void comicCover(const QByteArray &);
|
||||
void volumeComicsInfo(QString);
|
||||
void timeOut();
|
||||
void finished();
|
||||
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, int page=1);
|
||||
QByteArray getComicDetail(const QString & id, bool &outError, bool &outTimeout);
|
||||
void getComicCover(const QString & url);
|
||||
|
||||
void getComicId(const QString & id, int comicNumber);
|
||||
void getCoverURL(const QString & id);
|
||||
void getComicDetailAsync(const QString &id);
|
||||
protected slots:
|
||||
void proccessVolumesSearchData(const QByteArray & data);
|
||||
void proccessSeriesDetailData(const QByteArray & data);
|
||||
void processVolumeComicsInfo(const QByteArray & data);
|
||||
void proccessComicDetailData(const QByteArray & data);
|
||||
|
||||
};
|
||||
#endif // COMIC_VINE_CLIENT_H
|
||||
722
YACReaderLibrary/comic_vine/comic_vine_dialog.cpp
Normal file
722
YACReaderLibrary/comic_vine/comic_vine_dialog.cpp
Normal file
@ -0,0 +1,722 @@
|
||||
#include "comic_vine_dialog.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QStackedWidget>
|
||||
#include <QRadioButton>
|
||||
#include <QMessageBox>
|
||||
#include <QTableView>
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include <QtConcurrent/QtConcurrentRun>
|
||||
#else
|
||||
#include <QtConcurrentRun>
|
||||
#endif
|
||||
#include <QSqlDatabase>
|
||||
#include <QtScript>
|
||||
#include "data_base_management.h"
|
||||
|
||||
#include "yacreader_busy_widget.h"
|
||||
#include "comic_vine_client.h"
|
||||
#include "scraper_lineedit.h"
|
||||
#include "title_header.h"
|
||||
#include "series_question.h"
|
||||
#include "search_single_comic.h"
|
||||
#include "search_volume.h"
|
||||
#include "select_comic.h"
|
||||
#include "select_volume.h"
|
||||
#include "sort_volume_comics.h"
|
||||
#include "db_helper.h"
|
||||
#include "response_parser.h"
|
||||
|
||||
#include "QsLog.h"
|
||||
|
||||
|
||||
|
||||
ComicVineDialog::ComicVineDialog(QWidget *parent) :
|
||||
QDialog(parent)
|
||||
{
|
||||
doLayout();
|
||||
doStackedWidgets();
|
||||
doConnections();
|
||||
}
|
||||
|
||||
void ComicVineDialog::doLayout()
|
||||
{
|
||||
setStyleSheet(""
|
||||
"QDialog {background-color: #404040; }"
|
||||
"");
|
||||
|
||||
QString dialogButtonsStyleSheet = "QPushButton {border: 1px solid #242424; background: #2e2e2e; color:white; padding: 5px 26px 5px 26px; font-size:12px;font-family:Arial; font-weight:bold;}";
|
||||
|
||||
skipButton = new QPushButton(tr("skip"));
|
||||
backButton = new QPushButton(tr("back"));
|
||||
nextButton = new QPushButton(tr("next"));
|
||||
searchButton = new QPushButton(tr("search"));
|
||||
closeButton = new QPushButton(tr("close"));
|
||||
|
||||
skipButton->setStyleSheet(dialogButtonsStyleSheet);
|
||||
backButton->setStyleSheet(dialogButtonsStyleSheet);
|
||||
nextButton->setStyleSheet(dialogButtonsStyleSheet);
|
||||
searchButton->setStyleSheet(dialogButtonsStyleSheet);
|
||||
closeButton->setStyleSheet(dialogButtonsStyleSheet);
|
||||
|
||||
content = new QStackedWidget(this);
|
||||
|
||||
QVBoxLayout * mainLayout = new QVBoxLayout;
|
||||
|
||||
QHBoxLayout * buttonLayout = new QHBoxLayout;
|
||||
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(skipButton);
|
||||
buttonLayout->addWidget(backButton);
|
||||
buttonLayout->addWidget(nextButton);
|
||||
buttonLayout->addWidget(searchButton);
|
||||
buttonLayout->addWidget(closeButton);
|
||||
buttonLayout->setContentsMargins(0,0,0,0);
|
||||
|
||||
mainLayout->addWidget(titleHeader = new TitleHeader);
|
||||
mainLayout->addWidget(content);
|
||||
mainLayout->addStretch();
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
|
||||
mainLayout->setContentsMargins(26,16,26,11);
|
||||
|
||||
setLayout(mainLayout);
|
||||
setFixedSize(872,529);
|
||||
|
||||
setWindowTitle("Comic Vine Scraper (beta)");
|
||||
}
|
||||
|
||||
void ComicVineDialog::doStackedWidgets()
|
||||
{
|
||||
doLoading();
|
||||
content->addWidget(seriesQuestionWidget = new SeriesQuestion);
|
||||
content->addWidget(searchSingleComicWidget = new SearchSingleComic);
|
||||
content->addWidget(searchVolumeWidget = new SearchVolume);
|
||||
content->addWidget(selectVolumeWidget = new SelectVolume);
|
||||
content->addWidget(selectComicWidget = new SelectComic);
|
||||
content->addWidget(sortVolumeComicsWidget = new SortVolumeComics);
|
||||
}
|
||||
|
||||
void ComicVineDialog::doConnections()
|
||||
{
|
||||
connect(closeButton,SIGNAL(clicked()),this,SLOT(close()));
|
||||
connect(nextButton,SIGNAL(clicked()),this,SLOT(goNext()));
|
||||
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)));
|
||||
connect(sortVolumeComicsWidget,SIGNAL(loadPage(QString,int)),this,SLOT(getVolumeComicsInfo(QString,int)));
|
||||
}
|
||||
|
||||
void ComicVineDialog::goNext()
|
||||
{
|
||||
//
|
||||
if(content->currentWidget() == seriesQuestionWidget)
|
||||
{
|
||||
if(seriesQuestionWidget->getYes())
|
||||
{
|
||||
QString volumeSearchString = comics[0].getParentFolderName();
|
||||
mode = Volume;
|
||||
|
||||
if(volumeSearchString.isEmpty())
|
||||
showSearchVolume();
|
||||
else
|
||||
{
|
||||
status = AutoSearching;
|
||||
showLoading(tr("Looking for volume..."));
|
||||
searchVolume(volumeSearchString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = AutoSearching;
|
||||
mode = SingleComicInList;
|
||||
ComicDB comic = comics[currentIndex];
|
||||
QString title = comic.getTitleOrFileName();
|
||||
titleHeader->setSubTitle(tr("comic %1 of %2 - %3").arg(currentIndex+1).arg(comics.length()).arg(title));
|
||||
|
||||
showLoading(tr("Looking for volume..."));
|
||||
searchVolume(title);
|
||||
}
|
||||
}
|
||||
else if (content->currentWidget() == selectVolumeWidget) {
|
||||
currentVolumeId = selectVolumeWidget->getSelectedVolumeId();
|
||||
getVolumeComicsInfo(currentVolumeId);
|
||||
|
||||
} else if (content->currentWidget() == sortVolumeComicsWidget) {
|
||||
showLoading();
|
||||
|
||||
//ComicDB-ComicVineID
|
||||
QList<QPair<ComicDB,QString> > matchingInfo = sortVolumeComicsWidget->getMatchingInfo();
|
||||
int count = selectVolumeWidget->getSelectedVolumeNumIssues();
|
||||
QString publisher = selectVolumeWidget->getSelectedVolumePublisher();
|
||||
QtConcurrent::run(this, &ComicVineDialog::getComicsInfo,matchingInfo,count,publisher);
|
||||
} else if (content->currentWidget() == selectComicWidget)
|
||||
{
|
||||
showLoading();
|
||||
QString comicId = selectComicWidget->getSelectedComicId();
|
||||
int count = selectVolumeWidget->getSelectedVolumeNumIssues();
|
||||
QString publisher = selectVolumeWidget->getSelectedVolumePublisher();
|
||||
QtConcurrent::run(this, &ComicVineDialog::getComicInfo,comicId,count,publisher);
|
||||
}
|
||||
}
|
||||
|
||||
void ComicVineDialog::goBack()
|
||||
{
|
||||
switch (status) {
|
||||
case SelectingSeries:
|
||||
if(mode == Volume)
|
||||
showSearchVolume();
|
||||
else
|
||||
showSearchSingleComic();
|
||||
break;
|
||||
case SortingComics:
|
||||
showSelectVolume();
|
||||
break;
|
||||
case SelectingComic:
|
||||
if(mode == SingleComic)
|
||||
showSelectVolume();
|
||||
break;
|
||||
case AutoSearching:
|
||||
if(mode == Volume)
|
||||
showSearchVolume();
|
||||
else
|
||||
showSearchSingleComic();
|
||||
default:
|
||||
if(mode == Volume)
|
||||
showSearchVolume();
|
||||
else
|
||||
showSearchSingleComic();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ComicVineDialog::setComics(const QList<ComicDB> & comics)
|
||||
{
|
||||
this->comics = comics;
|
||||
}
|
||||
|
||||
void ComicVineDialog::show()
|
||||
{
|
||||
QDialog::show();
|
||||
|
||||
currentIndex = 0;
|
||||
|
||||
seriesQuestionWidget->setYes(true);
|
||||
searchSingleComicWidget->clean();
|
||||
searchVolumeWidget->clean();
|
||||
|
||||
if(comics.length() == 1)
|
||||
{
|
||||
status = AutoSearching;
|
||||
mode = SingleComic;
|
||||
|
||||
ComicDB singleComic = comics[0];
|
||||
QString title = singleComic.getTitleOrFileName();
|
||||
titleHeader->setSubTitle(title);
|
||||
showLoading(tr("Looking for volume..."));
|
||||
|
||||
searchVolume(singleComic.getParentFolderName());
|
||||
QLOG_TRACE() << singleComic.getParentFolderName();
|
||||
}else if(comics.length()>1)
|
||||
{
|
||||
titleHeader->setSubTitle(tr("%1 comics selected").arg(comics.length()));
|
||||
showSeriesQuestion();
|
||||
}
|
||||
}
|
||||
|
||||
void ComicVineDialog::doLoading()
|
||||
{
|
||||
QWidget * w = new QWidget;
|
||||
QVBoxLayout * l = new QVBoxLayout;
|
||||
|
||||
YACReaderBusyWidget * bw = new YACReaderBusyWidget;
|
||||
loadingMessage = new QLabel;
|
||||
|
||||
loadingMessage->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}");
|
||||
|
||||
l->addStretch();
|
||||
l->addWidget(bw,0,Qt::AlignHCenter);
|
||||
l->addStretch();
|
||||
l->addWidget(loadingMessage);
|
||||
|
||||
|
||||
l->setContentsMargins(0,0,0,0);
|
||||
w->setLayout(l);
|
||||
w->setContentsMargins(0,0,0,0);
|
||||
|
||||
content->addWidget(w);
|
||||
}
|
||||
|
||||
void ComicVineDialog::debugClientResults(const QString & string)
|
||||
{
|
||||
ResponseParser p;
|
||||
p.loadJSONResponse(string);
|
||||
//QMessageBox::information(0,"Result", QString("Number of results : %1").arg(p.getNumResults()));
|
||||
if(p.responseError())
|
||||
{
|
||||
QMessageBox::critical(0,tr("Error connecting to ComicVine"), tr("unknown error"));
|
||||
goBack();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case SingleComic: case SingleComicInList:
|
||||
if(p.getNumResults() == 0)
|
||||
showSearchSingleComic();
|
||||
else
|
||||
if(status == SearchingVolume)
|
||||
showSelectVolume(string);
|
||||
else
|
||||
showSelectComic(string);
|
||||
break;
|
||||
case Volume:
|
||||
if(p.getNumResults() == 0)
|
||||
showSearchVolume();
|
||||
else
|
||||
showSelectVolume(string);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ComicVineDialog::showSeriesQuestion()
|
||||
{
|
||||
status = AskingForInfo;
|
||||
content->setCurrentWidget(seriesQuestionWidget);
|
||||
backButton->setHidden(true);
|
||||
skipButton->setHidden(true);
|
||||
nextButton->setVisible(true);
|
||||
searchButton->setHidden(true);
|
||||
closeButton->setVisible(true);
|
||||
|
||||
if(mode == SingleComicInList)
|
||||
skipButton->setVisible(true);
|
||||
else
|
||||
skipButton->setHidden(true);
|
||||
}
|
||||
|
||||
void ComicVineDialog::showSearchSingleComic()
|
||||
{
|
||||
status = AskingForInfo;
|
||||
content->setCurrentWidget(searchSingleComicWidget);
|
||||
backButton->setHidden(true);
|
||||
skipButton->setHidden(true);
|
||||
nextButton->setHidden(true);
|
||||
searchButton->setVisible(true);
|
||||
closeButton->setVisible(true);
|
||||
|
||||
if(mode == SingleComicInList)
|
||||
skipButton->setVisible(true);
|
||||
else
|
||||
skipButton->setHidden(true);
|
||||
}
|
||||
|
||||
void ComicVineDialog::showSearchVolume()
|
||||
{
|
||||
status = AskingForInfo;
|
||||
content->setCurrentWidget(searchVolumeWidget);
|
||||
backButton->setHidden(true);
|
||||
nextButton->setHidden(true);
|
||||
searchButton->setVisible(true);
|
||||
closeButton->setVisible(true);
|
||||
toggleSkipButton();
|
||||
}
|
||||
|
||||
void ComicVineDialog::showSelectVolume(const QString & json)
|
||||
{
|
||||
showSelectVolume();
|
||||
selectVolumeWidget->load(json,currentVolumeSearchString);
|
||||
}
|
||||
|
||||
void ComicVineDialog::showSelectVolume()
|
||||
{
|
||||
status = SelectingSeries;
|
||||
|
||||
content->setCurrentWidget(selectVolumeWidget);
|
||||
|
||||
backButton->setVisible(true);
|
||||
nextButton->setVisible(true);
|
||||
searchButton->setHidden(true);
|
||||
closeButton->setVisible(true);
|
||||
toggleSkipButton();
|
||||
}
|
||||
|
||||
void ComicVineDialog::showSelectComic(const QString &json)
|
||||
{
|
||||
status = SelectingComic;
|
||||
|
||||
content->setCurrentWidget(selectComicWidget);
|
||||
selectComicWidget->load(json,currentVolumeId);
|
||||
|
||||
backButton->setVisible(true);
|
||||
nextButton->setVisible(true);
|
||||
searchButton->setHidden(true);
|
||||
closeButton->setVisible(true);
|
||||
toggleSkipButton();
|
||||
}
|
||||
|
||||
void ComicVineDialog::showSortVolumeComics(const QString &json)
|
||||
{
|
||||
status = SortingComics;
|
||||
|
||||
content->setCurrentWidget(sortVolumeComicsWidget);
|
||||
|
||||
sortVolumeComicsWidget->setData(comics, json, currentVolumeId);
|
||||
|
||||
backButton->setVisible(true);
|
||||
nextButton->setVisible(true);
|
||||
searchButton->setHidden(true);
|
||||
closeButton->setVisible(true);
|
||||
toggleSkipButton();
|
||||
}
|
||||
|
||||
void ComicVineDialog::queryTimeOut()
|
||||
{
|
||||
QMessageBox::warning(this,"Comic Vine error", "Time out connecting to Comic Vine");
|
||||
|
||||
switch (status) {
|
||||
case AutoSearching:
|
||||
if(mode == Volume)
|
||||
showSearchVolume();
|
||||
else
|
||||
showSearchSingleComic();
|
||||
break;
|
||||
case SearchingVolume:
|
||||
if(mode == Volume)
|
||||
showSearchVolume();
|
||||
else
|
||||
showSearchSingleComic();
|
||||
break;
|
||||
case SearchingSingleComic:
|
||||
showSearchSingleComic();
|
||||
break;
|
||||
case GettingVolumeComics:
|
||||
showSelectVolume();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ComicVineDialog::getComicsInfo(QList<QPair<ComicDB, QString> > & matchingInfo, int count,const QString & publisher)
|
||||
{
|
||||
QPair<ComicDB, QString> p;
|
||||
QList<ComicDB> comics;
|
||||
foreach (p, matchingInfo) {
|
||||
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()));
|
||||
bool error;
|
||||
bool timeout;
|
||||
QByteArray result = comicVineClient->getComicDetail(p.second,error,timeout); //TODO check timeOut or Connection error
|
||||
if(error || timeout)
|
||||
continue; //TODO
|
||||
ComicDB comic = parseComicInfo(p.first,result,count,publisher);//TODO check result error
|
||||
comic.info.comicVineID = p.second;
|
||||
comics.push_back(comic);
|
||||
|
||||
setLoadingMessage(tr("Retrieving tags for : %1").arg(p.first.getFileName()));
|
||||
}
|
||||
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
|
||||
db.open();
|
||||
db.transaction();
|
||||
foreach(ComicDB comic, comics)
|
||||
{
|
||||
DBHelper::update(&(comic.info),db);
|
||||
}
|
||||
db.commit();
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(databasePath);
|
||||
|
||||
close();
|
||||
emit accepted();
|
||||
}
|
||||
|
||||
void ComicVineDialog::getComicInfo(const QString &comicId, int count, const QString &publisher)
|
||||
{
|
||||
|
||||
ComicVineClient * comicVineClient = new ComicVineClient;
|
||||
bool error;
|
||||
bool timeout;
|
||||
QByteArray result = comicVineClient->getComicDetail(comicId,error,timeout); //TODO check timeOut or Connection error
|
||||
if(error || timeout)
|
||||
{
|
||||
//TODO
|
||||
if(mode == SingleComic || currentIndex == (comics.count()-1))
|
||||
{
|
||||
close();
|
||||
emit accepted();
|
||||
} else
|
||||
{
|
||||
goToNextComic();
|
||||
}
|
||||
}
|
||||
|
||||
ComicDB comic = parseComicInfo(comics[currentIndex],result,count,publisher); //TODO check result error
|
||||
comic.info.comicVineID = comicId;
|
||||
setLoadingMessage(tr("Retrieving tags for : %1").arg(comics[currentIndex].getFileName()));
|
||||
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
|
||||
db.open();
|
||||
db.transaction();
|
||||
|
||||
DBHelper::update(&(comic.info),db);
|
||||
|
||||
db.commit();
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(databasePath);
|
||||
|
||||
if(mode == SingleComic || currentIndex == (comics.count()-1))
|
||||
{
|
||||
close();
|
||||
emit accepted();
|
||||
} else
|
||||
{
|
||||
goToNextComic();
|
||||
}
|
||||
}
|
||||
|
||||
ComicDB ComicVineDialog::parseComicInfo(ComicDB & comic, const QString & json, int count, const QString & publisher)
|
||||
{
|
||||
QScriptEngine engine;
|
||||
QScriptValue sc;
|
||||
sc = engine.evaluate("(" + json + ")");
|
||||
|
||||
if (!sc.property("error").isValid() && sc.property("error").toString() != "OK")
|
||||
{
|
||||
qDebug("Error detected");
|
||||
}
|
||||
else
|
||||
{
|
||||
int numResults = sc.property("number_of_total_results").toString().toInt(); //fix to weird behaviour using hasNext
|
||||
|
||||
if(numResults > 0)
|
||||
{
|
||||
QScriptValue result = sc.property("results");
|
||||
|
||||
QString title = result.property("name").toString();
|
||||
|
||||
QString number = result.property("issue_number").toString();
|
||||
//QString count; //get from select volume
|
||||
|
||||
|
||||
QString volume = result.property("volume").property("name").toString();
|
||||
QString storyArc; //story_arc
|
||||
QString arcNumber; //??
|
||||
QString arcCount; //count_of_issue_appearances -> NO
|
||||
|
||||
QString genere; //no
|
||||
|
||||
QMap<QString,QString> authors = getAuthors(result.property("person_credits"));
|
||||
|
||||
QString writer = QStringList(authors.values("writer")).join("\n");
|
||||
QString penciller = QStringList(authors.values("penciller")).join("\n");
|
||||
QString inker = QStringList(authors.values("inker")).join("\n");
|
||||
QString colorist = QStringList(authors.values("colorist")).join("\n");
|
||||
QString letterer = QStringList(authors.values("letterer")).join("\n");
|
||||
QString coverArtist = QStringList(authors.values("cover")).join("\n");
|
||||
|
||||
QString date = result.property("cover_date").toString();
|
||||
|
||||
//QString publisher; //get from select volume
|
||||
QString format; //no
|
||||
bool color; //no
|
||||
QString ageRating; //no
|
||||
|
||||
QString synopsis = result.property("description").toString().remove(QRegExp("<[^>]*>")); //description
|
||||
QString characters = getCharacters(result.property("character_credits"));
|
||||
|
||||
comic.info.title = title;
|
||||
|
||||
comic.info.number = number;
|
||||
comic.info.count = count;
|
||||
|
||||
comic.info.writer = writer;
|
||||
comic.info.penciller = penciller;
|
||||
comic.info.inker = inker;
|
||||
comic.info.colorist = colorist;
|
||||
comic.info.letterer = letterer;
|
||||
comic.info.coverArtist = coverArtist;
|
||||
|
||||
QStringList tempList = date.split("-");
|
||||
std::reverse(tempList.begin(),tempList.end());
|
||||
comic.info.date = tempList.join("/");
|
||||
comic.info.volume = volume;
|
||||
|
||||
comic.info.publisher = publisher;
|
||||
|
||||
comic.info.synopsis = synopsis;
|
||||
comic.info.characters = characters;
|
||||
}
|
||||
}
|
||||
return comic;
|
||||
}
|
||||
|
||||
QString ComicVineDialog::getCharacters(const QScriptValue &json_characters)
|
||||
{
|
||||
QString characters;
|
||||
|
||||
QScriptValueIterator it(json_characters);
|
||||
QScriptValue resultsValue;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
if(it.flags() & QScriptValue::SkipInEnumeration)
|
||||
continue;
|
||||
resultsValue = it.value();
|
||||
|
||||
characters += resultsValue.property("name").toString() + "\n";
|
||||
}
|
||||
|
||||
return characters;
|
||||
}
|
||||
|
||||
QMap<QString, QString> ComicVineDialog::getAuthors(const QScriptValue &json_authors)
|
||||
{
|
||||
QMap<QString, QString> authors;
|
||||
|
||||
QScriptValueIterator it(json_authors);
|
||||
QScriptValue resultsValue;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
if(it.flags() & QScriptValue::SkipInEnumeration)
|
||||
continue;
|
||||
resultsValue = it.value();
|
||||
|
||||
QString authorName = resultsValue.property("name").toString();
|
||||
|
||||
QStringList roles = resultsValue.property("role").toString().split(",");
|
||||
foreach(QString role, roles)
|
||||
{
|
||||
if(role.trimmed() == "writer")
|
||||
authors.insertMulti("writer",authorName);
|
||||
else if(role.trimmed() == "inker")
|
||||
authors.insertMulti("inker",authorName);
|
||||
else if(role.trimmed() == "penciler" || role.trimmed() == "penciller")
|
||||
authors.insertMulti("penciller",authorName);
|
||||
else if(role.trimmed() == "colorist")
|
||||
authors.insertMulti("colorist",authorName);
|
||||
else if(role.trimmed() == "letterer")
|
||||
authors.insertMulti("letterer",authorName);
|
||||
else if(role.trimmed() == "cover")
|
||||
authors.insertMulti("cover",authorName);
|
||||
}
|
||||
}
|
||||
|
||||
return authors;
|
||||
}
|
||||
|
||||
void ComicVineDialog::toggleSkipButton()
|
||||
{
|
||||
if (mode == SingleComicInList)
|
||||
skipButton->setVisible(true);
|
||||
else
|
||||
skipButton->setHidden(true);
|
||||
}
|
||||
|
||||
void ComicVineDialog::goToNextComic()
|
||||
{
|
||||
if(mode == SingleComic || currentIndex == (comics.count()-1))
|
||||
{
|
||||
close();
|
||||
emit accepted();
|
||||
return;
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
|
||||
showSearchSingleComic();
|
||||
|
||||
ComicDB comic = comics[currentIndex];
|
||||
QString title = comic.getTitleOrFileName();
|
||||
titleHeader->setSubTitle(tr("comic %1 of %2 - %3").arg(currentIndex+1).arg(comics.length()).arg(title));
|
||||
}
|
||||
|
||||
void ComicVineDialog::showLoading(const QString &message)
|
||||
{
|
||||
content->setCurrentIndex(0);
|
||||
loadingMessage->setText(message);
|
||||
backButton->setHidden(true);
|
||||
skipButton->setHidden(true);
|
||||
nextButton->setHidden(true);
|
||||
searchButton->setHidden(true);
|
||||
closeButton->setVisible(true);
|
||||
}
|
||||
|
||||
void ComicVineDialog::setLoadingMessage(const QString &message)
|
||||
{
|
||||
loadingMessage->setText(message);
|
||||
}
|
||||
|
||||
void ComicVineDialog::search()
|
||||
{
|
||||
switch (mode) {
|
||||
case Volume:
|
||||
launchSearchVolume();
|
||||
break;
|
||||
default:
|
||||
launchSearchComic();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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,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..."));
|
||||
//TODO: check if volume info is empty.
|
||||
searchVolume(searchVolumeWidget->getVolumeInfo());
|
||||
}
|
||||
|
||||
void ComicVineDialog::launchSearchComic()
|
||||
{
|
||||
showLoading(tr("Looking for comic..."));
|
||||
|
||||
QString volumeInfo = searchSingleComicWidget->getVolumeInfo();
|
||||
//QString comicInfo = searchSingleComicWidget->getComicInfo();
|
||||
//int comicNumber = searchSingleComicWidget->getComicNumber();
|
||||
|
||||
//if(comicInfo.isEmpty() && comicNumber == -1)
|
||||
searchVolume(volumeInfo);
|
||||
}
|
||||
|
||||
130
YACReaderLibrary/comic_vine/comic_vine_dialog.h
Normal file
130
YACReaderLibrary/comic_vine/comic_vine_dialog.h
Normal file
@ -0,0 +1,130 @@
|
||||
#ifndef COMIC_VINE_DIALOG_H
|
||||
#define COMIC_VINE_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "comic_db.h"
|
||||
|
||||
class QPushButton;
|
||||
class QStackedWidget;
|
||||
class QLabel;
|
||||
class QRadioButton;
|
||||
class ComicVineClient;
|
||||
class QTableView;
|
||||
class TitleHeader;
|
||||
class SeriesQuestion;
|
||||
class SearchSingleComic;
|
||||
class SearchVolume;
|
||||
class SelectComic;
|
||||
class SelectVolume;
|
||||
class SortVolumeComics;
|
||||
class QScriptValue;
|
||||
|
||||
//TODO this should use a QStateMachine
|
||||
//----------------------------------------
|
||||
class ComicVineDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ComicVineDialog(QWidget *parent = 0);
|
||||
QString databasePath;
|
||||
QString basePath;
|
||||
void setComics(const QList<ComicDB> & comics);
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void show();
|
||||
|
||||
protected slots:
|
||||
void goNext();
|
||||
void goBack();
|
||||
void debugClientResults(const QString & string);
|
||||
//show widget methods
|
||||
void showSeriesQuestion();
|
||||
void showSearchSingleComic();
|
||||
void showSearchVolume();
|
||||
void showLoading(const QString & message = "");
|
||||
void search();
|
||||
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);
|
||||
void showSelectVolume();
|
||||
void showSelectComic(const QString & json);
|
||||
void showSortVolumeComics(const QString & json);
|
||||
void queryTimeOut();
|
||||
void getComicsInfo(QList<QPair<ComicDB,QString> > & matchingInfo, int count, const QString & publisher);
|
||||
void getComicInfo(const QString & comicId, int count, const QString & publisher);
|
||||
ComicDB parseComicInfo(ComicDB &comic, const QString & json, int count, const QString &publisher);
|
||||
void setLoadingMessage(const QString &message);
|
||||
void goToNextComic();
|
||||
|
||||
private:
|
||||
|
||||
QString getCharacters(const QScriptValue & json_characters);
|
||||
QMap<QString,QString> getAuthors(const QScriptValue & json_authors);
|
||||
|
||||
void toggleSkipButton();
|
||||
|
||||
enum ScraperMode
|
||||
{
|
||||
SingleComic, //the scraper has been opened for a single comic
|
||||
Volume, //the scraper is trying to get comics info for a whole volume
|
||||
SingleComicInList //the scraper has been opened for a list of unrelated comics
|
||||
};
|
||||
|
||||
enum ScraperStatus
|
||||
{
|
||||
AutoSearching,
|
||||
AskingForInfo,
|
||||
SelectingComic,
|
||||
SelectingSeries,
|
||||
SearchingSingleComic,
|
||||
SearchingVolume,
|
||||
SortingComics,
|
||||
GettingVolumeComics
|
||||
};
|
||||
|
||||
ScraperMode mode;
|
||||
ScraperStatus status;
|
||||
|
||||
int currentIndex;
|
||||
|
||||
TitleHeader * titleHeader;
|
||||
|
||||
QPushButton * skipButton;
|
||||
QPushButton * backButton;
|
||||
QPushButton * nextButton;
|
||||
QPushButton * searchButton;
|
||||
QPushButton * closeButton;
|
||||
|
||||
//stacked widgets
|
||||
QStackedWidget * content;
|
||||
|
||||
QWidget * infoNotFound;
|
||||
QWidget * singleComicBrowser;
|
||||
|
||||
QLabel * loadingMessage;
|
||||
|
||||
void doLayout();
|
||||
void doStackedWidgets();
|
||||
void doLoading();
|
||||
void doConnections();
|
||||
|
||||
QList<ComicDB> comics;
|
||||
|
||||
SeriesQuestion * seriesQuestionWidget;
|
||||
SearchSingleComic * searchSingleComicWidget;
|
||||
SearchVolume * searchVolumeWidget;
|
||||
SelectVolume * selectVolumeWidget;
|
||||
SelectComic * selectComicWidget;
|
||||
SortVolumeComics * sortVolumeComicsWidget;
|
||||
|
||||
QString currentVolumeSearchString;
|
||||
QString currentVolumeId;
|
||||
};
|
||||
|
||||
#endif // COMIC_VINE_DIALOG_H
|
||||
6
YACReaderLibrary/comic_vine/model/comics_model.cpp
Normal file
6
YACReaderLibrary/comic_vine/model/comics_model.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "comics_model.h"
|
||||
|
||||
ComicsModel::ComicsModel(QObject *parent) :
|
||||
JSONModel(parent)
|
||||
{
|
||||
}
|
||||
18
YACReaderLibrary/comic_vine/model/comics_model.h
Normal file
18
YACReaderLibrary/comic_vine/model/comics_model.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef COMICS_MODEL_H
|
||||
#define COMICS_MODEL_H
|
||||
|
||||
#include "json_model.h"
|
||||
|
||||
class ComicsModel : public JSONModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ComicsModel(QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // COMICS_MODEL_H
|
||||
6
YACReaderLibrary/comic_vine/model/json_model.cpp
Normal file
6
YACReaderLibrary/comic_vine/model/json_model.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "json_model.h"
|
||||
|
||||
JSONModel::JSONModel(QObject *parent) :
|
||||
QAbstractItemModel(parent)
|
||||
{
|
||||
}
|
||||
19
YACReaderLibrary/comic_vine/model/json_model.h
Normal file
19
YACReaderLibrary/comic_vine/model/json_model.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef JSON_MODEL_H
|
||||
#define JSON_MODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class JSONModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit JSONModel(QObject *parent = 0);
|
||||
virtual void load(const QString & json) = 0 ;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // JSON_MODEL_H
|
||||
183
YACReaderLibrary/comic_vine/model/local_comic_list_model.cpp
Normal file
183
YACReaderLibrary/comic_vine/model/local_comic_list_model.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
#include "local_comic_list_model.h"
|
||||
|
||||
LocalComicListModel::LocalComicListModel(QObject *parent) :
|
||||
QAbstractItemModel(parent),numExtraRows(0)
|
||||
{
|
||||
}
|
||||
|
||||
void LocalComicListModel::load(QList<ComicDB> &comics)
|
||||
{
|
||||
_data = comics;
|
||||
}
|
||||
|
||||
|
||||
QModelIndex LocalComicListModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
return QModelIndex(); //no parent
|
||||
}
|
||||
|
||||
int LocalComicListModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return _data.count();
|
||||
}
|
||||
|
||||
int LocalComicListModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
if(_data.isEmpty())
|
||||
return 0;
|
||||
else
|
||||
return 1;//_data.at(0)->count();
|
||||
}
|
||||
|
||||
QVariant LocalComicListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::DecorationRole)
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
if (role == Qt::TextAlignmentRole)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
if(role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
int row = index.row();
|
||||
|
||||
//if(row < _data.count())
|
||||
return _data[row].getFileName();
|
||||
//else
|
||||
//return QVariant();
|
||||
}
|
||||
|
||||
Qt::ItemFlags LocalComicListModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
}
|
||||
|
||||
QVariant LocalComicListModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
|
||||
if ( role == Qt::TextAlignmentRole)
|
||||
return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
{
|
||||
return QVariant(QString(tr("file name")));
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex LocalComicListModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(row, column);
|
||||
}
|
||||
|
||||
QList<ComicDB> LocalComicListModel::getData()
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
void LocalComicListModel::removeComics(const QList<QModelIndex> &selectedIndexes)
|
||||
{
|
||||
QModelIndex mi = selectedIndexes.first();
|
||||
QModelIndex lastMi = selectedIndexes.last();
|
||||
int sourceRow = mi.row();
|
||||
int sourceLastRow = lastMi.row();
|
||||
|
||||
beginRemoveRows(QModelIndex(),selectedIndexes.first().row(),selectedIndexes.last().row());
|
||||
|
||||
for(int i = sourceLastRow;i>=sourceRow;i--)
|
||||
{
|
||||
_removed.push_front(_data.at(i));
|
||||
_data.removeAt(i);
|
||||
}
|
||||
|
||||
endRemoveRows();
|
||||
|
||||
beginInsertRows(QModelIndex(),_data.count()-_removed.count(),_data.count()-1);
|
||||
for(int i = 0; i<_removed.count(); i++)
|
||||
_data.append(ComicDB());
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void LocalComicListModel::restoreAll()
|
||||
{
|
||||
int numItemsToRemove = 0;
|
||||
for(int i = 0;numItemsToRemove<_removed.count();i++)
|
||||
{
|
||||
if(_data.at(i).getFileName().isEmpty())
|
||||
{
|
||||
beginRemoveRows(QModelIndex(),i,i);
|
||||
_data.removeAt(i);
|
||||
endRemoveRows();
|
||||
|
||||
beginInsertRows(QModelIndex(),i,i);
|
||||
_data.insert(i,_removed.at(numItemsToRemove));
|
||||
endInsertRows();
|
||||
|
||||
numItemsToRemove++;
|
||||
}
|
||||
}
|
||||
|
||||
_removed.clear();
|
||||
}
|
||||
|
||||
void LocalComicListModel::moveSelectionUp(const QList<QModelIndex> &selectedIndexes)
|
||||
{
|
||||
QModelIndex mi = selectedIndexes.first();
|
||||
QModelIndex lastMi = selectedIndexes.last();
|
||||
int sourceRow = mi.row();
|
||||
int sourceLastRow = lastMi.row();
|
||||
int destRow = sourceRow - 1;
|
||||
|
||||
if(destRow < 0)
|
||||
return;
|
||||
|
||||
beginMoveRows(mi.parent(),sourceRow,sourceLastRow,mi.parent(),destRow);
|
||||
|
||||
for(int i = sourceRow; i <= sourceLastRow; i++)
|
||||
_data.swap(i, i-1);
|
||||
|
||||
endMoveRows();
|
||||
}
|
||||
|
||||
void LocalComicListModel::moveSelectionDown(const QList<QModelIndex> &selectedIndexes)
|
||||
{
|
||||
QModelIndex mi = selectedIndexes.first();
|
||||
QModelIndex lastMi = selectedIndexes.last();
|
||||
int sourceRow = mi.row();
|
||||
int sourceLastRow = lastMi.row();
|
||||
int destRow = sourceLastRow + 1;
|
||||
|
||||
if(destRow >= _data.count())
|
||||
return;
|
||||
|
||||
beginMoveRows(mi.parent(),sourceRow,sourceLastRow,mi.parent(),destRow+1);
|
||||
|
||||
for(int i = sourceLastRow; i >= sourceRow; i--)
|
||||
_data.swap(i, i+1);
|
||||
|
||||
endMoveRows();
|
||||
}
|
||||
|
||||
void LocalComicListModel::addExtraRows(int numRows)
|
||||
{
|
||||
numExtraRows = numRows;
|
||||
for(int i = 0; i<numExtraRows; i++)
|
||||
_data.append(ComicDB());
|
||||
}
|
||||
|
||||
42
YACReaderLibrary/comic_vine/model/local_comic_list_model.h
Normal file
42
YACReaderLibrary/comic_vine/model/local_comic_list_model.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef LOCAL_COMIC_LIST_MODEL_H
|
||||
#define LOCAL_COMIC_LIST_MODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
#include "comic_db.h"
|
||||
|
||||
class LocalComicListModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LocalComicListModel(QObject *parent = 0);
|
||||
|
||||
void load(QList<ComicDB> & comics);
|
||||
|
||||
//QAbstractItemModel methods
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||
QList<ComicDB> getData();
|
||||
|
||||
void removeComics(const QList<QModelIndex> & selectedIndexes);
|
||||
void restoreAll();
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void moveSelectionUp(const QList<QModelIndex> & selectedIndexes);
|
||||
void moveSelectionDown(const QList<QModelIndex> & selectedIndexes);
|
||||
void addExtraRows(int numRows);
|
||||
|
||||
private:
|
||||
int numExtraRows;
|
||||
QList<ComicDB> _data;
|
||||
QList<ComicDB> _removed;
|
||||
};
|
||||
|
||||
#endif // LOCAL_COMIC_LIST_MODEL_H
|
||||
61
YACReaderLibrary/comic_vine/model/response_parser.cpp
Normal file
61
YACReaderLibrary/comic_vine/model/response_parser.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "response_parser.h"
|
||||
|
||||
#include <QtScript>
|
||||
#include <QDebug>
|
||||
|
||||
ResponseParser::ResponseParser(QObject *parent) :
|
||||
QObject(parent),error(false),numResults(-1),currentPage(-1),totalPages(-1)
|
||||
{
|
||||
}
|
||||
|
||||
bool ResponseParser::responseError()
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
qint32 ResponseParser::getNumResults()
|
||||
{
|
||||
return numResults;
|
||||
}
|
||||
|
||||
qint32 ResponseParser::getCurrentPage()
|
||||
{
|
||||
return currentPage;
|
||||
}
|
||||
|
||||
qint32 ResponseParser::getTotalPages()
|
||||
{
|
||||
return totalPages;
|
||||
}
|
||||
|
||||
void ResponseParser::loadJSONResponse(const QString &response)
|
||||
{
|
||||
QScriptEngine engine;
|
||||
QScriptValue sc;
|
||||
sc = engine.evaluate("(" + response + ")");
|
||||
|
||||
if (!sc.property("error").isValid() && sc.property("error").toString() != "OK")
|
||||
{
|
||||
error = true;
|
||||
qDebug("Error detected");
|
||||
}
|
||||
else
|
||||
{
|
||||
error = false;
|
||||
if(sc.property("number_of_total_results").isValid())
|
||||
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;
|
||||
}
|
||||
}
|
||||
27
YACReaderLibrary/comic_vine/model/response_parser.h
Normal file
27
YACReaderLibrary/comic_vine/model/response_parser.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef RESPONSE_PARSER_H
|
||||
#define RESPONSE_PARSER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class ResponseParser : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ResponseParser(QObject *parent = 0);
|
||||
bool responseError();
|
||||
qint32 getNumResults();
|
||||
qint32 getCurrentPage();
|
||||
qint32 getTotalPages();
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void loadJSONResponse(const QString & response);
|
||||
|
||||
protected:
|
||||
bool error;
|
||||
qint32 numResults;
|
||||
qint32 currentPage;
|
||||
qint32 totalPages;
|
||||
};
|
||||
|
||||
#endif // RESPONSE_PARSER_H
|
||||
172
YACReaderLibrary/comic_vine/model/volume_comics_model.cpp
Normal file
172
YACReaderLibrary/comic_vine/model/volume_comics_model.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
#include "volume_comics_model.h"
|
||||
#include "qnaturalsorting.h"
|
||||
|
||||
|
||||
#include <QtScript>
|
||||
|
||||
bool lessThan(const QList<QString> & left, const QList<QString> & right)
|
||||
{
|
||||
if ((left.count() > 0) && (right.count() > 0))
|
||||
return naturalSortLessThanCI(left.at(0),right.at(0));
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
VolumeComicsModel::VolumeComicsModel(QObject * parent) :
|
||||
JSONModel(parent),numExtraRows(0)
|
||||
{
|
||||
}
|
||||
|
||||
void VolumeComicsModel::load(const QString & json)
|
||||
{
|
||||
QScriptEngine engine;
|
||||
QScriptValue sc;
|
||||
sc = engine.evaluate("(" + json + ")");
|
||||
|
||||
if (!sc.property("error").isValid() && sc.property("error").toString() != "OK")
|
||||
{
|
||||
qDebug("Error detected");
|
||||
}
|
||||
else
|
||||
{
|
||||
QScriptValueIterator it(sc.property("results"));
|
||||
//bool test;
|
||||
QScriptValue resultsValue;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
if(it.flags() & QScriptValue::SkipInEnumeration)
|
||||
continue;
|
||||
resultsValue = it.value();
|
||||
QString issueNumber = resultsValue.property("issue_number").toString();
|
||||
QString name = resultsValue.property("name").toString();
|
||||
QString coverURL = resultsValue.property("image").property("medium_url").toString();
|
||||
QString id = resultsValue.property("id").toString();
|
||||
QStringList l;
|
||||
l << issueNumber << name << coverURL << id;
|
||||
_data.push_back(l);
|
||||
}
|
||||
|
||||
qSort(_data.begin(),_data.end(),lessThan);
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex VolumeComicsModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
return QModelIndex(); //no parent
|
||||
}
|
||||
|
||||
int VolumeComicsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return _data.count() + numExtraRows;
|
||||
}
|
||||
|
||||
int VolumeComicsModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
if(_data.isEmpty())
|
||||
return 0;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
|
||||
QVariant VolumeComicsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
int row = index.row();
|
||||
int column = index.column();
|
||||
|
||||
if (role == Qt::DecorationRole)
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
if (role == Qt::TextAlignmentRole)
|
||||
{
|
||||
switch(column)//TODO obtener esto de la query
|
||||
{
|
||||
case ISSUE:
|
||||
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||
case TITLE:
|
||||
return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
}
|
||||
}
|
||||
|
||||
if(role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if(row<_data.count())
|
||||
return _data[row][column];
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
Qt::ItemFlags VolumeComicsModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
}
|
||||
|
||||
QVariant VolumeComicsModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
{
|
||||
switch(section)//TODO obtener esto de la query
|
||||
{
|
||||
case ISSUE:
|
||||
return QVariant(QString("issue"));
|
||||
case TITLE:
|
||||
return QVariant(QString(tr("title")));
|
||||
}
|
||||
}
|
||||
|
||||
if (orientation == Qt::Horizontal && role == Qt::TextAlignmentRole)
|
||||
{
|
||||
switch(section)//TODO obtener esto de la query
|
||||
{
|
||||
case ISSUE:
|
||||
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||
case TITLE:
|
||||
return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex VolumeComicsModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(row, column);
|
||||
}
|
||||
|
||||
QString VolumeComicsModel::getComicId(const QModelIndex &index) const
|
||||
{
|
||||
int row = index.row();
|
||||
if(row >= _data.count())
|
||||
return "";
|
||||
return _data[row][ID];
|
||||
}
|
||||
|
||||
QString VolumeComicsModel::getComicId(int row) const
|
||||
{
|
||||
if(row >= _data.count())
|
||||
return "";
|
||||
return _data[row][ID];
|
||||
}
|
||||
|
||||
QString VolumeComicsModel::getCoverURL(const QModelIndex &index) const
|
||||
{
|
||||
return _data[index.row()][COVER_URL];
|
||||
}
|
||||
|
||||
void VolumeComicsModel::addExtraRows(int numRows)
|
||||
{
|
||||
numExtraRows = numRows;
|
||||
}
|
||||
|
||||
41
YACReaderLibrary/comic_vine/model/volume_comics_model.h
Normal file
41
YACReaderLibrary/comic_vine/model/volume_comics_model.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef VOLUME_COMICS_MODEL_H
|
||||
#define VOLUME_COMICS_MODEL_H
|
||||
|
||||
#include "json_model.h"
|
||||
|
||||
class VolumeComicsModel : public JSONModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VolumeComicsModel(QObject *parent = 0);
|
||||
void load(const QString & json);
|
||||
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
QString getComicId(const QModelIndex &index) const;
|
||||
QString getComicId(int row) const;
|
||||
QString getCoverURL(const QModelIndex &index) const;
|
||||
void addExtraRows(int numRows);
|
||||
|
||||
private:
|
||||
int numExtraRows;
|
||||
QList <QList <QString> > _data;
|
||||
|
||||
enum Column {
|
||||
ISSUE = 0,
|
||||
TITLE,
|
||||
COVER_URL,
|
||||
ID
|
||||
};
|
||||
};
|
||||
|
||||
#endif // VOLUME_COMICS_MODEL_H
|
||||
161
YACReaderLibrary/comic_vine/model/volumes_model.cpp
Normal file
161
YACReaderLibrary/comic_vine/model/volumes_model.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
#include "volumes_model.h"
|
||||
|
||||
#include <QtScript>
|
||||
|
||||
|
||||
VolumesModel::VolumesModel(QObject *parent) :
|
||||
JSONModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
VolumesModel::~VolumesModel()
|
||||
{
|
||||
//std::for_each(_data.begin(), _data.end(), [](QList<QString> * ptr) { delete ptr; });
|
||||
}
|
||||
|
||||
void VolumesModel::load(const QString &json)
|
||||
{
|
||||
QScriptEngine engine;
|
||||
QScriptValue sc;
|
||||
sc = engine.evaluate("(" + json + ")");
|
||||
|
||||
if (!sc.property("error").isValid() && sc.property("error").toString() != "OK")
|
||||
{
|
||||
qDebug("Error detected");
|
||||
}
|
||||
else
|
||||
{
|
||||
int numResults = sc.property("number_of_total_results").toString().toInt(); //fix to weird behaviour using hasNext
|
||||
QScriptValueIterator it(sc.property("results"));
|
||||
bool test;
|
||||
QScriptValue resultsValue;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
resultsValue = it.value();
|
||||
QString numIssues = resultsValue.property("count_of_issues").toString();
|
||||
QString year = resultsValue.property("start_year").toString();
|
||||
QString name = resultsValue.property("name").toString();
|
||||
QString publisher = resultsValue.property("publisher").property("name").toString();
|
||||
QString url = resultsValue.property("image").property("medium_url").toString();
|
||||
QString deck = resultsValue.property("deck").toString();
|
||||
QString id = resultsValue.property("id").toString();
|
||||
QStringList l;
|
||||
l << name << year << numIssues << publisher << url << deck << id;
|
||||
test = name.isEmpty() && year.isEmpty() && numIssues.isEmpty() && url.isEmpty();
|
||||
if(numResults>0 && !test)
|
||||
_data.push_back(l);
|
||||
numResults--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex VolumesModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
return QModelIndex(); //no parent
|
||||
}
|
||||
|
||||
int VolumesModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return _data.count();
|
||||
}
|
||||
|
||||
int VolumesModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
if(_data.isEmpty())
|
||||
return 0;
|
||||
else
|
||||
return 4;//_data.at(0)->count();
|
||||
}
|
||||
|
||||
QVariant VolumesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::DecorationRole)
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
if (role == Qt::TextAlignmentRole)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
if(role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
int row = index.row();
|
||||
int column = index.column();
|
||||
return _data[row][column];
|
||||
}
|
||||
|
||||
Qt::ItemFlags VolumesModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
}
|
||||
|
||||
QVariant VolumesModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
{
|
||||
switch(section)//TODO obtener esto de la query
|
||||
{
|
||||
case SERIES:
|
||||
return QVariant(QString("series"));
|
||||
case YEAR:
|
||||
return QVariant(QString(tr("year")));
|
||||
case ISSUES:
|
||||
return QVariant(QString(tr("issues")));
|
||||
case PUBLISHER:
|
||||
return QVariant(QString(tr("publisher")));
|
||||
}
|
||||
}
|
||||
|
||||
if (orientation == Qt::Horizontal && role == Qt::TextAlignmentRole)
|
||||
{
|
||||
switch(section)//TODO obtener esto de la query
|
||||
{
|
||||
case YEAR:
|
||||
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||
case ISSUES:
|
||||
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex VolumesModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(row, column);
|
||||
}
|
||||
|
||||
QString VolumesModel::getVolumeId(const QModelIndex &index) const
|
||||
{
|
||||
return _data[index.row()][ID];
|
||||
}
|
||||
|
||||
int VolumesModel::getNumIssues(const QModelIndex &index) const
|
||||
{
|
||||
return _data[index.row()][ISSUES].toInt();
|
||||
}
|
||||
|
||||
QString VolumesModel::getPublisher(const QModelIndex &index) const
|
||||
{
|
||||
return _data[index.row()][PUBLISHER];
|
||||
}
|
||||
|
||||
QString VolumesModel::getCoverURL(const QModelIndex &index) const
|
||||
{
|
||||
return _data[index.row()][COVER_URL];
|
||||
}
|
||||
|
||||
50
YACReaderLibrary/comic_vine/model/volumes_model.h
Normal file
50
YACReaderLibrary/comic_vine/model/volumes_model.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef VOLUMES_MODEL_H
|
||||
#define VOLUMES_MODEL_H
|
||||
|
||||
#include "json_model.h"
|
||||
|
||||
class VolumesModel : public JSONModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VolumesModel(QObject *parent = 0);
|
||||
virtual ~VolumesModel();
|
||||
//receive a valid json with a list of volumes
|
||||
void load(const QString & json);
|
||||
|
||||
//QAbstractItemModel methods
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||
|
||||
QString getVolumeId(const QModelIndex & index) const;
|
||||
int getNumIssues(const QModelIndex & index) const;
|
||||
QString getPublisher(const QModelIndex & index) const;
|
||||
QString getCoverURL(const QModelIndex & index) const;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
QList <QList <QString> > _data;
|
||||
|
||||
public:
|
||||
enum Column {
|
||||
SERIES = 0,
|
||||
YEAR,
|
||||
ISSUES,
|
||||
PUBLISHER,
|
||||
COVER_URL,
|
||||
DECK,
|
||||
ID
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // VOLUMES_MODEL_H
|
||||
21
YACReaderLibrary/comic_vine/scraper_lineedit.cpp
Normal file
21
YACReaderLibrary/comic_vine/scraper_lineedit.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include "scraper_lineedit.h"
|
||||
#include <QLabel>
|
||||
|
||||
ScraperLineEdit::ScraperLineEdit(const QString & title, QWidget * widget)
|
||||
:QLineEdit(widget)
|
||||
{
|
||||
titleLabel = new QLabel(title,this);
|
||||
titleLabel->setStyleSheet("QLabel {color:white;}");
|
||||
|
||||
setStyleSheet(QString("QLineEdit {"
|
||||
"border:none; background-color: #2E2E2E; color : white; padding-left: %1; padding-bottom: 1px; margin-bottom: 0px;"
|
||||
"}").arg(titleLabel->sizeHint().width()+6));
|
||||
|
||||
setFixedHeight(22);
|
||||
}
|
||||
|
||||
void ScraperLineEdit::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
QSize szl = titleLabel->sizeHint();
|
||||
titleLabel->move(6,(rect().bottom() + 1 - szl.height())/2);
|
||||
}
|
||||
19
YACReaderLibrary/comic_vine/scraper_lineedit.h
Normal file
19
YACReaderLibrary/comic_vine/scraper_lineedit.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef SCRAPPER_LINEEDIT_H
|
||||
#define SCRAPPER_LINEEDIT_H
|
||||
|
||||
#include <QLineEdit>
|
||||
|
||||
class QLabel;
|
||||
|
||||
class ScraperLineEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ScraperLineEdit(const QString & title, QWidget * widget = 0);
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *);
|
||||
private:
|
||||
QLabel * titleLabel;
|
||||
};
|
||||
|
||||
#endif // SCRAPPER_LINEEDIT_H
|
||||
75
YACReaderLibrary/comic_vine/scraper_results_paginator.cpp
Normal file
75
YACReaderLibrary/comic_vine/scraper_results_paginator.cpp
Normal 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;
|
||||
}
|
||||
34
YACReaderLibrary/comic_vine/scraper_results_paginator.h
Normal file
34
YACReaderLibrary/comic_vine/scraper_results_paginator.h
Normal 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
|
||||
53
YACReaderLibrary/comic_vine/scraper_scroll_label.cpp
Normal file
53
YACReaderLibrary/comic_vine/scraper_scroll_label.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#include "scraper_scroll_label.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
|
||||
ScraperScrollLabel::ScraperScrollLabel(QWidget *parent) :
|
||||
QScrollArea(parent)
|
||||
{
|
||||
textLabel = new QLabel(this);
|
||||
textLabel->setStyleSheet("QLabel {background-color: #2B2B2B; color:white; font-size:12px; font-family:Arial; }");
|
||||
|
||||
textLabel->setWordWrap(true);
|
||||
textLabel->setMinimumSize(168,12);
|
||||
|
||||
setWidget(textLabel);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setStyleSheet(
|
||||
"QScrollArea {background-color:#2B2B2B; border:none;}"
|
||||
"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; }"
|
||||
"QScrollBar::handle:horizontal { background: #DDDDDD; width: 7px; min-height: 20px; }"
|
||||
"QScrollBar::add-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}"
|
||||
"QScrollBar::sub-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}"
|
||||
"QScrollBar::add-line:horizontal { border: none; background: #404040; width: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 0 3px 0;}"
|
||||
"QScrollBar::sub-line:horizontal { border: none; background: #404040; width: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 0 3px 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, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {background: none; }"
|
||||
);
|
||||
|
||||
connect(textLabel,SIGNAL(linkActivated(QString)),this,SLOT(openLink(QString)));
|
||||
}
|
||||
|
||||
void ScraperScrollLabel::setAltText(const QString &text)
|
||||
{
|
||||
textLabel->setAlignment(Qt::AlignTop|Qt::AlignHCenter);
|
||||
textLabel->setText(text);
|
||||
textLabel->adjustSize();
|
||||
}
|
||||
|
||||
void ScraperScrollLabel::setText(const QString &text)
|
||||
{
|
||||
textLabel->setAlignment(Qt::AlignTop|Qt::AlignLeft);
|
||||
textLabel->setText(text);
|
||||
textLabel->adjustSize();
|
||||
}
|
||||
|
||||
void ScraperScrollLabel::openLink(const QString & link)
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl("http://www.comicvine.com"+link));
|
||||
}
|
||||
25
YACReaderLibrary/comic_vine/scraper_scroll_label.h
Normal file
25
YACReaderLibrary/comic_vine/scraper_scroll_label.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef SCRAPER_SCROLL_LABEL_H
|
||||
#define SCRAPER_SCROLL_LABEL_H
|
||||
|
||||
#include <QScrollArea>
|
||||
|
||||
class QLabel;
|
||||
|
||||
class ScraperScrollLabel : public QScrollArea
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ScraperScrollLabel(QWidget *parent = 0);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void setText(const QString & text);
|
||||
void setAltText(const QString &text);
|
||||
|
||||
void openLink(const QString &link);
|
||||
private:
|
||||
QLabel * textLabel;
|
||||
};
|
||||
|
||||
#endif // SCRAPER_SCROLL_LABEL_H
|
||||
25
YACReaderLibrary/comic_vine/scraper_selector.cpp
Normal file
25
YACReaderLibrary/comic_vine/scraper_selector.cpp
Normal 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);
|
||||
}
|
||||
28
YACReaderLibrary/comic_vine/scraper_selector.h
Normal file
28
YACReaderLibrary/comic_vine/scraper_selector.h
Normal 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
|
||||
61
YACReaderLibrary/comic_vine/scraper_tableview.cpp
Normal file
61
YACReaderLibrary/comic_vine/scraper_tableview.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "scraper_tableview.h"
|
||||
|
||||
#include <QHeaderView>
|
||||
|
||||
ScraperTableView::ScraperTableView(QWidget *parent) :
|
||||
QTableView(parent)
|
||||
{
|
||||
QString tableStylesheet = "QTableView {color:white; border:0px;alternate-background-color: #2E2E2E;background-color: #2B2B2B; outline: 0px;}"
|
||||
"QTableView::item {outline: 0px; border: 0px; color:#FFFFFF;}"
|
||||
"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; }"
|
||||
"QScrollBar::handle:horizontal { background: #DDDDDD; width: 7px; min-height: 20px; }"
|
||||
"QScrollBar::add-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}"
|
||||
"QScrollBar::sub-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}"
|
||||
"QScrollBar::add-line:horizontal { border: none; background: #404040; width: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 0 3px 0;}"
|
||||
"QScrollBar::sub-line:horizontal { border: none; background: #404040; width: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 0 3px 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, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {background: none; }";
|
||||
|
||||
setStyleSheet(tableStylesheet);
|
||||
|
||||
setShowGrid(false);
|
||||
#if QT_VERSION >= 0x050000
|
||||
verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
|
||||
#else
|
||||
verticalHeader()->setResizeMode(QHeaderView::Fixed);
|
||||
#endif
|
||||
|
||||
//comicView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
|
||||
horizontalHeader()->setStretchLastSection(true);
|
||||
#if QT_VERSION >= 0x050000
|
||||
horizontalHeader()->setSectionsClickable(false);
|
||||
#else
|
||||
horizontalHeader()->setClickable(false);
|
||||
#endif
|
||||
//comicView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
|
||||
verticalHeader()->setDefaultSectionSize(24);
|
||||
#if QT_VERSION >= 0x050000
|
||||
verticalHeader()->setSectionsClickable(false); //TODO comportamiento anómalo
|
||||
#else
|
||||
verticalHeader()->setClickable(false); //TODO comportamiento anómalo
|
||||
#endif
|
||||
|
||||
setCornerButtonEnabled(false);
|
||||
|
||||
setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
setAlternatingRowColors(true);
|
||||
|
||||
verticalHeader()->hide();
|
||||
|
||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
}
|
||||
18
YACReaderLibrary/comic_vine/scraper_tableview.h
Normal file
18
YACReaderLibrary/comic_vine/scraper_tableview.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef SCRAPPER_TABLEVIEW_H
|
||||
#define SCRAPPER_TABLEVIEW_H
|
||||
|
||||
#include <QTableView>
|
||||
|
||||
class ScraperTableView : public QTableView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ScraperTableView(QWidget *parent = 0);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // SCRAPPER_TABLEVIEW_H
|
||||
62
YACReaderLibrary/comic_vine/search_single_comic.cpp
Normal file
62
YACReaderLibrary/comic_vine/search_single_comic.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
#include "search_single_comic.h"
|
||||
|
||||
#include "scraper_lineedit.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
SearchSingleComic::SearchSingleComic(QWidget * parent)
|
||||
:QWidget(parent)
|
||||
{
|
||||
|
||||
//QLabel * label = new QLabel(tr("Please provide some aditional information. At least one field is needed."));
|
||||
QLabel * label = new QLabel(tr("Please provide some aditional information."));
|
||||
label->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}");
|
||||
|
||||
//titleEdit = new ScraperLineEdit(tr("Title:"));
|
||||
//numberEdit = new ScraperLineEdit(tr("Number:"));
|
||||
volumeEdit = new ScraperLineEdit(tr("Series:"));
|
||||
|
||||
//numberEdit->setMaximumWidth(126);
|
||||
|
||||
QVBoxLayout * l = new QVBoxLayout;
|
||||
//QHBoxLayout * hl = new QHBoxLayout;
|
||||
//hl->addWidget(titleEdit);
|
||||
//hl->addWidget(numberEdit);
|
||||
|
||||
l->addSpacing(35);
|
||||
l->addWidget(label);
|
||||
//l->addLayout(hl);
|
||||
l->addWidget(volumeEdit);
|
||||
l->addStretch();
|
||||
|
||||
l->setContentsMargins(0,0,0,0);
|
||||
setLayout(l);
|
||||
setContentsMargins(0,0,0,0);
|
||||
}
|
||||
|
||||
QString SearchSingleComic::getVolumeInfo()
|
||||
{
|
||||
return volumeEdit->text();
|
||||
}
|
||||
|
||||
QString SearchSingleComic::getComicInfo()
|
||||
{
|
||||
//return titleEdit->text();
|
||||
return "";
|
||||
}
|
||||
|
||||
int SearchSingleComic::getComicNumber()
|
||||
{
|
||||
//QString numberText = numberEdit->text();
|
||||
//if(numberText.isEmpty())
|
||||
// return -1;
|
||||
//return numberText.toInt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SearchSingleComic::clean()
|
||||
{
|
||||
volumeEdit->clear();
|
||||
}
|
||||
22
YACReaderLibrary/comic_vine/search_single_comic.h
Normal file
22
YACReaderLibrary/comic_vine/search_single_comic.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef SEARCH_SINGLE_COMIC_H
|
||||
#define SEARCH_SINGLE_COMIC_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class ScraperLineEdit;
|
||||
|
||||
class SearchSingleComic : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SearchSingleComic(QWidget * parent = 0);
|
||||
QString getVolumeInfo();
|
||||
QString getComicInfo();
|
||||
int getComicNumber();
|
||||
void clean();
|
||||
private:
|
||||
ScraperLineEdit * titleEdit;
|
||||
ScraperLineEdit * numberEdit;
|
||||
ScraperLineEdit * volumeEdit;
|
||||
};
|
||||
#endif // SEARCH_SINGLE_COMIC_H
|
||||
36
YACReaderLibrary/comic_vine/search_volume.cpp
Normal file
36
YACReaderLibrary/comic_vine/search_volume.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "search_volume.h"
|
||||
|
||||
#include "scraper_lineedit.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
SearchVolume::SearchVolume(QWidget * parent)
|
||||
:QWidget(parent)
|
||||
{
|
||||
QLabel * label = new QLabel(tr("Please provide some aditional information."));
|
||||
label->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}");
|
||||
|
||||
volumeEdit = new ScraperLineEdit(tr("Series:"));
|
||||
|
||||
QVBoxLayout * l = new QVBoxLayout;
|
||||
|
||||
l->addSpacing(35);
|
||||
l->addWidget(label);
|
||||
l->addWidget(volumeEdit);
|
||||
l->addStretch();
|
||||
|
||||
l->setContentsMargins(0,0,0,0);
|
||||
setLayout(l);
|
||||
setContentsMargins(0,0,0,0);
|
||||
}
|
||||
|
||||
void SearchVolume::clean()
|
||||
{
|
||||
volumeEdit->clear();
|
||||
}
|
||||
|
||||
QString SearchVolume::getVolumeInfo()
|
||||
{
|
||||
return volumeEdit->text();
|
||||
}
|
||||
21
YACReaderLibrary/comic_vine/search_volume.h
Normal file
21
YACReaderLibrary/comic_vine/search_volume.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef SEARCH_VOLUME_H
|
||||
#define SEARCH_VOLUME_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class ScraperLineEdit;
|
||||
|
||||
|
||||
class SearchVolume : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SearchVolume(QWidget * parent = 0);
|
||||
void clean();
|
||||
public slots:
|
||||
QString getVolumeInfo();
|
||||
private:
|
||||
ScraperLineEdit * volumeEdit;
|
||||
};
|
||||
|
||||
#endif // SEARCH_VOLUME_H
|
||||
150
YACReaderLibrary/comic_vine/select_comic.cpp
Normal file
150
YACReaderLibrary/comic_vine/select_comic.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
#include "select_comic.h"
|
||||
|
||||
#include "comic_vine_client.h"
|
||||
#include "scraper_scroll_label.h"
|
||||
#include "scraper_tableview.h"
|
||||
#include "volume_comics_model.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
#include <QtScript>
|
||||
|
||||
SelectComic::SelectComic(QWidget *parent)
|
||||
:ScraperSelector(parent),model(0)
|
||||
{
|
||||
QString labelStylesheet = "QLabel {color:white; font-size:12px;font-family:Arial;}";
|
||||
|
||||
QLabel * label = new QLabel(tr("Please, select the right comic info."));
|
||||
label->setStyleSheet(labelStylesheet);
|
||||
|
||||
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);
|
||||
cover->setAlignment(Qt::AlignTop|Qt::AlignHCenter);
|
||||
cover->setMinimumSize(168,168*5.0/3);
|
||||
cover->setStyleSheet("QLabel {background-color: #2B2B2B; color:white; font-size:12px; font-family:Arial; }");
|
||||
detailLabel = new ScraperScrollLabel(this);
|
||||
|
||||
tableComics = new ScraperTableView(this);
|
||||
//connections
|
||||
connect(tableComics,SIGNAL(clicked(QModelIndex)),this,SLOT(loadComicInfo(QModelIndex)));
|
||||
|
||||
paginator->setCustomLabel(tr("comics"));
|
||||
|
||||
left->addWidget(cover);
|
||||
left->addWidget(detailLabel,1);
|
||||
left->addStretch();
|
||||
leftWidget->setMaximumWidth(180);
|
||||
leftWidget->setLayout(left);
|
||||
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->addLayout(right);
|
||||
|
||||
l->addSpacing(15);
|
||||
l->addWidget(label);
|
||||
l->addSpacing(5);
|
||||
l->addLayout(content);
|
||||
l->addStretch();
|
||||
|
||||
l->setContentsMargins(0,0,0,0);
|
||||
setLayout(l);
|
||||
setContentsMargins(0,0,0,0);
|
||||
}
|
||||
|
||||
void SelectComic::load(const QString &json, const QString & searchString)
|
||||
{
|
||||
VolumeComicsModel * tempM = new VolumeComicsModel();
|
||||
tempM->load(json);
|
||||
tableComics->setModel(tempM);
|
||||
|
||||
tableComics->setFixedSize(619,341);
|
||||
|
||||
if(model != 0)
|
||||
delete model;
|
||||
|
||||
model = tempM;
|
||||
|
||||
if(model->rowCount()>0)
|
||||
{
|
||||
tableComics->selectRow(0);
|
||||
loadComicInfo(model->index(0,0));
|
||||
}
|
||||
|
||||
tableComics->resizeColumnToContents(0);
|
||||
|
||||
ScraperSelector::load(json,searchString);
|
||||
}
|
||||
|
||||
SelectComic::~SelectComic() {}
|
||||
|
||||
void SelectComic::loadComicInfo(const QModelIndex &mi)
|
||||
{
|
||||
QString coverURL = model->getCoverURL(mi);
|
||||
QString id = model->getComicId(mi);
|
||||
|
||||
QString loadingStyle = "<font color='#AAAAAA'>%1</font>";
|
||||
cover->setText(loadingStyle.arg(tr("loading cover")));
|
||||
detailLabel->setAltText(loadingStyle.arg(tr("loading description")));
|
||||
|
||||
ComicVineClient * comicVineClient = new ComicVineClient;
|
||||
connect(comicVineClient,SIGNAL(comicCover(const QByteArray &)),this,SLOT(setCover(const QByteArray &)));
|
||||
connect(comicVineClient,SIGNAL(finished()),comicVineClient,SLOT(deleteLater()));
|
||||
comicVineClient->getComicCover(coverURL);
|
||||
|
||||
ComicVineClient * comicVineClient2 = new ComicVineClient;
|
||||
connect(comicVineClient2,SIGNAL(comicDetail(QString)),this,SLOT(setDescription(QString)));
|
||||
connect(comicVineClient2,SIGNAL(finished()),comicVineClient2,SLOT(deleteLater()));
|
||||
comicVineClient2->getComicDetailAsync(id);
|
||||
}
|
||||
|
||||
void SelectComic::setCover(const QByteArray & data)
|
||||
{
|
||||
QPixmap p;
|
||||
p.loadFromData(data);
|
||||
int w = p.width();
|
||||
int h = p.height();
|
||||
|
||||
cover->setPixmap(p);
|
||||
float aspectRatio = static_cast<float>(w)/h;
|
||||
|
||||
cover->setFixedSize(180,static_cast<int>(180/aspectRatio));
|
||||
|
||||
cover->update();
|
||||
}
|
||||
|
||||
void SelectComic::setDescription(const QString &jsonDetail)
|
||||
{
|
||||
QScriptEngine engine;
|
||||
QScriptValue sc;
|
||||
sc = engine.evaluate("(" + jsonDetail + ")");
|
||||
|
||||
if (!sc.property("error").isValid() && sc.property("error").toString() != "OK")
|
||||
{
|
||||
qDebug("Error detected");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
QScriptValue descriptionValues = sc.property("results").property("description");
|
||||
bool valid = !descriptionValues.isNull() && descriptionValues.isValid();
|
||||
detailLabel->setText(valid?descriptionValues.toString().replace("<a","<a style = 'color:#827A68; text-decoration:none;'"):tr("description unavailable"));
|
||||
}
|
||||
}
|
||||
|
||||
QString SelectComic::getSelectedComicId()
|
||||
{
|
||||
return model->getComicId(tableComics->currentIndex());
|
||||
}
|
||||
34
YACReaderLibrary/comic_vine/select_comic.h
Normal file
34
YACReaderLibrary/comic_vine/select_comic.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef SELECT_COMIC_H
|
||||
#define SELECT_COMIC_H
|
||||
|
||||
#include "scraper_selector.h"
|
||||
|
||||
class QLabel;
|
||||
class VolumeComicsModel;
|
||||
class QModelIndex;
|
||||
|
||||
class ScraperScrollLabel;
|
||||
class ScraperTableView;
|
||||
|
||||
class SelectComic : public ScraperSelector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SelectComic(QWidget * parent = 0);
|
||||
void load(const QString & json, const QString & searchString);
|
||||
virtual ~SelectComic();
|
||||
|
||||
public slots:
|
||||
void loadComicInfo(const QModelIndex & mi);
|
||||
void setCover(const QByteArray &);
|
||||
void setDescription(const QString & jsonDetail);
|
||||
QString getSelectedComicId();
|
||||
|
||||
private:
|
||||
QLabel * cover;
|
||||
ScraperScrollLabel * detailLabel;
|
||||
ScraperTableView * tableComics;
|
||||
VolumeComicsModel * model;
|
||||
};
|
||||
|
||||
#endif // SELECT_COMIC_H
|
||||
191
YACReaderLibrary/comic_vine/select_volume.cpp
Normal file
191
YACReaderLibrary/comic_vine/select_volume.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
#include "select_volume.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QScrollBar>
|
||||
#include <QModelIndex>
|
||||
#include <QScrollArea>
|
||||
#include <QDesktopServices>
|
||||
#include <QHeaderView>
|
||||
#include <QToolButton>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include "scraper_tableview.h"
|
||||
|
||||
#include <QtScript>
|
||||
|
||||
#include "volumes_model.h"
|
||||
#include "comic_vine_client.h"
|
||||
#include "scraper_scroll_label.h"
|
||||
|
||||
#include "response_parser.h"
|
||||
#include "scraper_results_paginator.h"
|
||||
|
||||
SelectVolume::SelectVolume(QWidget *parent)
|
||||
: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."));
|
||||
label->setStyleSheet(labelStylesheet);
|
||||
|
||||
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);
|
||||
cover->setAlignment(Qt::AlignTop|Qt::AlignHCenter);
|
||||
cover->setMinimumSize(168,168*5.0/3);
|
||||
cover->setStyleSheet("QLabel {background-color: #2B2B2B; color:white; font-size:12px; font-family:Arial; }");
|
||||
detailLabel = new ScraperScrollLabel(this);
|
||||
|
||||
tableVolumes = new ScraperTableView(this);
|
||||
tableVolumes->setSortingEnabled(true);
|
||||
#if QT_VERSION >= 0x050000
|
||||
tableVolumes->horizontalHeader()->setSectionsClickable(true);
|
||||
#else
|
||||
tableVolumes->horizontalHeader()->setClickable(true);
|
||||
#endif
|
||||
//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();
|
||||
leftWidget->setMaximumWidth(180);
|
||||
leftWidget->setLayout(left);
|
||||
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->addLayout(right);
|
||||
|
||||
l->addSpacing(15);
|
||||
l->addWidget(label);
|
||||
l->addSpacing(5);
|
||||
l->addLayout(content);
|
||||
l->addStretch();
|
||||
|
||||
l->setContentsMargins(0,0,0,0);
|
||||
setLayout(l);
|
||||
setContentsMargins(0,0,0,0);
|
||||
}
|
||||
|
||||
void SelectVolume::load(const QString & json, const QString & searchString)
|
||||
{
|
||||
VolumesModel * tempM = new VolumesModel();
|
||||
tempM->load(json);
|
||||
//tableVolumes->setModel(tempM);
|
||||
|
||||
proxyModel->setSourceModel( tempM );
|
||||
tableVolumes->setModel(proxyModel);
|
||||
tableVolumes->sortByColumn(0,Qt::AscendingOrder);
|
||||
tableVolumes->resizeColumnsToContents();
|
||||
|
||||
tableVolumes->setFixedSize(619,341);
|
||||
|
||||
if(model != 0)
|
||||
delete model;
|
||||
|
||||
model = tempM;
|
||||
|
||||
if(model->rowCount()>0)
|
||||
{
|
||||
tableVolumes->selectRow(0);
|
||||
loadVolumeInfo(proxyModel->index(0,0));
|
||||
}
|
||||
|
||||
tableVolumes->setColumnWidth(0,350);
|
||||
|
||||
ScraperSelector::load(json,searchString);
|
||||
}
|
||||
|
||||
SelectVolume::~SelectVolume() {}
|
||||
|
||||
void SelectVolume::loadVolumeInfo(const QModelIndex & omi)
|
||||
{
|
||||
QModelIndex mi = proxyModel->mapToSource(omi);
|
||||
QString coverURL = model->getCoverURL(mi);
|
||||
QString id = model->getVolumeId(mi);
|
||||
|
||||
QString loadingStyle = "<font color='#AAAAAA'>%1</font>";
|
||||
cover->setText(loadingStyle.arg(tr("loading cover")));
|
||||
detailLabel->setAltText(loadingStyle.arg(tr("loading description")));
|
||||
|
||||
ComicVineClient * comicVineClient = new ComicVineClient;
|
||||
connect(comicVineClient,SIGNAL(seriesCover(const QByteArray &)),this,SLOT(setCover(const QByteArray &)));
|
||||
connect(comicVineClient,SIGNAL(finished()),comicVineClient,SLOT(deleteLater()));
|
||||
comicVineClient->getSeriesCover(coverURL);
|
||||
|
||||
ComicVineClient * comicVineClient2 = new ComicVineClient;
|
||||
connect(comicVineClient2,SIGNAL(seriesDetail(QString)),this,SLOT(setDescription(QString)));
|
||||
connect(comicVineClient2,SIGNAL(finished()),comicVineClient2,SLOT(deleteLater()));
|
||||
comicVineClient2->getSeriesDetail(id);
|
||||
}
|
||||
|
||||
void SelectVolume::setCover(const QByteArray & data)
|
||||
{
|
||||
QPixmap p;
|
||||
p.loadFromData(data);
|
||||
int w = p.width();
|
||||
int h = p.height();
|
||||
|
||||
cover->setPixmap(p);
|
||||
float aspectRatio = static_cast<float>(w)/h;
|
||||
|
||||
cover->setFixedSize(180,static_cast<int>(180/aspectRatio));
|
||||
|
||||
cover->update();
|
||||
}
|
||||
|
||||
void SelectVolume::setDescription(const QString & jsonDetail)
|
||||
{
|
||||
QScriptEngine engine;
|
||||
QScriptValue sc;
|
||||
sc = engine.evaluate("(" + jsonDetail + ")");
|
||||
|
||||
if (!sc.property("error").isValid() && sc.property("error").toString() != "OK")
|
||||
{
|
||||
qDebug("Error detected");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
QScriptValue descriptionValues = sc.property("results").property("description");
|
||||
bool valid = !descriptionValues.isNull() && descriptionValues.isValid();
|
||||
detailLabel->setText(valid?descriptionValues.toString().replace("<a","<a style = 'color:#827A68; text-decoration:none;'"):tr("description unavailable"));
|
||||
}
|
||||
}
|
||||
|
||||
QString SelectVolume::getSelectedVolumeId()
|
||||
{
|
||||
return model->getVolumeId(proxyModel->mapToSource(tableVolumes->currentIndex()));
|
||||
}
|
||||
|
||||
int SelectVolume::getSelectedVolumeNumIssues()
|
||||
{
|
||||
return model->getNumIssues(proxyModel->mapToSource(tableVolumes->currentIndex()));
|
||||
}
|
||||
|
||||
QString SelectVolume::getSelectedVolumePublisher()
|
||||
{
|
||||
return model->getPublisher(proxyModel->mapToSource(tableVolumes->currentIndex()));
|
||||
}
|
||||
|
||||
|
||||
39
YACReaderLibrary/comic_vine/select_volume.h
Normal file
39
YACReaderLibrary/comic_vine/select_volume.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef SELECT_VOLUME_H
|
||||
#define SELECT_VOLUME_H
|
||||
|
||||
#include "scraper_selector.h"
|
||||
|
||||
class QLabel;
|
||||
class VolumesModel;
|
||||
class QModelIndex;
|
||||
class QToolButton;
|
||||
class QSortFilterProxyModel;
|
||||
|
||||
class ScraperScrollLabel;
|
||||
class ScraperTableView;
|
||||
|
||||
class SelectVolume : public ScraperSelector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SelectVolume(QWidget * parent = 0);
|
||||
void load(const QString & json, const QString & searchString);
|
||||
virtual ~SelectVolume();
|
||||
|
||||
public slots:
|
||||
void loadVolumeInfo(const QModelIndex & mi);
|
||||
void setCover(const QByteArray &);
|
||||
void setDescription(const QString & jsonDetail);
|
||||
QString getSelectedVolumeId();
|
||||
int getSelectedVolumeNumIssues();
|
||||
QString getSelectedVolumePublisher();
|
||||
|
||||
private:
|
||||
QLabel * cover;
|
||||
ScraperScrollLabel * detailLabel;
|
||||
ScraperTableView * tableVolumes;
|
||||
VolumesModel * model;
|
||||
QSortFilterProxyModel * proxyModel;
|
||||
};
|
||||
|
||||
#endif // SELECT_VOLUME_H
|
||||
46
YACReaderLibrary/comic_vine/series_question.cpp
Normal file
46
YACReaderLibrary/comic_vine/series_question.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "series_question.h"
|
||||
|
||||
#include <QRadioButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
|
||||
|
||||
SeriesQuestion::SeriesQuestion(QWidget * parent)
|
||||
:QWidget(parent)
|
||||
{
|
||||
QVBoxLayout * l = new QVBoxLayout;
|
||||
|
||||
QLabel * questionLabel = new QLabel(tr("You are trying to get information for various comics at once, are they part of the same series?"));
|
||||
questionLabel->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}");
|
||||
yes = new QRadioButton(tr("yes"));
|
||||
no = new QRadioButton(tr("no"));
|
||||
|
||||
QString rbStyle = "QRadioButton {margin-left:27px; margin-top:5px; color:white;font-size:12px;font-family:Arial;}"
|
||||
"QRadioButton::indicator {width:11px;height:11px;}"
|
||||
"QRadioButton::indicator::unchecked {image : url(:/images/comic_vine/radioUnchecked.png);}"
|
||||
"QRadioButton::indicator::checked {image : url(:/images/comic_vine/radioChecked.png);}";
|
||||
yes->setStyleSheet(rbStyle);
|
||||
no->setStyleSheet(rbStyle);
|
||||
|
||||
yes->setChecked(true);
|
||||
|
||||
l->addSpacing(35);
|
||||
l->addWidget(questionLabel);
|
||||
l->addWidget(yes);
|
||||
l->addWidget(no);
|
||||
l->addStretch();
|
||||
|
||||
l->setContentsMargins(0,0,0,0);
|
||||
setLayout(l);
|
||||
setContentsMargins(0,0,0,0);
|
||||
}
|
||||
|
||||
bool SeriesQuestion::getYes()
|
||||
{
|
||||
return yes->isChecked();
|
||||
}
|
||||
|
||||
void SeriesQuestion::setYes(bool y)
|
||||
{
|
||||
yes->setChecked(y);
|
||||
}
|
||||
23
YACReaderLibrary/comic_vine/series_question.h
Normal file
23
YACReaderLibrary/comic_vine/series_question.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef SERIES_QUESTION_H
|
||||
#define SERIES_QUESTION_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QRadioButton;
|
||||
|
||||
class SeriesQuestion : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SeriesQuestion(QWidget * parent = 0);
|
||||
bool getYes();
|
||||
void setYes(bool yes = true);
|
||||
|
||||
private:
|
||||
QRadioButton * yes;
|
||||
QRadioButton * no;
|
||||
};
|
||||
|
||||
|
||||
#endif // SERIES_QUESTION_H
|
||||
224
YACReaderLibrary/comic_vine/sort_volume_comics.cpp
Normal file
224
YACReaderLibrary/comic_vine/sort_volume_comics.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
#include "sort_volume_comics.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QScrollBar>
|
||||
#include <QAction>
|
||||
|
||||
#include "scraper_tableview.h"
|
||||
#include "local_comic_list_model.h"
|
||||
#include "volume_comics_model.h"
|
||||
|
||||
SortVolumeComics::SortVolumeComics(QWidget *parent) :
|
||||
ScraperSelector(parent)
|
||||
{
|
||||
QString labelStylesheet = "QLabel {color:white; font-size:12px;font-family:Arial;}";
|
||||
|
||||
QLabel * label = new QLabel(tr("Please, sort the list of comics on the left until it matches the comics' information."));
|
||||
label->setStyleSheet(labelStylesheet);
|
||||
|
||||
QLabel * sortLabel = new QLabel(tr("sort comics to match comic information"));
|
||||
sortLabel->setStyleSheet(labelStylesheet);
|
||||
|
||||
moveUpButtonCL = new ScrapperToolButton(ScrapperToolButton::LEFT);
|
||||
moveUpButtonCL->setIcon(QIcon(":/images/comic_vine/rowUp.png"));
|
||||
moveUpButtonCL->setAutoRepeat(true);
|
||||
moveDownButtonCL = new ScrapperToolButton(ScrapperToolButton::RIGHT);
|
||||
moveDownButtonCL->setIcon(QIcon(":/images/comic_vine/rowDown.png"));
|
||||
moveDownButtonCL->setAutoRepeat(true);
|
||||
//moveUpButtonIL = new ScrapperToolButton(ScrapperToolButton::LEFT);
|
||||
//moveUpButtonIL->setIcon(QIcon(":/images/comic_vine/rowUp.png"));
|
||||
//moveDownButtonIL = new ScrapperToolButton(ScrapperToolButton::RIGHT);
|
||||
//moveDownButtonIL->setIcon(QIcon(":/images/comic_vine/rowDown.png"));
|
||||
|
||||
connect(moveUpButtonCL,SIGNAL(clicked()),this,SLOT(moveUpCL()));
|
||||
connect(moveDownButtonCL,SIGNAL(clicked()),this,SLOT(moveDownCL()));
|
||||
//connect(moveUpButtonIL,SIGNAL(clicked()),this,SLOT(moveUpIL()));
|
||||
//connect(moveUpButtonIL,SIGNAL(clicked()),this,SLOT(moveDownIL()));
|
||||
|
||||
QVBoxLayout * l = new QVBoxLayout;
|
||||
QHBoxLayout * content = new QHBoxLayout;
|
||||
QHBoxLayout * sortButtonsLayout = new QHBoxLayout;
|
||||
|
||||
tableFiles = new ScraperTableView();
|
||||
tableVolumeComics = new ScraperTableView();
|
||||
|
||||
tableFiles->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
tableFiles->setSelectionMode(QAbstractItemView::ContiguousSelection);
|
||||
|
||||
tableFiles->setFixedSize(407,341);
|
||||
tableVolumeComics->setFixedSize(407,341);
|
||||
content->addWidget(tableFiles,0,Qt::AlignLeft|Qt::AlignTop);
|
||||
content->addWidget(tableVolumeComics,0,Qt::AlignRight|Qt::AlignTop);
|
||||
//content->addWidget(tableVolumes,0,Qt::AlignRight|Qt::AlignTop);
|
||||
|
||||
connect(tableVolumeComics->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(synchronizeScroll(int)));
|
||||
connect(tableFiles->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(synchronizeScroll(int)));
|
||||
|
||||
//connect(tableVolumeComics, SIGNAL(pressed(QModelIndex)), tableFiles, SLOT(setCurrentIndex(QModelIndex)));
|
||||
//connect(tableFiles, SIGNAL(pressed(QModelIndex)), tableVolumeComics, SLOT(setCurrentIndex(QModelIndex)));
|
||||
|
||||
paginator->setCustomLabel(tr("issues"));
|
||||
paginator->setMinimumWidth(422);
|
||||
|
||||
sortButtonsLayout->addWidget(moveUpButtonCL);
|
||||
sortButtonsLayout->addWidget(ScrapperToolButton::getSeparator());
|
||||
sortButtonsLayout->addWidget(moveDownButtonCL);
|
||||
sortButtonsLayout->addSpacing(10);
|
||||
//sortButtonsLayout->addStretch();
|
||||
sortButtonsLayout->addWidget(sortLabel);
|
||||
sortButtonsLayout->addStretch();
|
||||
sortButtonsLayout->addWidget(paginator);
|
||||
//sortButtonsLayout->addStretch();
|
||||
//sortButtonsLayout->addWidget(moveUpButtonIL);
|
||||
//sortButtonsLayout->addWidget(ScrapperToolButton::getSeparator());
|
||||
//sortButtonsLayout->addWidget(moveDownButtonIL);
|
||||
sortButtonsLayout->setSpacing(0);
|
||||
|
||||
l->addSpacing(15);
|
||||
l->addWidget(label);
|
||||
l->addSpacing(5);
|
||||
l->addLayout(content);
|
||||
l->addLayout(sortButtonsLayout);
|
||||
l->addStretch();
|
||||
|
||||
l->setContentsMargins(0,0,0,0);
|
||||
setLayout(l);
|
||||
setContentsMargins(0,0,0,0);
|
||||
|
||||
//rows actions
|
||||
QAction * removeItemFromList = new QAction(tr("remove selected comics"),this);
|
||||
QAction * restoreAllItems = new QAction(tr("restore all removed comics"),this);
|
||||
QAction * restoreItems = new QAction(tr("restore removed comics"),this);
|
||||
|
||||
tableFiles->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
tableFiles->addAction(removeItemFromList);
|
||||
tableFiles->addAction(restoreAllItems);
|
||||
//tableFiles->addAction(restoreItems);
|
||||
|
||||
connect(removeItemFromList,SIGNAL(triggered()),this,SLOT(removeSelectedComics()));
|
||||
connect(restoreAllItems,SIGNAL(triggered()),this,SLOT(restoreAllComics()));
|
||||
connect(restoreItems,SIGNAL(triggered()),this,SLOT(showRemovedComicsSelector()));
|
||||
}
|
||||
|
||||
void SortVolumeComics::setData(QList<ComicDB> & comics, const QString &json, const QString &vID)
|
||||
{
|
||||
//set up models
|
||||
localComicsModel = new LocalComicListModel;
|
||||
localComicsModel->load(comics);
|
||||
|
||||
volumeComicsModel = new VolumeComicsModel;
|
||||
volumeComicsModel->load(json);
|
||||
|
||||
int numLocalComics = localComicsModel->rowCount();
|
||||
int numVolumeComics = volumeComicsModel->rowCount();
|
||||
|
||||
if(numLocalComics > numVolumeComics)
|
||||
volumeComicsModel->addExtraRows(numLocalComics - numVolumeComics);
|
||||
if(numLocalComics < numVolumeComics)
|
||||
localComicsModel->addExtraRows(numVolumeComics - numLocalComics);
|
||||
|
||||
tableFiles->setModel(localComicsModel);
|
||||
tableVolumeComics->setModel(volumeComicsModel);
|
||||
|
||||
tableVolumeComics->resizeColumnToContents(0);
|
||||
|
||||
ScraperSelector::load(json,vID);
|
||||
}
|
||||
|
||||
void SortVolumeComics::synchronizeScroll(int pos)
|
||||
{
|
||||
void * senderObject = sender();
|
||||
|
||||
if(senderObject == 0) //invalid call
|
||||
return;
|
||||
|
||||
QScrollBar * tableVolumeComicsScrollBar = tableVolumeComics->verticalScrollBar();
|
||||
QScrollBar * tableFilesScrollBar = tableFiles->verticalScrollBar();
|
||||
|
||||
if(senderObject == tableVolumeComicsScrollBar)
|
||||
{
|
||||
disconnect(tableFilesScrollBar,SIGNAL(valueChanged(int)),this,0);
|
||||
tableFilesScrollBar->setValue(pos);
|
||||
connect(tableFilesScrollBar, SIGNAL(valueChanged(int)), this, SLOT(synchronizeScroll(int)));
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnect(tableVolumeComicsScrollBar,SIGNAL(valueChanged(int)),this,0);
|
||||
tableVolumeComicsScrollBar->setValue(pos);
|
||||
connect(tableVolumeComicsScrollBar, SIGNAL(valueChanged(int)), this, SLOT(synchronizeScroll(int)));
|
||||
}
|
||||
}
|
||||
|
||||
void SortVolumeComics::moveUpCL()
|
||||
{
|
||||
QList<QModelIndex> selection = tableFiles->selectionModel()->selectedIndexes();
|
||||
|
||||
if(selection.count() == 0)
|
||||
return;
|
||||
|
||||
localComicsModel->moveSelectionUp(selection);
|
||||
|
||||
selection = tableFiles->selectionModel()->selectedIndexes();
|
||||
tableFiles->scrollTo(selection.first());
|
||||
}
|
||||
|
||||
void SortVolumeComics::moveDownCL()
|
||||
{
|
||||
QList<QModelIndex> selection = tableFiles->selectionModel()->selectedIndexes();
|
||||
|
||||
if(selection.count() > 0)
|
||||
localComicsModel->moveSelectionDown(selection);
|
||||
|
||||
selection = tableFiles->selectionModel()->selectedIndexes();
|
||||
tableFiles->scrollTo(selection.last());
|
||||
}
|
||||
|
||||
void SortVolumeComics::moveUpIL()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SortVolumeComics::moveDownIL()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SortVolumeComics::removeSelectedComics()
|
||||
{
|
||||
QList<QModelIndex> selection = tableFiles->selectionModel()->selectedIndexes();
|
||||
|
||||
localComicsModel->removeComics(selection);
|
||||
}
|
||||
|
||||
void SortVolumeComics::restoreAllComics()
|
||||
{
|
||||
localComicsModel->restoreAll();
|
||||
}
|
||||
|
||||
void SortVolumeComics::showRemovedComicsSelector()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QList<QPair<ComicDB, QString> > SortVolumeComics::getMatchingInfo()
|
||||
{
|
||||
QList<ComicDB> comicList = localComicsModel->getData();
|
||||
QList<QPair<ComicDB, QString> > l;
|
||||
|
||||
int index = 0;
|
||||
|
||||
QString id;
|
||||
foreach(ComicDB c, comicList)
|
||||
{
|
||||
id = volumeComicsModel->getComicId(index);
|
||||
if(!c.getFileName().isEmpty() && !id.isEmpty()) //there is a valid comic, and valid comic ID
|
||||
{
|
||||
l.push_back(QPair<ComicDB, QString>(c,id));
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
99
YACReaderLibrary/comic_vine/sort_volume_comics.h
Normal file
99
YACReaderLibrary/comic_vine/sort_volume_comics.h
Normal file
@ -0,0 +1,99 @@
|
||||
#ifndef SORT_VOLUME_COMICS_H
|
||||
#define SORT_VOLUME_COMICS_H
|
||||
|
||||
#include "scraper_selector.h"
|
||||
|
||||
#include <QModelIndex>
|
||||
#include <QPushButton>
|
||||
#include <QPainter>
|
||||
|
||||
#include "comic_db.h"
|
||||
|
||||
class ScraperTableView;
|
||||
class LocalComicListModel;
|
||||
class VolumeComicsModel;
|
||||
|
||||
class ScrapperToolButton : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Appearance {
|
||||
DEFAULT,
|
||||
LEFT,
|
||||
RIGHT
|
||||
};
|
||||
|
||||
ScrapperToolButton(ScrapperToolButton::Appearance appearance = DEFAULT, QWidget * parent=0):QPushButton(parent),appearance(appearance) {
|
||||
setStyleSheet("QPushButton {border: none; background: #2e2e2e; color:white; border-radius:2px;}"
|
||||
"QPushButton::pressed {border: none; background: #282828; color:white; border-radius:2px;}");
|
||||
setFixedSize(18,17);
|
||||
}
|
||||
static QWidget * getSeparator(){QWidget * w = new QWidget; w->setFixedWidth(1); w->setStyleSheet("QWidget {background:#282828;}"); return w;}
|
||||
void setAppearance(ScrapperToolButton::Appearance appearance){this->appearance = appearance;}
|
||||
virtual ~ScrapperToolButton() {}
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent * e)
|
||||
{
|
||||
QPainter p(this);
|
||||
|
||||
switch (appearance) {
|
||||
case LEFT:
|
||||
p.fillRect(16,0,2,18,QColor("#2E2E2E"));
|
||||
break;
|
||||
case RIGHT:
|
||||
p.fillRect(0,0,2,18,QColor("#2E2E2E"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
QPushButton::paintEvent(e);
|
||||
}
|
||||
|
||||
private:
|
||||
Appearance appearance;
|
||||
};
|
||||
|
||||
|
||||
class SortVolumeComics : public ScraperSelector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SortVolumeComics(QWidget *parent = 0);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void setData(QList<ComicDB> & comics, const QString & json, const QString & vID);
|
||||
QList<QPair<ComicDB,QString> > getMatchingInfo();
|
||||
|
||||
protected slots:
|
||||
void synchronizeScroll(int pos);
|
||||
void moveUpCL();
|
||||
void moveDownCL();
|
||||
void moveUpIL();
|
||||
void moveDownIL();
|
||||
|
||||
void removeSelectedComics();
|
||||
void restoreAllComics();
|
||||
void showRemovedComicsSelector();
|
||||
|
||||
|
||||
private:
|
||||
ScraperTableView * tableFiles;
|
||||
ScraperTableView * tableVolumeComics;
|
||||
|
||||
LocalComicListModel * localComicsModel;
|
||||
VolumeComicsModel * volumeComicsModel;
|
||||
|
||||
ScrapperToolButton * moveUpButtonCL;
|
||||
ScrapperToolButton * moveDownButtonCL;
|
||||
ScrapperToolButton * moveUpButtonIL;
|
||||
ScrapperToolButton * moveDownButtonIL;
|
||||
|
||||
};
|
||||
|
||||
#endif // SORT_VOLUME_COMICS_H
|
||||
53
YACReaderLibrary/comic_vine/title_header.cpp
Normal file
53
YACReaderLibrary/comic_vine/title_header.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#include "title_header.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
TitleHeader::TitleHeader(QWidget * parent )
|
||||
:QWidget(parent)
|
||||
{
|
||||
mainTitleLabel = new QLabel();
|
||||
subTitleLabel = new QLabel();
|
||||
|
||||
mainTitleLabel->setStyleSheet("QLabel {color:white; font-size:18px;font-family:Arial;}");
|
||||
subTitleLabel->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}");
|
||||
|
||||
QHBoxLayout * titleLayout = new QHBoxLayout;
|
||||
QVBoxLayout * titleLabelsLayout = new QVBoxLayout;
|
||||
|
||||
titleLabelsLayout->addWidget(mainTitleLabel);
|
||||
titleLabelsLayout->addWidget(subTitleLabel);
|
||||
titleLabelsLayout->setSpacing(0);
|
||||
|
||||
titleLayout->addLayout(titleLabelsLayout);
|
||||
titleLayout->setContentsMargins(0,0,0,0);
|
||||
|
||||
setLayout(titleLayout);
|
||||
|
||||
setContentsMargins(0,0,0,0);
|
||||
|
||||
setTitle(tr("SEARCH"));
|
||||
}
|
||||
|
||||
void TitleHeader::setTitle(const QString & title)
|
||||
{
|
||||
mainTitleLabel->setText(title);
|
||||
}
|
||||
|
||||
void TitleHeader::setSubTitle(const QString & title)
|
||||
{
|
||||
subTitleLabel->setText(title);
|
||||
}
|
||||
|
||||
void TitleHeader::showButtons(bool show)
|
||||
{
|
||||
if(show)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
22
YACReaderLibrary/comic_vine/title_header.h
Normal file
22
YACReaderLibrary/comic_vine/title_header.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef TITLE_HEADER_H
|
||||
#define TITLE_HEADER_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QLabel;
|
||||
|
||||
class TitleHeader : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TitleHeader(QWidget * parent = 0);
|
||||
public slots:
|
||||
void setTitle(const QString & title);
|
||||
void setSubTitle(const QString & title);
|
||||
void showButtons(bool show);
|
||||
private:
|
||||
QLabel * mainTitleLabel;
|
||||
QLabel * subTitleLabel;
|
||||
};
|
||||
|
||||
#endif // TITLE_HEADER_H
|
||||
29
YACReaderLibrary/comics_remover.cpp
Normal file
29
YACReaderLibrary/comics_remover.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
#include "comics_remover.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
ComicsRemover::ComicsRemover(QModelIndexList & il, QList<QString> & ps, QObject *parent) :
|
||||
QThread(parent),indexList(il), paths(ps)
|
||||
{
|
||||
}
|
||||
|
||||
void ComicsRemover::run()
|
||||
{
|
||||
QString currentComicPath;
|
||||
QListIterator<QModelIndex> i(indexList);
|
||||
QListIterator<QString> i2(paths);
|
||||
i.toBack();
|
||||
i2.toBack();
|
||||
|
||||
while (i.hasPrevious() && i2.hasPrevious())
|
||||
{
|
||||
QModelIndex mi = i.previous();
|
||||
currentComicPath = i2.previous();
|
||||
if(QFile::remove(currentComicPath))
|
||||
emit remove(mi.row());
|
||||
else
|
||||
emit removeError();
|
||||
}
|
||||
|
||||
emit finished();
|
||||
}
|
||||
28
YACReaderLibrary/comics_remover.h
Normal file
28
YACReaderLibrary/comics_remover.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef COMICS_REMOVER_H
|
||||
#define COMICS_REMOVER_H
|
||||
|
||||
#include <QThread>
|
||||
|
||||
#include <QModelIndex>
|
||||
#include <comic_db.h>
|
||||
|
||||
class ComicsRemover : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ComicsRemover(QModelIndexList & indexList, QList<QString> & paths, QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
void remove(int);
|
||||
void removeError();
|
||||
void finished();
|
||||
|
||||
private:
|
||||
void run();
|
||||
|
||||
private:
|
||||
QModelIndexList indexList;
|
||||
QList<QString> paths;
|
||||
};
|
||||
|
||||
#endif // COMICS_REMOVER_H
|
||||
206
YACReaderLibrary/create_library_dialog.cpp
Normal file
206
YACReaderLibrary/create_library_dialog.cpp
Normal file
@ -0,0 +1,206 @@
|
||||
#include "create_library_dialog.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QFileDialog>
|
||||
#include <QSizePolicy>
|
||||
#include <QMessageBox>
|
||||
|
||||
CreateLibraryDialog::CreateLibraryDialog(QWidget * parent)
|
||||
:QDialog(parent)
|
||||
{
|
||||
setupUI();
|
||||
}
|
||||
|
||||
void CreateLibraryDialog::setupUI()
|
||||
{
|
||||
textLabel = new QLabel(tr("Comics folder : "));
|
||||
path = new QLineEdit;
|
||||
textLabel->setBuddy(path);
|
||||
connect(path,SIGNAL(textChanged(QString)),this,SLOT(pathSetted(QString)));
|
||||
|
||||
nameLabel = new QLabel(tr("Library Name : "));
|
||||
nameEdit = new QLineEdit;
|
||||
nameLabel->setBuddy(nameEdit);
|
||||
connect(nameEdit,SIGNAL(textChanged(QString)),this,SLOT(nameSetted(QString)));
|
||||
|
||||
accept = new QPushButton(tr("Create"));
|
||||
accept->setDisabled(true);
|
||||
connect(accept,SIGNAL(clicked()),this,SLOT(create()));
|
||||
|
||||
cancel = new QPushButton(tr("Cancel"));
|
||||
connect(cancel,SIGNAL(clicked()),this,SIGNAL(cancelCreate()));
|
||||
connect(cancel,SIGNAL(clicked()),this,SLOT(close()));
|
||||
|
||||
find = new QPushButton(QIcon(":/images/find_folder.png"),"");
|
||||
connect(find,SIGNAL(clicked()),this,SLOT(findPath()));
|
||||
|
||||
QGridLayout * content = new QGridLayout;
|
||||
|
||||
//QHBoxLayout *nameLayout = new QHBoxLayout;
|
||||
|
||||
content->addWidget(nameLabel,0,0);
|
||||
content->addWidget(nameEdit,0,1);
|
||||
|
||||
//QHBoxLayout *libraryLayout = new QHBoxLayout;
|
||||
|
||||
content->addWidget(textLabel,1,0);
|
||||
content->addWidget(path,1,1);
|
||||
content->addWidget(find,1,2);
|
||||
content->setColumnMinimumWidth(2,0); //TODO
|
||||
|
||||
QHBoxLayout *bottomLayout = new QHBoxLayout;
|
||||
bottomLayout->addWidget(message = new QLabel(tr("Create a library could take several minutes. You can stop the process and update the library later for completing the task.")));
|
||||
message->setWordWrap(true);
|
||||
//message->hide();
|
||||
bottomLayout->addStretch();
|
||||
bottomLayout->addWidget(accept);
|
||||
bottomLayout->addWidget(cancel);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(content);
|
||||
|
||||
mainLayout->addLayout(bottomLayout);
|
||||
|
||||
QHBoxLayout * imgMainLayout = new QHBoxLayout;
|
||||
QLabel * imgLabel = new QLabel(this);
|
||||
QPixmap p(":/images/new.png");
|
||||
imgLabel->setPixmap(p);
|
||||
imgMainLayout->addWidget(imgLabel);
|
||||
imgMainLayout->addLayout(mainLayout);
|
||||
|
||||
setLayout(imgMainLayout);
|
||||
|
||||
setModal(true);
|
||||
setWindowTitle(tr("Create new library"));
|
||||
}
|
||||
|
||||
void CreateLibraryDialog::show(const YACReaderLibraries & libs)
|
||||
{
|
||||
libraries = libs;
|
||||
QDialog::show();
|
||||
}
|
||||
|
||||
void CreateLibraryDialog::create()
|
||||
{
|
||||
|
||||
QFileInfo f(path->text());
|
||||
if(f.exists() && f.isDir() && f.isWritable())
|
||||
{
|
||||
if(!libraries.contains(nameEdit->text()))
|
||||
{
|
||||
emit(createLibrary(QDir::cleanPath(path->text()),QDir::cleanPath(path->text())+"/.yacreaderlibrary",nameEdit->text()));
|
||||
close();
|
||||
}
|
||||
else
|
||||
emit(libraryExists(nameEdit->text()));
|
||||
}
|
||||
else
|
||||
QMessageBox::critical(NULL,tr("Path not found"),tr("The selected path does not exist or is not a valid path. Be sure that you have write access to this folder"));
|
||||
}
|
||||
|
||||
void CreateLibraryDialog::nameSetted(const QString & text)
|
||||
{
|
||||
if(!text.isEmpty())
|
||||
{
|
||||
if(!path->text().isEmpty())
|
||||
{
|
||||
QFileInfo fi(path->text());
|
||||
if(fi.isDir())
|
||||
accept->setEnabled(true);
|
||||
else
|
||||
accept->setEnabled(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
accept->setEnabled(false);
|
||||
}
|
||||
|
||||
void CreateLibraryDialog::pathSetted(const QString & text)
|
||||
{
|
||||
QFileInfo fi(text);
|
||||
if(fi.isDir())
|
||||
{
|
||||
if(!nameEdit->text().isEmpty())
|
||||
accept->setEnabled(true);
|
||||
}
|
||||
else
|
||||
accept->setEnabled(false);
|
||||
}
|
||||
|
||||
void CreateLibraryDialog::findPath()
|
||||
{
|
||||
QString s = QFileDialog::getExistingDirectory(0,"Comics directory",".");
|
||||
if(!s.isEmpty())
|
||||
{
|
||||
path->setText(s);
|
||||
if(!nameEdit->text().isEmpty())
|
||||
accept->setEnabled(true);
|
||||
}
|
||||
else
|
||||
accept->setEnabled(false);
|
||||
}
|
||||
|
||||
void CreateLibraryDialog::close()
|
||||
{
|
||||
path->clear();
|
||||
nameEdit->clear();
|
||||
accept->setEnabled(false);
|
||||
QDialog::close();
|
||||
}
|
||||
|
||||
void CreateLibraryDialog::setDataAndStart(QString name, QString path)
|
||||
{
|
||||
this->path->setText(path);
|
||||
this->nameEdit->setText(name);
|
||||
QDialog::show();
|
||||
create();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// UpdateLibraryDialog
|
||||
//-----------------------------------------------------------------------------
|
||||
UpdateLibraryDialog::UpdateLibraryDialog(QWidget * parent)
|
||||
:QDialog(parent)
|
||||
{
|
||||
QVBoxLayout * mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(message = new QLabel(tr("Updating....")));
|
||||
mainLayout->addWidget(currentFileLabel = new QLabel("\n\n\n\n"));
|
||||
currentFileLabel->setWordWrap(true);
|
||||
|
||||
QHBoxLayout * bottom = new QHBoxLayout;
|
||||
bottom->addStretch();
|
||||
bottom->addWidget(cancel = new QPushButton(tr("Cancel")));
|
||||
|
||||
connect(cancel,SIGNAL(clicked()),this,SIGNAL(cancelUpdate()));
|
||||
connect(cancel,SIGNAL(clicked()),this,SLOT(close()));
|
||||
|
||||
mainLayout->addStretch();
|
||||
|
||||
mainLayout->addLayout(bottom);
|
||||
|
||||
QHBoxLayout * imgMainLayout = new QHBoxLayout;
|
||||
QLabel * imgLabel = new QLabel(this);
|
||||
QPixmap p(":/images/updateLibrary.png");
|
||||
imgLabel->setPixmap(p);
|
||||
imgMainLayout->addWidget(imgLabel);
|
||||
imgMainLayout->addLayout(mainLayout);
|
||||
|
||||
setLayout(imgMainLayout);
|
||||
|
||||
setModal(true);
|
||||
setWindowTitle(tr("Update library"));
|
||||
}
|
||||
|
||||
void UpdateLibraryDialog::showCurrentFile(QString file)
|
||||
{
|
||||
currentFileLabel->setText(file);
|
||||
currentFileLabel->update();
|
||||
this->update();
|
||||
}
|
||||
|
||||
void UpdateLibraryDialog::close()
|
||||
{
|
||||
currentFileLabel->setText("");
|
||||
this->adjustSize();
|
||||
QDialog::close();
|
||||
}
|
||||
61
YACReaderLibrary/create_library_dialog.h
Normal file
61
YACReaderLibrary/create_library_dialog.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef __CREATE_LIBRARY_DIALOG_H
|
||||
#define __CREATE_LIBRARY_DIALOG_H
|
||||
|
||||
#include "yacreader_libraries.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QThread>
|
||||
#include <QProgressBar>
|
||||
|
||||
class CreateLibraryDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CreateLibraryDialog(QWidget * parent = 0);
|
||||
private:
|
||||
QLabel * nameLabel;
|
||||
QLabel * textLabel;
|
||||
QLabel * message;
|
||||
QProgressBar *progressBar;
|
||||
QLineEdit * path;
|
||||
QLineEdit * nameEdit;
|
||||
QPushButton * find;
|
||||
QPushButton * accept;
|
||||
QPushButton * cancel;
|
||||
YACReaderLibraries libraries;
|
||||
void setupUI();
|
||||
public slots:
|
||||
void create();
|
||||
void findPath();
|
||||
void close();
|
||||
void setDataAndStart(QString name, QString paht);
|
||||
void nameSetted(const QString & text);
|
||||
void pathSetted(const QString & text);
|
||||
void show(const YACReaderLibraries &libraries);
|
||||
signals:
|
||||
void createLibrary(QString source, QString target, QString name);
|
||||
void cancelCreate();
|
||||
void libraryExists(const QString & name);
|
||||
};
|
||||
|
||||
class UpdateLibraryDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
UpdateLibraryDialog(QWidget * parent = 0);
|
||||
private:
|
||||
QLabel * message;
|
||||
QLabel * currentFileLabel;
|
||||
QProgressBar *progressBar;
|
||||
QPushButton * cancel;
|
||||
public slots:
|
||||
void showCurrentFile(QString file);
|
||||
void close();
|
||||
signals:
|
||||
void cancelUpdate();
|
||||
};
|
||||
|
||||
#endif
|
||||
686
YACReaderLibrary/db/data_base_management.cpp
Normal file
686
YACReaderLibrary/db/data_base_management.cpp
Normal file
@ -0,0 +1,686 @@
|
||||
#include "data_base_management.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include "library_creator.h"
|
||||
#include "check_new_version.h"
|
||||
|
||||
static QString fields = "title ,"
|
||||
|
||||
"coverPage,"
|
||||
"numPages,"
|
||||
|
||||
"number,"
|
||||
"isBis,"
|
||||
"count,"
|
||||
|
||||
"volume,"
|
||||
"storyArc,"
|
||||
"arcNumber,"
|
||||
"arcCount,"
|
||||
|
||||
"genere,"
|
||||
|
||||
"writer,"
|
||||
"penciller,"
|
||||
"inker,"
|
||||
"colorist,"
|
||||
"letterer,"
|
||||
"coverArtist,"
|
||||
|
||||
"date,"
|
||||
"publisher,"
|
||||
"format,"
|
||||
"color,"
|
||||
"ageRating,"
|
||||
|
||||
"synopsis,"
|
||||
"characters,"
|
||||
"notes,"
|
||||
|
||||
"comicVineID,"
|
||||
|
||||
"hash"
|
||||
;
|
||||
|
||||
DataBaseManagement::DataBaseManagement()
|
||||
:QObject(),dataBasesList()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*TreeModel * DataBaseManagement::newTreeModel(QString path)
|
||||
{
|
||||
//la consulta se ejecuta...
|
||||
QSqlQuery selectQuery(loadDatabase(path));
|
||||
selectQuery.setForwardOnly(true);
|
||||
selectQuery.exec("select * from folder order by parentId,name");
|
||||
//selectQuery.finish();
|
||||
return new TreeModel(selectQuery);
|
||||
}*/
|
||||
|
||||
QSqlDatabase DataBaseManagement::createDatabase(QString name, QString path)
|
||||
{
|
||||
return createDatabase(QDir::cleanPath(path) + "/" + name + ".ydb");
|
||||
}
|
||||
|
||||
QSqlDatabase DataBaseManagement::createDatabase(QString dest)
|
||||
{
|
||||
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE",dest);
|
||||
db.setDatabaseName(dest);
|
||||
if (!db.open())
|
||||
qDebug() << db.lastError();
|
||||
else {
|
||||
qDebug() << db.tables();
|
||||
}
|
||||
|
||||
{
|
||||
QSqlQuery pragma("PRAGMA foreign_keys = ON",db);
|
||||
//pragma.finish();
|
||||
DataBaseManagement::createTables(db);
|
||||
|
||||
QSqlQuery query("INSERT INTO folder (parentId, name, path) "
|
||||
"VALUES (1,'root', '/')",db);
|
||||
}
|
||||
//query.finish();
|
||||
//db.close();
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
QSqlDatabase DataBaseManagement::loadDatabase(QString path)
|
||||
{
|
||||
//TODO check path
|
||||
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE",path);
|
||||
db.setDatabaseName(path+"/library.ydb");
|
||||
if (!db.open()) {
|
||||
//se devuelve una base de datos vac<61>a e inv<6E>lida
|
||||
|
||||
return QSqlDatabase();
|
||||
}
|
||||
QSqlQuery pragma("PRAGMA foreign_keys = ON",db);
|
||||
//pragma.finish();
|
||||
//devuelve la base de datos
|
||||
return db;
|
||||
}
|
||||
|
||||
QSqlDatabase DataBaseManagement::loadDatabaseFromFile(QString filePath)
|
||||
{
|
||||
//TODO check path
|
||||
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE",filePath);
|
||||
db.setDatabaseName(filePath);
|
||||
if (!db.open()) {
|
||||
//se devuelve una base de datos vac<61>a e inv<6E>lida
|
||||
|
||||
return QSqlDatabase();
|
||||
}
|
||||
{
|
||||
QSqlQuery pragma("PRAGMA foreign_keys = ON",db);
|
||||
}
|
||||
//pragma.finish();
|
||||
//devuelve la base de datos
|
||||
return db;
|
||||
}
|
||||
|
||||
bool DataBaseManagement::createTables(QSqlDatabase & database)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
//FOLDER (representa una carpeta en disco)
|
||||
{
|
||||
QSqlQuery queryFolder(database);
|
||||
queryFolder.prepare("CREATE TABLE folder ("
|
||||
"id INTEGER PRIMARY KEY,"
|
||||
"parentId INTEGER NOT NULL,"
|
||||
"name TEXT NOT NULL,"
|
||||
"path TEXT NOT NULL,"
|
||||
//new 7.1 fields
|
||||
"finished BOOLEAN DEFAULT 0," //reading
|
||||
"completed BOOLEAN DEFAULT 1," //collecting
|
||||
//--
|
||||
"FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE)");
|
||||
success = success && queryFolder.exec();
|
||||
//queryFolder.finish();
|
||||
//COMIC INFO (representa la informaci<63>n de un c<>mic, cada c<>mic tendr<64> un id<69>ntificador <20>nico formado por un hash sha1'de los primeros 512kb' + su tama<6D>o en bytes)
|
||||
QSqlQuery queryComicInfo(database);
|
||||
queryComicInfo.prepare("CREATE TABLE comic_info ("
|
||||
"id INTEGER PRIMARY KEY,"
|
||||
"title TEXT,"
|
||||
|
||||
"coverPage INTEGER DEFAULT 1,"
|
||||
"numPages INTEGER,"
|
||||
|
||||
"number INTEGER,"
|
||||
"isBis BOOLEAN,"
|
||||
"count INTEGER,"
|
||||
|
||||
"volume TEXT,"
|
||||
"storyArc TEXT,"
|
||||
"arcNumber INTEGER,"
|
||||
"arcCount INTEGER,"
|
||||
|
||||
"genere TEXT,"
|
||||
|
||||
"writer TEXT,"
|
||||
"penciller TEXT,"
|
||||
"inker TEXT,"
|
||||
"colorist TEXT,"
|
||||
"letterer TEXT,"
|
||||
"coverArtist TEXT,"
|
||||
|
||||
"date TEXT," //dd/mm/yyyy --> se mostrar<61> en 3 campos diferentes
|
||||
"publisher TEXT,"
|
||||
"format TEXT,"
|
||||
"color BOOLEAN,"
|
||||
"ageRating BOOLEAN,"
|
||||
|
||||
"synopsis TEXT,"
|
||||
"characters TEXT,"
|
||||
"notes TEXT,"
|
||||
|
||||
"hash TEXT UNIQUE NOT NULL,"
|
||||
"edited BOOLEAN DEFAULT 0,"
|
||||
"read BOOLEAN DEFAULT 0,"
|
||||
//new 7.0 fields
|
||||
|
||||
"hasBeenOpened BOOLEAN DEFAULT 0,"
|
||||
"rating INTEGER DEFAULT 0,"
|
||||
"currentPage INTEGER DEFAULT 1, "
|
||||
"bookmark1 INTEGER DEFAULT -1, "
|
||||
"bookmark2 INTEGER DEFAULT -1, "
|
||||
"bookmark3 INTEGER DEFAULT -1, "
|
||||
"brightness INTEGER DEFAULT -1, "
|
||||
"contrast INTEGER DEFAULT -1, "
|
||||
"gamma INTEGER DEFAULT -1, "
|
||||
//new 7.1 fields
|
||||
"comicVineID TEXT"
|
||||
|
||||
")");
|
||||
success = success && queryComicInfo.exec();
|
||||
//queryComicInfo.finish();
|
||||
|
||||
//COMIC (representa un c<>mic en disco, contiene el nombre de fichero)
|
||||
QSqlQuery queryComic(database);
|
||||
queryComic.prepare("CREATE TABLE comic (id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, comicInfoId INTEGER NOT NULL, fileName TEXT NOT NULL, path TEXT, FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE, FOREIGN KEY(comicInfoId) REFERENCES comic_info(id))");
|
||||
success = success && queryComic.exec();
|
||||
//queryComic.finish();
|
||||
//DB INFO
|
||||
QSqlQuery queryDBInfo(database);
|
||||
queryDBInfo.prepare("CREATE TABLE db_info (version TEXT NOT NULL)");
|
||||
success = success && queryDBInfo.exec();
|
||||
//queryDBInfo.finish();
|
||||
|
||||
QSqlQuery query("INSERT INTO db_info (version) "
|
||||
"VALUES ('"VERSION"')",database);
|
||||
//query.finish();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
#include <qmessagebox.h>
|
||||
void DataBaseManagement::exportComicsInfo(QString source, QString dest)
|
||||
{
|
||||
//QSqlDatabase sourceDB = loadDatabase(source);
|
||||
QSqlDatabase destDB = loadDatabaseFromFile(dest);
|
||||
//sourceDB.open();
|
||||
{
|
||||
QSqlQuery attach(destDB);
|
||||
attach.prepare("ATTACH DATABASE '"+QDir().toNativeSeparators(dest) +"' AS dest;");
|
||||
//attach.bindValue(":dest",QDir().toNativeSeparators(dest));
|
||||
attach.exec();
|
||||
//attach.finish();
|
||||
|
||||
QSqlQuery attach2(destDB);
|
||||
attach2.prepare("ATTACH DATABASE '"+QDir().toNativeSeparators(source) +"' AS source;");
|
||||
attach2.exec();
|
||||
//attach2.finish();
|
||||
|
||||
//sourceDB.close();
|
||||
QSqlQuery queryDBInfo(destDB);
|
||||
queryDBInfo.prepare("CREATE TABLE dest.db_info (version TEXT NOT NULL)");
|
||||
queryDBInfo.exec();
|
||||
//queryDBInfo.finish();
|
||||
|
||||
/*QSqlQuery queryComicsInfo(sourceDB);
|
||||
queryComicsInfo.prepare("CREATE TABLE dest.comic_info (id INTEGER PRIMARY KEY, hash TEXT NOT NULL, edited BOOLEAN DEFAULT FALSE, title TEXT, read BOOLEAN)");
|
||||
queryComicsInfo.exec();*/
|
||||
|
||||
QSqlQuery query("INSERT INTO dest.db_info (version) "
|
||||
"VALUES ('"VERSION"')",destDB);
|
||||
//query.finish();
|
||||
|
||||
QSqlQuery exportData(destDB);
|
||||
exportData.prepare("create table dest.comic_info as select " + fields +
|
||||
" from source.comic_info where source.comic_info.edited = 1");
|
||||
exportData.exec();
|
||||
//exportData.finish();
|
||||
}
|
||||
|
||||
//sourceDB.close();
|
||||
destDB.close();
|
||||
QSqlDatabase::removeDatabase(dest);
|
||||
|
||||
}
|
||||
|
||||
bool DataBaseManagement::importComicsInfo(QString source, QString dest)
|
||||
{
|
||||
QString error;
|
||||
QString driver;
|
||||
QStringList hashes;
|
||||
|
||||
bool b = false;
|
||||
|
||||
QSqlDatabase sourceDB = loadDatabaseFromFile(source);
|
||||
QSqlDatabase destDB = loadDatabaseFromFile(dest);
|
||||
|
||||
{
|
||||
QSqlQuery pragma("PRAGMA synchronous=OFF",destDB);
|
||||
|
||||
|
||||
QSqlQuery newInfo(sourceDB);
|
||||
newInfo.prepare("SELECT * FROM comic_info");
|
||||
newInfo.exec();
|
||||
destDB.transaction();
|
||||
int cp;
|
||||
while (newInfo.next()) //cada tupla deber<65> ser insertada o actualizada
|
||||
{
|
||||
QSqlQuery update(destDB);
|
||||
update.prepare("UPDATE comic_info SET "
|
||||
"title = :title,"
|
||||
|
||||
"coverPage = :coverPage,"
|
||||
"numPages = :numPages,"
|
||||
|
||||
"number = :number,"
|
||||
"isBis = :isBis,"
|
||||
"count = :count,"
|
||||
|
||||
"volume = :volume,"
|
||||
"storyArc = :storyArc,"
|
||||
"arcNumber = :arcNumber,"
|
||||
"arcCount = :arcCount,"
|
||||
|
||||
"genere = :genere,"
|
||||
|
||||
"writer = :writer,"
|
||||
"penciller = :penciller,"
|
||||
"inker = :inker,"
|
||||
"colorist = :colorist,"
|
||||
"letterer = :letterer,"
|
||||
"coverArtist = :coverArtist,"
|
||||
|
||||
"date = :date,"
|
||||
"publisher = :publisher,"
|
||||
"format = :format,"
|
||||
"color = :color,"
|
||||
"ageRating = :ageRating,"
|
||||
|
||||
"synopsis = :synopsis,"
|
||||
"characters = :characters,"
|
||||
"notes = :notes,"
|
||||
|
||||
"edited = :edited,"
|
||||
|
||||
"comicVineID = :comicVineID"
|
||||
|
||||
" WHERE hash = :hash ");
|
||||
|
||||
QSqlQuery insert(destDB);
|
||||
insert.prepare("INSERT INTO comic_info "
|
||||
"(title,"
|
||||
"coverPage,"
|
||||
"numPages,"
|
||||
"number,"
|
||||
"isBis,"
|
||||
"count,"
|
||||
"volume,"
|
||||
"storyArc,"
|
||||
"arcNumber,"
|
||||
"arcCount,"
|
||||
"genere,"
|
||||
"writer,"
|
||||
"penciller,"
|
||||
"inker,"
|
||||
"colorist,"
|
||||
"letterer,"
|
||||
"coverArtist,"
|
||||
"date,"
|
||||
"publisher,"
|
||||
"format,"
|
||||
"color,"
|
||||
"ageRating,"
|
||||
"synopsis,"
|
||||
"characters,"
|
||||
"notes,"
|
||||
"read,"
|
||||
"edited,"
|
||||
"comicVineID,"
|
||||
"hash)"
|
||||
|
||||
"VALUES (:title,"
|
||||
":coverPage,"
|
||||
":numPages,"
|
||||
":number,"
|
||||
":isBis,"
|
||||
":count,"
|
||||
|
||||
":volume,"
|
||||
":storyArc,"
|
||||
":arcNumber,"
|
||||
":arcCount,"
|
||||
|
||||
":genere,"
|
||||
|
||||
":writer,"
|
||||
":penciller,"
|
||||
":inker,"
|
||||
":colorist,"
|
||||
":letterer,"
|
||||
":coverArtist,"
|
||||
|
||||
":date,"
|
||||
":publisher,"
|
||||
":format,"
|
||||
":color,"
|
||||
":ageRating,"
|
||||
|
||||
":synopsis,"
|
||||
":characters,"
|
||||
":notes,"
|
||||
|
||||
":read,"
|
||||
":edited,"
|
||||
":comicVineID,"
|
||||
|
||||
":hash )");
|
||||
|
||||
QSqlRecord record = newInfo.record();
|
||||
cp = record.value("coverPage").toInt();
|
||||
if(cp>1)
|
||||
{
|
||||
QSqlQuery checkCoverPage(destDB);
|
||||
checkCoverPage.prepare("SELECT coverPage FROM comic_info where hash = :hash");
|
||||
checkCoverPage.bindValue(":hash",record.value("hash").toString());
|
||||
checkCoverPage.exec();
|
||||
bool extract = false;
|
||||
if(checkCoverPage.next())
|
||||
{
|
||||
extract = checkCoverPage.record().value("coverPage").toInt() != cp;
|
||||
}
|
||||
if(extract)
|
||||
hashes.append(record.value("hash").toString());
|
||||
}
|
||||
|
||||
bindValuesFromRecord(record,update);
|
||||
|
||||
update.bindValue(":edited",1);
|
||||
|
||||
|
||||
update.exec();
|
||||
|
||||
if(update.numRowsAffected() == 0)
|
||||
{
|
||||
|
||||
bindValuesFromRecord(record,insert);
|
||||
insert.bindValue(":edited",1);
|
||||
insert.bindValue(":read",0);
|
||||
|
||||
insert.exec();
|
||||
|
||||
QString error1 = insert.lastError().databaseText();
|
||||
QString error2 = insert.lastError().driverText();
|
||||
|
||||
//QMessageBox::critical(NULL,"db",error1);
|
||||
//QMessageBox::critical(NULL,"driver",error2);
|
||||
}
|
||||
//update.finish();
|
||||
//insert.finish();
|
||||
}
|
||||
}
|
||||
|
||||
destDB.commit();
|
||||
QString hash;
|
||||
foreach(hash, hashes)
|
||||
{
|
||||
QSqlQuery getComic(destDB);
|
||||
getComic.prepare("SELECT c.path,ci.coverPage FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) where ci.hash = :hash");
|
||||
getComic.bindValue(":hash",hash);
|
||||
getComic.exec();
|
||||
if(getComic.next())
|
||||
{
|
||||
QString basePath = QString(dest).remove("/.yacreaderlibrary/library.ydb");
|
||||
QString path = basePath + getComic.record().value("path").toString();
|
||||
int coverPage = getComic.record().value("coverPage").toInt();
|
||||
ThumbnailCreator tc(path,basePath+"/.yacreaderlibrary/covers/"+hash+".jpg",coverPage);
|
||||
tc.create();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
destDB.close();
|
||||
sourceDB.close();
|
||||
QSqlDatabase::removeDatabase(source);
|
||||
QSqlDatabase::removeDatabase(dest);
|
||||
return b;
|
||||
|
||||
}
|
||||
//TODO fix these bindings
|
||||
void DataBaseManagement::bindValuesFromRecord(const QSqlRecord & record, QSqlQuery & query)
|
||||
{
|
||||
bindString("title",record,query);
|
||||
|
||||
bindInt("coverPage",record,query);
|
||||
bindInt("numPages",record,query);
|
||||
|
||||
bindInt("number",record,query);
|
||||
bindInt("isBis",record,query);
|
||||
bindInt("count",record,query);
|
||||
|
||||
bindString("volume",record,query);
|
||||
bindString("storyArc",record,query);
|
||||
bindInt("arcNumber",record,query);
|
||||
bindInt("arcCount",record,query);
|
||||
|
||||
bindString("genere",record,query);
|
||||
|
||||
bindString("writer",record,query);
|
||||
bindString("penciller",record,query);
|
||||
bindString("inker",record,query);
|
||||
bindString("colorist",record,query);
|
||||
bindString("letterer",record,query);
|
||||
bindString("coverArtist",record,query);
|
||||
|
||||
bindString("date",record,query);
|
||||
bindString("publisher",record,query);
|
||||
bindString("format",record,query);
|
||||
bindInt("color",record,query);
|
||||
bindString("ageRating",record,query);
|
||||
|
||||
bindString("synopsis",record,query);
|
||||
bindString("characters",record,query);
|
||||
bindString("notes",record,query);
|
||||
|
||||
bindString("comicVineID",record,query);
|
||||
|
||||
bindString("hash",record,query);
|
||||
}
|
||||
|
||||
bool DataBaseManagement::addColumns(const QString &tableName, const QStringList &columnDefs, const QSqlDatabase &db)
|
||||
{
|
||||
QString sql = "ALTER TABLE %1 ADD COLUMN %2";
|
||||
bool returnValue = true;
|
||||
|
||||
foreach(QString columnDef, columnDefs)
|
||||
{
|
||||
QSqlQuery alterTable(db);
|
||||
alterTable.prepare(sql.arg(tableName).arg(columnDef));
|
||||
//alterTableComicInfo.bindValue(":column_def",columnDef);
|
||||
alterTable.exec();
|
||||
returnValue = returnValue && (alterTable.numRowsAffected() > 0);
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
void DataBaseManagement::bindString(const QString & name, const QSqlRecord & record, QSqlQuery & query)
|
||||
{
|
||||
if(!record.value(name).isNull())
|
||||
{
|
||||
query.bindValue(":"+name,record.value(name).toString());
|
||||
}
|
||||
}
|
||||
void DataBaseManagement::bindInt(const QString & name, const QSqlRecord & record, QSqlQuery & query)
|
||||
{
|
||||
if(!record.value(name).isNull())
|
||||
{
|
||||
query.bindValue(":"+name,record.value(name).toInt());
|
||||
}
|
||||
}
|
||||
|
||||
QString DataBaseManagement::checkValidDB(const QString & fullPath)
|
||||
{
|
||||
QSqlDatabase db = loadDatabaseFromFile(fullPath);
|
||||
QString versionString = "";
|
||||
if(db.isValid() && db.isOpen())
|
||||
{
|
||||
QSqlQuery version(db);
|
||||
version.prepare("SELECT * FROM db_info");
|
||||
version.exec();
|
||||
|
||||
if(version.next())
|
||||
versionString = version.record().value("version").toString();
|
||||
}
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(fullPath);
|
||||
return versionString;
|
||||
}
|
||||
|
||||
int DataBaseManagement::compareVersions(const QString & v1, const QString v2)
|
||||
{
|
||||
QStringList v1l = v1.split('.');
|
||||
QStringList v2l = v2.split('.');
|
||||
QList<int> v1il;
|
||||
QList<int> v2il;
|
||||
|
||||
foreach(QString s, v1l)
|
||||
v1il.append(s.toInt());
|
||||
|
||||
foreach(QString s,v2l)
|
||||
v2il.append(s.toInt());
|
||||
|
||||
for(int i=0;i<qMin(v1il.length(),v2il.length());i++)
|
||||
{
|
||||
if(v1il[i]<v2il[i])
|
||||
return -1;
|
||||
if(v1il[i]>v2il[i])
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(v1il.length() < v2il.length())
|
||||
return -1;
|
||||
if(v1il.length() == v2il.length())
|
||||
return 0;
|
||||
if(v1il.length() > v2il.length())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DataBaseManagement::updateToCurrentVersion(const QString & fullPath)
|
||||
{
|
||||
bool pre7 = false;
|
||||
bool pre7_1 = false;
|
||||
if(compareVersions(DataBaseManagement::checkValidDB(fullPath),"7.0.0")<0)
|
||||
pre7 = true;
|
||||
if(compareVersions(DataBaseManagement::checkValidDB(fullPath),"7.0.3")<0)
|
||||
pre7_1 = true;
|
||||
|
||||
QSqlDatabase db = loadDatabaseFromFile(fullPath);
|
||||
bool returnValue = false;
|
||||
if(db.isValid() && db.isOpen())
|
||||
{
|
||||
QSqlQuery updateVersion(db);
|
||||
updateVersion.prepare("UPDATE db_info SET "
|
||||
"version = :version");
|
||||
updateVersion.bindValue(":version",VERSION);
|
||||
updateVersion.exec();
|
||||
|
||||
if(updateVersion.numRowsAffected() > 0)
|
||||
returnValue = true;
|
||||
|
||||
if(pre7) //TODO: execute only if previous version was < 7.0
|
||||
{
|
||||
//new 7.0 fields
|
||||
QStringList columnDefs;
|
||||
columnDefs << "hasBeenOpened BOOLEAN DEFAULT 0"
|
||||
<< "rating INTEGER DEFAULT 0"
|
||||
<< "currentPage INTEGER DEFAULT 1"
|
||||
<< "bookmark1 INTEGER DEFAULT -1"
|
||||
<< "bookmark2 INTEGER DEFAULT -1"
|
||||
<< "bookmark3 INTEGER DEFAULT -1"
|
||||
<< "brightness INTEGER DEFAULT -1"
|
||||
<< "contrast INTEGER DEFAULT -1"
|
||||
<< "gamma INTEGER DEFAULT -1";
|
||||
|
||||
returnValue = returnValue && addColumns("comic_info", columnDefs, db);
|
||||
}
|
||||
//TODO update hasBeenOpened value
|
||||
|
||||
if(pre7_1)
|
||||
{
|
||||
{
|
||||
QStringList columnDefs;
|
||||
columnDefs << "finished BOOLEAN DEFAULT 0"
|
||||
<< "completed BOOLEAN DEFAULT 1";
|
||||
returnValue = returnValue && addColumns("folder", columnDefs, db);
|
||||
}
|
||||
|
||||
{//comic_info
|
||||
QStringList columnDefs;
|
||||
columnDefs << "comicVineID TEXT DEFAULT NULL";
|
||||
returnValue = returnValue && addColumns("comic_info", columnDefs, db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(fullPath);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
//COMICS_INFO_EXPORTER
|
||||
ComicsInfoExporter::ComicsInfoExporter()
|
||||
:QThread()
|
||||
{
|
||||
}
|
||||
|
||||
void ComicsInfoExporter::exportComicsInfo(QSqlDatabase & source, QSqlDatabase & dest)
|
||||
{
|
||||
Q_UNUSED(source)
|
||||
Q_UNUSED(dest)
|
||||
//TODO check this method
|
||||
}
|
||||
|
||||
void ComicsInfoExporter::run()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//COMICS_INFO_IMPORTER
|
||||
ComicsInfoImporter::ComicsInfoImporter()
|
||||
:QThread()
|
||||
{
|
||||
}
|
||||
|
||||
void ComicsInfoImporter::importComicsInfo(QSqlDatabase & source, QSqlDatabase & dest)
|
||||
{
|
||||
Q_UNUSED(source)
|
||||
Q_UNUSED(dest)
|
||||
//TODO check this method
|
||||
}
|
||||
|
||||
void ComicsInfoImporter::run()
|
||||
{
|
||||
|
||||
}
|
||||
61
YACReaderLibrary/db/data_base_management.h
Normal file
61
YACReaderLibrary/db/data_base_management.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef __DATA_BASE_MANAGEMENT_H
|
||||
#define __DATA_BASE_MANAGEMENT_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtSql>
|
||||
#include <QSqlDatabase>
|
||||
|
||||
#include "treemodel.h"
|
||||
|
||||
class ComicsInfoExporter : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ComicsInfoExporter();
|
||||
void exportComicsInfo(QSqlDatabase & source, QSqlDatabase & dest);
|
||||
private:
|
||||
void run();
|
||||
};
|
||||
|
||||
class ComicsInfoImporter : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ComicsInfoImporter();
|
||||
void importComicsInfo(QSqlDatabase & source, QSqlDatabase & dest);
|
||||
private:
|
||||
void run();
|
||||
|
||||
};
|
||||
|
||||
class DataBaseManagement : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QList<QString> dataBasesList;
|
||||
static void bindString(const QString & name, const QSqlRecord & record, QSqlQuery & query);
|
||||
static void bindInt(const QString & name, const QSqlRecord & record, QSqlQuery & query);
|
||||
static void bindValuesFromRecord(const QSqlRecord & record, QSqlQuery & query);
|
||||
|
||||
static bool addColumns(const QString & tableName, const QStringList & columnDefs, const QSqlDatabase & db);
|
||||
|
||||
public:
|
||||
DataBaseManagement();
|
||||
//TreeModel * newTreeModel(QString path);
|
||||
//crea una base de datos y todas sus tablas
|
||||
static QSqlDatabase createDatabase(QString name, QString path);
|
||||
static QSqlDatabase createDatabase(QString dest);
|
||||
//carga una base de datos desde la ruta path
|
||||
static QSqlDatabase loadDatabase(QString path);
|
||||
static QSqlDatabase loadDatabaseFromFile(QString path);
|
||||
static bool createTables(QSqlDatabase & database);
|
||||
|
||||
static void exportComicsInfo(QString source, QString dest);
|
||||
static bool importComicsInfo(QString source, QString dest);
|
||||
|
||||
static QString checkValidDB(const QString & fullPath); //retorna "" si la DB es inv<6E>lida <20> la versi<73>n si es v<>lida.
|
||||
static int compareVersions(const QString & v1, const QString v2); //retorna <0 si v1 < v2, 0 si v1 = v2 y >0 si v1 > v2
|
||||
static bool updateToCurrentVersion(const QString & path);
|
||||
};
|
||||
|
||||
#endif
|
||||
47
YACReaderLibrary/db/tableitem.cpp
Normal file
47
YACReaderLibrary/db/tableitem.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
#include "tableitem.h"
|
||||
|
||||
//! [0]
|
||||
TableItem::TableItem(const QList<QVariant> &data)
|
||||
|
||||
{
|
||||
itemData = data;
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
TableItem::~TableItem()
|
||||
{
|
||||
|
||||
}
|
||||
//! [1]
|
||||
|
||||
|
||||
//! [5]
|
||||
int TableItem::columnCount() const
|
||||
{
|
||||
return itemData.count();
|
||||
}
|
||||
//! [5]
|
||||
|
||||
//! [6]
|
||||
QVariant TableItem::data(int column) const
|
||||
{
|
||||
return itemData.value(column);
|
||||
}
|
||||
//! [6]
|
||||
|
||||
void TableItem::setData(int column,const QVariant & value)
|
||||
{
|
||||
itemData[column] = value;
|
||||
}
|
||||
|
||||
//! [8]
|
||||
int TableItem::row() const
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
//! [8]
|
||||
27
YACReaderLibrary/db/tableitem.h
Normal file
27
YACReaderLibrary/db/tableitem.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef TABLEITEM_H
|
||||
#define TABLEITEM_H
|
||||
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
|
||||
//! [0]
|
||||
class TableItem : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TableItem(const QList<QVariant> &data);
|
||||
~TableItem();
|
||||
int columnCount() const;
|
||||
QVariant data(int column) const;
|
||||
void setData(int column,const QVariant & value);
|
||||
int row() const;
|
||||
//unsigned long long int id; //TODO sustituir por una clase adecuada
|
||||
//Comic comic;
|
||||
private:
|
||||
QList<QVariant> itemData;
|
||||
|
||||
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif
|
||||
615
YACReaderLibrary/db/tablemodel.cpp
Normal file
615
YACReaderLibrary/db/tablemodel.cpp
Normal file
@ -0,0 +1,615 @@
|
||||
|
||||
#include <QtGui>
|
||||
#include <QtDebug>
|
||||
#include <limits>
|
||||
|
||||
#include "tableitem.h"
|
||||
#include "tablemodel.h"
|
||||
#include "data_base_management.h"
|
||||
#include "qnaturalsorting.h"
|
||||
#include "comic_db.h"
|
||||
#include "db_helper.h"
|
||||
|
||||
//ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read
|
||||
|
||||
|
||||
|
||||
TableModel::TableModel(QObject *parent)
|
||||
: QAbstractItemModel(parent)
|
||||
{
|
||||
connect(this,SIGNAL(beforeReset()),this,SIGNAL(modelAboutToBeReset()));
|
||||
connect(this,SIGNAL(reset()),this,SIGNAL(modelReset()));
|
||||
}
|
||||
|
||||
//! [0]
|
||||
TableModel::TableModel( QSqlQuery &sqlquery, QObject *parent)
|
||||
: QAbstractItemModel(parent)
|
||||
{
|
||||
setupModelData(sqlquery);
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
TableModel::~TableModel()
|
||||
{
|
||||
qDeleteAll(_data);
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
int TableModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
if(_data.isEmpty())
|
||||
return 0;
|
||||
return _data.first()->columnCount();
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
QVariant TableModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
/*if (index.column() == TableModel::Rating && role == Qt::DecorationRole)
|
||||
{
|
||||
TableItem *item = static_cast<TableItem*>(index.internalPointer());
|
||||
return QPixmap(QString(":/images/rating%1.png").arg(item->data(index.column()).toInt()));
|
||||
}*/
|
||||
|
||||
if (role == Qt::DecorationRole)
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (role == Qt::TextAlignmentRole)
|
||||
{
|
||||
switch(index.column())//TODO obtener esto de la query
|
||||
{
|
||||
case TableModel::Number:
|
||||
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||
case TableModel::NumPages:
|
||||
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||
case TableModel::Hash:
|
||||
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||
case TableModel::CurrentPage:
|
||||
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||
default:
|
||||
return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
return (item->data(TableModel::CurrentPage).toInt()==item->data(TableModel::NumPages).toInt() || item->data(TableModel::ReadColumn).toBool())?QVariant(tr("yes")):QVariant(tr("no"));
|
||||
if(index.column() == TableModel::CurrentPage)
|
||||
return item->data(TableModel::HasBeenOpened).toBool()?item->data(index.column()):QVariant("-");
|
||||
|
||||
if (index.column() == TableModel::Rating)
|
||||
return QVariant();
|
||||
|
||||
return item->data(index.column());
|
||||
}
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
if(index.column() == TableModel::Rating)
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
QVariant TableModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
{
|
||||
switch(section)//TODO obtener esto de la query
|
||||
{
|
||||
case TableModel::Number:
|
||||
return QVariant(QString("#"));
|
||||
case TableModel::Title:
|
||||
return QVariant(QString(tr("Title")));
|
||||
case TableModel::FileName:
|
||||
return QVariant(QString(tr("File Name")));
|
||||
case TableModel::NumPages:
|
||||
return QVariant(QString(tr("Pages")));
|
||||
case TableModel::Hash:
|
||||
return QVariant(QString(tr("Size")));
|
||||
case TableModel::ReadColumn:
|
||||
return QVariant(QString(tr("Read")));
|
||||
case TableModel::CurrentPage:
|
||||
return QVariant(QString(tr("Current Page")));
|
||||
case TableModel::Rating:
|
||||
return QVariant(QString(tr("Rating")));
|
||||
}
|
||||
}
|
||||
|
||||
if (orientation == Qt::Horizontal && role == Qt::TextAlignmentRole)
|
||||
{
|
||||
switch(section)//TODO obtener esto de la query
|
||||
{
|
||||
case TableModel::Number:
|
||||
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||
case TableModel::NumPages:
|
||||
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||
case TableModel::Hash:
|
||||
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||
case TableModel::CurrentPage:
|
||||
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||
default:
|
||||
return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(orientation == Qt::Vertical && role == Qt::DecorationRole)
|
||||
{
|
||||
QString fileName = _data.value(section)->data(TableModel::FileName).toString();
|
||||
QFileInfo fi(fileName);
|
||||
QString ext = fi.suffix();
|
||||
|
||||
if (ext.compare("cbr",Qt::CaseInsensitive) == 0)
|
||||
return QVariant(QIcon(":/images/comicRar.png"));
|
||||
else if (ext.compare("cbz",Qt::CaseInsensitive) == 0)
|
||||
return QVariant(QIcon(":/images/comicZip.png"));
|
||||
else if(ext.compare("pdf",Qt::CaseInsensitive) == 0)
|
||||
return QVariant(QIcon(":/images/pdf.png"));
|
||||
else if (ext.compare("tar",Qt::CaseInsensitive) == 0)
|
||||
return QVariant(QIcon(":/images/tar.png"));
|
||||
else if(ext.compare("zip",Qt::CaseInsensitive) == 0)
|
||||
return QVariant(QIcon(":/images/zip.png"));
|
||||
else if(ext.compare("rar",Qt::CaseInsensitive) == 0)
|
||||
return QVariant(QIcon(":/images/rar.png"));
|
||||
else if (ext.compare("7z",Qt::CaseInsensitive) == 0)
|
||||
return QVariant(QIcon(":/images/7z.png"));
|
||||
else if (ext.compare("cb7",Qt::CaseInsensitive) == 0)
|
||||
return QVariant(QIcon(":/images/comic7z.png"));
|
||||
else if (ext.compare("cb7",Qt::CaseInsensitive) == 0)
|
||||
return QVariant(QIcon(":/images/comicTar.png"));
|
||||
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
//! [5]
|
||||
|
||||
//! [6]
|
||||
QModelIndex TableModel::index(int row, int column, const QModelIndex &parent)
|
||||
const
|
||||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(row, column, _data.at(row));
|
||||
}
|
||||
//! [6]
|
||||
|
||||
//! [7]
|
||||
QModelIndex TableModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
return QModelIndex();
|
||||
}
|
||||
//! [7]
|
||||
|
||||
//! [8]
|
||||
int TableModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
if (!parent.isValid())
|
||||
return _data.count();
|
||||
|
||||
return 0;
|
||||
}
|
||||
//! [8]
|
||||
|
||||
QStringList TableModel::getPaths(const QString & _source)
|
||||
{
|
||||
QStringList paths;
|
||||
QString source = _source + "/.yacreaderlibrary/covers/";
|
||||
QList<TableItem *>::ConstIterator itr;
|
||||
for(itr = _data.constBegin();itr != _data.constEnd();itr++)
|
||||
{
|
||||
QString hash = (*itr)->data(TableModel::Hash).toString();
|
||||
paths << source+ hash +".jpg";
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
void TableModel::setupModelData(unsigned long long int folderId,const QString & databasePath)
|
||||
{
|
||||
//QFile f(QCoreApplication::applicationDirPath()+"/performance.txt");
|
||||
//f.open(QIODevice::Append);
|
||||
beginResetModel();
|
||||
//QElapsedTimer timer;
|
||||
//timer.start();
|
||||
qDeleteAll(_data);
|
||||
_data.clear();
|
||||
|
||||
//QTextStream txtS(&f);
|
||||
//txtS << "TABLEMODEL: Tiempo de borrado: " << timer.elapsed() << "ms\r\n";
|
||||
_databasePath = databasePath;
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
|
||||
{
|
||||
//crear la consulta
|
||||
//timer.restart();
|
||||
QSqlQuery selectQuery(db); //TODO check
|
||||
selectQuery.prepare("select ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened from comic c inner join comic_info ci on (c.comicInfoId = ci.id) where c.parentId = :parentId");
|
||||
selectQuery.bindValue(":parentId", folderId);
|
||||
selectQuery.exec();
|
||||
//txtS << "TABLEMODEL: Tiempo de consulta: " << timer.elapsed() << "ms\r\n";
|
||||
//timer.restart();
|
||||
setupModelData(selectQuery);
|
||||
//txtS << "TABLEMODEL: Tiempo de creaci<63>n del modelo: " << timer.elapsed() << "ms\r\n";
|
||||
//selectQuery.finish();
|
||||
}
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
endResetModel();
|
||||
//f.close();
|
||||
}
|
||||
|
||||
QString TableModel::getComicPath(QModelIndex mi)
|
||||
{
|
||||
if(mi.isValid())
|
||||
return _data.at(mi.row())->data(TableModel::Path).toString();
|
||||
return "";
|
||||
}
|
||||
|
||||
void TableModel::setupModelData(QSqlQuery &sqlquery)
|
||||
{
|
||||
TableItem * currentItem;
|
||||
while (sqlquery.next())
|
||||
{
|
||||
QList<QVariant> data;
|
||||
QSqlRecord record = sqlquery.record();
|
||||
for(int i=0;i<record.count();i++)
|
||||
data << record.value(i);
|
||||
|
||||
currentItem = new TableItem(data);
|
||||
bool lessThan = false;
|
||||
if(_data.isEmpty())
|
||||
_data.append(currentItem);
|
||||
else
|
||||
{
|
||||
TableItem * last = _data.back();
|
||||
QString nameLast = last->data(TableModel::FileName).toString();
|
||||
QString nameCurrent = currentItem->data(TableModel::FileName).toString();
|
||||
int numberLast,numberCurrent;
|
||||
int max = (std::numeric_limits<int>::max)();
|
||||
numberLast = numberCurrent = max;
|
||||
|
||||
if(!last->data(TableModel::Number).isNull())
|
||||
numberLast = last->data(TableModel::Number).toInt();
|
||||
|
||||
if(!currentItem->data(TableModel::Number).isNull())
|
||||
numberCurrent = currentItem->data(TableModel::Number).toInt();
|
||||
|
||||
QList<TableItem *>::iterator i;
|
||||
i = _data.end();
|
||||
i--;
|
||||
|
||||
if(numberCurrent != max)
|
||||
{
|
||||
while ((lessThan =numberCurrent < numberLast) && i != _data.begin())
|
||||
{
|
||||
i--;
|
||||
numberLast = max;
|
||||
|
||||
if(!(*i)->data(TableModel::Number).isNull())
|
||||
numberLast = (*i)->data(TableModel::Number).toInt();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((lessThan = naturalSortLessThanCI(nameCurrent,nameLast)) && i != _data.begin() && numberLast == max)
|
||||
{
|
||||
i--;
|
||||
nameLast = (*i)->data(TableModel::FileName).toString();
|
||||
numberLast = max;
|
||||
|
||||
if(!(*i)->data(TableModel::Number).isNull())
|
||||
numberLast = (*i)->data(TableModel::Number).toInt();
|
||||
}
|
||||
|
||||
}
|
||||
if(!lessThan) //si se ha encontrado un elemento menor que current, se inserta justo despu<70>s
|
||||
{
|
||||
if(numberCurrent != max)
|
||||
{
|
||||
if(numberCurrent == numberLast)
|
||||
if(currentItem->data(TableModel::IsBis).toBool())
|
||||
{
|
||||
_data.insert(++i,currentItem);
|
||||
}
|
||||
else
|
||||
_data.insert(i,currentItem);
|
||||
else
|
||||
_data.insert(++i,currentItem);
|
||||
}
|
||||
else
|
||||
_data.insert(++i,currentItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
_data.insert(i,currentItem);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ComicDB TableModel::getComic(const QModelIndex & mi)
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
ComicDB c = DBHelper::loadComic(_data.at(mi.row())->data(TableModel::Id).toULongLong(),db);
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
ComicDB TableModel::_getComic(const QModelIndex & mi)
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
ComicDB c = DBHelper::loadComic(_data.at(mi.row())->data(TableModel::Id).toULongLong(),db);
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
QVector<YACReaderComicReadStatus> TableModel::getReadList()
|
||||
{
|
||||
int numComics = _data.count();
|
||||
QVector<YACReaderComicReadStatus> readList(numComics);
|
||||
for(int i=0;i<numComics;i++)
|
||||
{
|
||||
if(_data.value(i)->data(TableModel::ReadColumn).toBool())
|
||||
readList[i] = YACReader::Read;
|
||||
else if (_data.value(i)->data(TableModel::CurrentPage).toInt() == _data.value(i)->data(TableModel::NumPages).toInt())
|
||||
readList[i] = YACReader::Read;
|
||||
else if (_data.value(i)->data(TableModel::HasBeenOpened).toBool())
|
||||
readList[i] = YACReader::Opened;
|
||||
else
|
||||
readList[i] = YACReader::Unread;
|
||||
}
|
||||
return readList;
|
||||
}
|
||||
//TODO untested, this method is no longer used
|
||||
QVector<YACReaderComicReadStatus> TableModel::setAllComicsRead(YACReaderComicReadStatus read)
|
||||
{
|
||||
return setComicsRead(persistentIndexList(),read);
|
||||
}
|
||||
|
||||
QList<ComicDB> TableModel::getAllComics()
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
db.transaction();
|
||||
|
||||
QList<ComicDB> comics;
|
||||
int numComics = _data.count();
|
||||
for(int i=0;i<numComics;i++)
|
||||
{
|
||||
comics.append(DBHelper::loadComic(_data.value(i)->data(TableModel::Id).toULongLong(),db));
|
||||
}
|
||||
|
||||
db.commit();
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
|
||||
return comics;
|
||||
}
|
||||
|
||||
QList<ComicDB> TableModel::getComics(QList<QModelIndex> list)
|
||||
{
|
||||
QList<ComicDB> comics;
|
||||
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
db.transaction();
|
||||
QList<QModelIndex>::const_iterator itr;
|
||||
for(itr = list.constBegin(); itr!= list.constEnd();itr++)
|
||||
{
|
||||
comics.append(_getComic(*itr));
|
||||
}
|
||||
db.commit();
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
return comics;
|
||||
}
|
||||
//TODO
|
||||
QVector<YACReaderComicReadStatus> TableModel::setComicsRead(QList<QModelIndex> list,YACReaderComicReadStatus read)
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
db.transaction();
|
||||
foreach (QModelIndex mi, list)
|
||||
{
|
||||
if(read == YACReader::Read)
|
||||
{
|
||||
_data.value(mi.row())->setData(TableModel::ReadColumn, QVariant(true));
|
||||
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(TableModel::Id).toULongLong(),db);
|
||||
c.info.read = true;
|
||||
DBHelper::update(&(c.info),db);
|
||||
}
|
||||
if(read == YACReader::Unread)
|
||||
{
|
||||
_data.value(mi.row())->setData(TableModel::ReadColumn, QVariant(false));
|
||||
_data.value(mi.row())->setData(TableModel::CurrentPage, QVariant(1));
|
||||
_data.value(mi.row())->setData(TableModel::HasBeenOpened, QVariant(false));
|
||||
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(TableModel::Id).toULongLong(),db);
|
||||
c.info.read = false;
|
||||
c.info.currentPage = 1;
|
||||
c.info.hasBeenOpened = false;
|
||||
DBHelper::update(&(c.info),db);
|
||||
}
|
||||
}
|
||||
db.commit();
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
|
||||
emit dataChanged(index(list.first().row(),TableModel::ReadColumn),index(list.last().row(),TableModel::CurrentPage+1));
|
||||
|
||||
return getReadList();
|
||||
}
|
||||
qint64 TableModel::asignNumbers(QList<QModelIndex> list,int startingNumber)
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
db.transaction();
|
||||
qint64 idFirst = _data.value(list[0].row())->data(TableModel::Id).toULongLong();
|
||||
int i = 0;
|
||||
foreach (QModelIndex mi, list)
|
||||
{
|
||||
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(TableModel::Id).toULongLong(),db);
|
||||
c.info.number = startingNumber+i;
|
||||
c.info.edited = true;
|
||||
DBHelper::update(&(c.info),db);
|
||||
i++;
|
||||
}
|
||||
|
||||
db.commit();
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
|
||||
//emit dataChanged(index(list.first().row(),READ),index(list.last().row(),READ));
|
||||
|
||||
return idFirst;
|
||||
}
|
||||
QModelIndex TableModel::getIndexFromId(quint64 id)
|
||||
{
|
||||
QList<TableItem *>::ConstIterator itr;
|
||||
int i=0;
|
||||
for(itr = _data.constBegin();itr != _data.constEnd();itr++)
|
||||
{
|
||||
if((*itr)->data(TableModel::Id).toULongLong() == id)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
return index(i,0);
|
||||
}
|
||||
|
||||
void TableModel::startTransaction()
|
||||
{
|
||||
|
||||
dbTransaction = DataBaseManagement::loadDatabase(_databasePath);
|
||||
dbTransaction.transaction();
|
||||
}
|
||||
|
||||
void TableModel::finishTransaction()
|
||||
{
|
||||
dbTransaction.commit();
|
||||
dbTransaction.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void TableModel::removeInTransaction(int row)
|
||||
{
|
||||
ComicDB c = DBHelper::loadComic(_data.at(row)->data(TableModel::Id).toULongLong(),dbTransaction);
|
||||
|
||||
DBHelper::removeFromDB(&c,dbTransaction);
|
||||
beginRemoveRows(QModelIndex(),row,row);
|
||||
removeRow(row);
|
||||
delete _data.at(row);
|
||||
_data.removeAt(row);
|
||||
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
void TableModel::remove(ComicDB * comic, int row)
|
||||
{
|
||||
beginRemoveRows(QModelIndex(),row,row);
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
|
||||
DBHelper::removeFromDB(comic,db);
|
||||
|
||||
removeRow(row);
|
||||
delete _data.at(row);
|
||||
_data.removeAt(row);
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
ComicDB TableModel::getComic(int row)
|
||||
{
|
||||
return getComic(index(row,0));
|
||||
}
|
||||
|
||||
void TableModel::remove(int row)
|
||||
{
|
||||
removeInTransaction(row);
|
||||
}
|
||||
|
||||
void TableModel::reload(const ComicDB & comic)
|
||||
{
|
||||
int row = 0;
|
||||
bool found = false;
|
||||
foreach(TableItem * item,_data)
|
||||
{
|
||||
if(item->data(TableModel::Id).toULongLong() == comic.id)
|
||||
{
|
||||
found = true;
|
||||
item->setData(TableModel::ReadColumn,comic.info.read);
|
||||
item->setData(TableModel::CurrentPage,comic.info.currentPage);
|
||||
item->setData(TableModel::HasBeenOpened,true);
|
||||
break;
|
||||
|
||||
}
|
||||
row++;
|
||||
}
|
||||
if(found)
|
||||
emit dataChanged(index(row,TableModel::CurrentPage),index(row,TableModel::CurrentPage));
|
||||
}
|
||||
|
||||
void TableModel::resetComicRating(const QModelIndex &mi)
|
||||
{
|
||||
ComicDB comic = getComic(mi);
|
||||
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
|
||||
comic.info.rating = 0;
|
||||
_data[mi.row()]->setData(TableModel::Rating,0);
|
||||
DBHelper::update(&(comic.info),db);
|
||||
|
||||
emit dataChanged(mi,mi);
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
}
|
||||
|
||||
void TableModel::updateRating(int rating, QModelIndex mi)
|
||||
{
|
||||
ComicDB comic = getComic(mi);
|
||||
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
//TODO optimize update
|
||||
|
||||
comic.info.rating = rating;
|
||||
_data[mi.row()]->setData(TableModel::Rating,rating);
|
||||
DBHelper::update(&(comic.info),db);
|
||||
|
||||
emit dataChanged(mi,mi);
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
}
|
||||
95
YACReaderLibrary/db/tablemodel.h
Normal file
95
YACReaderLibrary/db/tablemodel.h
Normal file
@ -0,0 +1,95 @@
|
||||
#ifndef TABLEMODEL_H
|
||||
#define TABLEMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QModelIndex>
|
||||
#include <QVariant>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlDatabase>
|
||||
|
||||
#include "yacreader_global.h"
|
||||
|
||||
class ComicDB;
|
||||
|
||||
class TableItem;
|
||||
|
||||
using namespace YACReader;
|
||||
|
||||
//! [0]
|
||||
class TableModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TableModel(QObject *parent = 0);
|
||||
TableModel( QSqlQuery &sqlquery, QObject *parent = 0);
|
||||
~TableModel();
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const;
|
||||
QModelIndex index(int row, int column,
|
||||
const QModelIndex &parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
void setupModelData(unsigned long long int parentFolder,const QString & databasePath);
|
||||
|
||||
//M<>todos de conveniencia
|
||||
QStringList getPaths(const QString & _source);
|
||||
QString getComicPath(QModelIndex mi);
|
||||
ComicDB getComic(const QModelIndex & mi); //--> para la edici<63>n
|
||||
ComicDB getComic(int row);
|
||||
QVector<YACReaderComicReadStatus> getReadList();
|
||||
QVector<YACReaderComicReadStatus> setAllComicsRead(YACReaderComicReadStatus readStatus);
|
||||
QList<ComicDB> getComics(QList<QModelIndex> list); //--> recupera la informaci<63>n com<6F>n a los comics seleccionados
|
||||
QList<ComicDB> getAllComics();
|
||||
QModelIndex getIndexFromId(quint64 id);
|
||||
//setcomicInfo(QModelIndex & mi); --> inserta en la base datos
|
||||
//setComicInfoForAllComics(); --> inserta la informaci<63>n com<6F>n a todos los c<>mics de una sola vez.
|
||||
//setComicInfoForSelectedComis(QList<QModelIndex> list); -->inserta la informaci<63>n com<6F>n para los comics seleccionados
|
||||
QVector<YACReaderComicReadStatus> setComicsRead(QList<QModelIndex> list,YACReaderComicReadStatus read);
|
||||
qint64 asignNumbers(QList<QModelIndex> list,int startingNumber);
|
||||
void remove(ComicDB * comic, int row);
|
||||
void removeInTransaction(int row);
|
||||
void reload(const ComicDB & comic);
|
||||
void resetComicRating(const QModelIndex & mi);
|
||||
|
||||
enum Columns {
|
||||
Number = 0,
|
||||
Title = 1,
|
||||
FileName = 2,
|
||||
NumPages = 3,
|
||||
Id = 4,
|
||||
Parent_Id = 5,
|
||||
Path = 6,
|
||||
Hash = 7,
|
||||
ReadColumn = 8,
|
||||
IsBis = 9,
|
||||
CurrentPage = 10,
|
||||
Rating = 11,
|
||||
HasBeenOpened = 12
|
||||
};
|
||||
public slots:
|
||||
void remove(int row);
|
||||
void startTransaction();
|
||||
void finishTransaction();
|
||||
void updateRating(int rating, QModelIndex mi);
|
||||
|
||||
private:
|
||||
void setupModelData( QSqlQuery &sqlquery);
|
||||
ComicDB _getComic(const QModelIndex & mi);
|
||||
QList<TableItem *> _data;
|
||||
|
||||
QString _databasePath;
|
||||
|
||||
QSqlDatabase dbTransaction;
|
||||
|
||||
signals:
|
||||
void beforeReset();
|
||||
void reset();
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif
|
||||
152
YACReaderLibrary/db/treeitem.cpp
Normal file
152
YACReaderLibrary/db/treeitem.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples 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 Nokia Corporation 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
treeitem.cpp
|
||||
|
||||
A container for items of data supplied by the simple tree model.
|
||||
*/
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
#include "treeitem.h"
|
||||
#include "qnaturalsorting.h"
|
||||
|
||||
//! [0]
|
||||
TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent)
|
||||
{
|
||||
parentItem = parent;
|
||||
itemData = data;
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
TreeItem::~TreeItem()
|
||||
{
|
||||
qDeleteAll(childItems);
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
void TreeItem::appendChild(TreeItem *item)
|
||||
{
|
||||
item->parentItem = this;
|
||||
|
||||
if(childItems.isEmpty())
|
||||
childItems.append(item);
|
||||
else
|
||||
{
|
||||
TreeItem * last = childItems.back();
|
||||
QString nameLast = last->data(1).toString(); //TODO usar info name si est<73> disponible, sino el nombre del fichero.....
|
||||
QString nameCurrent = item->data(1).toString();
|
||||
QList<TreeItem *>::iterator i;
|
||||
i = childItems.end();
|
||||
i--;
|
||||
while (naturalSortLessThanCI(nameCurrent,nameLast) && i != childItems.begin())
|
||||
{
|
||||
i--;
|
||||
nameLast = (*i)->data(1).toString();
|
||||
}
|
||||
if(!naturalSortLessThanCI(nameCurrent,nameLast)) //si se ha encontrado un elemento menor que current, se inserta justo despu<70>s
|
||||
childItems.insert(++i,item);
|
||||
else
|
||||
childItems.insert(i,item);
|
||||
|
||||
}
|
||||
|
||||
//childItems.append(item);
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
TreeItem *TreeItem::child(int row)
|
||||
{
|
||||
return childItems.value(row);
|
||||
}
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
int TreeItem::childCount() const
|
||||
{
|
||||
return childItems.count();
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
int TreeItem::columnCount() const
|
||||
{
|
||||
return itemData.count();
|
||||
}
|
||||
//! [5]
|
||||
|
||||
//! [6]
|
||||
QVariant TreeItem::data(int column) const
|
||||
{
|
||||
return itemData.value(column);
|
||||
}
|
||||
//! [6]
|
||||
|
||||
void TreeItem::setData(int column, const QVariant & value)
|
||||
{
|
||||
itemData[column] = value;
|
||||
}
|
||||
|
||||
//! [7]
|
||||
TreeItem *TreeItem::parent()
|
||||
{
|
||||
return parentItem;
|
||||
}
|
||||
//! [7]
|
||||
|
||||
//! [8]
|
||||
int TreeItem::row() const
|
||||
{
|
||||
if (parentItem)
|
||||
return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));
|
||||
|
||||
return 0;
|
||||
}
|
||||
//! [8]
|
||||
|
||||
|
||||
QList<QVariant> TreeItem::getData() const
|
||||
{
|
||||
return itemData;
|
||||
}
|
||||
79
YACReaderLibrary/db/treeitem.h
Normal file
79
YACReaderLibrary/db/treeitem.h
Normal file
@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples 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 Nokia Corporation 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef TREEITEM_H
|
||||
#define TREEITEM_H
|
||||
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
#include <QModelIndex>
|
||||
|
||||
//! [0]
|
||||
class TreeItem
|
||||
{
|
||||
public:
|
||||
TreeItem(const QList<QVariant> &data, TreeItem *parent = 0);
|
||||
~TreeItem();
|
||||
|
||||
void appendChild(TreeItem *child);
|
||||
|
||||
TreeItem *child(int row);
|
||||
int childCount() const;
|
||||
int columnCount() const;
|
||||
QVariant data(int column) const;
|
||||
QList<QVariant> getData() const;
|
||||
int row() const;
|
||||
TreeItem *parent();
|
||||
TreeItem *parentItem;
|
||||
unsigned long long int id;
|
||||
QList<QString> comicNames;
|
||||
TreeItem * originalItem;
|
||||
void setData(int column, const QVariant &value);
|
||||
private:
|
||||
QList<TreeItem*> childItems;
|
||||
QList<QVariant> itemData;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif
|
||||
520
YACReaderLibrary/db/treemodel.cpp
Normal file
520
YACReaderLibrary/db/treemodel.cpp
Normal file
@ -0,0 +1,520 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples 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 Nokia Corporation 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
treemodel.cpp
|
||||
|
||||
Provides a simple tree model to show how to create and use hierarchical
|
||||
models.
|
||||
*/
|
||||
|
||||
#include <QtGui>
|
||||
|
||||
|
||||
#include "treeitem.h"
|
||||
#include "treemodel.h"
|
||||
#include "data_base_management.h"
|
||||
#include "folder.h"
|
||||
#include "db_helper.h"
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include <QFileIconProvider>
|
||||
QIcon finishedFolderIcon;
|
||||
void drawMacOSXFinishedFolderIcon()
|
||||
{
|
||||
QIcon ico = QFileIconProvider().icon(QFileIconProvider::Folder);
|
||||
QPixmap pixNormalOff = ico.pixmap(16,16, QIcon::Normal, QIcon::Off);
|
||||
QPixmap pixNormalOn = ico.pixmap(16,16, QIcon::Normal, QIcon::On);
|
||||
QPixmap pixSelectedOff = ico.pixmap(16,16, QIcon::Selected, QIcon::Off);
|
||||
QPixmap pixSelectedOn = ico.pixmap(16,16, QIcon::Selected, QIcon::On);
|
||||
QPixmap tick(":/images/folder_finished_macosx.png");
|
||||
|
||||
|
||||
{
|
||||
QPainter p(&pixNormalOff);
|
||||
p.drawPixmap(4,7,tick);
|
||||
}
|
||||
finishedFolderIcon.addPixmap(pixNormalOff, QIcon::Normal, QIcon::Off);
|
||||
|
||||
{
|
||||
QPainter p(&pixNormalOn);
|
||||
p.drawPixmap(4,7,tick);
|
||||
}
|
||||
finishedFolderIcon.addPixmap(pixNormalOn, QIcon::Normal, QIcon::On);
|
||||
|
||||
{
|
||||
QPainter p(&pixSelectedOff);
|
||||
p.drawPixmap(4,7,tick);
|
||||
}
|
||||
finishedFolderIcon.addPixmap(pixSelectedOff, QIcon::Selected, QIcon::Off);
|
||||
|
||||
{
|
||||
QPainter p(&pixSelectedOn);
|
||||
p.drawPixmap(4,7,tick);
|
||||
}
|
||||
finishedFolderIcon.addPixmap(pixSelectedOn, QIcon::Selected, QIcon::On);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ROOT 1
|
||||
|
||||
TreeModel::TreeModel(QObject *parent)
|
||||
: QAbstractItemModel(parent),rootItem(0),rootBeforeFilter(0),filterEnabled(false),includeComics(false)
|
||||
{
|
||||
connect(this,SIGNAL(beforeReset()),this,SIGNAL(modelAboutToBeReset()));
|
||||
connect(this,SIGNAL(reset()),this,SIGNAL(modelReset()));
|
||||
}
|
||||
|
||||
//! [0]
|
||||
TreeModel::TreeModel( QSqlQuery &sqlquery, QObject *parent)
|
||||
: QAbstractItemModel(parent),rootItem(0),rootBeforeFilter(0),filterEnabled(false),includeComics(false)
|
||||
{
|
||||
//lo m<>s probable es que el nodo ra<72>z no necesite tener informaci<63>n
|
||||
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)
|
||||
rootItem = new TreeItem(rootData);
|
||||
rootItem->id = ROOT;
|
||||
rootItem->parentItem = 0;
|
||||
setupModelData(sqlquery, rootItem);
|
||||
//sqlquery.finish();
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
TreeModel::~TreeModel()
|
||||
{
|
||||
if(rootItem != 0)
|
||||
delete rootItem;
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
int TreeModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
|
||||
else
|
||||
return rootItem->columnCount();
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
QVariant TreeModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
|
||||
if (role == Qt::DecorationRole)
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
if(item->data(TreeModel::Finished).toBool()){
|
||||
if(finishedFolderIcon.isNull()){
|
||||
drawMacOSXFinishedFolderIcon();
|
||||
}
|
||||
|
||||
return QVariant(finishedFolderIcon);
|
||||
}
|
||||
else {
|
||||
return QVariant(QFileIconProvider().icon(QFileIconProvider::Folder));
|
||||
}
|
||||
#else
|
||||
if(item->data(TreeModel::Finished).toBool())
|
||||
return QVariant(QIcon(":/images/folder_finished.png"));
|
||||
else
|
||||
return QVariant(QIcon(":/images/folder.png"));
|
||||
#endif
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
|
||||
|
||||
return item->data(index.column());
|
||||
}
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
return rootItem->data(section);
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
//! [5]
|
||||
|
||||
//! [6]
|
||||
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent)
|
||||
const
|
||||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
TreeItem *parentItem;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentItem = rootItem;
|
||||
else
|
||||
parentItem = static_cast<TreeItem*>(parent.internalPointer());
|
||||
|
||||
TreeItem *childItem = parentItem->child(row);
|
||||
if (childItem)
|
||||
return createIndex(row, column, childItem);
|
||||
else
|
||||
return QModelIndex();
|
||||
}
|
||||
//! [6]
|
||||
|
||||
//! [7]
|
||||
QModelIndex TreeModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
|
||||
TreeItem *parentItem = childItem->parent();
|
||||
|
||||
if (parentItem == rootItem)
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(parentItem->row(), 0, parentItem);
|
||||
}
|
||||
//! [7]
|
||||
|
||||
QModelIndex TreeModel::indexFromItem(TreeItem * item,int column)
|
||||
{
|
||||
//if(item->parent() != 0)
|
||||
// return index(item->row(),column,parent(indexFromItem(item->parent(),column-1)));
|
||||
//else
|
||||
// return index(item->row(),0,QModelIndex());
|
||||
return createIndex(item->row(), column, item);
|
||||
}
|
||||
|
||||
|
||||
//! [8]
|
||||
int TreeModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
TreeItem *parentItem;
|
||||
if (parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentItem = rootItem;
|
||||
else
|
||||
parentItem = static_cast<TreeItem*>(parent.internalPointer());
|
||||
|
||||
return parentItem->childCount();
|
||||
}
|
||||
//! [8]
|
||||
|
||||
void TreeModel::setupModelData(QString path)
|
||||
{
|
||||
beginResetModel();
|
||||
if(rootItem != 0)
|
||||
delete rootItem; //TODO comprobar que se libera bien la memoria
|
||||
filterEnabled = false;
|
||||
rootItem = 0;
|
||||
rootBeforeFilter = 0;
|
||||
//inicializar el nodo ra<72>z
|
||||
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)
|
||||
rootItem = new TreeItem(rootData);
|
||||
rootItem->id = ROOT;
|
||||
rootItem->parentItem = 0;
|
||||
|
||||
//cargar la base de datos
|
||||
_databasePath = path;
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(path);
|
||||
//crear la consulta
|
||||
{
|
||||
QSqlQuery selectQuery("select * from folder where id <> 1 order by parentId,name",db);
|
||||
|
||||
setupModelData(selectQuery,rootItem);
|
||||
}
|
||||
//selectQuery.finish();
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(path);
|
||||
endResetModel();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void TreeModel::setupModelData(QSqlQuery &sqlquery, TreeItem *parent)
|
||||
{
|
||||
//64 bits para la primary key, es decir la misma precisi<73>n que soporta sqlit 2^64
|
||||
//el diccionario permitir<69> encontrar cualquier nodo del <20>rbol r<>pidamente, de forma que a<>adir un hijo a un padre sea O(1)
|
||||
items.clear();
|
||||
//se a<>ade el nodo 0
|
||||
items.insert(parent->id,parent);
|
||||
|
||||
while (sqlquery.next()) {
|
||||
QList<QVariant> data;
|
||||
QSqlRecord record = sqlquery.record();
|
||||
|
||||
data << record.value("name").toString();
|
||||
data << record.value("path").toString();
|
||||
data << record.value("finished").toBool();
|
||||
data << record.value("completed").toBool();
|
||||
TreeItem * item = new TreeItem(data);
|
||||
|
||||
item->id = record.value("id").toULongLong();
|
||||
//la inserci<63>n de hijos se hace de forma ordenada
|
||||
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.
|
||||
parent->appendChild(item);
|
||||
//se a<>ade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones
|
||||
items.insert(item->id,item);
|
||||
}
|
||||
}
|
||||
|
||||
void TreeModel::setupFilteredModelData()
|
||||
{
|
||||
beginResetModel();
|
||||
|
||||
//TODO hay que liberar memoria de anteriores filtrados
|
||||
|
||||
//inicializar el nodo ra<72>z
|
||||
|
||||
if(rootBeforeFilter == 0)
|
||||
rootBeforeFilter = rootItem;
|
||||
else
|
||||
delete rootItem;//los resultados de la b<>squeda anterior deben ser borrados
|
||||
|
||||
QList<QVariant> rootData;
|
||||
rootData << "root"; //id 1, padre 1, title "root" (el id, y el id del padre van a ir en la clase TreeItem)
|
||||
rootItem = new TreeItem(rootData);
|
||||
rootItem->id = ROOT;
|
||||
rootItem->parentItem = 0;
|
||||
|
||||
//cargar la base de datos
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
//crear la consulta
|
||||
{
|
||||
QSqlQuery selectQuery(db); //TODO check
|
||||
if(!includeComics)
|
||||
{
|
||||
selectQuery.prepare("select * from folder where id <> 1 and upper(name) like upper(:filter) order by parentId,name ");
|
||||
selectQuery.bindValue(":filter", "%%"+filter+"%%");
|
||||
}
|
||||
else
|
||||
{
|
||||
selectQuery.prepare("SELECT DISTINCT f.id, f.parentId, f.name, f.path, f.finished, f.completed FROM folder f INNER JOIN comic c ON (f.id = c.parentId) WHERE f.id <> 1 AND ((UPPER(c.fileName) like UPPER(:filter)) OR (UPPER(f.name) like UPPER(:filter2))) ORDER BY f.parentId,f.name");
|
||||
selectQuery.bindValue(":filter", "%%"+filter+"%%");
|
||||
selectQuery.bindValue(":filter2", "%%"+filter+"%%");
|
||||
}
|
||||
selectQuery.exec();
|
||||
|
||||
setupFilteredModelData(selectQuery,rootItem);
|
||||
}
|
||||
//selectQuery.finish();
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void TreeModel::setupFilteredModelData(QSqlQuery &sqlquery, TreeItem *parent)
|
||||
{
|
||||
//64 bits para la primary key, es decir la misma precisi<73>n que soporta sqlit 2^64
|
||||
filteredItems.clear();
|
||||
|
||||
//se a<>ade el nodo 0 al modelo que representa el arbol de elementos que cumplen con el filtro
|
||||
filteredItems.insert(parent->id,parent);
|
||||
|
||||
while (sqlquery.next()) { //se procesan todos los folders que cumplen con el filtro
|
||||
//datos de la base de datos
|
||||
QList<QVariant> data;
|
||||
QSqlRecord record = sqlquery.record();
|
||||
|
||||
data << record.value("name").toString();
|
||||
data << record.value("path").toString();
|
||||
data << record.value("finished").toBool();
|
||||
data << record.value("completed").toBool();
|
||||
|
||||
TreeItem * item = new TreeItem(data);
|
||||
item->id = sqlquery.value(0).toULongLong();
|
||||
|
||||
//id del padre
|
||||
quint64 parentId = record.value("parentId").toULongLong();
|
||||
|
||||
//se a<>ade el item al map, de forma que se pueda encontrar como padre en siguientes iteraciones
|
||||
if(!filteredItems.contains(item->id))
|
||||
filteredItems.insert(item->id,item);
|
||||
|
||||
//es necesario conocer las coordenadas de origen para poder realizar scroll autom<6F>tico en la vista
|
||||
item->originalItem = items.value(item->id);
|
||||
|
||||
//si el padre ya existe en el modelo, el item se a<>ade como hijo
|
||||
if(filteredItems.contains(parentId))
|
||||
filteredItems.value(parentId)->appendChild(item);
|
||||
else//si el padre a<>n no se ha a<>adido, hay que a<>adirlo a <20>l y todos los padres hasta el nodo ra<72>z
|
||||
{
|
||||
//comprobamos con esta variable si el <20>ltimo de los padres (antes del nodo ra<72>z) ya exist<73>a en el modelo
|
||||
bool parentPreviousInserted = false;
|
||||
|
||||
//mientras no se alcance el nodo ra<72>z se procesan todos los padres (de abajo a arriba)
|
||||
while(parentId != ROOT )
|
||||
{
|
||||
//el padre no estaba en el modelo filtrado, as<61> que se rescata del modelo original
|
||||
TreeItem * parentItem = items.value(parentId);
|
||||
//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<69> a la estructura de directorios filtrados
|
||||
newparentItem->id = parentId;
|
||||
|
||||
newparentItem->originalItem = parentItem;
|
||||
|
||||
//si el modelo contiene al padre, se a<>ade el item actual como hijo
|
||||
if(filteredItems.contains(parentId))
|
||||
{
|
||||
filteredItems.value(parentId)->appendChild(item);
|
||||
parentPreviousInserted = true;
|
||||
}
|
||||
//sino se registra el nodo para poder encontrarlo con posterioridad y se a<>ade el item actual como hijo
|
||||
else
|
||||
{
|
||||
newparentItem->appendChild(item);
|
||||
filteredItems.insert(newparentItem->id,newparentItem);
|
||||
parentPreviousInserted = false;
|
||||
}
|
||||
|
||||
//variables de control del bucle, se avanza hacia el nodo padre
|
||||
item = newparentItem;
|
||||
parentId = parentItem->parentItem->id;
|
||||
}
|
||||
|
||||
//si el nodo es hijo de 1 y no hab<61>a sido previamente insertado como hijo, se a<>ade como tal
|
||||
if(!parentPreviousInserted)
|
||||
filteredItems.value(ROOT)->appendChild(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
QString TreeModel::getDatabase()
|
||||
{
|
||||
return _databasePath;
|
||||
}
|
||||
|
||||
QString TreeModel::getFolderPath(const QModelIndex &folder)
|
||||
{
|
||||
return static_cast<TreeItem*>(folder.internalPointer())->data(TreeModel::Path).toString();
|
||||
}
|
||||
|
||||
void TreeModel::setFilter(QString filter, bool includeComics)
|
||||
{
|
||||
this->filter = filter;
|
||||
this->includeComics = includeComics;
|
||||
filterEnabled = true;
|
||||
setupFilteredModelData();
|
||||
}
|
||||
|
||||
void TreeModel::resetFilter()
|
||||
{
|
||||
beginResetModel();
|
||||
filter = "";
|
||||
includeComics = false;
|
||||
//TODO hay que liberar la memoria reservada para el filtrado
|
||||
//items.clear();
|
||||
filteredItems.clear();
|
||||
TreeItem * root = rootItem;
|
||||
rootItem = rootBeforeFilter; //TODO si no se aplica el filtro previamente, esto invalidar<61>a en modelo
|
||||
if(root !=0)
|
||||
delete root;
|
||||
|
||||
rootBeforeFilter = 0;
|
||||
filterEnabled = false;
|
||||
endResetModel();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void TreeModel::updateFolderCompletedStatus(const QModelIndexList &list, bool status)
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
db.transaction();
|
||||
foreach (QModelIndex mi, list)
|
||||
{
|
||||
TreeItem * item = static_cast<TreeItem*>(mi.internalPointer());
|
||||
item->setData(TreeModel::Completed,status);
|
||||
|
||||
Folder f = DBHelper::loadFolder(item->id,db);
|
||||
f.setCompleted(status);
|
||||
DBHelper::update(f,db);
|
||||
}
|
||||
db.commit();
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
|
||||
emit dataChanged(index(list.first().row(),TreeModel::Name),index(list.last().row(),TreeModel::Completed));
|
||||
}
|
||||
|
||||
void TreeModel::updateFolderFinishedStatus(const QModelIndexList &list, bool status)
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
db.transaction();
|
||||
foreach (QModelIndex mi, list)
|
||||
{
|
||||
TreeItem * item = static_cast<TreeItem*>(mi.internalPointer());
|
||||
item->setData(TreeModel::Finished,status);
|
||||
|
||||
Folder f = DBHelper::loadFolder(item->id,db);
|
||||
f.setFinished(status);
|
||||
DBHelper::update(f,db);
|
||||
}
|
||||
db.commit();
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
|
||||
emit dataChanged(index(list.first().row(),TreeModel::Name),index(list.last().row(),TreeModel::Completed));
|
||||
}
|
||||
117
YACReaderLibrary/db/treemodel.h
Normal file
117
YACReaderLibrary/db/treemodel.h
Normal file
@ -0,0 +1,117 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples 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 Nokia Corporation 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef TREEMODEL_H
|
||||
#define TREEMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QModelIndex>
|
||||
#include <QVariant>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlDatabase>
|
||||
|
||||
class TreeItem;
|
||||
|
||||
//! [0]
|
||||
class TreeModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TreeModel(QObject *parent = 0);
|
||||
TreeModel( QSqlQuery &sqlquery, QObject *parent = 0);
|
||||
~TreeModel();
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const;
|
||||
QModelIndex index(int row, int column,
|
||||
const QModelIndex &parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
QModelIndex indexFromItem(TreeItem * item, int column);
|
||||
/*QModelIndex _indexFromItem(TreeItem * item, int column);
|
||||
int column;*/
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
void setupModelData(QString path);
|
||||
QString getDatabase();
|
||||
|
||||
//M<>todos de conveniencia
|
||||
QString getFolderPath(const QModelIndex &folder);
|
||||
|
||||
void setFilter(QString filter, bool includeComics);
|
||||
void resetFilter();
|
||||
bool isFilterEnabled(){return filterEnabled;};
|
||||
|
||||
void updateFolderCompletedStatus(const QModelIndexList & list, bool status);
|
||||
void updateFolderFinishedStatus(const QModelIndexList & list, bool status);
|
||||
|
||||
enum Columns {
|
||||
Name = 0,
|
||||
Path = 1,
|
||||
Finished = 2,
|
||||
Completed = 3
|
||||
};//id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, name TEXT NOT NULL, path TEXT NOT NULL
|
||||
|
||||
private:
|
||||
void setupModelData( QSqlQuery &sqlquery, TreeItem *parent);
|
||||
void setupFilteredModelData( QSqlQuery &sqlquery, TreeItem *parent);
|
||||
void setupFilteredModelData();
|
||||
|
||||
TreeItem *rootItem; //el <20>rbol
|
||||
QMap<unsigned long long int, TreeItem *> items; //relaci<63>n entre folders
|
||||
|
||||
TreeItem *rootBeforeFilter;
|
||||
QMap<unsigned long long int, TreeItem *> filteredItems; //relaci<63>n entre folders
|
||||
|
||||
QString _databasePath;
|
||||
|
||||
bool includeComics;
|
||||
QString filter;
|
||||
bool filterEnabled;
|
||||
signals:
|
||||
void beforeReset();
|
||||
void reset();
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif
|
||||
674
YACReaderLibrary/db_helper.cpp
Normal file
674
YACReaderLibrary/db_helper.cpp
Normal file
@ -0,0 +1,674 @@
|
||||
#include "db_helper.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QDateTime>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QCoreApplication>
|
||||
#include <QTextStream>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlRecord>
|
||||
#include <QSqlQuery>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "library_item.h"
|
||||
#include "comic_db.h"
|
||||
#include "data_base_management.h"
|
||||
#include "folder.h"
|
||||
#include "yacreader_libraries.h"
|
||||
|
||||
#include "qnaturalsorting.h"
|
||||
|
||||
//server
|
||||
|
||||
YACReaderLibraries DBHelper::getLibraries()
|
||||
{
|
||||
YACReaderLibraries libraries;
|
||||
libraries.load();
|
||||
return libraries;
|
||||
}
|
||||
QList<LibraryItem *> DBHelper::getFolderContentFromLibrary(const QString & libraryName, qulonglong folderId)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryName);
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
|
||||
|
||||
QList<LibraryItem *> list = DBHelper::getFoldersFromParent(folderId,db,false);
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(libraryPath);
|
||||
return list;
|
||||
}
|
||||
QList<LibraryItem *> DBHelper::getFolderComicsFromLibrary(const QString & libraryName, qulonglong folderId)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryName);
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
|
||||
|
||||
QList<LibraryItem *> list = DBHelper::getComicsFromParent(folderId,db,false);
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(libraryPath);
|
||||
return list;
|
||||
}
|
||||
qulonglong DBHelper::getParentFromComicFolderId(const QString & libraryName, qulonglong id)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryName);
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
|
||||
|
||||
Folder f = DBHelper::loadFolder(id,db);
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(libraryPath);
|
||||
return f.parentId;
|
||||
}
|
||||
ComicDB DBHelper::getComicInfo(const QString & libraryName, qulonglong id)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryName);
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
|
||||
|
||||
ComicDB comic = DBHelper::loadComic(id,db);
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(libraryPath);
|
||||
return comic;
|
||||
}
|
||||
|
||||
QList<ComicDB> DBHelper::getSiblings(const QString & libraryName, qulonglong parentId)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryName);
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
|
||||
|
||||
QList<ComicDB> comics = DBHelper::getSortedComicsFromParent(parentId,db);
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(libraryPath);
|
||||
return comics;
|
||||
}
|
||||
|
||||
QString DBHelper::getFolderName(const QString & libraryName, qulonglong id)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryName);
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
|
||||
|
||||
QString name="";
|
||||
|
||||
{
|
||||
QSqlQuery selectQuery(db); //TODO check
|
||||
selectQuery.prepare("SELECT name FROM folder WHERE id = :id");
|
||||
selectQuery.bindValue(":id", id);
|
||||
selectQuery.exec();
|
||||
|
||||
if(selectQuery.next())
|
||||
{
|
||||
QSqlRecord record = selectQuery.record();
|
||||
name = record.value(0).toString();
|
||||
}
|
||||
}
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(libraryPath);
|
||||
return name;
|
||||
}
|
||||
QList<QString> DBHelper::getLibrariesNames()
|
||||
{
|
||||
QStringList names = getLibraries().getNames();
|
||||
qSort(names.begin(),names.end(),naturalSortLessThanCI);
|
||||
return names;
|
||||
}
|
||||
QString DBHelper::getLibraryName(int id)
|
||||
{
|
||||
return getLibraries().getName(id);
|
||||
}
|
||||
//objects management
|
||||
//deletes
|
||||
void DBHelper::removeFromDB(LibraryItem * item, QSqlDatabase & db)
|
||||
{
|
||||
if(item->isDir())
|
||||
DBHelper::removeFromDB(dynamic_cast<Folder *>(item),db);
|
||||
else
|
||||
DBHelper::removeFromDB(dynamic_cast<ComicDB *>(item),db);
|
||||
}
|
||||
void DBHelper::removeFromDB(Folder * folder, QSqlDatabase & db)
|
||||
{
|
||||
QSqlQuery query(db);
|
||||
query.prepare("DELETE FROM folder WHERE id = :id");
|
||||
query.bindValue(":id", folder->id);
|
||||
query.exec();
|
||||
}
|
||||
void DBHelper::removeFromDB(ComicDB * comic, QSqlDatabase & db)
|
||||
{
|
||||
QSqlQuery query(db);
|
||||
query.prepare("DELETE FROM comic WHERE id = :id");
|
||||
query.bindValue(":id", comic->id);
|
||||
query.exec();
|
||||
}
|
||||
|
||||
//updates
|
||||
void DBHelper::update(ComicDB * comic, QSqlDatabase & db)
|
||||
{
|
||||
Q_UNUSED(comic)
|
||||
Q_UNUSED(db)
|
||||
//do nothing
|
||||
}
|
||||
|
||||
void DBHelper::update(const QString & libraryName, ComicInfo & comicInfo)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryName);
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
|
||||
|
||||
DBHelper::update(&comicInfo,db);
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(libraryPath);
|
||||
}
|
||||
|
||||
void DBHelper::update(ComicInfo * comicInfo, QSqlDatabase & db)
|
||||
{
|
||||
QSqlQuery updateComicInfo(db);
|
||||
updateComicInfo.prepare("UPDATE comic_info SET "
|
||||
"title = :title,"
|
||||
|
||||
"coverPage = :coverPage,"
|
||||
"numPages = :numPages,"
|
||||
|
||||
"number = :number,"
|
||||
"isBis = :isBis,"
|
||||
"count = :count,"
|
||||
|
||||
"volume = :volume,"
|
||||
"storyArc = :storyArc,"
|
||||
"arcNumber = :arcNumber,"
|
||||
"arcCount = :arcCount,"
|
||||
|
||||
"genere = :genere,"
|
||||
|
||||
"writer = :writer,"
|
||||
"penciller = :penciller,"
|
||||
"inker = :inker,"
|
||||
"colorist = :colorist,"
|
||||
"letterer = :letterer,"
|
||||
"coverArtist = :coverArtist,"
|
||||
|
||||
"date = :date,"
|
||||
"publisher = :publisher,"
|
||||
"format = :format,"
|
||||
"color = :color,"
|
||||
"ageRating = :ageRating,"
|
||||
|
||||
"synopsis = :synopsis,"
|
||||
"characters = :characters,"
|
||||
"notes = :notes,"
|
||||
|
||||
"read = :read,"
|
||||
"edited = :edited,"
|
||||
//new 7.0 fields
|
||||
"hasBeenOpened = :hasBeenOpened,"
|
||||
|
||||
"currentPage = :currentPage,"
|
||||
"bookmark1 = :bookmark1,"
|
||||
"bookmark2 = :bookmark2,"
|
||||
"bookmark3 = :bookmark3,"
|
||||
"brightness = :brightness,"
|
||||
"contrast = :contrast, "
|
||||
"gamma = :gamma,"
|
||||
"rating = :rating,"
|
||||
|
||||
//new 7.1 fields
|
||||
"comicVineID = :comicVineID"
|
||||
//--
|
||||
" WHERE id = :id ");
|
||||
|
||||
updateComicInfo.bindValue(":title",comicInfo->title);
|
||||
|
||||
updateComicInfo.bindValue(":coverPage", comicInfo->coverPage);
|
||||
updateComicInfo.bindValue(":numPages", comicInfo->numPages);
|
||||
|
||||
updateComicInfo.bindValue(":number", comicInfo->number);
|
||||
updateComicInfo.bindValue(":isBis", comicInfo->isBis);
|
||||
updateComicInfo.bindValue(":count", comicInfo->count);
|
||||
|
||||
updateComicInfo.bindValue(":volume", comicInfo->volume);
|
||||
updateComicInfo.bindValue(":storyArc", comicInfo->storyArc);
|
||||
updateComicInfo.bindValue(":arcNumber",comicInfo->arcNumber);
|
||||
updateComicInfo.bindValue(":arcCount",comicInfo->arcCount);
|
||||
|
||||
updateComicInfo.bindValue(":genere",comicInfo->genere);
|
||||
|
||||
updateComicInfo.bindValue(":writer",comicInfo->writer);
|
||||
updateComicInfo.bindValue(":penciller",comicInfo->penciller);
|
||||
updateComicInfo.bindValue(":inker",comicInfo->inker);
|
||||
updateComicInfo.bindValue(":colorist",comicInfo->colorist);
|
||||
updateComicInfo.bindValue(":letterer",comicInfo->letterer);
|
||||
updateComicInfo.bindValue(":coverArtist",comicInfo->coverArtist);
|
||||
|
||||
updateComicInfo.bindValue(":date",comicInfo->date);
|
||||
updateComicInfo.bindValue(":publisher",comicInfo->publisher);
|
||||
updateComicInfo.bindValue(":format",comicInfo->format);
|
||||
updateComicInfo.bindValue(":color",comicInfo->color);
|
||||
updateComicInfo.bindValue(":ageRating",comicInfo->ageRating);
|
||||
|
||||
updateComicInfo.bindValue(":synopsis",comicInfo->synopsis);
|
||||
updateComicInfo.bindValue(":characters",comicInfo->characters);
|
||||
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)
|
||||
updateComicInfo.bindValue(":read", read?1:0);
|
||||
updateComicInfo.bindValue(":id", comicInfo->id);
|
||||
updateComicInfo.bindValue(":edited", comicInfo->edited?1:0);
|
||||
|
||||
updateComicInfo.bindValue(":hasBeenOpened", comicInfo->hasBeenOpened?1:0);
|
||||
updateComicInfo.bindValue(":currentPage", comicInfo->currentPage);
|
||||
updateComicInfo.bindValue(":bookmark1", comicInfo->bookmark1);
|
||||
updateComicInfo.bindValue(":bookmark2", comicInfo->bookmark2);
|
||||
updateComicInfo.bindValue(":bookmark3", comicInfo->bookmark3);
|
||||
updateComicInfo.bindValue(":brightness", comicInfo->brightness);
|
||||
updateComicInfo.bindValue(":contrast", comicInfo->contrast);
|
||||
updateComicInfo.bindValue(":gamma", comicInfo->gamma);
|
||||
updateComicInfo.bindValue(":rating", comicInfo->rating);
|
||||
|
||||
updateComicInfo.bindValue(":comicVineID", comicInfo->comicVineID);
|
||||
|
||||
updateComicInfo.exec();
|
||||
}
|
||||
|
||||
void DBHelper::updateRead(ComicInfo * comicInfo, QSqlDatabase & db)
|
||||
{
|
||||
QSqlQuery updateComicInfo(db);
|
||||
updateComicInfo.prepare("UPDATE comic_info SET "
|
||||
"read = :read"
|
||||
" WHERE id = :id ");
|
||||
|
||||
updateComicInfo.bindValue(":read", comicInfo->read?1:0);
|
||||
updateComicInfo.bindValue(":id", comicInfo->id);
|
||||
updateComicInfo.exec();
|
||||
}
|
||||
|
||||
void DBHelper::update(const Folder & folder, QSqlDatabase &db)
|
||||
{
|
||||
QSqlQuery updateFolderInfo(db);
|
||||
updateFolderInfo.prepare("UPDATE folder SET "
|
||||
"finished = :finished, "
|
||||
"completed = :completed "
|
||||
"WHERE id = :id ");
|
||||
updateFolderInfo.bindValue(":finished", folder.isFinished()?1:0);
|
||||
updateFolderInfo.bindValue(":completed", folder.isCompleted()?1:0);
|
||||
updateFolderInfo.bindValue(":id", folder.id);
|
||||
updateFolderInfo.exec();
|
||||
}
|
||||
//inserts
|
||||
qulonglong DBHelper::insert(Folder * folder, QSqlDatabase & db)
|
||||
{
|
||||
QSqlQuery query(db);
|
||||
query.prepare("INSERT INTO folder (parentId, name, path) "
|
||||
"VALUES (:parentId, :name, :path)");
|
||||
query.bindValue(":parentId", folder->parentId);
|
||||
query.bindValue(":name", folder->name);
|
||||
query.bindValue(":path", folder->path);
|
||||
query.exec();
|
||||
return query.lastInsertId().toULongLong();
|
||||
}
|
||||
|
||||
qulonglong DBHelper::insert(ComicDB * comic, QSqlDatabase & db)
|
||||
{
|
||||
if(!comic->info.existOnDb)
|
||||
{
|
||||
QSqlQuery comicInfoInsert(db);
|
||||
comicInfoInsert.prepare("INSERT INTO comic_info (hash,numPages) "
|
||||
"VALUES (:hash,:numPages)");
|
||||
comicInfoInsert.bindValue(":hash", comic->info.hash);
|
||||
comicInfoInsert.bindValue(":numPages", comic->info.numPages);
|
||||
comicInfoInsert.exec();
|
||||
comic->info.id =comicInfoInsert.lastInsertId().toULongLong();
|
||||
comic->_hasCover = false;
|
||||
}
|
||||
else
|
||||
comic->_hasCover = true;
|
||||
|
||||
QSqlQuery query(db);
|
||||
query.prepare("INSERT INTO comic (parentId, comicInfoId, fileName, path) "
|
||||
"VALUES (:parentId,:comicInfoId,:name, :path)");
|
||||
query.bindValue(":parentId", comic->parentId);
|
||||
query.bindValue(":comicInfoId", comic->info.id);
|
||||
query.bindValue(":name", comic->name);
|
||||
query.bindValue(":path", comic->path);
|
||||
query.exec();
|
||||
return query.lastInsertId().toULongLong();
|
||||
}
|
||||
//queries
|
||||
QList<LibraryItem *> DBHelper::getFoldersFromParent(qulonglong parentId, QSqlDatabase & db, bool sort)
|
||||
{
|
||||
QList<LibraryItem *> list;
|
||||
|
||||
QSqlQuery selectQuery(db); //TODO check
|
||||
selectQuery.prepare("SELECT * FROM folder WHERE parentId = :parentId and id <> 1");
|
||||
selectQuery.bindValue(":parentId", parentId);
|
||||
selectQuery.exec();
|
||||
|
||||
Folder * currentItem;
|
||||
while (selectQuery.next())
|
||||
{
|
||||
QList<QVariant> data;
|
||||
QSqlRecord record = selectQuery.record();
|
||||
for(int i=0;i<record.count();i++)
|
||||
data << record.value(i);
|
||||
//TODO sort by sort indicator and name
|
||||
currentItem = new Folder(record.value("id").toULongLong(),record.value("parentId").toULongLong(),record.value("name").toString(),record.value("path").toString());
|
||||
int lessThan = 0;
|
||||
|
||||
if(list.isEmpty() || !sort)
|
||||
list.append(currentItem);
|
||||
else
|
||||
{
|
||||
Folder * last = static_cast<Folder *>(list.back());
|
||||
QString nameLast = last->name;
|
||||
QString nameCurrent = currentItem->name;
|
||||
QList<LibraryItem *>::iterator i;
|
||||
i = list.end();
|
||||
i--;
|
||||
while ((0 > (lessThan = naturalSortLessThanCI(nameCurrent,nameLast))) && i != list.begin())
|
||||
{
|
||||
i--;
|
||||
nameLast = (*i)->name;
|
||||
}
|
||||
if(lessThan>=0) //si se ha encontrado un elemento menor que current, se inserta justo después
|
||||
list.insert(++i,currentItem);
|
||||
else
|
||||
list.insert(i,currentItem);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QList<ComicDB> DBHelper::getSortedComicsFromParent(qulonglong parentId, QSqlDatabase & db)
|
||||
{
|
||||
|
||||
QList <ComicDB> list;
|
||||
|
||||
QSqlQuery selectQuery(db);
|
||||
selectQuery.prepare("select c.id,c.parentId,c.fileName,c.path,ci.hash from comic c inner join comic_info ci on (c.comicInfoId = ci.id) where c.parentId = :parentId");
|
||||
selectQuery.bindValue(":parentId", parentId);
|
||||
selectQuery.exec();
|
||||
|
||||
ComicDB currentItem;
|
||||
while (selectQuery.next())
|
||||
{
|
||||
QList<QVariant> data;
|
||||
QSqlRecord record = selectQuery.record();
|
||||
for(int i=0;i<record.count();i++)
|
||||
data << record.value(i);
|
||||
|
||||
currentItem.id = record.value("id").toULongLong();
|
||||
currentItem.parentId = record.value(1).toULongLong();
|
||||
currentItem.name = record.value(2).toString();
|
||||
currentItem.path = record.value(3).toString();
|
||||
currentItem.info = DBHelper::loadComicInfo(record.value(4).toString(),db);
|
||||
int lessThan = 0;
|
||||
if(list.isEmpty())
|
||||
list.append(currentItem);
|
||||
else
|
||||
{
|
||||
ComicDB last = static_cast<ComicDB>(list.back());
|
||||
QString nameLast = last.name;
|
||||
QString nameCurrent = currentItem.name;
|
||||
|
||||
int numberLast,numberCurrent;
|
||||
int max = (std::numeric_limits<int>::max)();
|
||||
numberLast = numberCurrent = max; //TODO change by std limit
|
||||
|
||||
if(!last.info.number.isNull())
|
||||
numberLast = last.info.number.toInt();
|
||||
|
||||
if(!currentItem.info.number.isNull())
|
||||
numberCurrent = currentItem.info.number.toInt();
|
||||
|
||||
QList<ComicDB>::iterator i;
|
||||
i = list.end();
|
||||
i--;
|
||||
|
||||
if(numberCurrent != max)
|
||||
{
|
||||
while ((lessThan =numberCurrent < numberLast) && i != list.begin())
|
||||
{
|
||||
i--;
|
||||
numberLast = max;
|
||||
|
||||
if(!(*i).info.number.isNull())
|
||||
numberLast = (*i).info.number.toInt();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((lessThan = naturalSortLessThanCI(nameCurrent,nameLast)) && i != list.begin() && numberLast == max)
|
||||
{
|
||||
i--;
|
||||
nameLast = (*i).name;
|
||||
numberLast = max;
|
||||
|
||||
if(!(*i).info.number.isNull())
|
||||
numberLast = (*i).info.number.toInt();
|
||||
}
|
||||
|
||||
}
|
||||
if(!lessThan) //si se ha encontrado un elemento menor que current, se inserta justo después
|
||||
{
|
||||
if(numberCurrent != max)
|
||||
{
|
||||
if(numberCurrent == numberLast)
|
||||
if(currentItem.info.isBis.toBool())
|
||||
{
|
||||
list.insert(++i,currentItem);
|
||||
}
|
||||
else
|
||||
list.insert(i,currentItem);
|
||||
else
|
||||
list.insert(++i,currentItem);
|
||||
}
|
||||
else
|
||||
list.insert(++i,currentItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
list.insert(i,currentItem);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//selectQuery.finish();
|
||||
return list;
|
||||
}
|
||||
QList<LibraryItem *> DBHelper::getComicsFromParent(qulonglong parentId, QSqlDatabase & db, bool sort)
|
||||
{
|
||||
QList<LibraryItem *> list;
|
||||
|
||||
QSqlQuery selectQuery(db);
|
||||
selectQuery.prepare("select c.id,c.parentId,c.fileName,c.path,ci.hash from comic c inner join comic_info ci on (c.comicInfoId = ci.id) where c.parentId = :parentId");
|
||||
selectQuery.bindValue(":parentId", parentId);
|
||||
selectQuery.exec();
|
||||
|
||||
ComicDB * currentItem;
|
||||
while (selectQuery.next())
|
||||
{
|
||||
QList<QVariant> data;
|
||||
QSqlRecord record = selectQuery.record();
|
||||
for(int i=0;i<record.count();i++)
|
||||
data << record.value(i);
|
||||
|
||||
currentItem = new ComicDB();
|
||||
currentItem->id = record.value("id").toULongLong();
|
||||
currentItem->parentId = record.value(1).toULongLong();
|
||||
currentItem->name = record.value(2).toString();
|
||||
currentItem->path = record.value(3).toString();
|
||||
currentItem->info = DBHelper::loadComicInfo(record.value(4).toString(),db);
|
||||
int lessThan = 0;
|
||||
if(list.isEmpty() || !sort)
|
||||
list.append(currentItem);
|
||||
else
|
||||
{
|
||||
ComicDB * last = static_cast<ComicDB *>(list.back());
|
||||
QString nameLast = last->name;
|
||||
QString nameCurrent = currentItem->name;
|
||||
QList<LibraryItem *>::iterator i;
|
||||
i = list.end();
|
||||
i--;
|
||||
while ((0 > (lessThan = nameCurrent.localeAwareCompare(nameLast))) && i != list.begin()) //se usa la misma ordenación que en QDir
|
||||
{
|
||||
i--;
|
||||
nameLast = (*i)->name;
|
||||
}
|
||||
if(lessThan>0) //si se ha encontrado un elemento menor que current, se inserta justo después
|
||||
list.insert(++i,currentItem);
|
||||
else
|
||||
list.insert(i,currentItem);
|
||||
|
||||
}
|
||||
}
|
||||
//selectQuery.finish();
|
||||
return list;
|
||||
}
|
||||
|
||||
//loads
|
||||
Folder DBHelper::loadFolder(qulonglong id, QSqlDatabase & db)
|
||||
{
|
||||
Folder folder;
|
||||
|
||||
QSqlQuery query(db);
|
||||
query.prepare("SELECT * FROM folder WHERE id = :id");
|
||||
query.bindValue(":id",id);
|
||||
query.exec();
|
||||
folder.id = id;
|
||||
folder.parentId = 0;
|
||||
if(query.next())
|
||||
{
|
||||
QSqlRecord record = query.record();
|
||||
folder.parentId = record.value("parentId").toULongLong();
|
||||
folder.name = record.value("name").toString();
|
||||
folder.path = record.value("path").toString();
|
||||
//new 7.1
|
||||
folder.setFinished(record.value("finished").toBool());
|
||||
folder.setCompleted(record.value("completed").toBool());
|
||||
}
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
ComicDB DBHelper::loadComic(qulonglong id, QSqlDatabase & db)
|
||||
{
|
||||
ComicDB comic;
|
||||
|
||||
QSqlQuery selectQuery(db);
|
||||
selectQuery.prepare("select c.id,c.parentId,c.fileName,c.path,ci.hash from comic c inner join comic_info ci on (c.comicInfoId = ci.id) where c.id = :id");
|
||||
selectQuery.bindValue(":id", id);
|
||||
selectQuery.exec();
|
||||
comic.id = id;
|
||||
if(selectQuery.next())
|
||||
{
|
||||
QSqlRecord record = selectQuery.record();
|
||||
//id = record.value("id").toULongLong();
|
||||
comic.parentId = record.value("parentId").toULongLong();
|
||||
comic.name = record.value("name").toString();
|
||||
comic.path = record.value("path").toString();
|
||||
comic.info = DBHelper::loadComicInfo(record.value("hash").toString(),db);
|
||||
}
|
||||
|
||||
return comic;
|
||||
}
|
||||
|
||||
ComicDB DBHelper::loadComic(QString cname, QString cpath, QString chash, QSqlDatabase & database)
|
||||
{
|
||||
ComicDB comic;
|
||||
|
||||
//comic.parentId = cparentId;
|
||||
comic.name = cname;
|
||||
comic.path = cpath;
|
||||
|
||||
comic.info = DBHelper::loadComicInfo(chash,database);
|
||||
|
||||
if(!comic.info.existOnDb)
|
||||
{
|
||||
comic.info.hash = chash;
|
||||
comic.info.coverPage = 1;
|
||||
comic._hasCover = false;
|
||||
}
|
||||
else
|
||||
comic._hasCover = true;
|
||||
|
||||
return comic;
|
||||
}
|
||||
|
||||
ComicInfo DBHelper::loadComicInfo(QString hash, QSqlDatabase & db)
|
||||
{
|
||||
ComicInfo comicInfo;
|
||||
|
||||
QSqlQuery findComicInfo(db);
|
||||
findComicInfo.prepare("SELECT * FROM comic_info WHERE hash = :hash");
|
||||
findComicInfo.bindValue(":hash", hash);
|
||||
findComicInfo.exec();
|
||||
|
||||
|
||||
if(findComicInfo.next())
|
||||
{
|
||||
comicInfo.hash = hash;
|
||||
QSqlRecord record = findComicInfo.record();
|
||||
|
||||
comicInfo.hash = hash;
|
||||
comicInfo.id = record.value("id").toULongLong();
|
||||
comicInfo.read = record.value("read").toBool();
|
||||
comicInfo.edited = record.value("edited").toBool();
|
||||
|
||||
//new 7.0 fields
|
||||
comicInfo.hasBeenOpened = record.value("hasBeenOpened").toBool();
|
||||
comicInfo.currentPage = record.value("currentPage").toInt();
|
||||
comicInfo.bookmark1 = record.value("bookmark1").toInt();
|
||||
comicInfo.bookmark2 = record.value("bookmark2").toInt();
|
||||
comicInfo.bookmark3 = record.value("bookmark3").toInt();
|
||||
comicInfo.brightness = record.value("brightness").toInt();
|
||||
comicInfo.contrast = record.value("contrast").toInt();
|
||||
comicInfo.gamma = record.value("gamma").toInt();
|
||||
comicInfo.rating = record.value("rating").toInt();
|
||||
//--
|
||||
|
||||
comicInfo.title = record.value("title");
|
||||
comicInfo.numPages = record.value("numPages");
|
||||
|
||||
comicInfo.coverPage = record.value("coverPage");
|
||||
|
||||
comicInfo.number = record.value("number");
|
||||
comicInfo.isBis = record.value("isBis");
|
||||
comicInfo.count = record.value("count");
|
||||
|
||||
comicInfo.volume = record.value("volume");
|
||||
comicInfo.storyArc = record.value("storyArc");
|
||||
comicInfo.arcNumber = record.value("arcNumber");
|
||||
comicInfo.arcCount = record.value("arcCount");
|
||||
|
||||
comicInfo.genere = record.value("genere");
|
||||
|
||||
comicInfo.writer = record.value("writer");
|
||||
comicInfo.penciller = record.value("penciller");
|
||||
comicInfo.inker = record.value("inker");
|
||||
comicInfo.colorist = record.value("colorist");
|
||||
comicInfo.letterer = record.value("letterer");
|
||||
comicInfo.coverArtist = record.value("coverArtist");
|
||||
|
||||
comicInfo.date = record.value("date");
|
||||
comicInfo.publisher = record.value("publisher");
|
||||
comicInfo.format = record.value("format");
|
||||
comicInfo.color = record.value("color");
|
||||
comicInfo.ageRating = record.value("ageRating");
|
||||
|
||||
comicInfo.synopsis = record.value("synopsis");
|
||||
comicInfo.characters = record.value("characters");
|
||||
comicInfo.notes = record.value("notes");
|
||||
|
||||
comicInfo.comicVineID = record.value("comicVineID");
|
||||
|
||||
comicInfo.existOnDb = true;
|
||||
}
|
||||
else
|
||||
comicInfo.existOnDb = false;
|
||||
|
||||
return comicInfo;
|
||||
}
|
||||
56
YACReaderLibrary/db_helper.h
Normal file
56
YACReaderLibrary/db_helper.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef DB_HELPER_H
|
||||
#define DB_HELPER_H
|
||||
|
||||
class QString;
|
||||
#include <QMap>
|
||||
#include <QList>
|
||||
|
||||
class ComicDB;
|
||||
class Folder;
|
||||
class LibraryItem;
|
||||
class QSqlDatabase;
|
||||
class ComicInfo;
|
||||
class QSqlRecord;
|
||||
class QSqlQuery;
|
||||
class YACReaderLibraries;
|
||||
|
||||
class DBHelper
|
||||
{
|
||||
public:
|
||||
//server
|
||||
static YACReaderLibraries getLibraries();
|
||||
static QList<LibraryItem *> getFolderContentFromLibrary(const QString & libraryName, qulonglong folderId);
|
||||
static QList<LibraryItem *> getFolderComicsFromLibrary(const QString & libraryName, qulonglong folderId);
|
||||
static qulonglong getParentFromComicFolderId(const QString & libraryName, qulonglong id);
|
||||
static ComicDB getComicInfo(const QString & libraryName, qulonglong id);
|
||||
static QList<ComicDB> getSiblings(const QString & libraryName, qulonglong parentId);
|
||||
static QString getFolderName(const QString & libraryName, qulonglong id);
|
||||
static QList<QString> getLibrariesNames();
|
||||
static QString getLibraryName(int id);
|
||||
|
||||
//objects management
|
||||
//deletes
|
||||
static void removeFromDB(LibraryItem * item, QSqlDatabase & db);
|
||||
static void removeFromDB(Folder * folder, QSqlDatabase & db);
|
||||
static void removeFromDB(ComicDB * comic, QSqlDatabase & db);
|
||||
//inserts
|
||||
static qulonglong insert(Folder * folder, QSqlDatabase & db);
|
||||
static qulonglong insert(ComicDB * comic, QSqlDatabase & db);
|
||||
//updates
|
||||
static void update(const QString & libraryName, ComicInfo & comicInfo);
|
||||
static void update(ComicDB * comics, QSqlDatabase & db);
|
||||
static void update(ComicInfo * comicInfo, QSqlDatabase & db);
|
||||
static void updateRead(ComicInfo * comicInfo, QSqlDatabase & db);
|
||||
static void update(const Folder & folder, QSqlDatabase & db);
|
||||
//queries
|
||||
static QList<LibraryItem *> getFoldersFromParent(qulonglong parentId, QSqlDatabase & db, bool sort = true);
|
||||
static QList<ComicDB> getSortedComicsFromParent(qulonglong parentId, QSqlDatabase & db);
|
||||
static QList<LibraryItem *> getComicsFromParent(qulonglong parentId, QSqlDatabase & db, bool sort = true);
|
||||
//load
|
||||
static Folder loadFolder(qulonglong id, QSqlDatabase & db);
|
||||
static ComicDB loadComic(qulonglong id, QSqlDatabase & db);
|
||||
static ComicDB loadComic(QString cname, QString cpath, QString chash, QSqlDatabase & database);
|
||||
static ComicInfo loadComicInfo(QString hash, QSqlDatabase & db);
|
||||
};
|
||||
|
||||
#endif
|
||||
92
YACReaderLibrary/export_comics_info_dialog.cpp
Normal file
92
YACReaderLibrary/export_comics_info_dialog.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include "export_comics_info_dialog.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QFileDialog>
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "data_base_management.h"
|
||||
|
||||
ExportComicsInfoDialog::ExportComicsInfoDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
textLabel = new QLabel(tr("Output file : "));
|
||||
path = new QLineEdit;
|
||||
textLabel->setBuddy(path);
|
||||
|
||||
accept = new QPushButton(tr("Create"));
|
||||
accept->setDisabled(true);
|
||||
connect(accept,SIGNAL(clicked()),this,SLOT(exportComicsInfo()));
|
||||
|
||||
cancel = new QPushButton(tr("Cancel"));
|
||||
connect(cancel,SIGNAL(clicked()),this,SLOT(close()));
|
||||
connect(cancel,SIGNAL(clicked()),this,SIGNAL(rejected()));
|
||||
|
||||
find = new QPushButton(QIcon(":/images/find_folder.png"),"");
|
||||
connect(find,SIGNAL(clicked()),this,SLOT(findPath()));
|
||||
|
||||
QHBoxLayout *libraryLayout = new QHBoxLayout;
|
||||
|
||||
libraryLayout->addWidget(textLabel);
|
||||
libraryLayout->addWidget(path);
|
||||
libraryLayout->addWidget(find);
|
||||
libraryLayout->setStretchFactor(find,0); //TODO
|
||||
|
||||
QHBoxLayout *bottomLayout = new QHBoxLayout;
|
||||
bottomLayout->addStretch();
|
||||
bottomLayout->addWidget(accept);
|
||||
bottomLayout->addWidget(cancel);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(libraryLayout);
|
||||
mainLayout->addWidget(progress=new QLabel());
|
||||
mainLayout->addStretch();
|
||||
mainLayout->addLayout(bottomLayout);
|
||||
|
||||
QHBoxLayout * imgMainLayout = new QHBoxLayout;
|
||||
QLabel * imgLabel = new QLabel(this);
|
||||
QPixmap p(":/images/exportComicsInfo.png");
|
||||
imgLabel->setPixmap(p);
|
||||
imgMainLayout->addWidget(imgLabel);
|
||||
imgMainLayout->addLayout(mainLayout);
|
||||
|
||||
setLayout(imgMainLayout);
|
||||
|
||||
setModal(true);
|
||||
setWindowTitle(tr("Export comics info"));
|
||||
}
|
||||
|
||||
ExportComicsInfoDialog::~ExportComicsInfoDialog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ExportComicsInfoDialog::findPath()
|
||||
{
|
||||
QString s = QFileDialog::getSaveFileName(this,tr("Destination database name"),".","*.ydb");
|
||||
if(!s.isEmpty())
|
||||
{
|
||||
path->setText(s);
|
||||
accept->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ExportComicsInfoDialog::exportComicsInfo()
|
||||
{
|
||||
QFileInfo f(path->text());
|
||||
QFileInfo fPath(f.absoluteDir().path());
|
||||
if(fPath.exists() && fPath.isDir() && fPath.isWritable())
|
||||
{
|
||||
DataBaseManagement::exportComicsInfo(source,path->text());
|
||||
close();
|
||||
}
|
||||
else
|
||||
QMessageBox::critical(NULL,tr("Problem found while writing"),tr("The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder"));
|
||||
}
|
||||
|
||||
void ExportComicsInfoDialog::close()
|
||||
{
|
||||
path->clear();
|
||||
QDialog::close();
|
||||
}
|
||||
35
YACReaderLibrary/export_comics_info_dialog.h
Normal file
35
YACReaderLibrary/export_comics_info_dialog.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef EXPORT_COMICS_INFO_DIALOG_H
|
||||
#define EXPORT_COMICS_INFO_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
|
||||
|
||||
class ExportComicsInfoDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ExportComicsInfoDialog(QWidget *parent = 0);
|
||||
~ExportComicsInfoDialog();
|
||||
QString source;
|
||||
|
||||
public slots:
|
||||
void findPath();
|
||||
void exportComicsInfo();
|
||||
void close();
|
||||
|
||||
private:
|
||||
QLabel * progress;
|
||||
QLabel * textLabel;
|
||||
QLineEdit * path;
|
||||
QPushButton * find;
|
||||
QPushButton * accept;
|
||||
QPushButton * cancel;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // EXPORT_COMICS_INFO_DIALOG_H
|
||||
100
YACReaderLibrary/export_library_dialog.cpp
Normal file
100
YACReaderLibrary/export_library_dialog.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include "export_library_dialog.h"
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
|
||||
ExportLibraryDialog::ExportLibraryDialog(QWidget * parent)
|
||||
:QDialog(parent),progressCount(0)
|
||||
{
|
||||
textLabel = new QLabel(tr("Output folder : "));
|
||||
path = new QLineEdit;
|
||||
textLabel->setBuddy(path);
|
||||
|
||||
accept = new QPushButton(tr("Create"));
|
||||
accept->setDisabled(true);
|
||||
connect(accept,SIGNAL(clicked()),this,SLOT(exportLibrary()));
|
||||
|
||||
cancel = new QPushButton(tr("Cancel"));
|
||||
connect(cancel,SIGNAL(clicked()),this,SLOT(close()));
|
||||
connect(cancel,SIGNAL(clicked()),this,SIGNAL(rejected()));
|
||||
|
||||
find = new QPushButton(QIcon(":/images/find_folder.png"),"");
|
||||
connect(find,SIGNAL(clicked()),this,SLOT(findPath()));
|
||||
|
||||
QHBoxLayout *libraryLayout = new QHBoxLayout;
|
||||
|
||||
libraryLayout->addWidget(textLabel);
|
||||
libraryLayout->addWidget(path);
|
||||
libraryLayout->addWidget(find);
|
||||
libraryLayout->setStretchFactor(find,0); //TODO
|
||||
|
||||
QHBoxLayout *bottomLayout = new QHBoxLayout;
|
||||
bottomLayout->addStretch();
|
||||
bottomLayout->addWidget(accept);
|
||||
bottomLayout->addWidget(cancel);
|
||||
|
||||
progressBar = new QProgressBar(this);
|
||||
progressBar->setMinimum(0);
|
||||
progressBar->setMaximum(0);
|
||||
progressBar->setTextVisible(false);
|
||||
progressBar->hide();
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(libraryLayout);
|
||||
mainLayout->addStretch();
|
||||
mainLayout->addWidget(progressBar);
|
||||
mainLayout->addLayout(bottomLayout);
|
||||
|
||||
QHBoxLayout * imgMainLayout = new QHBoxLayout;
|
||||
QLabel * imgLabel = new QLabel(this);
|
||||
QPixmap p(":/images/exportLibrary.png");
|
||||
imgLabel->setPixmap(p);
|
||||
imgMainLayout->addWidget(imgLabel);
|
||||
imgMainLayout->addLayout(mainLayout);
|
||||
|
||||
setLayout(imgMainLayout);
|
||||
|
||||
setModal(true);
|
||||
setWindowTitle(tr("Create covers package"));
|
||||
}
|
||||
|
||||
void ExportLibraryDialog::exportLibrary()
|
||||
{
|
||||
QFileInfo f(path->text());
|
||||
if(f.exists() && f.isDir() && f.isWritable())
|
||||
{
|
||||
progressBar->show();
|
||||
accept->setEnabled(false);
|
||||
emit exportPath(QDir::cleanPath(path->text()));
|
||||
}
|
||||
else
|
||||
QMessageBox::critical(NULL,tr("Problem found while writing"),tr("The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder"));
|
||||
|
||||
}
|
||||
|
||||
void ExportLibraryDialog::findPath()
|
||||
{
|
||||
QString s = QFileDialog::getExistingDirectory(0,tr("Destination directory"),".");
|
||||
if(!s.isEmpty())
|
||||
{
|
||||
path->setText(s);
|
||||
accept->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ExportLibraryDialog::close()
|
||||
{
|
||||
path->clear();
|
||||
progressBar->hide();
|
||||
accept->setEnabled(false);
|
||||
progressCount=0;
|
||||
QDialog::close();
|
||||
}
|
||||
|
||||
void ExportLibraryDialog::run()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
35
YACReaderLibrary/export_library_dialog.h
Normal file
35
YACReaderLibrary/export_library_dialog.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef EXPORT_LIBRARY_DIALOG_H
|
||||
#define EXPORT_LIBRARY_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QString>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QProgressBar>
|
||||
|
||||
class ExportLibraryDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExportLibraryDialog(QWidget * parent = 0);
|
||||
public slots:
|
||||
void exportLibrary();
|
||||
void findPath();
|
||||
void close();
|
||||
private:
|
||||
int progressCount;
|
||||
QProgressBar *progressBar;
|
||||
QLabel * textLabel;
|
||||
QLineEdit * path;
|
||||
QPushButton * find;
|
||||
QPushButton * accept;
|
||||
QPushButton * cancel;
|
||||
void run();
|
||||
signals:
|
||||
void exportPath(QString);
|
||||
};
|
||||
|
||||
#endif
|
||||
12
YACReaderLibrary/files.qrc
Normal file
12
YACReaderLibrary/files.qrc
Normal file
@ -0,0 +1,12 @@
|
||||
<RCC>
|
||||
<qresource>
|
||||
<file>../files/about.html</file>
|
||||
<file>../files/helpYACReaderLibrary.html</file>
|
||||
</qresource>
|
||||
|
||||
<qresource lang="es_ES">
|
||||
<file alias="/files/about.html">../files/about_es_ES.html</file>
|
||||
<file alias="/files/helpYACReaderLibrary.html">../files/helpYACReaderLibrary_es_ES.html</file>
|
||||
</qresource>
|
||||
|
||||
</RCC>
|
||||
BIN
YACReaderLibrary/icon.ico
Normal file
BIN
YACReaderLibrary/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
3
YACReaderLibrary/icon.rc
Normal file
3
YACReaderLibrary/icon.rc
Normal file
@ -0,0 +1,3 @@
|
||||
IDI_ICON1 ICON DISCARDABLE "icon.ico"
|
||||
IDI_ICON2 ICON DISCARDABLE "icon2.ico"
|
||||
IDI_ICON3 ICON DISCARDABLE "icon3.ico"
|
||||
BIN
YACReaderLibrary/icon2.ico
Normal file
BIN
YACReaderLibrary/icon2.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
BIN
YACReaderLibrary/icon3.ico
Normal file
BIN
YACReaderLibrary/icon3.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 81 KiB |
105
YACReaderLibrary/images.qrc
Normal file
105
YACReaderLibrary/images.qrc
Normal file
@ -0,0 +1,105 @@
|
||||
<RCC>
|
||||
<qresource prefix="/" >
|
||||
<file>../images/folder.png</file>
|
||||
<file>../images/folder_finished.png</file>
|
||||
<file>../images/icon.png</file>
|
||||
<file>../images/iconLibrary.png</file>
|
||||
<file>../images/new.png</file>
|
||||
<file>../images/openLibrary.png</file>
|
||||
<file>../images/removeLibraryIcon.png</file>
|
||||
<file>../images/updateLibraryIcon.png</file>
|
||||
<file>../images/comicFolder.png</file>
|
||||
<file>../images/notCover.png</file>
|
||||
<file>../images/edit.png</file>
|
||||
<file>../images/editIcon.png</file>
|
||||
<file>../images/flow1.png</file>
|
||||
<file>../images/flow2.png</file>
|
||||
<file>../images/flow3.png</file>
|
||||
<file>../images/flow4.png</file>
|
||||
<file>../images/flow5.png</file>
|
||||
<file>../images/importLibrary.png</file>
|
||||
<file>../images/importLibraryIcon.png</file>
|
||||
<file>../images/exportLibrary.png</file>
|
||||
<file>../images/exportLibraryIcon.png</file>
|
||||
<file>../images/importLibraryIcon.png</file>
|
||||
<file>../images/open.png</file>
|
||||
<file>../images/coversPackage.png</file>
|
||||
<file>../images/setRead.png</file>
|
||||
<!--<file>../images/setAllRead.png</file>-->
|
||||
<file>../images/setUnread.png</file>
|
||||
<!--<file>../images/setAllUnread.png</file>-->
|
||||
<file>../images/showMarks.png</file>
|
||||
<file>../images/editComic.png</file>
|
||||
<file>../images/selectAll.png</file>
|
||||
<file>../images/hideComicFlow.png</file>
|
||||
<file>../images/exportComicsInfo.png</file>
|
||||
<file>../images/importComicsInfo.png</file>
|
||||
<file>../images/exportComicsInfoIcon.png</file>
|
||||
<file>../images/importComicsInfoIcon.png</file>
|
||||
<file>../images/db.png</file>
|
||||
<file>../images/asignNumber.png</file>
|
||||
<file>../images/defaultCover.png</file>
|
||||
<file>../images/iphoneConfig.png</file>
|
||||
<file>../images/onStartFlowSelection.png</file>
|
||||
<file>../images/onStartFlowSelection_es.png</file>
|
||||
<file>../images/useNewFlowButton.png</file>
|
||||
<file>../images/useOldFlowButton.png</file>
|
||||
<file>../images/serverConfigBackground.png</file>
|
||||
<file>../images/noLibrariesIcon.png</file>
|
||||
<file>../images/noLibrariesLine.png</file>
|
||||
<file>../images/importingIcon.png</file>
|
||||
<file>../images/updatingIcon.png</file>
|
||||
<file>../images/importTopCoversDecoration.png</file>
|
||||
<file>../images/importBottomCoversDecoration.png</file>
|
||||
<file>../images/glowLine.png</file>
|
||||
<file>../images/clearSearch.png</file>
|
||||
<file>../images/iconSearch.png</file>
|
||||
<file>../images/readRibbon.png</file>
|
||||
<file>../images/readingRibbon.png</file>
|
||||
<file>../images/shownCovers.png</file>
|
||||
<file>../images/hiddenCovers.png</file>
|
||||
<file>../images/trash.png</file>
|
||||
<file>../images/setReadButton.png</file>
|
||||
<file>../images/openInYACReader.png</file>
|
||||
<!--<file>../images/deleting_progress/imgTopLeft.png</file>
|
||||
<file>../images/deleting_progress/imgTopMiddle.png</file>
|
||||
<file>../images/deleting_progress/imgTopRight.png</file>
|
||||
<file>../images/deleting_progress/imgLeftMiddle.png</file>
|
||||
<file>../images/deleting_progress/imgRightMiddle.png</file>
|
||||
<file>../images/deleting_progress/imgBottomLeft.png</file>
|
||||
<file>../images/deleting_progress/imgBottomMiddle.png</file>
|
||||
<file>../images/deleting_progress/imgBottomRight.png</file>
|
||||
<file>../images/deleting_progress/icon.png</file>
|
||||
<file>../images/social_dialog/close.png</file>
|
||||
<file>../images/social_dialog/facebook.png</file>
|
||||
<file>../images/social_dialog/google+.png</file>
|
||||
<file>../images/social_dialog/icon.png</file>
|
||||
<file>../images/social_dialog/shadow.png</file>
|
||||
<file>../images/social_dialog/twitter.png</file>
|
||||
<file>../images/social_dialog/separator.png</file>-->
|
||||
<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/libraryIconSelected.png</file>
|
||||
<file>../images/libraryOptions.png</file>
|
||||
<file>../images/branch-open.png</file>
|
||||
<file>../images/branch-closed.png</file>
|
||||
<file>../images/expanded_branch_selected.png</file>
|
||||
<file>../images/collapsed_branch_selected.png</file>
|
||||
<file>../images/previousCoverPage.png</file>
|
||||
<file>../images/nextCoverPage.png</file>
|
||||
<file>../images/getInfo.png</file>
|
||||
<file>../images/comic_vine/radioChecked.png</file>
|
||||
<file>../images/comic_vine/radioUnchecked.png</file>
|
||||
<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>
|
||||
</RCC>
|
||||
21
YACReaderLibrary/images_osx.qrc
Normal file
21
YACReaderLibrary/images_osx.qrc
Normal file
@ -0,0 +1,21 @@
|
||||
<RCC>
|
||||
<qresource prefix="/" >
|
||||
<file>../images/folder_finished_macosx.png</file>
|
||||
<file alias="images/main_toolbar/back.png">../images/main_toolbar/back_osx.png</file>
|
||||
|
||||
<file alias="images/main_toolbar/back_disabled.png">../images/main_toolbar/back_disabled_osx.png</file>
|
||||
<file alias="images/main_toolbar/forward.png">../images/main_toolbar/forward_osx.png</file>
|
||||
<file alias="images/main_toolbar/forward_disabled.png">../images/main_toolbar/forward_disabled_osx.png</file>
|
||||
<file alias="images/main_toolbar/settings.png">../images/main_toolbar/settings_osx.png</file>
|
||||
<file alias="images/main_toolbar/server.png">../images/main_toolbar/server_osx.png</file>
|
||||
<file alias="images/main_toolbar/help.png">../images/main_toolbar/help_osx.png</file>
|
||||
<file alias="images/main_toolbar/fullscreen.png">../images/main_toolbar/fullscreen_osx.png</file>
|
||||
|
||||
<file alias="images/libraryIcon.png">../images/libraryIcon_osx.png</file>
|
||||
<file alias="images/setRoot.png">../images/setRoot_osx.png</file>
|
||||
<file alias="images/expand.png">../images/expand_osx.png</file>
|
||||
<file alias="images/colapse.png">../images/colapse_osx.png</file>
|
||||
<file alias="images/newLibraryIcon.png">../images/newLibraryIcon_osx.png</file>
|
||||
<file alias="images/openLibraryIcon.png">../images/openLibraryIcon_osx.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
19
YACReaderLibrary/images_win.qrc
Normal file
19
YACReaderLibrary/images_win.qrc
Normal file
@ -0,0 +1,19 @@
|
||||
<RCC>
|
||||
<qresource prefix="/" >
|
||||
<file>../images/main_toolbar/back.png</file>
|
||||
<file>../images/main_toolbar/back_disabled.png</file>
|
||||
<file>../images/main_toolbar/forward.png</file>
|
||||
<file>../images/main_toolbar/forward_disabled.png</file>
|
||||
<file>../images/main_toolbar/settings.png</file>
|
||||
<file>../images/main_toolbar/server.png</file>
|
||||
<file>../images/main_toolbar/help.png</file>
|
||||
<file>../images/main_toolbar/fullscreen.png</file>
|
||||
|
||||
<file>../images/libraryIcon.png</file>
|
||||
<file>../images/setRoot.png</file>
|
||||
<file>../images/expand.png</file>
|
||||
<file>../images/colapse.png</file>
|
||||
<file>../images/newLibraryIcon.png</file>
|
||||
<file>../images/openLibraryIcon.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
111
YACReaderLibrary/import_comics_info_dialog.cpp
Normal file
111
YACReaderLibrary/import_comics_info_dialog.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include "import_comics_info_dialog.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QFileDialog>
|
||||
#include <QProgressBar>
|
||||
|
||||
#include "data_base_management.h"
|
||||
|
||||
ImportComicsInfoDialog::ImportComicsInfoDialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
setModal(true);
|
||||
setWindowTitle(tr("Import comics info"));
|
||||
|
||||
|
||||
textLabel = new QLabel(tr("Info database location : "));
|
||||
path = new QLineEdit;
|
||||
textLabel->setBuddy(path);
|
||||
|
||||
accept = new QPushButton(tr("Import"));
|
||||
accept->setDisabled(true);
|
||||
connect(accept,SIGNAL(clicked()),this,SLOT(import()));
|
||||
|
||||
cancel = new QPushButton(tr("Cancel"));
|
||||
connect(cancel,SIGNAL(clicked()),this,SLOT(close()));
|
||||
//connect(cancel,SIGNAL(clicked()),this,SIGNAL(rejected()));
|
||||
|
||||
find = new QPushButton(QIcon(":/images/find_folder.png"),"");
|
||||
connect(find,SIGNAL(clicked()),this,SLOT(findPath()));
|
||||
|
||||
QHBoxLayout *libraryLayout = new QHBoxLayout;
|
||||
|
||||
libraryLayout->addWidget(textLabel);
|
||||
libraryLayout->addWidget(path);
|
||||
libraryLayout->addWidget(find);
|
||||
libraryLayout->setStretchFactor(find,0); //TODO
|
||||
|
||||
progressBar = new QProgressBar(this);
|
||||
progressBar->setMinimum(0);
|
||||
progressBar->setMaximum(0);
|
||||
progressBar->setTextVisible(false);
|
||||
progressBar->hide();
|
||||
connect(accept,SIGNAL(clicked()),progressBar,SLOT(show()));
|
||||
|
||||
QHBoxLayout *bottomLayout = new QHBoxLayout;
|
||||
bottomLayout->addStretch();
|
||||
bottomLayout->addWidget(accept);
|
||||
bottomLayout->addWidget(cancel);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(libraryLayout);
|
||||
mainLayout->addStretch();
|
||||
mainLayout->addWidget(progressBar);
|
||||
mainLayout->addLayout(bottomLayout);
|
||||
|
||||
QHBoxLayout * imgMainLayout = new QHBoxLayout;
|
||||
QLabel * imgLabel = new QLabel(this);
|
||||
QPixmap p(":/images/importComicsInfo.png");
|
||||
imgLabel->setPixmap(p);
|
||||
imgMainLayout->addWidget(imgLabel);
|
||||
imgMainLayout->addLayout(mainLayout);
|
||||
|
||||
setLayout(imgMainLayout);
|
||||
|
||||
setModal(true);
|
||||
}
|
||||
|
||||
ImportComicsInfoDialog::~ImportComicsInfoDialog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ImportComicsInfoDialog::findPath()
|
||||
{
|
||||
QString s = QFileDialog::getOpenFileName(0,"Comics Info",".",tr("Comics info file (*.ydb)"));
|
||||
if(!s.isEmpty())
|
||||
{
|
||||
path->setText(s);
|
||||
accept->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ImportComicsInfoDialog::import()
|
||||
{
|
||||
progressBar->show();
|
||||
|
||||
Importer * importer = new Importer();
|
||||
importer->source = path->text();
|
||||
importer->dest = dest;
|
||||
connect(importer,SIGNAL(finished()),this,SLOT(close()));
|
||||
connect(importer,SIGNAL(finished()),this,SLOT(hide()));
|
||||
importer->start();
|
||||
}
|
||||
|
||||
void ImportComicsInfoDialog::close()
|
||||
{
|
||||
path->clear();
|
||||
progressBar->hide();
|
||||
accept->setDisabled(true);
|
||||
QDialog::close();
|
||||
emit(finished(0));
|
||||
}
|
||||
|
||||
void Importer::run()
|
||||
{
|
||||
DataBaseManagement::importComicsInfo(source,dest);
|
||||
}
|
||||
|
||||
|
||||
52
YACReaderLibrary/import_comics_info_dialog.h
Normal file
52
YACReaderLibrary/import_comics_info_dialog.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef IMPORT_COMICS_INFO_DIALOG_H
|
||||
#define IMPORT_COMICS_INFO_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QProgressBar>
|
||||
#include <QThread>
|
||||
|
||||
class Importer : public QThread
|
||||
{
|
||||
public:
|
||||
QString source;
|
||||
QString dest;
|
||||
private:
|
||||
void run();
|
||||
};
|
||||
|
||||
class ImportComicsInfoDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ImportComicsInfoDialog(QWidget *parent = 0);
|
||||
~ImportComicsInfoDialog();
|
||||
QString dest;
|
||||
|
||||
private:
|
||||
QLabel * nameLabel;
|
||||
QLabel * textLabel;
|
||||
QLabel * destLabel;
|
||||
QLineEdit * path;
|
||||
QLineEdit * destPath;
|
||||
QLineEdit * nameEdit;
|
||||
QPushButton * find;
|
||||
QPushButton * findDest;
|
||||
QPushButton * accept;
|
||||
QPushButton * cancel;
|
||||
QLabel * progress;
|
||||
void setupUI();
|
||||
int progressCount;
|
||||
QProgressBar *progressBar;
|
||||
|
||||
public slots:
|
||||
void findPath();
|
||||
void import();
|
||||
void close();
|
||||
};
|
||||
|
||||
#endif // IMPORT_COMICS_INFO_DIALOG_H
|
||||
157
YACReaderLibrary/import_library_dialog.cpp
Normal file
157
YACReaderLibrary/import_library_dialog.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
#include "import_library_dialog.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QFileDialog>
|
||||
#include <QGridLayout>
|
||||
#include <QCloseEvent>
|
||||
|
||||
ImportLibraryDialog::ImportLibraryDialog(QWidget * parent)
|
||||
:QDialog(parent),progressCount(0)
|
||||
{
|
||||
setupUI();
|
||||
}
|
||||
|
||||
void ImportLibraryDialog::setupUI()
|
||||
{
|
||||
nameLabel = new QLabel(tr("Library Name : "));
|
||||
nameEdit = new QLineEdit;
|
||||
nameLabel->setBuddy(nameEdit);
|
||||
connect(nameEdit,SIGNAL(textChanged(QString)),this,SLOT(nameEntered()));
|
||||
|
||||
textLabel = new QLabel(tr("Package location : "));
|
||||
path = new QLineEdit;
|
||||
textLabel->setBuddy(path);
|
||||
|
||||
destLabel = new QLabel(tr("Destination folder : "));
|
||||
destPath = new QLineEdit;
|
||||
textLabel->setBuddy(destPath);
|
||||
|
||||
accept = new QPushButton(tr("Unpack"));
|
||||
accept->setDisabled(true);
|
||||
connect(accept,SIGNAL(clicked()),this,SLOT(add()));
|
||||
|
||||
cancel = new QPushButton(tr("Cancel"));
|
||||
connect(cancel,SIGNAL(clicked()),this,SLOT(close()));
|
||||
//connect(cancel,SIGNAL(clicked()),this,SIGNAL(rejected()));
|
||||
|
||||
find = new QPushButton(QIcon(":/images/find_folder.png"),"");
|
||||
connect(find,SIGNAL(clicked()),this,SLOT(findPath()));
|
||||
|
||||
findDest = new QPushButton(QIcon(":/images/find_folder.png"),"");
|
||||
connect(findDest,SIGNAL(clicked()),this,SLOT(findDestination()));
|
||||
|
||||
QGridLayout * content = new QGridLayout;
|
||||
|
||||
content->addWidget(nameLabel,0,0);
|
||||
content->addWidget(nameEdit,0,1);
|
||||
|
||||
content->addWidget(textLabel,1,0);
|
||||
content->addWidget(path,1,1);
|
||||
content->addWidget(find,1,2);
|
||||
content->setColumnStretch(2,0); //TODO
|
||||
|
||||
content->addWidget(destLabel,2,0);
|
||||
content->addWidget(destPath,2,1);
|
||||
content->addWidget(findDest,2,2);
|
||||
//destLayout->setStretchFactor(findDest,0); //TODO
|
||||
|
||||
QHBoxLayout *bottomLayout = new QHBoxLayout;
|
||||
bottomLayout->addStretch();
|
||||
bottomLayout->addWidget(accept);
|
||||
bottomLayout->addWidget(cancel);
|
||||
|
||||
progressBar = new QProgressBar(this);
|
||||
progressBar->setMinimum(0);
|
||||
progressBar->setMaximum(0);
|
||||
progressBar->setTextVisible(false);
|
||||
progressBar->hide();
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(content);
|
||||
//mainLayout->addWidget(progress = new QLabel());
|
||||
mainLayout->addStretch();
|
||||
mainLayout->addWidget(progressBar);
|
||||
mainLayout->addLayout(bottomLayout);
|
||||
|
||||
QHBoxLayout * imgMainLayout = new QHBoxLayout;
|
||||
QLabel * imgLabel = new QLabel(this);
|
||||
QPixmap p(":/images/importLibrary.png");
|
||||
imgLabel->setPixmap(p);
|
||||
imgMainLayout->addWidget(imgLabel);
|
||||
imgMainLayout->addLayout(mainLayout);
|
||||
|
||||
setLayout(imgMainLayout);
|
||||
|
||||
setModal(true);
|
||||
setWindowTitle(tr("Extract a catalog"));
|
||||
}
|
||||
void ImportLibraryDialog::show(const YACReaderLibraries &libs)
|
||||
{
|
||||
libraries = libs;
|
||||
QDialog::show();
|
||||
}
|
||||
|
||||
void ImportLibraryDialog::add()
|
||||
{
|
||||
if(!libraries.contains(nameEdit->text()))
|
||||
{
|
||||
accept->setEnabled(false);
|
||||
progressBar->show();
|
||||
emit(unpackCLC(QDir::cleanPath(path->text()),QDir::cleanPath(destPath->text()),nameEdit->text()));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit(libraryExists(nameEdit->text()));
|
||||
}
|
||||
}
|
||||
|
||||
void ImportLibraryDialog::findPath()
|
||||
{
|
||||
QString s = QFileDialog::getOpenFileName(0,"Covers Package",".",tr("Compresed library covers (*.clc)"));
|
||||
if(!s.isEmpty())
|
||||
{
|
||||
path->setText(s);
|
||||
if(!destPath->text().isEmpty() && !nameEdit->text().isEmpty())
|
||||
accept->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ImportLibraryDialog::findDestination()
|
||||
{
|
||||
QString s = QFileDialog::getExistingDirectory(0,"Folder",".",QFileDialog::ShowDirsOnly);
|
||||
if(!s.isEmpty())
|
||||
{
|
||||
destPath->setText(s);
|
||||
if(!path->text().isEmpty() && !nameEdit->text().isEmpty())
|
||||
accept->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ImportLibraryDialog::nameEntered()
|
||||
{
|
||||
if(!nameEdit->text().isEmpty())
|
||||
{
|
||||
if(!path->text().isEmpty() && !destPath->text().isEmpty())
|
||||
accept->setEnabled(true);
|
||||
}
|
||||
else
|
||||
accept->setEnabled(false);
|
||||
}
|
||||
|
||||
void ImportLibraryDialog::close()
|
||||
{
|
||||
path->clear();
|
||||
destPath->clear();
|
||||
nameEdit->clear();
|
||||
accept->setEnabled(false);
|
||||
progressBar->hide();
|
||||
QDialog::hide();
|
||||
}
|
||||
|
||||
void ImportLibraryDialog::closeEvent ( QCloseEvent * e )
|
||||
{
|
||||
close();
|
||||
e->accept();
|
||||
}
|
||||
46
YACReaderLibrary/import_library_dialog.h
Normal file
46
YACReaderLibrary/import_library_dialog.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef IMPORT_LIBRARY_DIALOG_H
|
||||
#define IMPORT_LIBRARY_DIALOG_H
|
||||
#include "yacreader_libraries.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QThread>
|
||||
#include <QProgressBar>
|
||||
|
||||
class ImportLibraryDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ImportLibraryDialog(QWidget * parent = 0);
|
||||
private:
|
||||
QLabel * nameLabel;
|
||||
QLabel * textLabel;
|
||||
QLabel * destLabel;
|
||||
QLineEdit * path;
|
||||
QLineEdit * destPath;
|
||||
QLineEdit * nameEdit;
|
||||
QPushButton * find;
|
||||
QPushButton * findDest;
|
||||
QPushButton * accept;
|
||||
QPushButton * cancel;
|
||||
QProgressBar *progressBar;
|
||||
void setupUI();
|
||||
int progressCount;
|
||||
void closeEvent ( QCloseEvent * e );
|
||||
YACReaderLibraries libraries;
|
||||
public slots:
|
||||
void add();
|
||||
void findPath();
|
||||
void findDestination();
|
||||
void close();
|
||||
void nameEntered();
|
||||
void show(const YACReaderLibraries & libs);
|
||||
|
||||
signals:
|
||||
void unpackCLC(QString clc,QString targetFolder, QString name);
|
||||
void libraryExists(const QString & name);
|
||||
};
|
||||
|
||||
#endif
|
||||
385
YACReaderLibrary/import_widget.cpp
Normal file
385
YACReaderLibrary/import_widget.cpp
Normal file
@ -0,0 +1,385 @@
|
||||
#include "import_widget.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsPixmapItem>
|
||||
#include <QScrollBar>
|
||||
#include <QGraphicsItemAnimation>
|
||||
#include <QTimeLine>
|
||||
#include <QGLWidget>
|
||||
#include <QTimer>
|
||||
#include <QElapsedTimer>
|
||||
#include <QToolButton>
|
||||
#include <QResizeEvent>
|
||||
|
||||
#include <QPropertyAnimation>
|
||||
#include <QGraphicsOpacityEffect>
|
||||
|
||||
class YACReaderActivityIndicatorWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
YACReaderActivityIndicatorWidget(QWidget * parent = 0);
|
||||
public slots:
|
||||
|
||||
private:
|
||||
QLabel * normal;
|
||||
QLabel * glow;
|
||||
};
|
||||
|
||||
YACReaderActivityIndicatorWidget::YACReaderActivityIndicatorWidget(QWidget * parent)
|
||||
:QWidget(parent)
|
||||
{
|
||||
QPixmap line(":/images/noLibrariesLine.png");
|
||||
QPixmap glowLine(":/images/glowLine.png");
|
||||
normal = new QLabel(this);
|
||||
glow = new QLabel(this);
|
||||
|
||||
normal->setPixmap(line);
|
||||
glow->setPixmap(glowLine);
|
||||
|
||||
|
||||
|
||||
QHBoxLayout * layout = new QHBoxLayout();
|
||||
|
||||
layout->addWidget(normal,0,Qt::AlignVCenter);
|
||||
|
||||
setLayout(layout);
|
||||
|
||||
layout->setMargin(4);
|
||||
layout->setSpacing(0);
|
||||
|
||||
//setFixedHeight(3);
|
||||
//resize(579,3);
|
||||
glow->setGeometry(4,4,glowLine.width(),glowLine.height());
|
||||
//normal->setGeometry(0,1,579,1);
|
||||
|
||||
QGraphicsOpacityEffect * effect = new QGraphicsOpacityEffect();
|
||||
//effect->setOpacity(1.0);
|
||||
|
||||
|
||||
QPropertyAnimation * animation = new QPropertyAnimation(effect,"opacity");
|
||||
|
||||
animation->setDuration(1000);
|
||||
animation->setStartValue(1);
|
||||
animation->setEndValue(0);
|
||||
//animation->setEasingCurve(QEasingCurve::InQuint);
|
||||
|
||||
QPropertyAnimation * animation2 = new QPropertyAnimation(effect,"opacity");
|
||||
|
||||
animation2->setDuration(1000);
|
||||
animation2->setStartValue(0);
|
||||
animation2->setEndValue(1);
|
||||
//animation2->setEasingCurve(QEasingCurve::InQuint);
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
glow->setGraphicsEffect(effect);
|
||||
#endif
|
||||
|
||||
connect(animation,SIGNAL(finished()),animation2,SLOT(start()));
|
||||
connect(animation2,SIGNAL(finished()),animation,SLOT(start()));
|
||||
|
||||
animation->start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ImportWidget::ImportWidget(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
|
||||
|
||||
QPalette p(palette());
|
||||
p.setColor(QPalette::Background, QColor(250,250,250));
|
||||
setAutoFillBackground(true);
|
||||
setPalette(p);
|
||||
|
||||
QPixmap icon(":/images/importingIcon.png");
|
||||
iconLabel = new QLabel();
|
||||
iconLabel->setPixmap(icon);
|
||||
|
||||
/*QPixmap line(":/images/noLibrariesLine.png");
|
||||
QLabel * lineLabel = new QLabel();
|
||||
lineLabel->setPixmap(line);*/
|
||||
|
||||
YACReaderActivityIndicatorWidget * activityIndicator = new YACReaderActivityIndicatorWidget();
|
||||
|
||||
text = new QLabel();//"<font color=\"#495252\">"+tr("Importing comics")+"</font>");
|
||||
text->setStyleSheet("QLabel {font-size:25px;font-weight:bold;}");
|
||||
textDescription = new QLabel();//"<font color=\"#565959\">"+tr("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")+"</font>");
|
||||
textDescription->setWordWrap(true);
|
||||
textDescription->setMaximumWidth(330);
|
||||
currentComicLabel = new QLabel("<font color=\"#565959\">...</font>");
|
||||
|
||||
coversViewContainer = new QWidget(this);
|
||||
QVBoxLayout * coversViewLayout = new QVBoxLayout;
|
||||
coversViewContainer->setLayout(coversViewLayout);
|
||||
coversView = new QGraphicsView();
|
||||
//coversView->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
|
||||
coversView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
coversView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
coversView->setMaximumHeight(300);
|
||||
coversView->setStyleSheet("QGraphicsView {background-color: #E6E6E6;border:none;}");
|
||||
|
||||
coversScene = new QGraphicsScene();
|
||||
coversScene->setSceneRect(0,0,coversView->width(),coversView->height());
|
||||
coversView->setAlignment(Qt::AlignLeft);
|
||||
coversView->setScene(coversScene);
|
||||
|
||||
|
||||
QLabel * topDecorator = new QLabel();
|
||||
QLabel * bottomDecorator = new QLabel();
|
||||
QPixmap top(":/images/importTopCoversDecoration.png");
|
||||
QPixmap bottom(":/images/importBottomCoversDecoration.png");
|
||||
topDecorator->setPixmap(top);
|
||||
bottomDecorator->setPixmap(bottom);
|
||||
topDecorator->setScaledContents(true);
|
||||
bottomDecorator->setScaledContents(true);
|
||||
topDecorator->setFixedHeight(top.height());
|
||||
bottomDecorator->setFixedHeight(bottom.height());
|
||||
|
||||
coversViewLayout->addWidget(topDecorator,0);
|
||||
coversViewLayout->addWidget(coversView,1);
|
||||
coversViewLayout->addWidget(bottomDecorator,0);
|
||||
coversViewLayout->setMargin(0);
|
||||
coversViewLayout->setSpacing(0);
|
||||
|
||||
QPushButton * stop = new QPushButton(tr("stop"));
|
||||
stop->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Maximum);
|
||||
|
||||
QVBoxLayout * layout = new QVBoxLayout(this);
|
||||
QHBoxLayout * buttonLayout = new QHBoxLayout();
|
||||
QHBoxLayout * topLayout = new QHBoxLayout();
|
||||
QVBoxLayout * textLayout = new QVBoxLayout();
|
||||
|
||||
QWidget * topWidget = new QWidget();
|
||||
topWidget->setFixedWidth(650);
|
||||
textLayout->addStretch();
|
||||
textLayout->addWidget(text);
|
||||
textLayout->addSpacing(12);
|
||||
textLayout->addWidget(textDescription);
|
||||
textLayout->addStretch();
|
||||
|
||||
topLayout->addStretch();
|
||||
topLayout->addWidget(iconLabel,0,Qt::AlignVCenter);
|
||||
topLayout->addSpacing(30);
|
||||
topLayout->addLayout(textLayout,1);
|
||||
topLayout->addStretch();
|
||||
topLayout->setMargin(0);
|
||||
|
||||
topWidget->setLayout(topLayout);
|
||||
|
||||
layout->setAlignment(Qt::AlignHCenter);
|
||||
|
||||
buttonLayout->addSpacing(250);
|
||||
buttonLayout->addWidget(stop);
|
||||
buttonLayout->addSpacing(250);
|
||||
|
||||
layout->addSpacing(50);
|
||||
layout->addWidget(topWidget,0,Qt::AlignHCenter);
|
||||
layout->addSpacing(20);
|
||||
layout->addWidget(activityIndicator,0,Qt::AlignHCenter);
|
||||
layout->addSpacing(10);
|
||||
layout->addLayout(buttonLayout,0);
|
||||
layout->addSpacing(10);
|
||||
layout->addStretch();
|
||||
portadasLabel = new QLabel("<font color=\"#565959\">"+tr("Some of the comics being added...")+"</font>");
|
||||
|
||||
hideButton = new QToolButton(this);
|
||||
hideButton->setFixedSize(25,18);
|
||||
hideButton->setStyleSheet("QToolButton {background: url(\":/images/shownCovers.png\"); border:none;}"
|
||||
" QToolButton:checked {background:url(\":/images/hiddenCovers.png\"); border:none;}");
|
||||
hideButton->setCheckable(true);
|
||||
|
||||
connect(hideButton,SIGNAL(toggled(bool)),this,SLOT(showCovers(bool)));
|
||||
|
||||
layout->addWidget(portadasLabel,0,Qt::AlignHCenter);
|
||||
layout->addWidget(coversViewContainer);
|
||||
//layout->addStretch();
|
||||
layout->addWidget(currentComicLabel,0,Qt::AlignHCenter);
|
||||
layout->setContentsMargins(0,layout->contentsMargins().top(),0,layout->contentsMargins().bottom());
|
||||
|
||||
connect(stop,SIGNAL(clicked()),this,SIGNAL(stop()));
|
||||
//connect(stop,SIGNAL(clicked()),this,SLOT(addCoverTest()));
|
||||
|
||||
previousWidth = 10;
|
||||
updatingCovers = false;
|
||||
elapsedTimer = new QElapsedTimer();
|
||||
}
|
||||
|
||||
void ImportWidget::newComic(const QString & path, const QString & coverPath)
|
||||
{
|
||||
currentComicLabel->setText("<font color=\"#565959\">"+path+"</font>");
|
||||
|
||||
if(((elapsedTimer->elapsed()>=1000) || ((previousWidth < coversView->width()) && (elapsedTimer->elapsed()>=500))) && !updatingCovers)//todo elapsed time
|
||||
{
|
||||
|
||||
QPixmap p(coverPath);
|
||||
p = p.scaledToHeight(300,Qt::SmoothTransformation);
|
||||
QGraphicsPixmapItem * item = new QGraphicsPixmapItem(p);
|
||||
item->setPos(previousWidth,0);
|
||||
item->setZValue(i/10000.0);
|
||||
previousWidth += 10 + p.width();
|
||||
coversScene->addItem(item);
|
||||
|
||||
elapsedTimer->start();
|
||||
if(previousWidth >= coversView->width()+200 && !updatingCovers)
|
||||
{
|
||||
updatingCovers = true;
|
||||
|
||||
foreach(QGraphicsItem * itemToRemove, coversScene->items())
|
||||
{
|
||||
QGraphicsPixmapItem * last = dynamic_cast<QGraphicsPixmapItem *>(itemToRemove);
|
||||
|
||||
if((last->pos().x()+last->pixmap().width())<=0)
|
||||
{
|
||||
coversScene->removeItem(last);
|
||||
delete last;
|
||||
}
|
||||
//else
|
||||
// break;
|
||||
}
|
||||
|
||||
int width = p.width();
|
||||
|
||||
foreach(QGraphicsItem * itemToMove, coversScene->items())
|
||||
{
|
||||
QTimeLine *timer = new QTimeLine(400);
|
||||
timer->setFrameRange(0, 24);
|
||||
timer->setUpdateInterval(17);
|
||||
|
||||
QGraphicsItemAnimation *animation = new QGraphicsItemAnimation;
|
||||
animation->setItem(itemToMove);
|
||||
animation->setTimeLine(timer);
|
||||
|
||||
QPointF point = itemToMove->scenePos();
|
||||
float step = (width+10)/24.0;
|
||||
for (int i = 0; i < 24; ++i)
|
||||
animation->setPosAt(i / 24.0, QPointF(point.x()-((i+1)*step), point.y()));
|
||||
|
||||
timer->start();
|
||||
connect(timer,SIGNAL(finished()),timer,SLOT(deleteLater()));
|
||||
connect(timer,SIGNAL(finished()),animation,SLOT(deleteLater()));
|
||||
}
|
||||
|
||||
QTimer::singleShot(400,this,SLOT(finishedUpdatingCover()));
|
||||
|
||||
previousWidth -= 10+width;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ImportWidget::finishedUpdatingCover()
|
||||
{
|
||||
updatingCovers = false;
|
||||
}
|
||||
|
||||
void ImportWidget::newCover(const QPixmap & image)
|
||||
{
|
||||
Q_UNUSED(image)
|
||||
}
|
||||
static int i = 1;
|
||||
static int previousWidth = 10;
|
||||
static int j = 0;
|
||||
void ImportWidget::addCoverTest()
|
||||
{
|
||||
QPixmap p(QString("c:/temp/%1.jpg").arg(i));
|
||||
p = p.scaledToHeight(300,Qt::SmoothTransformation);
|
||||
QGraphicsPixmapItem * item = new QGraphicsPixmapItem(p);
|
||||
item->setPos(previousWidth,0);
|
||||
item->setZValue(i/10000.0);
|
||||
previousWidth += 10 + p.width();
|
||||
coversScene->addItem(item);
|
||||
if(previousWidth >= coversView->width())
|
||||
{
|
||||
QGraphicsItem * last = coversScene->items().last();
|
||||
int width = p.width();
|
||||
if(j>=1)
|
||||
{
|
||||
coversScene->removeItem(last);
|
||||
delete last;
|
||||
}
|
||||
else
|
||||
j++;
|
||||
|
||||
foreach(QGraphicsItem * itemToMove, coversScene->items())
|
||||
{
|
||||
|
||||
QTimeLine *timer = new QTimeLine(/*350*/1000);
|
||||
timer->setFrameRange(0, 60);
|
||||
|
||||
QGraphicsItemAnimation *animation = new QGraphicsItemAnimation;
|
||||
animation->setItem(itemToMove);
|
||||
animation->setTimeLine(timer);
|
||||
|
||||
QPointF point = itemToMove->scenePos();
|
||||
float step = (width+10)/60.0;
|
||||
for (int i = 0; i < 60; ++i)
|
||||
animation->setPosAt(i / 60.0, QPointF(point.x()-((i+1)*step), point.y()));
|
||||
|
||||
timer->start();
|
||||
}
|
||||
previousWidth -= 10+width;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
void ImportWidget::clear()
|
||||
{
|
||||
previousWidth = 10;
|
||||
|
||||
//nos aseguramos de que las animaciones han finalizado antes de borrar
|
||||
QList<QGraphicsItem*> all = coversScene->items();
|
||||
for (int i = 0; i < all.size(); i++)
|
||||
{
|
||||
QGraphicsItem *gi = all[i];
|
||||
if(gi->parentItem()==NULL)
|
||||
delete gi;
|
||||
}
|
||||
coversScene->clear();
|
||||
|
||||
updatingCovers = false;
|
||||
|
||||
currentComicLabel->setText("<font color=\"#565959\">...</font>");
|
||||
|
||||
this->i = 0;
|
||||
}
|
||||
|
||||
void ImportWidget::setImportLook()
|
||||
{
|
||||
iconLabel->setPixmap(QPixmap(":/images/importingIcon.png"));
|
||||
text->setText("<font color=\"#495252\">"+tr("Importing comics")+"</font>");
|
||||
textDescription->setText("<font color=\"#565959\">"+tr("<p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p>")+"</font>");
|
||||
}
|
||||
|
||||
void ImportWidget::setUpdateLook()
|
||||
{
|
||||
iconLabel->setPixmap(QPixmap(":/images/updatingIcon.png"));
|
||||
text->setText("<font color=\"#495252\">"+tr("Updating the library")+"</font>");
|
||||
textDescription->setText("<font color=\"#565959\">"+tr("<p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p>")+"</font>");
|
||||
}
|
||||
|
||||
void ImportWidget::clearScene()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ImportWidget::showCovers(bool hide)
|
||||
{
|
||||
portadasLabel->setHidden(hide);
|
||||
coversViewContainer->setHidden(hide);
|
||||
}
|
||||
|
||||
void ImportWidget::resizeEvent(QResizeEvent * event)
|
||||
{
|
||||
hideButton->move(event->size().width()-hideButton->width()- (currentComicLabel->height()/2),event->size().height()-hideButton->height()- (currentComicLabel->height()/2));
|
||||
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
52
YACReaderLibrary/import_widget.h
Normal file
52
YACReaderLibrary/import_widget.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef IMPORT_WIDGET_H
|
||||
#define IMPORT_WIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QLabel;
|
||||
class QGraphicsView;
|
||||
class QGraphicsScene;
|
||||
class QElapsedTimer;
|
||||
class QVBoxLayout;
|
||||
class QToolButton;
|
||||
class QResizeEvent;
|
||||
|
||||
class ImportWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ImportWidget(QWidget *parent = 0);
|
||||
|
||||
signals:
|
||||
void stop();
|
||||
public slots:
|
||||
void newComic(const QString & path, const QString & coverPath);
|
||||
void newCover(const QPixmap & image);
|
||||
void clear();
|
||||
void addCoverTest();
|
||||
void finishedUpdatingCover();
|
||||
void clearScene();
|
||||
void setImportLook();
|
||||
void setUpdateLook();
|
||||
void showCovers(bool hide);
|
||||
private:
|
||||
QLabel * currentComicLabel;
|
||||
QLabel * portadasLabel;
|
||||
QLabel * iconLabel;
|
||||
QLabel * text;
|
||||
QLabel * textDescription;
|
||||
QWidget * coversViewContainer;
|
||||
QGraphicsView * coversView;
|
||||
QGraphicsScene * coversScene;
|
||||
int previousWidth;
|
||||
bool updatingCovers;
|
||||
QElapsedTimer * elapsedTimer;
|
||||
quint64 i;
|
||||
|
||||
QToolButton * hideButton;
|
||||
|
||||
void resizeEvent(QResizeEvent * event);
|
||||
|
||||
};
|
||||
|
||||
#endif // IMPORT_WIDGET_H
|
||||
631
YACReaderLibrary/library_creator.cpp
Normal file
631
YACReaderLibrary/library_creator.cpp
Normal file
@ -0,0 +1,631 @@
|
||||
#include "library_creator.h"
|
||||
#include "custom_widgets.h"
|
||||
|
||||
#include <QMutex>
|
||||
#include <QDebug>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlRecord>
|
||||
#include <QApplication>
|
||||
#include <QLibrary>
|
||||
|
||||
#include "data_base_management.h"
|
||||
#include "qnaturalsorting.h"
|
||||
#include "db_helper.h"
|
||||
|
||||
#include "compressed_archive.h"
|
||||
#include "comic.h"
|
||||
|
||||
#include "yacreader_global.h"
|
||||
|
||||
#include "QsLog.h"
|
||||
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include "pdf_comic.h"
|
||||
#else
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include "poppler-qt5.h"
|
||||
#else
|
||||
#include "poppler-qt4.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
LibraryCreator::LibraryCreator()
|
||||
:creation(false)
|
||||
{
|
||||
_nameFilter << "*.cbr" << "*.cbz" << "*.rar" << "*.zip" << "*.tar" << "*.pdf" << "*.7z" << "*.cb7" << "*.arj" << "*.cbt";
|
||||
}
|
||||
|
||||
void LibraryCreator::createLibrary(const QString &source, const QString &target)
|
||||
{
|
||||
creation = true;
|
||||
processLibrary(source,target);
|
||||
}
|
||||
|
||||
void LibraryCreator::updateLibrary(const QString &source, const QString &target)
|
||||
{
|
||||
processLibrary(source,target);
|
||||
}
|
||||
|
||||
void LibraryCreator::processLibrary(const QString & source, const QString & target)
|
||||
{
|
||||
_source = source;
|
||||
_target = target;
|
||||
if(DataBaseManagement::checkValidDB(target+"/library.ydb")=="")
|
||||
{
|
||||
//se limpia el directorio ./yacreaderlibrary
|
||||
delTree(target);
|
||||
_mode = CREATOR;
|
||||
}
|
||||
else //
|
||||
_mode = UPDATER;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
void LibraryCreator::run()
|
||||
{
|
||||
stopRunning = false;
|
||||
|
||||
//check for 7z lib
|
||||
QLibrary *sevenzLib = new QLibrary(QApplication::applicationDirPath()+"/utils/7z");
|
||||
if(!sevenzLib->load())
|
||||
{
|
||||
QLOG_ERROR() << "Loading 7z.dll : " + sevenzLib->errorString() << endl;
|
||||
QApplication::exit(YACReader::SevenZNotFound);
|
||||
exit();
|
||||
}
|
||||
sevenzLib->deleteLater();
|
||||
|
||||
if(_mode == CREATOR)
|
||||
{
|
||||
QLOG_INFO() << "Starting to create new library ( " << _source << "," << _target << ")";
|
||||
_currentPathFolders.clear();
|
||||
_currentPathFolders.append(Folder(1,1,"root","/"));
|
||||
//se crean los directorios .yacreaderlibrary y .yacreaderlibrary/covers
|
||||
QDir dir;
|
||||
dir.mkpath(_target+"/covers");
|
||||
|
||||
//se crea la base de datos .yacreaderlibrary/library.ydb
|
||||
_database = DataBaseManagement::createDatabase("library",_target);//
|
||||
if(!_database.isOpen())
|
||||
{
|
||||
QLOG_ERROR() << "Unable to create data base" << _database.lastError().databaseText() + "-" + _database.lastError().driverText();
|
||||
emit failedCreatingDB(_database.lastError().databaseText() + "-" + _database.lastError().driverText());
|
||||
emit finished();
|
||||
creation = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/*QSqlQuery pragma("PRAGMA foreign_keys = ON",_database);*/
|
||||
_database.transaction();
|
||||
//se crea la librer<65>a
|
||||
create(QDir(_source));
|
||||
_database.commit();
|
||||
_database.close();
|
||||
QSqlDatabase::removeDatabase(_database.connectionName());
|
||||
emit(created());
|
||||
QLOG_INFO() << "Create library END";
|
||||
}
|
||||
else
|
||||
{
|
||||
QLOG_INFO() << "Starting to update library ( " << _source << "," << _target << ")";
|
||||
_currentPathFolders.clear();
|
||||
_currentPathFolders.append(Folder(1,1,"root","/"));
|
||||
_database = DataBaseManagement::loadDatabase(_target);
|
||||
//_database.setDatabaseName(_target+"/library.ydb");
|
||||
if(!_database.open())
|
||||
{
|
||||
QLOG_ERROR() << "Unable to open data base" << _database.lastError().databaseText() + "-" + _database.lastError().driverText();
|
||||
emit failedOpeningDB(_database.lastError().databaseText() + "-" + _database.lastError().driverText());
|
||||
emit finished();
|
||||
creation = false;
|
||||
return;
|
||||
}
|
||||
QSqlQuery pragma("PRAGMA foreign_keys = ON",_database);
|
||||
_database.transaction();
|
||||
update(QDir(_source));
|
||||
_database.commit();
|
||||
_database.close();
|
||||
QSqlDatabase::removeDatabase(_target);
|
||||
//si estabamos en modo creaci<63>n, se est<73> a<>adiendo una librer<65>a que ya exist<73>a y se ha actualizado antes de a<>adirse.
|
||||
if(!creation)
|
||||
emit(updated());
|
||||
else
|
||||
emit(created());
|
||||
QLOG_INFO() << "Update library END";
|
||||
}
|
||||
msleep(100);//TODO try to solve the problem with the udpate dialog (ya no se usa m<>s...)
|
||||
emit(finished());
|
||||
creation = false;
|
||||
}
|
||||
|
||||
void LibraryCreator::stop()
|
||||
{
|
||||
_database.commit();
|
||||
stopRunning = true;
|
||||
}
|
||||
|
||||
//retorna el id del ultimo de los folders
|
||||
qulonglong LibraryCreator::insertFolders()
|
||||
{
|
||||
QList<Folder>::iterator i;
|
||||
int currentId = 0;
|
||||
for (i = _currentPathFolders.begin(); i != _currentPathFolders.end(); ++i)
|
||||
{
|
||||
if(!(i->knownId))
|
||||
{
|
||||
i->setFather(currentId);
|
||||
currentId = DBHelper::insert(&(*i),_database);//insertFolder(currentId,*i);
|
||||
i->setId(currentId);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentId = i->id;
|
||||
}
|
||||
}
|
||||
return currentId;
|
||||
}
|
||||
|
||||
void LibraryCreator::create(QDir dir)
|
||||
{
|
||||
dir.setNameFilters(_nameFilter);
|
||||
dir.setFilter(QDir::AllDirs|QDir::Files|QDir::NoDotAndDotDot);
|
||||
QFileInfoList list = dir.entryInfoList();
|
||||
for (int i = 0; i < list.size(); ++i)
|
||||
{
|
||||
if(stopRunning)
|
||||
return;
|
||||
QFileInfo fileInfo = list.at(i);
|
||||
QString fileName = fileInfo.fileName();
|
||||
#ifdef Q_OS_MAC
|
||||
QStringList src = _source.split("/");
|
||||
QString filePath = fileInfo.absoluteFilePath();
|
||||
QStringList fp = filePath.split("/");
|
||||
for(int i = 0; i< src.count();i++)
|
||||
{
|
||||
fp.removeFirst();
|
||||
}
|
||||
QString relativePath = "/" + fp.join("/");
|
||||
#else
|
||||
QString relativePath = QDir::cleanPath(fileInfo.absoluteFilePath()).remove(_source);
|
||||
#endif
|
||||
if(fileInfo.isDir())
|
||||
{
|
||||
//se a<>ade al path actual el folder, a<>n no se sabe si habr<62> que a<>adirlo a la base de datos
|
||||
_currentPathFolders.append(Folder(fileInfo.fileName(),relativePath));
|
||||
create(QDir(fileInfo.absoluteFilePath()));
|
||||
//una vez importada la informaci<63>n del folder, se retira del path actual ya que no volver<65> a ser visitado
|
||||
_currentPathFolders.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
insertComic(relativePath,fileInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LibraryCreator::checkCover(const QString & hash)
|
||||
{
|
||||
return QFile::exists(_target+"/covers/"+hash+".jpg");
|
||||
}
|
||||
|
||||
void LibraryCreator::insertComic(const QString & relativePath,const QFileInfo & fileInfo)
|
||||
{
|
||||
//Se calcula el hash del c<>mic
|
||||
|
||||
QCryptographicHash crypto(QCryptographicHash::Sha1);
|
||||
QFile file(fileInfo.absoluteFilePath());
|
||||
file.open(QFile::ReadOnly);
|
||||
crypto.addData(file.read(524288));
|
||||
file.close();
|
||||
//hash Sha1 del primer 0.5MB + filesize
|
||||
QString hash = QString(crypto.result().toHex().constData()) + QString::number(fileInfo.size());
|
||||
ComicDB comic = DBHelper::loadComic(fileInfo.fileName(),relativePath,hash,_database);
|
||||
int numPages = 0;
|
||||
|
||||
if(! ( comic.hasCover() && checkCover(hash)))
|
||||
{
|
||||
ThumbnailCreator tc(QDir::cleanPath(fileInfo.absoluteFilePath()),_target+"/covers/"+hash+".jpg",comic.info.coverPage.toInt());
|
||||
tc.create();
|
||||
numPages = tc.getNumPages();
|
||||
if (numPages > 0)
|
||||
emit(comicAdded(relativePath,_target+"/covers/"+hash+".jpg"));
|
||||
}
|
||||
|
||||
if (numPages > 0)
|
||||
{
|
||||
//en este punto sabemos que todos los folders que hay en _currentPath, deber<65>an estar a<>adidos a la base de datos
|
||||
insertFolders();
|
||||
comic.info.numPages = numPages;
|
||||
comic.parentId = _currentPathFolders.last().id;
|
||||
DBHelper::insert(&comic,_database);
|
||||
}
|
||||
}
|
||||
|
||||
void LibraryCreator::update(QDir dirS)
|
||||
{
|
||||
//QLOG_TRACE() << "Updating" << dirS.absolutePath();
|
||||
//QLOG_TRACE() << "Getting info from dir" << dirS.absolutePath();
|
||||
dirS.setNameFilters(_nameFilter);
|
||||
dirS.setFilter(QDir::AllDirs|QDir::NoDotAndDotDot);
|
||||
dirS.setSorting(QDir::Name|QDir::IgnoreCase|QDir::LocaleAware);
|
||||
QFileInfoList listSFolders = dirS.entryInfoList();
|
||||
dirS.setFilter(QDir::Files|QDir::NoDotAndDotDot);
|
||||
dirS.setSorting(QDir::Name|QDir::IgnoreCase|QDir::LocaleAware);
|
||||
QFileInfoList listSFiles = dirS.entryInfoList();
|
||||
|
||||
qSort(listSFolders.begin(),listSFolders.end(),naturalSortLessThanCIFileInfo);
|
||||
qSort(listSFiles.begin(),listSFiles.end(),naturalSortLessThanCIFileInfo);
|
||||
|
||||
QFileInfoList listS;
|
||||
listS.append(listSFolders);
|
||||
listS.append(listSFiles);
|
||||
//QLOG_DEBUG() << "---------------------------------------------------------";
|
||||
//foreach(QFileInfo info,listS)
|
||||
// QLOG_DEBUG() << info.fileName();
|
||||
|
||||
//QLOG_TRACE() << "END Getting info from dir" << dirS.absolutePath();
|
||||
|
||||
//QLOG_TRACE() << "Getting info from DB" << dirS.absolutePath();
|
||||
QList<LibraryItem *> folders = DBHelper::getFoldersFromParent(_currentPathFolders.last().id,_database);
|
||||
QList<LibraryItem *> comics = DBHelper::getComicsFromParent(_currentPathFolders.last().id,_database);
|
||||
//QLOG_TRACE() << "END Getting info from DB" << dirS.absolutePath();
|
||||
|
||||
QList <LibraryItem *> listD;
|
||||
qSort(folders.begin(),folders.end(),naturalSortLessThanCILibraryItem);
|
||||
qSort(comics.begin(),comics.end(),naturalSortLessThanCILibraryItem);
|
||||
listD.append(folders);
|
||||
listD.append(comics);
|
||||
//QLOG_DEBUG() << "---------------------------------------------------------";
|
||||
//foreach(LibraryItem * info,listD)
|
||||
// QLOG_DEBUG() << info->name;
|
||||
//QLOG_DEBUG() << "---------------------------------------------------------";
|
||||
int lenghtS = listS.size();
|
||||
int lenghtD = listD.size();
|
||||
//QLOG_DEBUG() << "S len" << lenghtS << "D len" << lenghtD;
|
||||
//QLOG_DEBUG() << "---------------------------------------------------------";
|
||||
|
||||
bool updated;
|
||||
int i,j;
|
||||
for (i=0,j=0; (i < lenghtS)||(j < lenghtD);)
|
||||
{
|
||||
if(stopRunning)
|
||||
return;
|
||||
updated = false;
|
||||
if(i>=lenghtS) //finished source files/dirs
|
||||
{
|
||||
//QLOG_WARN() << "finished source files/dirs" << dirS.absolutePath();
|
||||
//delete listD //from j
|
||||
for(;j<lenghtD;j++)
|
||||
{
|
||||
if(stopRunning)
|
||||
return;
|
||||
DBHelper::removeFromDB(listD.at(j),(_database));
|
||||
}
|
||||
updated = true;
|
||||
}
|
||||
if(j>=lenghtD) //finished library files/dirs
|
||||
{
|
||||
//QLOG_WARN() << "finished library files/dirs" << dirS.absolutePath();
|
||||
//create listS //from i
|
||||
for(;i<lenghtS;i++)
|
||||
{
|
||||
if(stopRunning)
|
||||
return;
|
||||
QFileInfo fileInfoS = listS.at(i);
|
||||
if(fileInfoS.isDir()) //create folder
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
QStringList src = _source.split("/");
|
||||
QString filePath = fileInfoS.absoluteFilePath();
|
||||
QStringList fp = filePath.split("/");
|
||||
for(int i = 0; i< src.count();i++)
|
||||
{
|
||||
fp.removeFirst();
|
||||
}
|
||||
QString path = "/" + fp.join("/");
|
||||
#else
|
||||
QString path = QDir::cleanPath(fileInfoS.absoluteFilePath()).remove(_source);
|
||||
#endif
|
||||
_currentPathFolders.append(Folder(fileInfoS.fileName(),path)); //folder actual no est<73> en la BD
|
||||
create(QDir(fileInfoS.absoluteFilePath()));
|
||||
_currentPathFolders.pop_back();
|
||||
}
|
||||
else //create comic
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
QStringList src = _source.split("/");
|
||||
QString filePath = fileInfoS.absoluteFilePath();
|
||||
QStringList fp = filePath.split("/");
|
||||
for(int i = 0; i< src.count();i++)
|
||||
{
|
||||
fp.removeFirst();
|
||||
}
|
||||
QString path = "/" + fp.join("/");
|
||||
#else
|
||||
|
||||
QString path = QDir::cleanPath(fileInfoS.absoluteFilePath()).remove(_source);
|
||||
#endif
|
||||
insertComic(path,fileInfoS);
|
||||
}
|
||||
}
|
||||
updated = true;
|
||||
}
|
||||
if(!updated)
|
||||
{
|
||||
QFileInfo fileInfoS = listS.at(i);
|
||||
LibraryItem * fileInfoD = listD.at(j);
|
||||
QString nameS = QDir::cleanPath(fileInfoS.absoluteFilePath()).remove(QDir::cleanPath(fileInfoS.absolutePath())); //remove source
|
||||
QString nameD = "/"+fileInfoD->name;
|
||||
|
||||
int comparation = QString::localeAwareCompare(nameS,nameD);
|
||||
if(fileInfoS.isDir()&&fileInfoD->isDir())
|
||||
if(comparation == 0)//same folder, update
|
||||
{
|
||||
_currentPathFolders.append(*static_cast<Folder *>(fileInfoD));//fileInfoD conoce su padre y su id
|
||||
update(QDir(fileInfoS.absoluteFilePath()));
|
||||
_currentPathFolders.pop_back();
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
else
|
||||
if(comparation < 0) //nameS doesn't exist on DB
|
||||
{
|
||||
|
||||
if(nameS!="/.yacreaderlibrary")
|
||||
{
|
||||
//QLOG_WARN() << "dir source < dest" << nameS << nameD;
|
||||
#ifdef Q_OS_MAC
|
||||
QStringList src = _source.split("/");
|
||||
QString filePath = fileInfoS.absoluteFilePath();
|
||||
QStringList fp = filePath.split("/");
|
||||
for(int i = 0; i< src.count();i++)
|
||||
{
|
||||
fp.removeFirst();
|
||||
}
|
||||
QString path = "/" + fp.join("/");
|
||||
#else
|
||||
QString path = QDir::cleanPath(fileInfoS.absoluteFilePath()).remove(_source);
|
||||
#endif
|
||||
_currentPathFolders.append(Folder(fileInfoS.fileName(),path));
|
||||
create(QDir(fileInfoS.absoluteFilePath()));
|
||||
_currentPathFolders.pop_back();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else //nameD no longer avaliable on Source folder...
|
||||
{
|
||||
if(nameS!="/.yacreaderlibrary")
|
||||
{
|
||||
//QLOG_WARN() << "dir source > dest" << nameS << nameD;
|
||||
DBHelper::removeFromDB(fileInfoD,_database);
|
||||
j++;
|
||||
}
|
||||
else
|
||||
i++; //skip library directory
|
||||
}
|
||||
else // one of them(or both) is a file
|
||||
if(fileInfoS.isDir()) //this folder doesn't exist on library
|
||||
{
|
||||
if(nameS!="/.yacreaderlibrary") //skip .yacreaderlibrary folder
|
||||
{
|
||||
//QLOG_WARN() << "one of them(or both) is a file" << nameS << nameD;
|
||||
#ifdef Q_OS_MAC
|
||||
QStringList src = _source.split("/");
|
||||
QString filePath = fileInfoS.absoluteFilePath();
|
||||
QStringList fp = filePath.split("/");
|
||||
for(int i = 0; i< src.count();i++)
|
||||
{
|
||||
fp.removeFirst();
|
||||
}
|
||||
QString path = "/" + fp.join("/");
|
||||
#else
|
||||
QString path = QDir::cleanPath(fileInfoS.absoluteFilePath()).remove(_source);
|
||||
#endif
|
||||
_currentPathFolders.append(Folder(fileInfoS.fileName(),path));
|
||||
create(QDir(fileInfoS.absoluteFilePath()));
|
||||
_currentPathFolders.pop_back();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else
|
||||
if(fileInfoD->isDir()) //delete this folder from library
|
||||
{
|
||||
DBHelper::removeFromDB(fileInfoD,_database);
|
||||
j++;
|
||||
}
|
||||
else //both are files //BUG on windows (no case sensitive)
|
||||
{
|
||||
//nameD.remove(nameD.size()-4,4);
|
||||
int comparation = QString::localeAwareCompare(nameS,nameD);
|
||||
if(comparation < 0) //create new thumbnail
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
QStringList src = _source.split("/");
|
||||
QString filePath = fileInfoS.absoluteFilePath();
|
||||
QStringList fp = filePath.split("/");
|
||||
for(int i = 0; i< src.count();i++)
|
||||
{
|
||||
fp.removeFirst();
|
||||
}
|
||||
QString path = "/" + fp.join("/");
|
||||
#else
|
||||
QString path = QDir::cleanPath(fileInfoS.absoluteFilePath()).remove(_source);
|
||||
#endif
|
||||
insertComic(path,fileInfoS);
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(comparation > 0) //delete thumbnail
|
||||
{
|
||||
DBHelper::removeFromDB(fileInfoD,_database);
|
||||
j++;
|
||||
}
|
||||
else //same file
|
||||
{
|
||||
if(fileInfoS.isFile() && !fileInfoD->isDir())
|
||||
{
|
||||
//TODO comprobar fechas + tama<6D>o
|
||||
//if(fileInfoS.lastModified()>fileInfoD.lastModified())
|
||||
//{
|
||||
// dirD.mkpath(_target+(QDir::cleanPath(fileInfoS.absolutePath()).remove(_source)));
|
||||
// emit(coverExtracted(QDir::cleanPath(fileInfoS.absoluteFilePath()).remove(_source)));
|
||||
// ThumbnailCreator tc(QDir::cleanPath(fileInfoS.absoluteFilePath()),_target+(QDir::cleanPath(fileInfoS.absoluteFilePath()).remove(_source))+".jpg");
|
||||
// tc.create();
|
||||
//}
|
||||
}
|
||||
i++;j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ThumbnailCreator::crash = false;
|
||||
|
||||
ThumbnailCreator::ThumbnailCreator(QString fileSource, QString target, int coverPage)
|
||||
:_fileSource(fileSource),_target(target),_numPages(0),_coverPage(coverPage)
|
||||
{
|
||||
}
|
||||
|
||||
void ThumbnailCreator::create()
|
||||
{
|
||||
QFileInfo fi(_fileSource);
|
||||
if(!fi.exists()) //TODO: error file not found.
|
||||
{
|
||||
_cover.load(":/images/notCover.png");
|
||||
QLOG_WARN() << "Extracting cover: file not found " << _fileSource;
|
||||
return;
|
||||
}
|
||||
|
||||
if(fi.suffix().compare("pdf",Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
MacOSXPDFComic * pdfComic = new MacOSXPDFComic();
|
||||
if(!pdfComic->openComic(_fileSource))
|
||||
{
|
||||
delete pdfComic;
|
||||
//QImage p;
|
||||
//p.load(":/images/notCover.png");
|
||||
//p.save(_target);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
Poppler::Document * pdfComic = Poppler::Document::load(_fileSource);
|
||||
#endif
|
||||
if (!pdfComic)
|
||||
{
|
||||
QLOG_WARN() << "Extracting cover: unable to open PDF file " << _fileSource;
|
||||
//delete pdfComic; //TODO check if the delete is needed
|
||||
pdfComic = 0;
|
||||
//QImage p;
|
||||
//p.load(":/images/notCover.png");
|
||||
//p.save(_target);
|
||||
return;
|
||||
}
|
||||
_numPages = pdfComic->numPages();
|
||||
if(_numPages >= _coverPage)
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
{
|
||||
QImage p = pdfComic->getPage(_coverPage-1); //TODO check if the page is valid
|
||||
#else
|
||||
QImage p = pdfComic->page(_coverPage-1)->renderToImage(72,72);
|
||||
#endif
|
||||
_cover = QPixmap::fromImage(p);
|
||||
if(_target!="")
|
||||
{
|
||||
QImage scaled;
|
||||
if(p.width()>p.height()) //landscape??
|
||||
scaled = p.scaledToWidth(640,Qt::SmoothTransformation);
|
||||
else
|
||||
scaled = p.scaledToWidth(480,Qt::SmoothTransformation);
|
||||
scaled.save(_target,0,75);
|
||||
}
|
||||
#ifdef Q_OS_MAC
|
||||
}
|
||||
pdfComic->releaseLastPageData();
|
||||
#endif
|
||||
}
|
||||
else if(_target!="")
|
||||
{
|
||||
QLOG_WARN() << "Extracting cover: requested cover index greater than numPages " << _fileSource;
|
||||
//QImage p;
|
||||
//p.load(":/images/notCover.png");
|
||||
//p.save(_target);
|
||||
}
|
||||
|
||||
delete pdfComic;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if(crash)
|
||||
return;
|
||||
|
||||
CompressedArchive archive(_fileSource);
|
||||
if(!archive.toolsLoaded())
|
||||
{
|
||||
QLOG_WARN() << "Extracting cover: 7z lib not loaded";
|
||||
crash = true;
|
||||
return;
|
||||
}
|
||||
if(!archive.isValid())
|
||||
QLOG_WARN() << "Extracting cover: file format not supported " << _fileSource;
|
||||
//se filtran para obtener s<>lo los formatos soportados
|
||||
QList<QString> order = archive.getFileNames();
|
||||
QList<QString> fileNames = FileComic::filter(order);
|
||||
_numPages = fileNames.size();
|
||||
if(_numPages == 0)
|
||||
{
|
||||
QLOG_WARN() << "Extracting cover: empty comic " << _fileSource;
|
||||
_cover.load(":/images/notCover.png");
|
||||
if(_target!="")
|
||||
_cover.save(_target);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(_coverPage > _numPages)
|
||||
_coverPage = 1;
|
||||
qSort(fileNames.begin(),fileNames.end(), naturalSortLessThanCI);
|
||||
int index = order.indexOf(fileNames.at(_coverPage-1));
|
||||
|
||||
if(_target=="")
|
||||
{
|
||||
if(!_cover.loadFromData(archive.getRawDataAtIndex(index)))
|
||||
{
|
||||
QLOG_WARN() << "Extracting cover: unable to load image from extracted cover " << _fileSource;
|
||||
_cover.load(":/images/notCover.png");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QImage p;
|
||||
if(p.loadFromData(archive.getRawDataAtIndex(index)))
|
||||
{
|
||||
QImage scaled;
|
||||
if(p.width()>p.height()) //landscape??
|
||||
scaled = p.scaledToWidth(640,Qt::SmoothTransformation);
|
||||
else
|
||||
scaled = p.scaledToWidth(480,Qt::SmoothTransformation);
|
||||
scaled.save(_target,0,75);
|
||||
}
|
||||
else
|
||||
{
|
||||
QLOG_WARN() << "Extracting cover: unable to load image from extracted cover " << _fileSource;
|
||||
//p.load(":/images/notCover.png");
|
||||
//p.save(_target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
86
YACReaderLibrary/library_creator.h
Normal file
86
YACReaderLibrary/library_creator.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef __LIBRARY_CREATOR_H
|
||||
#define __LIBRARY_CREATOR_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QByteArray>
|
||||
#include <QRegExp>
|
||||
#include <QProcess>
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#include <QMutex>
|
||||
#include <QThread>
|
||||
#include <QSqlDatabase>
|
||||
|
||||
#include "folder.h"
|
||||
#include "comic_db.h"
|
||||
|
||||
|
||||
class LibraryCreator : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LibraryCreator();
|
||||
void createLibrary(const QString & source, const QString & target);
|
||||
void updateLibrary(const QString & source, const QString & target);
|
||||
void stop();
|
||||
private:
|
||||
void processLibrary(const QString & source, const QString & target);
|
||||
enum Mode {CREATOR,UPDATER};
|
||||
//atributos "globales" durante el proceso de creaci<63>n y actualizaci<63>n
|
||||
enum Mode _mode;
|
||||
QString _source;
|
||||
QString _target;
|
||||
QStringList _nameFilter;
|
||||
QSqlDatabase _database;
|
||||
QList<Folder> _currentPathFolders; //lista de folders en el orden en el que est<73>n siendo explorados, el <20>ltimo es el folder actual
|
||||
//recursive method
|
||||
void create(QDir currentDirectory);
|
||||
void update(QDir currentDirectory);
|
||||
void run();
|
||||
qulonglong insertFolders();//devuelve el id del <20>ltimo folder a<>adido (<28>ltimo en la ruta)
|
||||
bool checkCover(const QString & hash);
|
||||
void insertComic(const QString & relativePath,const QFileInfo & fileInfo);
|
||||
//qulonglong insertFolder(qulonglong parentId,const Folder & folder);
|
||||
//qulonglong insertComic(const Comic & comic);
|
||||
bool stopRunning;
|
||||
//LibraryCreator est<73> en modo creaci<63>n si creation == true;
|
||||
bool creation;
|
||||
signals:
|
||||
void finished();
|
||||
void coverExtracted(QString);
|
||||
void folderUpdated(QString);
|
||||
void comicAdded(QString,QString);
|
||||
void updated();
|
||||
void created();
|
||||
void failedCreatingDB(QString);
|
||||
void failedOpeningDB(QString);
|
||||
};
|
||||
|
||||
class ThumbnailCreator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ThumbnailCreator(QString fileSource, QString target="", int coverPage = 1);
|
||||
private:
|
||||
QString _fileSource;
|
||||
QString _target;
|
||||
QString _currentName;
|
||||
int _numPages;
|
||||
QPixmap _cover;
|
||||
int _coverPage;
|
||||
static bool crash;
|
||||
|
||||
public slots:
|
||||
void create();
|
||||
int getNumPages(){return _numPages;};
|
||||
QPixmap getCover(){return _cover;};
|
||||
signals:
|
||||
void openingError(QProcess::ProcessError error);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
1846
YACReaderLibrary/library_window.cpp
Normal file
1846
YACReaderLibrary/library_window.cpp
Normal file
File diff suppressed because it is too large
Load Diff
296
YACReaderLibrary/library_window.h
Normal file
296
YACReaderLibrary/library_window.h
Normal file
@ -0,0 +1,296 @@
|
||||
#ifndef __LIBRARYWINDOW_H
|
||||
#define __LIBRARYWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QMap>
|
||||
#include <QModelIndex>
|
||||
#include <QFileInfo>
|
||||
#include "yacreader_global.h"
|
||||
#include <yacreader_libraries.h>
|
||||
|
||||
class QTreeView;
|
||||
class QDirModel;
|
||||
class QAction;
|
||||
class QToolBar;
|
||||
class QComboBox;
|
||||
class QThread;
|
||||
class QStackedWidget;
|
||||
class YACReaderSearchLineEdit;
|
||||
class CreateLibraryDialog;
|
||||
class ExportLibraryDialog;
|
||||
class ImportLibraryDialog;
|
||||
class ExportComicsInfoDialog;
|
||||
class ImportComicsInfoDialog;
|
||||
class AddLibraryDialog;
|
||||
class LibraryCreator;
|
||||
class HelpAboutDialog;
|
||||
class RenameLibraryDialog;
|
||||
class PropertiesDialog;
|
||||
class PackageManager;
|
||||
class ComicFlowWidget;
|
||||
class QCheckBox;
|
||||
class QPushButton;
|
||||
class TableModel;
|
||||
class QSplitter;
|
||||
class TreeItem;
|
||||
class TreeModel;
|
||||
class QItemSelectionModel;
|
||||
class QString;
|
||||
class QLabel;
|
||||
class NoLibrariesWidget;
|
||||
class OptionsDialog;
|
||||
class ServerConfigDialog;
|
||||
class QCloseEvent;
|
||||
class ImportWidget;
|
||||
class QSettings;
|
||||
class LibraryItem;
|
||||
class YACReaderTableView;
|
||||
class YACReaderSideBar;
|
||||
class YACReaderLibraryListWidget;
|
||||
class YACReaderTreeView;
|
||||
class YACReaderMainToolBar;
|
||||
class ComicVineDialog;
|
||||
#include "comic_db.h"
|
||||
|
||||
using namespace YACReader;
|
||||
|
||||
class LibraryWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
YACReaderSideBar * sideBar;
|
||||
QSplitter * sVertical;
|
||||
CreateLibraryDialog * createLibraryDialog;
|
||||
ExportLibraryDialog * exportLibraryDialog;
|
||||
ImportLibraryDialog * importLibraryDialog;
|
||||
ExportComicsInfoDialog * exportComicsInfoDialog;
|
||||
ImportComicsInfoDialog * importComicsInfoDialog;
|
||||
AddLibraryDialog * addLibraryDialog;
|
||||
LibraryCreator * libraryCreator;
|
||||
HelpAboutDialog * had;
|
||||
RenameLibraryDialog * renameLibraryDialog;
|
||||
PropertiesDialog * propertiesDialog;
|
||||
ComicVineDialog * comicVineDialog;
|
||||
//YACReaderSocialDialog * socialDialog;
|
||||
bool fullscreen;
|
||||
bool importedCovers; //if true, the library is read only (not updates,open comic or properties)
|
||||
bool fromMaximized;
|
||||
//Ya no se usan proxies, el rendimiento de la BD es suficiente
|
||||
//YACReaderTreeSearch * proxyFilter;
|
||||
//YACReaderSortComics * proxySort;
|
||||
PackageManager * packageManager;
|
||||
|
||||
ComicFlowWidget * comicFlow;
|
||||
QSize slideSizeW;
|
||||
QSize slideSizeF;
|
||||
//search filter
|
||||
YACReaderSearchLineEdit * foldersFilter;
|
||||
TreeItem * index; //index al que hay que hacer scroll despu<70>s de pulsar sobre un folder filtrado
|
||||
int column;
|
||||
QString previousFilter;
|
||||
QPushButton * clearFoldersFilter;
|
||||
QCheckBox * includeComicsCheckBox;
|
||||
//-------------
|
||||
QWidget *comics;
|
||||
YACReaderTableView * comicView;
|
||||
YACReaderTreeView * foldersView;
|
||||
YACReaderLibraryListWidget * selectedLibrary;
|
||||
TreeModel * dm;
|
||||
TableModel * dmCV;
|
||||
//QStringList paths;
|
||||
YACReaderLibraries libraries;
|
||||
QLabel * fullScreenToolTip;
|
||||
|
||||
QStackedWidget * mainWidget;
|
||||
NoLibrariesWidget * noLibrariesWidget;
|
||||
ImportWidget * importWidget;
|
||||
|
||||
bool fetching;
|
||||
|
||||
int i;
|
||||
|
||||
QAction * backAction;
|
||||
QAction * forwardAction;
|
||||
|
||||
QAction * openComicAction;
|
||||
QAction * createLibraryAction;
|
||||
QAction * openLibraryAction;
|
||||
|
||||
QAction * exportComicsInfo;
|
||||
QAction * importComicsInfo;
|
||||
|
||||
QAction * exportLibraryAction;
|
||||
QAction * importLibraryAction;
|
||||
|
||||
QAction * updateLibraryAction;
|
||||
QAction * removeLibraryAction;
|
||||
QAction * helpAboutAction;
|
||||
QAction * renameLibraryAction;
|
||||
QAction * toggleFullScreenAction;
|
||||
QAction * optionsAction;
|
||||
QAction * serverConfigAction;
|
||||
//QAction * socialAction;
|
||||
|
||||
//tree actions
|
||||
QAction * setRootIndexAction;
|
||||
QAction * expandAllNodesAction;
|
||||
QAction * colapseAllNodesAction;
|
||||
|
||||
QAction * openContainingFolderAction;
|
||||
//--
|
||||
QAction * setFolderAsNotCompletedAction;
|
||||
QAction * setFolderAsCompletedAction;
|
||||
//--
|
||||
QAction * setFolderAsFinishedAction;
|
||||
QAction * setFolderAsNotFinishedAction;
|
||||
|
||||
QAction * openContainingFolderComicAction;
|
||||
QAction * setAsReadAction;
|
||||
QAction * setAsNonReadAction;
|
||||
//QAction * setAllAsReadAction;
|
||||
//QAction * setAllAsNonReadAction;
|
||||
QAction * showHideMarksAction;
|
||||
QAction * getInfoAction; //comic vine
|
||||
QAction * resetComicRatingAction;
|
||||
|
||||
//edit info actions
|
||||
QAction * selectAllComicsAction;
|
||||
QAction * editSelectedComicsAction;
|
||||
QAction * asignOrderActions;
|
||||
QAction * forceConverExtractedAction;
|
||||
QAction * deleteComicsAction;
|
||||
QAction * hideComicViewAction;
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
QToolBar * libraryToolBar;
|
||||
#else
|
||||
YACReaderMainToolBar * libraryToolBar;
|
||||
#endif
|
||||
QToolBar * treeActions;
|
||||
QToolBar * comicsToolBar;
|
||||
QToolBar * editInfoToolBar;
|
||||
|
||||
OptionsDialog * optionsDialog;
|
||||
ServerConfigDialog * serverConfigDialog;
|
||||
|
||||
QString libraryPath;
|
||||
QString comicsPath;
|
||||
|
||||
QString _lastAdded;
|
||||
QString _sourceLastAdded;
|
||||
|
||||
//QModelIndex _rootIndex;
|
||||
//QModelIndex _rootIndexCV;
|
||||
|
||||
quint64 _comicIdEdited;
|
||||
|
||||
void setupUI();
|
||||
void createActions();
|
||||
void createToolBars();
|
||||
void createMenus();
|
||||
void createConnections();
|
||||
void doLayout();
|
||||
void doDialogs();
|
||||
void doModels();
|
||||
|
||||
//ACTIONS MANAGEMENT
|
||||
void disableComicsActions(bool disabled);
|
||||
void disableLibrariesActions(bool disabled);
|
||||
void disableNoUpdatedLibrariesActions(bool disabled);
|
||||
void disableFoldersActions(bool disabled);
|
||||
|
||||
void disableAllActions();
|
||||
//void disableActions();
|
||||
//void enableActions();
|
||||
//void enableLibraryActions();
|
||||
|
||||
QString currentPath();
|
||||
|
||||
//settings
|
||||
QSettings * settings;
|
||||
|
||||
//navigation backward and forward
|
||||
int currentFolderNavigation;
|
||||
QList<QModelIndex> history;
|
||||
|
||||
bool removeError;
|
||||
|
||||
protected:
|
||||
virtual void closeEvent ( QCloseEvent * event );
|
||||
public:
|
||||
LibraryWindow();
|
||||
public slots:
|
||||
void loadLibrary(const QString & path);
|
||||
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);
|
||||
void showAddLibrary();
|
||||
void openLibrary(QString path, QString name);
|
||||
void loadLibraries();
|
||||
void saveLibraries();
|
||||
void reloadCurrentLibrary();
|
||||
void openLastCreated();
|
||||
void updateLibrary();
|
||||
//void deleteLibrary();
|
||||
void openContainingFolder();
|
||||
void setFolderAsNotCompleted();
|
||||
void setFolderAsCompleted();
|
||||
void setFolderAsFinished();
|
||||
void setFolderAsNotFinished();
|
||||
void openContainingFolderComic();
|
||||
void deleteCurrentLibrary();
|
||||
void removeLibrary();
|
||||
void renameLibrary();
|
||||
void rename(QString newName);
|
||||
void cancelCreating();
|
||||
void stopLibraryCreator();
|
||||
void setRootIndex();
|
||||
void toggleFullScreen();
|
||||
void toNormal();
|
||||
void toFullScreen();
|
||||
void setFoldersFilter(QString filter);
|
||||
void showProperties();
|
||||
void exportLibrary(QString destPath);
|
||||
void importLibrary(QString clc,QString destPath,QString name);
|
||||
void reloadOptions();
|
||||
void setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus);
|
||||
void setCurrentComicReaded();
|
||||
void setCurrentComicUnreaded();
|
||||
void setComicsReaded();
|
||||
void setComicsUnreaded();
|
||||
void hideComicFlow(bool hide);
|
||||
void showExportComicsInfo();
|
||||
void showImportComicsInfo();
|
||||
void asignNumbers();
|
||||
void showNoLibrariesWidget();
|
||||
void showRootWidget();
|
||||
void showImportingWidget();
|
||||
void manageCreatingError(const QString & error);
|
||||
void manageUpdatingError(const QString & error);
|
||||
void manageOpeningLibraryError(const QString & error);
|
||||
QModelIndexList getSelectedComics();
|
||||
void deleteComics();
|
||||
//void showSocial();
|
||||
void backward();
|
||||
void forward();
|
||||
void updateHistory(const QModelIndex & mi);
|
||||
void updateFoldersViewConextMenu(const QModelIndex & mi);
|
||||
void libraryAlreadyExists(const QString & name);
|
||||
void importLibraryPackage();
|
||||
void updateComicsView(quint64 libraryId, const ComicDB & comic);
|
||||
void setCurrentComicOpened();
|
||||
void showComicVineScraper();
|
||||
void setRemoveError();
|
||||
void checkRemoveError();
|
||||
void resetComicRating();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
210
YACReaderLibrary/main.cpp
Normal file
210
YACReaderLibrary/main.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
#include "library_window.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTranslator>
|
||||
#include <QSettings>
|
||||
#include <QLocale>
|
||||
#include <QDir>
|
||||
#include <QSysInfo>
|
||||
#include <QFileInfo>
|
||||
#include <QSettings>
|
||||
#include <QLibrary>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "yacreader_global.h"
|
||||
#include "startup.h"
|
||||
#include "yacreader_local_server.h"
|
||||
#include "comic_db.h"
|
||||
#include "db_helper.h"
|
||||
#include "yacreader_libraries.h"
|
||||
#include "exit_check.h"
|
||||
|
||||
#include "QsLog.h"
|
||||
#include "QsLogDest.h"
|
||||
|
||||
#define PICTUREFLOW_QT4 1
|
||||
|
||||
//interfaz al servidor
|
||||
Startup * s;
|
||||
|
||||
using namespace QsLogging;
|
||||
|
||||
void logSystemAndConfig()
|
||||
{
|
||||
QLOG_INFO() << "---------- System & configuration ----------";
|
||||
#if defined(Q_OS_WIN)
|
||||
switch (QSysInfo::windowsVersion())
|
||||
{
|
||||
case QSysInfo::WV_NT:
|
||||
QLOG_INFO() << "SO : Windows NT";
|
||||
break;
|
||||
case QSysInfo::WV_2000:
|
||||
QLOG_INFO() << "SO : Windows 2000";
|
||||
break;
|
||||
case QSysInfo::WV_XP:
|
||||
QLOG_INFO() << "SO : Windows XP";
|
||||
break;
|
||||
case QSysInfo::WV_2003:
|
||||
QLOG_INFO() << "SO : Windows 2003";
|
||||
break;
|
||||
case QSysInfo::WV_VISTA:
|
||||
QLOG_INFO() << "SO : Windows Vista";
|
||||
break;
|
||||
case QSysInfo::WV_WINDOWS7:
|
||||
QLOG_INFO() << "SO : Windows 7";
|
||||
break;
|
||||
case QSysInfo::WV_WINDOWS8:
|
||||
QLOG_INFO() << "SO : Windows 8";
|
||||
break;
|
||||
default:
|
||||
QLOG_INFO() << "Windows (unknown version)";
|
||||
break;
|
||||
}
|
||||
|
||||
#elif defined(Q_OS_MAC)
|
||||
|
||||
switch (QSysInfo::MacVersion())
|
||||
{
|
||||
case QSysInfo::MV_SNOWLEOPARD:
|
||||
QLOG_INFO() << "SO : MacOSX Snow Leopard";
|
||||
break;
|
||||
case QSysInfo::MV_LION:
|
||||
QLOG_INFO() << "SO : MacOSX Lion";
|
||||
break;
|
||||
case QSysInfo::MV_MOUNTAINLION:
|
||||
QLOG_INFO() << "SO : MacOSX Mountain Lion";
|
||||
break;
|
||||
#if QT_VERSION >= 0x050000
|
||||
case QSysInfo::MV_MAVERICKS:
|
||||
QLOG_INFO() << "SO : MacOSX Maverics";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
QLOG_INFO() << "SO : MacOSX (unknown version)";
|
||||
break;
|
||||
}
|
||||
|
||||
#elif defined(Q_OS_LINUX)
|
||||
QLOG_INFO() << "SO : Linux (unknown version)";
|
||||
|
||||
#else
|
||||
QLOG_INFO() << "SO : Unknown";
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if(QLibrary::isLibrary(QApplication::applicationDirPath()+"/utils/7z.dll"))
|
||||
#else
|
||||
if(QLibrary::isLibrary(QApplication::applicationDirPath()+"/utils/7z.so"))
|
||||
#endif
|
||||
QLOG_INFO() << "7z : found";
|
||||
else
|
||||
QLOG_ERROR() << "7z : not found";
|
||||
|
||||
if(QFileInfo(QApplication::applicationDirPath()+"/utils/qrencode.exe").exists() || QFileInfo("./util/qrencode").exists())
|
||||
QLOG_INFO() << "qrencode : found";
|
||||
else
|
||||
QLOG_INFO() << "qrencode : not found";
|
||||
|
||||
QSettings settings(YACReader::getSettingsPath()+"/YACReaderLibrary.ini",QSettings::IniFormat);
|
||||
settings.beginGroup("libraryConfig");
|
||||
if(settings.value(SERVER_ON,true).toBool())
|
||||
QLOG_INFO() << "server : enabled";
|
||||
else
|
||||
QLOG_INFO() << "server : disabled";
|
||||
|
||||
if(settings.value(USE_OPEN_GL).toBool())
|
||||
QLOG_INFO() << "OpenGL : enabled" << " - " << (settings.value(V_SYNC).toBool()?"VSync on":"VSync off");
|
||||
else
|
||||
QLOG_INFO() << "OpenGL : disabled";
|
||||
|
||||
QLOG_INFO() << "Libraries: " << DBHelper::getLibraries().getLibraries();
|
||||
QLOG_INFO() << "--------------------------------------------";
|
||||
}
|
||||
|
||||
int main( int argc, char ** argv )
|
||||
{
|
||||
//fix for misplaced text in Qt4.8 and Mavericks
|
||||
#ifdef Q_OS_MAC
|
||||
#if QT_VERSION < 0x050000
|
||||
if(QSysInfo::MacintoshVersion > QSysInfo::MV_10_8)
|
||||
QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
QApplication app( argc, argv );
|
||||
|
||||
app.setApplicationName("YACReaderLibrary");
|
||||
app.setOrganizationName("YACReader");
|
||||
|
||||
QString destLog = YACReader::getSettingsPath()+"/yacreaderlibrary.log";
|
||||
QDir().mkpath(YACReader::getSettingsPath());
|
||||
|
||||
Logger& logger = Logger::instance();
|
||||
logger.setLoggingLevel(QsLogging::TraceLevel);
|
||||
|
||||
DestinationPtr fileDestination(DestinationFactory::MakeFileDestination(
|
||||
destLog, EnableLogRotation, MaxSizeBytes(1048576), MaxOldLogCount(2)));
|
||||
DestinationPtr debugDestination(DestinationFactory::MakeDebugOutputDestination());
|
||||
logger.addDestination(debugDestination);
|
||||
logger.addDestination(fileDestination);
|
||||
|
||||
QTranslator translator;
|
||||
QString sufix = QLocale::system().name();
|
||||
translator.load(QCoreApplication::applicationDirPath()+"/languages/yacreaderlibrary_"+sufix);
|
||||
app.installTranslator(&translator);
|
||||
|
||||
QTranslator viewerTranslator;
|
||||
viewerTranslator.load(QCoreApplication::applicationDirPath()+"/languages/yacreader_"+sufix);
|
||||
app.installTranslator(&viewerTranslator);
|
||||
app.setApplicationName("YACReaderLibrary");
|
||||
|
||||
qRegisterMetaType<ComicDB>("ComicDB");
|
||||
|
||||
#ifdef SERVER_RELEASE
|
||||
QSettings * settings = new QSettings(YACReader::getSettingsPath()+"/YACReaderLibrary.ini",QSettings::IniFormat); //TODO unificar la creaci<63>n del fichero de config con el servidor
|
||||
settings->beginGroup("libraryConfig");
|
||||
|
||||
s = new Startup();
|
||||
|
||||
if(settings->value(SERVER_ON,true).toBool())
|
||||
{
|
||||
|
||||
s->start();
|
||||
}
|
||||
#endif
|
||||
QLOG_INFO() << "YACReaderLibrary attempting to start";
|
||||
|
||||
logSystemAndConfig();
|
||||
|
||||
if(YACReaderLocalServer::isRunning()) //s<>lo se permite una instancia de YACReaderLibrary
|
||||
{
|
||||
QLOG_WARN() << "another instance of YACReaderLibrary is running";
|
||||
QsLogging::Logger::destroyInstance();
|
||||
return 0;
|
||||
}
|
||||
QLOG_INFO() << "YACReaderLibrary starting";
|
||||
|
||||
YACReaderLocalServer * localServer = new YACReaderLocalServer();
|
||||
|
||||
LibraryWindow * mw = new LibraryWindow();
|
||||
|
||||
mw->connect(localServer,SIGNAL(comicUpdated(quint64, const ComicDB &)),mw,SLOT(updateComicsView(quint64, const ComicDB &)));
|
||||
|
||||
//connections to localServer
|
||||
|
||||
mw->show();
|
||||
|
||||
int ret = app.exec();
|
||||
|
||||
QLOG_INFO() << "YACReaderLibrary closed with exit code :" << ret;
|
||||
|
||||
YACReader::exitCheck(ret);
|
||||
|
||||
//server shutdown
|
||||
s->stop();
|
||||
delete s;
|
||||
|
||||
QsLogging::Logger::destroyInstance();
|
||||
|
||||
return ret;
|
||||
}
|
||||
80
YACReaderLibrary/no_libraries_widget.cpp
Normal file
80
YACReaderLibrary/no_libraries_widget.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
#include "no_libraries_widget.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
|
||||
NoLibrariesWidget::NoLibrariesWidget(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
|
||||
|
||||
QPalette p(palette());
|
||||
p.setColor(QPalette::Background, QColor(250,250,250));
|
||||
setAutoFillBackground(true);
|
||||
setPalette(p);
|
||||
|
||||
QPixmap icon(":/images/noLibrariesIcon.png");
|
||||
QLabel * iconLabel = new QLabel();
|
||||
iconLabel->setPixmap(icon);
|
||||
|
||||
QPixmap line(":/images/noLibrariesLine.png");
|
||||
QLabel * lineLabel = new QLabel();
|
||||
lineLabel->setPixmap(line);
|
||||
|
||||
QLabel * text = new QLabel("<font color=\"#495252\">"+tr("You don't have any librarires yet")+"</font>");
|
||||
text->setStyleSheet("QLabel {font-size:25px;font-weight:bold;}");
|
||||
QLabel * textDescription = new QLabel("<font color=\"#565959\">"+tr("<p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p>")+"</font>");
|
||||
textDescription->setWordWrap(true);
|
||||
textDescription->setMaximumWidth(330);
|
||||
|
||||
QPushButton * createButton = new QPushButton(tr("create your first library"));
|
||||
createButton->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
|
||||
QPushButton * addButton = new QPushButton(tr("add an existing one"));
|
||||
addButton->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
|
||||
|
||||
QVBoxLayout * layout = new QVBoxLayout(this);
|
||||
QHBoxLayout * buttonLayout = new QHBoxLayout();
|
||||
QHBoxLayout * topLayout = new QHBoxLayout();
|
||||
QVBoxLayout * textLayout = new QVBoxLayout();
|
||||
|
||||
QWidget * topWidget = new QWidget();
|
||||
topWidget->setFixedWidth(650);
|
||||
textLayout->addStretch();
|
||||
textLayout->addWidget(text);
|
||||
textLayout->addSpacing(12);
|
||||
textLayout->addWidget(textDescription);
|
||||
textLayout->addStretch();
|
||||
|
||||
topLayout->addStretch();
|
||||
topLayout->addWidget(iconLabel,0,Qt::AlignVCenter);
|
||||
topLayout->addSpacing(30);
|
||||
topLayout->addLayout(textLayout,1);
|
||||
topLayout->addStretch();
|
||||
topLayout->setMargin(0);
|
||||
|
||||
topWidget->setLayout(topLayout);
|
||||
|
||||
layout->setAlignment(Qt::AlignHCenter);
|
||||
|
||||
buttonLayout->addSpacing(125);
|
||||
buttonLayout->addWidget(createButton);
|
||||
layout->addSpacing(25);
|
||||
buttonLayout->addWidget(addButton);
|
||||
buttonLayout->addSpacing(125);
|
||||
|
||||
layout->addStretch();
|
||||
layout->addWidget(topWidget);
|
||||
layout->addSpacing(20);
|
||||
layout->addWidget(lineLabel,0,Qt::AlignHCenter);
|
||||
layout->addSpacing(10);
|
||||
layout->addLayout(buttonLayout,0);
|
||||
layout->addSpacing(150);
|
||||
layout->addStretch();
|
||||
|
||||
connect(createButton,SIGNAL(clicked()),this,SIGNAL(createNewLibrary()));
|
||||
connect(addButton,SIGNAL(clicked()),this,SIGNAL(addExistingLibrary()));
|
||||
|
||||
|
||||
}
|
||||
19
YACReaderLibrary/no_libraries_widget.h
Normal file
19
YACReaderLibrary/no_libraries_widget.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef NO_LIBRARIES_WIDGET_H
|
||||
#define NO_LIBRARIES_WIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class NoLibrariesWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NoLibrariesWidget(QWidget *parent = 0);
|
||||
|
||||
signals:
|
||||
void createNewLibrary();
|
||||
void addExistingLibrary();
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // NO_LIBRARIES_WIDGET_H
|
||||
52
YACReaderLibrary/options_dialog.cpp
Normal file
52
YACReaderLibrary/options_dialog.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include "options_dialog.h"
|
||||
|
||||
#include "yacreader_flow_gl.h"
|
||||
#include "yacreader_flow_config_widget.h"
|
||||
#include "yacreader_gl_flow_config_widget.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QFileDialog>
|
||||
#include <QGroupBox>
|
||||
#include <QRadioButton>
|
||||
#include <QTextStream>
|
||||
#include <QCoreApplication>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QCheckBox>
|
||||
|
||||
FlowType flowType = Strip;
|
||||
|
||||
OptionsDialog::OptionsDialog(QWidget * parent)
|
||||
:YACReaderOptionsDialog(parent)
|
||||
{
|
||||
QVBoxLayout * layout = new QVBoxLayout;
|
||||
|
||||
QHBoxLayout * switchFlowType = new QHBoxLayout;
|
||||
switchFlowType->addStretch();
|
||||
switchFlowType->addWidget(useGL);
|
||||
|
||||
|
||||
|
||||
QHBoxLayout * buttons = new QHBoxLayout();
|
||||
buttons->addStretch();
|
||||
buttons->addWidget(accept);
|
||||
buttons->addWidget(cancel);
|
||||
|
||||
layout->addWidget(sw);
|
||||
layout->addWidget(gl);
|
||||
layout->addLayout(switchFlowType);
|
||||
layout->addLayout(buttons);
|
||||
|
||||
sw->hide();
|
||||
|
||||
setLayout(layout);
|
||||
//restoreOptions(settings); //load options
|
||||
//resize(200,0);
|
||||
setModal (true);
|
||||
setWindowTitle(tr("Options"));
|
||||
|
||||
this->layout()->setSizeConstraint(QLayout::SetFixedSize);
|
||||
}
|
||||
|
||||
|
||||
18
YACReaderLibrary/options_dialog.h
Normal file
18
YACReaderLibrary/options_dialog.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef __OPTIONS_DIALOG_H
|
||||
#define __OPTIONS_DIALOG_H
|
||||
|
||||
#include "yacreader_options_dialog.h"
|
||||
|
||||
#include "yacreader_global.h"
|
||||
|
||||
using namespace YACReader;
|
||||
|
||||
class OptionsDialog : public YACReaderOptionsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OptionsDialog(QWidget * parent = 0);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
47
YACReaderLibrary/package_manager.cpp
Normal file
47
YACReaderLibrary/package_manager.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "package_manager.h"
|
||||
#include <QCoreApplication>
|
||||
|
||||
PackageManager::PackageManager()
|
||||
:_7z(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PackageManager::createPackage(const QString & libraryPath,const QString & dest)
|
||||
{
|
||||
QStringList attributes;
|
||||
attributes << "a" << "-y" << "-ttar" << dest+".clc" << libraryPath ;
|
||||
_7z = new QProcess();
|
||||
connect(_7z,SIGNAL(error(QProcess::ProcessError)),this,SLOT(openingError(QProcess::ProcessError)));
|
||||
connect(_7z,SIGNAL(finished(int,QProcess::ExitStatus)),this,SIGNAL(exported()));
|
||||
_7z->start(QCoreApplication::applicationDirPath()+"/utils/7z",attributes);
|
||||
}
|
||||
|
||||
void PackageManager::extractPackage(const QString & packagePath,const QString & destDir)
|
||||
{
|
||||
QStringList attributes;
|
||||
QString output = "-o";
|
||||
output += destDir;
|
||||
attributes << "x" << "-y" << output << packagePath;
|
||||
_7z = new QProcess();
|
||||
connect(_7z,SIGNAL(error(QProcess::ProcessError)),this,SLOT(openingError(QProcess::ProcessError)));
|
||||
connect(_7z,SIGNAL(finished(int,QProcess::ExitStatus)),this,SIGNAL(imported()));
|
||||
_7z->start(QCoreApplication::applicationDirPath()+"/utils/7z",attributes);
|
||||
}
|
||||
|
||||
void PackageManager::cancel()
|
||||
{
|
||||
if(_7z!=0)
|
||||
{
|
||||
_7z->disconnect();
|
||||
_7z->kill();
|
||||
if(creating)
|
||||
{
|
||||
//TODO remove dest+".clc"
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO fixed: is done by libraryWindow
|
||||
}
|
||||
}
|
||||
}
|
||||
24
YACReaderLibrary/package_manager.h
Normal file
24
YACReaderLibrary/package_manager.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef PACKAGE_MANAGER_H
|
||||
#define PACKAGE_MANAGER_H
|
||||
|
||||
#include <QProcess>
|
||||
|
||||
class PackageManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PackageManager();
|
||||
void createPackage(const QString & libraryPath,const QString & dest);
|
||||
void extractPackage(const QString & packagePath,const QString & destDir);
|
||||
public slots:
|
||||
void cancel();
|
||||
private:
|
||||
bool creating;
|
||||
QProcess * _7z;
|
||||
|
||||
signals:
|
||||
void exported();
|
||||
void imported();
|
||||
};
|
||||
|
||||
#endif
|
||||
896
YACReaderLibrary/properties_dialog.cpp
Normal file
896
YACReaderLibrary/properties_dialog.cpp
Normal file
@ -0,0 +1,896 @@
|
||||
#include "properties_dialog.h"
|
||||
|
||||
#include "data_base_management.h"
|
||||
#include "library_creator.h"
|
||||
#include "yacreader_field_edit.h"
|
||||
#include "yacreader_field_plain_text_edit.h"
|
||||
#include "db_helper.h"
|
||||
//#include "yacreader_busy_widget.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QSizePolicy>
|
||||
#include <QFormLayout>
|
||||
#include <QCheckBox>
|
||||
#include <QTabWidget>
|
||||
#include <QIntValidator>
|
||||
#include <QFileInfo>
|
||||
#include <QLabel>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QToolButton>
|
||||
#include <QPushButton>
|
||||
#include <QMessageBox>
|
||||
|
||||
PropertiesDialog::PropertiesDialog(QWidget * parent)
|
||||
:QDialog(parent)
|
||||
{
|
||||
|
||||
createCoverBox();
|
||||
createGeneralInfoBox();
|
||||
createAuthorsBox();
|
||||
createPublishingBox();
|
||||
createButtonBox();
|
||||
createPlotBox();
|
||||
|
||||
createTabBar();
|
||||
|
||||
mainLayout = new QGridLayout;
|
||||
//mainLayout->addWidget(coverBox,0,0);
|
||||
mainLayout->addWidget(tabBar,0,1);
|
||||
mainLayout->setColumnStretch(1,1);
|
||||
/*mainLayout->addWidget(authorsBox,1,1);
|
||||
mainLayout->addWidget(publishingBox,2,1);*/
|
||||
mainLayout->addWidget(buttonBox,1,1,Qt::AlignBottom);
|
||||
|
||||
mainWidget = new QWidget(this);
|
||||
mainWidget->setAutoFillBackground(true);
|
||||
mainWidget->setFixedSize(470,444);
|
||||
mainWidget->setLayout(mainLayout);
|
||||
mainLayout->setSizeConstraint(QLayout::SetMinimumSize);
|
||||
|
||||
int heightDesktopResolution = QApplication::desktop()->screenGeometry().height();
|
||||
int widthDesktopResolution = QApplication::desktop()->screenGeometry().width();
|
||||
int sHeight,sWidth;
|
||||
sHeight = static_cast<int>(heightDesktopResolution*0.65);
|
||||
sWidth = static_cast<int>(sHeight*1.4);
|
||||
//setCover(QPixmap(":/images/notCover.png"));
|
||||
|
||||
this->move(QPoint((widthDesktopResolution-sWidth)/2,((heightDesktopResolution-sHeight)-40)/2));
|
||||
setModal(true);
|
||||
|
||||
setFixedSize( sizeHint() );
|
||||
mainWidget->move(280,0);
|
||||
}
|
||||
|
||||
QSize PropertiesDialog::sizeHint()
|
||||
{
|
||||
return QSize(750,444);
|
||||
}
|
||||
|
||||
void PropertiesDialog::createTabBar()
|
||||
{
|
||||
tabBar = new QTabWidget;
|
||||
tabBar->addTab(generalInfoBox,tr("General info"));
|
||||
tabBar->addTab(authorsBox,tr("Authors"));
|
||||
tabBar->addTab(publishingBox,tr("Publishing"));
|
||||
tabBar->addTab(plotBox,tr("Plot"));
|
||||
}
|
||||
|
||||
void PropertiesDialog::createCoverBox()
|
||||
{
|
||||
coverBox = new QWidget(this);
|
||||
|
||||
QHBoxLayout * layout = new QHBoxLayout;
|
||||
|
||||
QLabel * label = new QLabel(tr("Cover page"));
|
||||
label->setStyleSheet("QLabel {color: white; font-weight:bold; font-size:14px;}");
|
||||
layout->addWidget(label);
|
||||
layout->addStretch();
|
||||
|
||||
coverPageEdit = new YACReaderFieldEdit();
|
||||
|
||||
showPreviousCoverPageButton = new QToolButton();
|
||||
showPreviousCoverPageButton->setIcon(QIcon(":/images/previousCoverPage.png"));
|
||||
showPreviousCoverPageButton->setStyleSheet("QToolButton {border:none;}");
|
||||
showNextCoverPageButton = new QToolButton();
|
||||
showNextCoverPageButton->setIcon(QIcon(":/images/nextCoverPage.png"));
|
||||
showNextCoverPageButton->setStyleSheet("QToolButton {border:none;}");
|
||||
|
||||
coverPageNumberLabel = new QLabel("-");
|
||||
|
||||
coverPageNumberLabel->setStyleSheet("QLabel {color: white; font-weight:bold; font-size:14px;}");
|
||||
|
||||
layout->addWidget(showPreviousCoverPageButton);
|
||||
layout->addSpacing(5);
|
||||
layout->addWidget(coverPageNumberLabel);
|
||||
layout->addSpacing(5);
|
||||
layout->addWidget(showNextCoverPageButton);
|
||||
|
||||
coverPageEdit->setStyleSheet("QLineEdit {border:none;}");
|
||||
layout->setSpacing(0);
|
||||
|
||||
coverBox->setLayout(layout);
|
||||
|
||||
coverBox->setFixedWidth(280);
|
||||
coverBox->move(0,444-28);
|
||||
layout->setContentsMargins(5,4,5,0);
|
||||
|
||||
//busyIndicator = new YACReaderBusyWidget(this);
|
||||
//busyIndicator->move((280-busyIndicator->width())/2,(444-busyIndicator->height()-28)/2);
|
||||
//busyIndicator->hide();
|
||||
|
||||
connect(showPreviousCoverPageButton,SIGNAL(clicked()),this,SLOT(loadPreviousCover()));
|
||||
connect(showNextCoverPageButton,SIGNAL(clicked()),this,SLOT(loadNextCover()));
|
||||
|
||||
}
|
||||
|
||||
QFrame * createLine()
|
||||
{
|
||||
QFrame * line = new QFrame();
|
||||
line->setObjectName(QString::fromUtf8("line"));
|
||||
//line->setGeometry(QRect(320, 150, 118, 3));
|
||||
line->setFrameShape(QFrame::HLine);
|
||||
line->setFrameShadow(QFrame::Sunken);
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
void PropertiesDialog::createGeneralInfoBox()
|
||||
{
|
||||
generalInfoBox = new QWidget;
|
||||
|
||||
QFormLayout *generalInfoLayout = new QFormLayout;
|
||||
|
||||
generalInfoLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
|
||||
//generalInfoLayout->setRowWrapPolicy(QFormLayout::WrapAllRows);
|
||||
generalInfoLayout->addRow(tr("Title:"), title = new YACReaderFieldEdit());
|
||||
|
||||
|
||||
QHBoxLayout * number = new QHBoxLayout;
|
||||
number->addWidget(numberEdit = new YACReaderFieldEdit());
|
||||
numberValidator.setBottom(0);
|
||||
numberEdit->setValidator(&numberValidator);
|
||||
number->addWidget(new QLabel("Bis:"));
|
||||
number->addWidget(isBisCheck = new QCheckBox());
|
||||
number->addWidget(new QLabel("of:"));
|
||||
number->addWidget(countEdit = new YACReaderFieldEdit());
|
||||
countValidator.setBottom(0);
|
||||
countEdit->setValidator(&countValidator);
|
||||
number->addStretch(1);
|
||||
/*generalInfoLayout->addRow(tr("&Issue number:"), );
|
||||
generalInfoLayout->addRow(tr("&Bis:"), );*/
|
||||
generalInfoLayout->addRow(tr("Issue number:"), number);
|
||||
|
||||
generalInfoLayout->addRow(tr("Volume:"), volumeEdit = new YACReaderFieldEdit());
|
||||
|
||||
QHBoxLayout * arc = new QHBoxLayout;
|
||||
arc->addWidget(storyArcEdit = new YACReaderFieldEdit());
|
||||
arc->addWidget(new QLabel("Arc number:"));
|
||||
arc->addWidget(arcNumberEdit = new YACReaderFieldEdit());
|
||||
arcNumberValidator.setBottom(0);
|
||||
arcNumberEdit->setValidator(&arcNumberValidator);
|
||||
arc->addWidget(new QLabel("of:"));
|
||||
arc->addWidget(arcCountEdit = new YACReaderFieldEdit());
|
||||
arcCountValidator.setBottom(0);
|
||||
arcCountEdit->setValidator(&arcCountValidator);
|
||||
arc->addStretch(1);
|
||||
generalInfoLayout->addRow(tr("Story arc:"), arc);
|
||||
|
||||
generalInfoLayout->addRow(tr("Genere:"), genereEdit = new YACReaderFieldEdit());
|
||||
|
||||
generalInfoLayout->addRow(tr("Size:"), size = new QLabel("size"));
|
||||
|
||||
//generalInfoLayout->addRow(tr("Comic Vine link:"), comicVineLink = new QLabel("..."));
|
||||
//generalInfoLayout->addRow(bottom);
|
||||
|
||||
QVBoxLayout * main = new QVBoxLayout;
|
||||
main->addLayout(generalInfoLayout);
|
||||
main->addStretch();
|
||||
main->addWidget(comicVineLink = new QLabel("Comic Vine link : ..."));
|
||||
comicVineLink->setOpenExternalLinks(true);
|
||||
|
||||
generalInfoBox->setLayout(main);
|
||||
}
|
||||
|
||||
void PropertiesDialog::createAuthorsBox()
|
||||
{
|
||||
authorsBox = new QWidget;
|
||||
|
||||
QVBoxLayout *authorsLayout = new QVBoxLayout;
|
||||
|
||||
//authorsLayout->setRowWrapPolicy(QFormLayout::WrapAllRows);
|
||||
QHBoxLayout * h1 = new QHBoxLayout;
|
||||
QVBoxLayout * vl1 = new QVBoxLayout;
|
||||
QVBoxLayout * vr1 = new QVBoxLayout;
|
||||
vl1->addWidget(new QLabel(tr("Writer(s):")));
|
||||
vl1->addWidget(writer = new YACReaderFieldPlainTextEdit());
|
||||
h1->addLayout(vl1);
|
||||
vr1->addWidget(new QLabel(tr("Penciller(s):")));
|
||||
vr1->addWidget(penciller = new YACReaderFieldPlainTextEdit());
|
||||
h1->addLayout(vr1);
|
||||
//authorsLayout->addRow(tr("Writer(s):"), new YACReaderFieldPlainTextEdit());
|
||||
//authorsLayout->addRow(tr("Penciller(s):"), new YACReaderFieldPlainTextEdit());
|
||||
QHBoxLayout * h2 = new QHBoxLayout;
|
||||
QVBoxLayout * vl2 = new QVBoxLayout;
|
||||
QVBoxLayout * vr2 = new QVBoxLayout;
|
||||
vl2->addWidget(new QLabel(tr("Inker(s):")));
|
||||
vl2->addWidget(inker = new YACReaderFieldPlainTextEdit());
|
||||
h2->addLayout(vl2);
|
||||
vr2->addWidget(new QLabel(tr("Colorist(s):")));
|
||||
vr2->addWidget(colorist = new YACReaderFieldPlainTextEdit());
|
||||
h2->addLayout(vr2);
|
||||
|
||||
//authorsLayout->addRow(tr("Inker(s):"), new YACReaderFieldPlainTextEdit());
|
||||
//authorsLayout->addRow(tr("Colorist(s):"), new YACReaderFieldPlainTextEdit());
|
||||
|
||||
QHBoxLayout * h3 = new QHBoxLayout;
|
||||
QVBoxLayout * vl3 = new QVBoxLayout;
|
||||
QVBoxLayout * vr3 = new QVBoxLayout;
|
||||
vl3->addWidget(new QLabel(tr("Letterer(s):")));
|
||||
vl3->addWidget(letterer = new YACReaderFieldPlainTextEdit());
|
||||
h3->addLayout(vl3);
|
||||
vr3->addWidget(new QLabel(tr("Cover Artist(s):")));
|
||||
vr3->addWidget(coverArtist = new YACReaderFieldPlainTextEdit());
|
||||
h3->addLayout(vr3);
|
||||
//authorsLayout->addRow(tr("Letterer(es):"), new YACReaderFieldPlainTextEdit());
|
||||
//authorsLayout->addRow(tr("Cover Artist(s):"), new YACReaderFieldPlainTextEdit());
|
||||
|
||||
authorsLayout->addLayout(h1);
|
||||
authorsLayout->addLayout(h2);
|
||||
authorsLayout->addLayout(h3);
|
||||
authorsLayout->addStretch(1);
|
||||
authorsBox->setLayout(authorsLayout);
|
||||
|
||||
}
|
||||
|
||||
void PropertiesDialog::createPublishingBox()
|
||||
{
|
||||
publishingBox = new QWidget;
|
||||
|
||||
QFormLayout *publishingLayout = new QFormLayout;
|
||||
|
||||
publishingLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
|
||||
|
||||
QHBoxLayout * date = new QHBoxLayout;
|
||||
date->addWidget(new QLabel(tr("Day:")));
|
||||
date->addWidget(dayEdit = new YACReaderFieldEdit());
|
||||
dayValidator.setRange(1,31);
|
||||
dayEdit->setValidator(&dayValidator);
|
||||
date->addWidget(new QLabel(tr("Month:")));
|
||||
date->addWidget(monthEdit = new YACReaderFieldEdit());
|
||||
monthValidator.setRange(1,12);
|
||||
monthEdit->setValidator(&monthValidator);
|
||||
date->addWidget(new QLabel(tr("Year:")));
|
||||
date->addWidget(yearEdit = new YACReaderFieldEdit());
|
||||
yearValidator.setRange(1,9999);
|
||||
yearEdit->setValidator(&yearValidator);
|
||||
date->addStretch(1);
|
||||
|
||||
publishingLayout->setRowWrapPolicy(QFormLayout::WrapAllRows);
|
||||
publishingLayout->addRow(date);
|
||||
publishingLayout->addRow(tr("Publisher:"), publisherEdit = new YACReaderFieldEdit());
|
||||
publishingLayout->addRow(tr("Format:"), formatEdit = new YACReaderFieldEdit());
|
||||
publishingLayout->addRow(tr("Color/BW:"), colorCheck = new QCheckBox());
|
||||
publishingLayout->addRow(tr("Age rating:"), ageRatingEdit = new YACReaderFieldEdit());
|
||||
|
||||
publishingBox->setLayout(publishingLayout);
|
||||
}
|
||||
|
||||
void PropertiesDialog::createPlotBox()
|
||||
{
|
||||
plotBox = new QWidget;
|
||||
|
||||
QFormLayout *plotLayout = new QFormLayout;
|
||||
plotLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
|
||||
|
||||
plotLayout->setRowWrapPolicy(QFormLayout::WrapAllRows);
|
||||
plotLayout->addRow(tr("Synopsis:"), synopsis = new YACReaderFieldPlainTextEdit());
|
||||
plotLayout->addRow(tr("Characters:"), characters = new YACReaderFieldPlainTextEdit());
|
||||
plotLayout->addRow(tr("Notes:"), notes = new YACReaderFieldPlainTextEdit());
|
||||
|
||||
plotBox->setLayout(plotLayout);
|
||||
|
||||
}
|
||||
|
||||
void PropertiesDialog::createButtonBox()
|
||||
{
|
||||
buttonBox = new QDialogButtonBox;
|
||||
|
||||
closeButton = buttonBox->addButton(QDialogButtonBox::Close);
|
||||
saveButton = buttonBox->addButton(QDialogButtonBox::Save);
|
||||
//rotateWidgetsButton = buttonBox->addButton(tr("Rotate &Widgets"),QDialogButtonBox::ActionRole);
|
||||
|
||||
//connect(rotateWidgetsButton, SIGNAL(clicked()), this, SLOT(rotateWidgets()));
|
||||
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
|
||||
connect(saveButton, SIGNAL(clicked()), this, SLOT(save()));
|
||||
}
|
||||
|
||||
QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly = false)
|
||||
{
|
||||
int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
|
||||
int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
|
||||
|
||||
QImage result = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
int r1 = rect.top();
|
||||
int r2 = rect.bottom();
|
||||
int c1 = rect.left();
|
||||
int c2 = rect.right();
|
||||
|
||||
int bpl = result.bytesPerLine();
|
||||
int rgba[4];
|
||||
unsigned char* p;
|
||||
|
||||
int i1 = 0;
|
||||
int i2 = 3;
|
||||
|
||||
if (alphaOnly)
|
||||
i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
|
||||
|
||||
for (int col = c1; col <= c2; col++) {
|
||||
p = result.scanLine(r1) + col * 4;
|
||||
for (int i = i1; i <= i2; i++)
|
||||
rgba[i] = p[i] << 4;
|
||||
|
||||
p += bpl;
|
||||
for (int j = r1; j < r2; j++, p += bpl)
|
||||
for (int i = i1; i <= i2; i++)
|
||||
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
|
||||
}
|
||||
|
||||
for (int row = r1; row <= r2; row++) {
|
||||
p = result.scanLine(row) + c1 * 4;
|
||||
for (int i = i1; i <= i2; i++)
|
||||
rgba[i] = p[i] << 4;
|
||||
|
||||
p += 4;
|
||||
for (int j = c1; j < c2; j++, p += 4)
|
||||
for (int i = i1; i <= i2; i++)
|
||||
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
|
||||
}
|
||||
|
||||
for (int col = c1; col <= c2; col++) {
|
||||
p = result.scanLine(r2) + col * 4;
|
||||
for (int i = i1; i <= i2; i++)
|
||||
rgba[i] = p[i] << 4;
|
||||
|
||||
p -= bpl;
|
||||
for (int j = r1; j < r2; j++, p -= bpl)
|
||||
for (int i = i1; i <= i2; i++)
|
||||
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
|
||||
}
|
||||
|
||||
for (int row = r1; row <= r2; row++) {
|
||||
p = result.scanLine(row) + c2 * 4;
|
||||
for (int i = i1; i <= i2; i++)
|
||||
rgba[i] = p[i] << 4;
|
||||
|
||||
p -= 4;
|
||||
for (int j = c1; j < c2; j++, p -= 4)
|
||||
for (int i = i1; i <= i2; i++)
|
||||
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PropertiesDialog::setComics(QList<ComicDB> comics)
|
||||
{
|
||||
this->comics = comics;
|
||||
|
||||
ComicDB comic = comics.at(0);
|
||||
|
||||
if(!comic.info.title.isNull())
|
||||
title->setText(comic.info.title.toString());
|
||||
if(!comic.info.comicVineID.isNull())
|
||||
{
|
||||
comicVineLink->setHidden(false);
|
||||
comicVineLink->setText(QString(tr("Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href=\"http://www.comicvine.com/comic/4000-%1/\"> view </a>").arg(comic.info.comicVineID.toString())));
|
||||
}
|
||||
else
|
||||
comicVineLink->setHidden(true);
|
||||
|
||||
if(comics.length()==1 && !comic.info.coverPage.isNull())
|
||||
{
|
||||
coverPageEdit->setText(comic.info.coverPage.toString());
|
||||
coverPageValidator.setRange(1,comic.info.numPages.toInt());
|
||||
coverPageEdit->setValidator(&coverPageValidator);
|
||||
//----------
|
||||
int coverPage = comic.info.coverPage.toInt();
|
||||
coverPageNumberLabel->setText(QString::number(coverPage));
|
||||
coverPageNumberLabel->adjustSize();
|
||||
|
||||
showPreviousCoverPageButton->setEnabled(true);
|
||||
showNextCoverPageButton->setEnabled(true);
|
||||
|
||||
if(coverPage == 1)
|
||||
showPreviousCoverPageButton->setDisabled(true);
|
||||
if(coverPage == comic.info.numPages.toInt())
|
||||
showNextCoverPageButton->setDisabled(true);
|
||||
|
||||
coverChanged = false;
|
||||
coverBox->show();
|
||||
|
||||
if(!QFileInfo(basePath+comics[0].path).exists())
|
||||
{
|
||||
QMessageBox::warning(this,tr("Not found"),tr("Comic not found. You should update your library."));
|
||||
showPreviousCoverPageButton->setDisabled(true);
|
||||
showNextCoverPageButton->setDisabled(true);
|
||||
}
|
||||
}
|
||||
/*if(comic.info.numPages != NULL)
|
||||
numPagesEdit->setText(QString::number(*comic.info.numPages));*/
|
||||
|
||||
|
||||
if(!comic.info.number.isNull())
|
||||
numberEdit->setText(comic.info.number.toString());
|
||||
if(!comic.info.isBis.isNull())
|
||||
isBisCheck->setChecked(comic.info.isBis.toBool());
|
||||
if(!comic.info.count.isNull())
|
||||
countEdit->setText(comic.info.count.toString());
|
||||
|
||||
if(!comic.info.volume.isNull())
|
||||
volumeEdit->setText(comic.info.volume.toString());
|
||||
if(!comic.info.storyArc.isNull())
|
||||
storyArcEdit->setText(comic.info.storyArc.toString());
|
||||
if(!comic.info.arcNumber.isNull())
|
||||
arcNumberEdit->setText(comic.info.arcNumber.toString());
|
||||
if(!comic.info.arcCount.isNull())
|
||||
arcCountEdit->setText(comic.info.arcCount.toString());
|
||||
|
||||
if(!comic.info.genere.isNull())
|
||||
genereEdit->setText(comic.info.genere.toString());
|
||||
|
||||
if(!comic.info.writer.isNull())
|
||||
writer->setPlainText(comic.info.writer.toString());
|
||||
if(!comic.info.penciller.isNull())
|
||||
penciller->setPlainText(comic.info.penciller.toString());
|
||||
if(!comic.info.inker.isNull())
|
||||
inker->setPlainText(comic.info.inker.toString());
|
||||
if(!comic.info.colorist.isNull())
|
||||
colorist->setPlainText(comic.info.colorist.toString());
|
||||
if(!comic.info.letterer.isNull())
|
||||
letterer->setPlainText(comic.info.letterer.toString());
|
||||
if(!comic.info.coverArtist.isNull())
|
||||
coverArtist->setPlainText(comic.info.coverArtist.toString());
|
||||
|
||||
size->setText(QString::number(comic.info.hash.right(comic.info.hash.length()-40).toInt()/1024.0/1024.0,'f',2)+"Mb");
|
||||
|
||||
if(!comic.info.date.isNull())
|
||||
{
|
||||
QStringList date = (comic.info.date.toString()).split("/");
|
||||
dayEdit->setText(date[0]);
|
||||
monthEdit->setText(date[1]);
|
||||
yearEdit->setText(date[2]);
|
||||
}
|
||||
if(!comic.info.publisher.isNull())
|
||||
publisherEdit->setText(comic.info.publisher.toString());
|
||||
if(!comic.info.format.isNull())
|
||||
formatEdit->setText(comic.info.format.toString());
|
||||
if(!comic.info.color.isNull())
|
||||
colorCheck->setChecked(comic.info.color.toBool());
|
||||
else
|
||||
colorCheck->setCheckState(Qt::PartiallyChecked);
|
||||
|
||||
if(!comic.info.ageRating.isNull())
|
||||
ageRatingEdit->setText(comic.info.ageRating.toString());
|
||||
|
||||
if(!comic.info.synopsis.isNull())
|
||||
synopsis->setPlainText(comic.info.synopsis.toString());
|
||||
if(!comic.info.characters.isNull())
|
||||
characters->setPlainText(comic.info.characters.toString());
|
||||
if(!comic.info.notes.isNull())
|
||||
notes->setPlainText(comic.info.notes.toString());
|
||||
|
||||
|
||||
if(comics.length() > 1)
|
||||
{
|
||||
coverBox->hide();
|
||||
|
||||
setDisableUniqueValues(true);
|
||||
this->setWindowTitle(tr("Edit selected comics information"));
|
||||
setMultipleCover();
|
||||
|
||||
QList<ComicDB>::iterator itr;
|
||||
for(itr = ++comics.begin();itr!=comics.end();itr++)
|
||||
{
|
||||
if(itr->info.title.isNull() || itr->info.title.toString() != title->text())
|
||||
title->clear();
|
||||
|
||||
if(itr->info.count.isNull() || itr->info.count.toString() != countEdit->text())
|
||||
countEdit->clear();
|
||||
|
||||
if(itr->info.volume.isNull() || itr->info.volume.toString() != volumeEdit->text())
|
||||
volumeEdit->clear();
|
||||
if(itr->info.storyArc.isNull() || itr->info.storyArc.toString() != storyArcEdit->text())
|
||||
storyArcEdit->clear();
|
||||
if(itr->info.arcCount.isNull() || itr->info.arcCount.toString() != storyArcEdit->text())
|
||||
arcCountEdit->clear();
|
||||
|
||||
if(itr->info.genere.isNull() || itr->info.genere.toString() != genereEdit->text())
|
||||
genereEdit->clear();
|
||||
|
||||
if(itr->info.writer.isNull() || itr->info.writer.toString() != writer->toPlainText())
|
||||
writer->clear();
|
||||
if(itr->info.penciller.isNull() || itr->info.penciller.toString() != penciller->toPlainText())
|
||||
penciller->clear();
|
||||
if(itr->info.inker.isNull() || itr->info.inker.toString() != inker->toPlainText())
|
||||
inker->clear();
|
||||
if(itr->info.colorist.isNull() || itr->info.colorist.toString() != colorist->toPlainText())
|
||||
colorist->clear();
|
||||
if(itr->info.letterer.isNull() || itr->info.letterer.toString() != letterer->toPlainText())
|
||||
letterer->clear();
|
||||
if(itr->info.coverArtist.isNull() || itr->info.coverArtist.toString() != coverArtist->toPlainText())
|
||||
coverArtist->clear();
|
||||
|
||||
if(itr->info.date.isNull())
|
||||
{
|
||||
dayEdit->clear();
|
||||
monthEdit->clear();
|
||||
yearEdit->clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
QStringList date = itr->info.date.toString().split("/");
|
||||
if(dayEdit->text() != date[0])
|
||||
dayEdit->clear();
|
||||
if(monthEdit->text() != date[1])
|
||||
monthEdit->clear();
|
||||
if(yearEdit->text() != date[2])
|
||||
yearEdit->clear();
|
||||
}
|
||||
|
||||
if(itr->info.publisher.isNull() || itr->info.publisher.toString() != publisherEdit->text())
|
||||
publisherEdit->clear();
|
||||
if(itr->info.format.isNull() || itr->info.format.toString() != formatEdit->text())
|
||||
formatEdit->clear();
|
||||
if(itr->info.color.isNull() || itr->info.color.toBool() != colorCheck->isChecked())
|
||||
colorCheck->setCheckState(Qt::PartiallyChecked);
|
||||
if(itr->info.ageRating.isNull() || itr->info.ageRating.toString() != ageRatingEdit->text())
|
||||
ageRatingEdit->clear();
|
||||
|
||||
if(itr->info.synopsis.isNull() || itr->info.synopsis.toString() != synopsis->toPlainText())
|
||||
synopsis->clear();
|
||||
if(itr->info.characters.isNull() || itr->info.characters.toString() != characters->toPlainText())
|
||||
characters->clear();
|
||||
if(itr->info.notes.isNull() || itr->info.notes.toString() != notes->toPlainText())
|
||||
notes->clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->setWindowTitle(tr("Edit comic information"));
|
||||
setCover(comic.info.getCover(basePath));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PropertiesDialog::updateComics()
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
|
||||
db.open();
|
||||
db.transaction();
|
||||
QList<ComicDB>::iterator itr;
|
||||
for(itr = comics.begin();itr!=comics.end();itr++)
|
||||
{
|
||||
if(itr->info.edited)
|
||||
DBHelper::update(&(itr->info),db);
|
||||
}
|
||||
db.commit();
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(databasePath);
|
||||
}
|
||||
|
||||
void PropertiesDialog::setMultipleCover()
|
||||
{
|
||||
ComicDB lastComic = comics.last();
|
||||
QPixmap last = lastComic.info.getCover(basePath);
|
||||
last = last.scaledToHeight(444,Qt::SmoothTransformation);
|
||||
|
||||
coverImage = QPixmap::fromImage(blurred(last.toImage(),QRect(0,0,last.width(),last.height()),15));
|
||||
}
|
||||
|
||||
void PropertiesDialog::setCover(const QPixmap & coverI)
|
||||
{
|
||||
coverImage = coverI.scaledToHeight(444,Qt::SmoothTransformation);
|
||||
}
|
||||
|
||||
void PropertiesDialog::setFilename(const QString & nameString)
|
||||
{
|
||||
title->setText(nameString);
|
||||
}
|
||||
void PropertiesDialog::setNumpages(int pagesNum)
|
||||
{
|
||||
numPagesEdit->setText(QString::number(pagesNum));
|
||||
}
|
||||
void PropertiesDialog::setSize(float sizeFloat)
|
||||
{
|
||||
|
||||
size->setText(QString::number(sizeFloat,'f',2) + " MB");
|
||||
}
|
||||
|
||||
void PropertiesDialog::save()
|
||||
{
|
||||
QList<ComicDB>::iterator itr;
|
||||
for(itr = comics.begin();itr!=comics.end();itr++)
|
||||
{
|
||||
//Comic & comic = comics[0];
|
||||
bool edited = false;
|
||||
|
||||
if(title->isModified())
|
||||
{
|
||||
itr->info.title = title->text();
|
||||
edited = true;
|
||||
}
|
||||
|
||||
if(comics.size()==1)
|
||||
if(coverChanged)
|
||||
{
|
||||
itr->info.coverPage = coverPageNumberLabel->text();
|
||||
edited = true;
|
||||
}
|
||||
|
||||
/*if(comic.info.numPages != NULL)
|
||||
numPagesEdit->setText(QString::number(*comic.info.numPages));*/
|
||||
if(comics.size()==1)
|
||||
if(numberEdit->isModified())
|
||||
{
|
||||
if (numberEdit->text().isEmpty())
|
||||
itr->info.number = QVariant();
|
||||
else
|
||||
itr->info.number = numberEdit->text();
|
||||
edited = true;
|
||||
}
|
||||
if(comics.size()==1)
|
||||
if(!itr->info.isBis.isNull() || isBisCheck->isChecked())
|
||||
{
|
||||
itr->info.isBis = isBisCheck->isChecked();
|
||||
edited = true;
|
||||
}
|
||||
|
||||
if(countEdit->isModified())
|
||||
{
|
||||
itr->info.count = countEdit->text();
|
||||
edited = true;
|
||||
}
|
||||
|
||||
if(volumeEdit->isModified())
|
||||
{
|
||||
itr->info.volume = volumeEdit->text();
|
||||
edited = true;
|
||||
}
|
||||
if(storyArcEdit->isModified())
|
||||
{
|
||||
itr->info.storyArc = storyArcEdit->text();
|
||||
edited = true;
|
||||
}
|
||||
if(comics.size()==1)
|
||||
if(arcNumberEdit->isModified() && !arcNumberEdit->text().isEmpty())
|
||||
{
|
||||
itr->info.arcNumber = arcNumberEdit->text();
|
||||
edited = true;
|
||||
}
|
||||
if(arcCountEdit->isModified())
|
||||
{
|
||||
itr->info.arcCount = arcCountEdit->text();
|
||||
edited = true;
|
||||
}
|
||||
|
||||
if(genereEdit->isModified())
|
||||
{
|
||||
itr->info.genere = genereEdit->text();
|
||||
edited = true;
|
||||
}
|
||||
|
||||
if(writer->document()->isModified())
|
||||
{
|
||||
itr->info.writer = writer->toPlainText();
|
||||
edited = true;
|
||||
}
|
||||
if(penciller->document()->isModified())
|
||||
{
|
||||
itr->info.penciller = penciller->toPlainText();
|
||||
edited = true;
|
||||
}
|
||||
if(inker->document()->isModified())
|
||||
{
|
||||
itr->info.inker = inker->toPlainText();
|
||||
edited = true;
|
||||
}
|
||||
if(colorist->document()->isModified())
|
||||
{
|
||||
itr->info.colorist = colorist->toPlainText();
|
||||
edited = true;
|
||||
}
|
||||
if(letterer->document()->isModified())
|
||||
{
|
||||
itr->info.letterer = letterer->toPlainText();
|
||||
edited = true;
|
||||
}
|
||||
if(coverArtist->document()->isModified())
|
||||
{
|
||||
itr->info.coverArtist = coverArtist->toPlainText();
|
||||
edited = true;
|
||||
}
|
||||
|
||||
if(dayEdit->isModified() || monthEdit->isModified() || yearEdit->isModified() )
|
||||
{
|
||||
itr->info.date = dayEdit->text()+"/"+monthEdit->text()+"/"+yearEdit->text();
|
||||
edited = true;
|
||||
}
|
||||
if(publisherEdit->isModified())
|
||||
{
|
||||
itr->info.publisher = publisherEdit->text();
|
||||
edited = true;
|
||||
}
|
||||
if(formatEdit->isModified())
|
||||
{
|
||||
itr->info.format = formatEdit->text();
|
||||
edited = true;
|
||||
}
|
||||
if(colorCheck->checkState() != Qt::PartiallyChecked)
|
||||
{
|
||||
itr->info.color = colorCheck->isChecked();
|
||||
edited = true;
|
||||
}
|
||||
if(ageRatingEdit->isModified())
|
||||
{
|
||||
itr->info.ageRating = ageRatingEdit->text();
|
||||
edited = true;
|
||||
}
|
||||
|
||||
if(synopsis->document()->isModified())
|
||||
{
|
||||
itr->info.synopsis = synopsis->toPlainText();
|
||||
edited = true;
|
||||
}
|
||||
if(characters->document()->isModified())
|
||||
{
|
||||
itr->info.characters = characters->toPlainText();
|
||||
edited = true;
|
||||
}
|
||||
if(notes->document()->isModified())
|
||||
{
|
||||
itr->info.notes = notes->toPlainText();
|
||||
edited = true;
|
||||
}
|
||||
|
||||
itr->info.edited = edited;
|
||||
}
|
||||
updateComics();
|
||||
if(comics.count() == 1)
|
||||
{
|
||||
if(coverChanged)// && coverPageEdit->text().toInt() != *comics[0].info.coverPage)
|
||||
{
|
||||
ThumbnailCreator tc(basePath+comics[0].path,basePath+"/.yacreaderlibrary/covers/"+comics[0].info.hash+".jpg", comics[0].info.coverPage.toInt());
|
||||
tc.create();
|
||||
}
|
||||
}
|
||||
close();
|
||||
emit(accepted());
|
||||
}
|
||||
|
||||
void PropertiesDialog::setDisableUniqueValues(bool disabled)
|
||||
{
|
||||
coverPageEdit->setDisabled(disabled);
|
||||
coverPageEdit->clear();
|
||||
numberEdit->setDisabled(disabled);
|
||||
numberEdit->clear();
|
||||
isBisCheck->setDisabled(disabled);
|
||||
isBisCheck->setChecked(false);
|
||||
arcNumberEdit->setDisabled(disabled);
|
||||
arcNumberEdit->clear();
|
||||
}
|
||||
|
||||
void PropertiesDialog::closeEvent ( QCloseEvent * e )
|
||||
{
|
||||
|
||||
title->clear();
|
||||
title->setModified(false);
|
||||
coverPageEdit->clear();
|
||||
// numPagesEdit->setText(QString::number(*comic.info.numPages));
|
||||
numberEdit->clear();
|
||||
isBisCheck->setChecked(false);
|
||||
countEdit->clear();
|
||||
volumeEdit->clear();
|
||||
storyArcEdit->clear();
|
||||
arcNumberEdit->clear();
|
||||
arcCountEdit->clear();
|
||||
genereEdit->clear();
|
||||
writer->clear();
|
||||
penciller->clear();
|
||||
inker->clear();
|
||||
colorist->clear();
|
||||
letterer->clear();
|
||||
coverArtist->clear();
|
||||
dayEdit->clear();
|
||||
monthEdit->clear();
|
||||
yearEdit->clear();
|
||||
publisherEdit->clear();
|
||||
formatEdit->clear();
|
||||
colorCheck->setCheckState(Qt::PartiallyChecked);
|
||||
ageRatingEdit->clear();
|
||||
synopsis->clear();
|
||||
characters->clear();
|
||||
notes->clear();
|
||||
|
||||
setDisableUniqueValues(false);
|
||||
|
||||
tabBar->setCurrentIndex(0);
|
||||
|
||||
coverPageEdit->setFocus();
|
||||
|
||||
QDialog::closeEvent(e);
|
||||
}
|
||||
|
||||
void PropertiesDialog::paintEvent(QPaintEvent * event)
|
||||
{
|
||||
QDialog::paintEvent(event);
|
||||
|
||||
QPainter p(this);
|
||||
|
||||
p.drawPixmap(0,0,coverImage);
|
||||
|
||||
//QPixmap shadow(":/images/social_dialog/shadow.png");
|
||||
//p.drawPixmap(280-shadow.width(),0,shadow.width(),444,shadow);
|
||||
p.drawLine(279,0,279,444);
|
||||
if(comics.length()==1)
|
||||
p.fillRect(0,444-28,280,28,QColor(0,0,0,153));
|
||||
}
|
||||
|
||||
void PropertiesDialog::updateCoverPageNumberLabel(int n)
|
||||
{
|
||||
coverPageNumberLabel->setText(QString::number(n));
|
||||
coverPageNumberLabel->adjustSize();
|
||||
}
|
||||
|
||||
void PropertiesDialog::loadNextCover()
|
||||
{
|
||||
int current = coverPageNumberLabel->text().toInt();
|
||||
if(current < comics.at(0).info.numPages.toInt())
|
||||
{
|
||||
updateCoverPageNumberLabel(current+1);
|
||||
|
||||
ThumbnailCreator tc(basePath+comics[0].path,"",current+1);
|
||||
tc.create();
|
||||
setCover(tc.getCover());
|
||||
repaint();
|
||||
|
||||
if((current+1) == comics.at(0).info.numPages.toInt())
|
||||
{
|
||||
showNextCoverPageButton->setDisabled(true);
|
||||
}
|
||||
|
||||
showPreviousCoverPageButton->setEnabled(true);
|
||||
//busyIndicator->show();
|
||||
if(current+1 != comics.at(0).info.coverPage)
|
||||
coverChanged = true;
|
||||
else
|
||||
coverChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
void PropertiesDialog::loadPreviousCover()
|
||||
{
|
||||
int current = coverPageNumberLabel->text().toInt();
|
||||
if(current!=1)
|
||||
{
|
||||
updateCoverPageNumberLabel(current-1);
|
||||
ThumbnailCreator tc(basePath+comics[0].path,"",current-1);
|
||||
tc.create();
|
||||
setCover(tc.getCover());
|
||||
repaint();
|
||||
|
||||
if((current-1) == 1)
|
||||
{
|
||||
showPreviousCoverPageButton->setDisabled(true);
|
||||
}
|
||||
|
||||
showNextCoverPageButton->setEnabled(true);
|
||||
//busyIndicator->show();
|
||||
if(current-1 != comics.at(0).info.coverPage.toInt())
|
||||
coverChanged = true;
|
||||
else
|
||||
coverChanged = false;
|
||||
}
|
||||
}
|
||||
141
YACReaderLibrary/properties_dialog.h
Normal file
141
YACReaderLibrary/properties_dialog.h
Normal file
@ -0,0 +1,141 @@
|
||||
#ifndef __PROPERTIES_DIALOG_H
|
||||
#define __PROPERTIES_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <QIntValidator>
|
||||
|
||||
class QGridLayout;
|
||||
class QTabWidget;
|
||||
class QGroupBox;
|
||||
class QLabel;
|
||||
class QScrollArea;
|
||||
class QWidget;
|
||||
class YACReaderFieldEdit;
|
||||
class YACReaderFieldPlainTextEdit;
|
||||
class QDialogButtonBox;
|
||||
class QCheckBox;
|
||||
//class YACReaderBusyWidget;
|
||||
class QToolButton;
|
||||
|
||||
#include "comic_db.h"
|
||||
|
||||
class PropertiesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QWidget * mainWidget;
|
||||
//YACReaderBusyWidget * busyIndicator;
|
||||
|
||||
QGridLayout * mainLayout;
|
||||
|
||||
QTabWidget * tabBar;
|
||||
|
||||
QWidget * coverBox;
|
||||
QLabel * cover;
|
||||
QScrollArea * sa;
|
||||
|
||||
QWidget * generalInfoBox;
|
||||
YACReaderFieldEdit * title;
|
||||
YACReaderFieldEdit * numPagesEdit;
|
||||
QLabel * size;
|
||||
QLabel * comicVineLink;
|
||||
|
||||
YACReaderFieldEdit * coverPageEdit;
|
||||
QIntValidator coverPageValidator;
|
||||
|
||||
YACReaderFieldEdit * numberEdit;
|
||||
QIntValidator numberValidator;
|
||||
QCheckBox * isBisCheck;
|
||||
YACReaderFieldEdit * countEdit;
|
||||
QIntValidator countValidator;
|
||||
|
||||
YACReaderFieldEdit * volumeEdit;
|
||||
YACReaderFieldEdit * storyArcEdit;
|
||||
YACReaderFieldEdit * arcNumberEdit;
|
||||
QIntValidator arcNumberValidator;
|
||||
YACReaderFieldEdit * arcCountEdit;
|
||||
QIntValidator arcCountValidator;
|
||||
|
||||
YACReaderFieldEdit * genereEdit;
|
||||
|
||||
YACReaderFieldPlainTextEdit * writer;
|
||||
YACReaderFieldPlainTextEdit * penciller;
|
||||
YACReaderFieldPlainTextEdit * inker;
|
||||
YACReaderFieldPlainTextEdit * colorist;
|
||||
YACReaderFieldPlainTextEdit * letterer;
|
||||
YACReaderFieldPlainTextEdit * coverArtist;
|
||||
|
||||
YACReaderFieldEdit * dayEdit;
|
||||
QIntValidator dayValidator;
|
||||
YACReaderFieldEdit * monthEdit;
|
||||
QIntValidator monthValidator;
|
||||
YACReaderFieldEdit * yearEdit;
|
||||
QIntValidator yearValidator;
|
||||
YACReaderFieldEdit * publisherEdit;
|
||||
YACReaderFieldEdit * formatEdit;
|
||||
QCheckBox * colorCheck;
|
||||
YACReaderFieldEdit * ageRatingEdit;
|
||||
|
||||
YACReaderFieldPlainTextEdit * synopsis;
|
||||
YACReaderFieldPlainTextEdit * characters;
|
||||
YACReaderFieldPlainTextEdit * notes;
|
||||
|
||||
QWidget * authorsBox;
|
||||
|
||||
QWidget * publishingBox;
|
||||
|
||||
QWidget * plotBox;
|
||||
|
||||
QDialogButtonBox *buttonBox;
|
||||
QPushButton *closeButton;
|
||||
QPushButton *saveButton;
|
||||
QPushButton *restoreButton; //??
|
||||
|
||||
QPixmap coverImage;
|
||||
|
||||
QToolButton * showPreviousCoverPageButton;
|
||||
QToolButton * showNextCoverPageButton;
|
||||
QLabel * coverPageNumberLabel;
|
||||
|
||||
void createTabBar();
|
||||
void createCoverBox();
|
||||
void createGeneralInfoBox();
|
||||
void createAuthorsBox();
|
||||
void createPublishingBox();
|
||||
void createPlotBox();
|
||||
|
||||
void createButtonBox();
|
||||
|
||||
void setDisableUniqueValues(bool disabled);
|
||||
|
||||
QList<ComicDB> comics;
|
||||
void closeEvent ( QCloseEvent * e );
|
||||
void updateCoverPageNumberLabel(int n);
|
||||
|
||||
bool coverChanged;
|
||||
|
||||
public:
|
||||
PropertiesDialog(QWidget * parent = 0);
|
||||
QString databasePath;
|
||||
QString basePath;
|
||||
QSize sizeHint();
|
||||
void paintEvent(QPaintEvent * event);
|
||||
|
||||
public slots:
|
||||
void setComics(QList<ComicDB> comics);
|
||||
void updateComics();
|
||||
void save();
|
||||
//Deprecated
|
||||
void setCover(const QPixmap & cover);
|
||||
void setMultipleCover();
|
||||
void setFilename(const QString & name);
|
||||
void setNumpages(int pages);
|
||||
void setSize(float size);
|
||||
void loadNextCover();
|
||||
void loadPreviousCover();
|
||||
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
76
YACReaderLibrary/rename_library_dialog.cpp
Normal file
76
YACReaderLibrary/rename_library_dialog.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include "rename_library_dialog.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QFileDialog>
|
||||
|
||||
|
||||
|
||||
RenameLibraryDialog::RenameLibraryDialog(QWidget * parent)
|
||||
:QDialog(parent)
|
||||
{
|
||||
setupUI();
|
||||
}
|
||||
|
||||
void RenameLibraryDialog::setupUI()
|
||||
{
|
||||
newNameLabel = new QLabel(tr("New Library Name : "));
|
||||
newNameEdit = new QLineEdit;
|
||||
newNameLabel->setBuddy(newNameEdit);
|
||||
connect(newNameEdit,SIGNAL(textChanged(QString)),this,SLOT(nameSetted(QString)));
|
||||
|
||||
accept = new QPushButton(tr("Rename"));
|
||||
accept->setDisabled(true);
|
||||
connect(accept,SIGNAL(clicked()),this,SLOT(rename()));
|
||||
|
||||
cancel = new QPushButton(tr("Cancel"));
|
||||
connect(cancel,SIGNAL(clicked()),this,SLOT(close()));
|
||||
|
||||
QHBoxLayout *nameLayout = new QHBoxLayout;
|
||||
|
||||
nameLayout->addWidget(newNameLabel);
|
||||
nameLayout->addWidget(newNameEdit);
|
||||
|
||||
QHBoxLayout *bottomLayout = new QHBoxLayout;
|
||||
bottomLayout->addStretch();
|
||||
bottomLayout->addWidget(accept);
|
||||
bottomLayout->addWidget(cancel);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(nameLayout);
|
||||
mainLayout->addStretch();
|
||||
mainLayout->addLayout(bottomLayout);
|
||||
|
||||
QHBoxLayout * imgMainLayout = new QHBoxLayout;
|
||||
QLabel * imgLabel = new QLabel(this);
|
||||
QPixmap p(":/images/edit.png");
|
||||
imgLabel->setPixmap(p);
|
||||
imgMainLayout->addWidget(imgLabel);
|
||||
imgMainLayout->addLayout(mainLayout);
|
||||
|
||||
setLayout(imgMainLayout);
|
||||
|
||||
setModal(true);
|
||||
setWindowTitle(tr("Rename current library"));
|
||||
}
|
||||
|
||||
void RenameLibraryDialog::rename()
|
||||
{
|
||||
//accept->setEnabled(false);
|
||||
emit(renameLibrary(newNameEdit->text()));
|
||||
}
|
||||
|
||||
void RenameLibraryDialog::nameSetted(const QString & text)
|
||||
{
|
||||
if(!text.isEmpty())
|
||||
accept->setEnabled(true);
|
||||
else
|
||||
accept->setEnabled(false);
|
||||
}
|
||||
|
||||
void RenameLibraryDialog::close()
|
||||
{
|
||||
newNameEdit->clear();
|
||||
//accept->setEnabled(false);
|
||||
QDialog::close();
|
||||
}
|
||||
31
YACReaderLibrary/rename_library_dialog.h
Normal file
31
YACReaderLibrary/rename_library_dialog.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef __RENAME_LIBRARY_DIALOG_H
|
||||
#define __RENAME_LIBRARY_DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
|
||||
|
||||
class RenameLibraryDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RenameLibraryDialog(QWidget * parent = 0);
|
||||
private:
|
||||
QLabel * newNameLabel;
|
||||
QLineEdit * newNameEdit;
|
||||
QPushButton * accept;
|
||||
QPushButton * cancel;
|
||||
void setupUI();
|
||||
public slots:
|
||||
void rename();
|
||||
void close();
|
||||
void nameSetted(const QString & name);
|
||||
signals:
|
||||
void renameLibrary(QString newName);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user