Creada provisionalmente clase Comic2 que evita los problemas de gesti?n de memoria

This commit is contained in:
Luis Ángel San Martín 2012-09-16 11:13:33 +02:00
parent d123df4f53
commit dc6fcf3677
11 changed files with 559 additions and 52 deletions

View File

@ -13,22 +13,31 @@
//-----------------------------------------------------------------------------
Comic::Comic()
:_pages(),_index(0),_path(),_loaded(false),bm(new Bookmarks())
:_pages(),_index(0),_path(),_loaded(false),bm(new Bookmarks()),_loadedPages()
{
setup();
}
//-----------------------------------------------------------------------------
Comic::Comic(const QString pathFile)
:_pages(),_index(0),_path(pathFile),_loaded(false),bm(new Bookmarks())
:_pages(),_index(0),_path(pathFile),_loaded(false),bm(new Bookmarks()),_loadedPages()
{
setup();
loadFromFile(pathFile);
}
//-----------------------------------------------------------------------------
Comic::~Comic()
{
QThread::~QThread();
/*delete _7z;
delete _7ze;
delete bm;*/ //TODO safe delete
}
//-----------------------------------------------------------------------------
void Comic::setup()
{
connect(this,SIGNAL(pageChanged(int)),this,SLOT(checkIsBookmark(int)));
connect(this,SIGNAL(imageLoaded(int)),this,SLOT(updateBookmarkImage(int)));
connect(this,SIGNAL(imageLoaded(int)),this,SLOT(setPageLoaded(int)));
}
//-----------------------------------------------------------------------------
bool Comic::load(const QString & path)
@ -93,6 +102,7 @@ void Comic::run()
int nPages = list.size();
_pages.clear();
_pages.resize(nPages);
_loadedPages = QVector<bool>(nPages,false);
if(nPages==0)
{
QMessageBox::critical(NULL,tr("No images found"),tr("There are not images on the selected folder"));
@ -141,6 +151,7 @@ void Comic::loadSizes()
return;
}
_pages.resize(_sizes.size());
_loadedPages = QVector<bool>(_sizes.size(),false);
emit pageChanged(0); // this indicates new comic, index=0
emit numPages(_pages.size());
@ -298,3 +309,289 @@ void Comic::updateBookmarkImage(int index)
}
}
//-----------------------------------------------------------------------------
void Comic::setPageLoaded(int page)
{
_loadedPages[page] = true;
}
//-----------------------------------------------------------------------------
QByteArray Comic::getRawPage(int page)
{
if(page < 0 || page >= _pages.size())
return QByteArray();
return _pages[page];
}
//-----------------------------------------------------------------------------
bool Comic::pageIsLoaded(int page)
{
if(page < 0 || page >= _pages.size())
return false;
return _loadedPages[page];
}
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
Comic2::Comic2()
:_pages(),_index(0),_path(),_loaded(false),_loadedPages()
{
setup();
}
//-----------------------------------------------------------------------------
Comic2::Comic2(const QString pathFile)
:_pages(),_index(0),_path(pathFile),_loaded(false),_loadedPages()
{
setup();
loadFromFile(pathFile);
}
//-----------------------------------------------------------------------------
Comic2::~Comic2()
{
/*delete _7z;
delete _7ze;
delete bm;*/ //TODO safe delete
}
//-----------------------------------------------------------------------------
void Comic2::setup()
{
connect(this,SIGNAL(pageChanged(int)),this,SLOT(checkIsBookmark(int)));
connect(this,SIGNAL(imageLoaded(int)),this,SLOT(updateBookmarkImage(int)));
connect(this,SIGNAL(imageLoaded(int)),this,SLOT(setPageLoaded(int)));
}
//-----------------------------------------------------------------------------
bool Comic2::load(const QString & path)
{
QFileInfo fi(path);
if(fi.exists())
{
if(fi.isFile())
{
loadFromFile(path);
}
else
{
}
return true;
}
else
{
emit errorOpening();
return false;
}
}
//-----------------------------------------------------------------------------
void Comic2::loadFromFile(const QString & pathFile)
{
_path = QDir::cleanPath(pathFile);
//load files size
_7z = new QProcess();
QStringList attributes;
attributes << "l" << "-ssc-" << "-r" << _path EXTENSIONS;
connect(_7z,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(loadSizes(void)));
connect(_7z,SIGNAL(error(QProcess::ProcessError)),this,SLOT(openingError(QProcess::ProcessError)));
_7z->start(QCoreApplication::applicationDirPath()+"/utils/7z",attributes);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void Comic2::loadSizes()
{
QRegExp rx("[0-9]{4}-[0-9]{2}-[0-9]{2}[ ]+[0-9]{2}:[0-9]{2}:[0-9]{2}[ ]+.{5}[ ]+([0-9]+)[ ]+([0-9]+)[ ]+(.+)");
QByteArray ba = _7z->readAllStandardOutput();
QList<QByteArray> lines = ba.split('\n');
QByteArray line;
QString name;
foreach(line,lines)
{
if(rx.indexIn(QString(line))!=-1)
{
_sizes.push_back(rx.cap(1).toInt());
name = rx.cap(3).trimmed();
_order.push_back(name);
_fileNames.push_back(name);
}
}
if(_sizes.size()==0)
{
//QMessageBox::critical(NULL,tr("File error"),tr("File not found or not images in file"));
emit errorOpening();
return;
}
_pages.resize(_sizes.size());
_loadedPages = QVector<bool>(_sizes.size(),false);
emit pageChanged(0); // this indicates new comic, index=0
emit numPages(_pages.size());
_loaded = true;
_cfi=0;
qSort(_fileNames.begin(),_fileNames.end(), naturalSortLessThanCI);
int i=0;
foreach(name,_fileNames)
{
_newOrder.insert(name,i);
i++;
}
_7ze = new QProcess();
QStringList attributes;
attributes << "e" << "-ssc-" << "-so" << "-r" << _path EXTENSIONS;
connect(_7ze,SIGNAL(error(QProcess::ProcessError)),this,SLOT(openingError(QProcess::ProcessError)));
connect(_7ze,SIGNAL(readyReadStandardOutput()),this,SLOT(loadImages(void)));
connect(_7ze,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(loadFinished(void)));
_7ze->start(QCoreApplication::applicationDirPath()+"/utils/7z",attributes);
}
//-----------------------------------------------------------------------------
void Comic2::loadImages()
{
QByteArray ba = _7ze->readAllStandardOutput();
int s;
int rigthIndex;
while(ba.size()>0)
{
rigthIndex = _newOrder.value(_order[_cfi]);
s = _pages[rigthIndex].size();
_pages[rigthIndex].append(ba.left(_sizes[_cfi]-s));
ba.remove(0,_sizes[_cfi]-s);
if(_pages[rigthIndex].size()==static_cast<int>(_sizes[_cfi]))
{
emit imageLoaded(rigthIndex);
emit imageLoaded(rigthIndex,_pages[rigthIndex]);
_cfi++;
}
}
}
//-----------------------------------------------------------------------------
void Comic2::openingError(QProcess::ProcessError error)
{
switch(error)
{
case QProcess::FailedToStart:
QMessageBox::critical(NULL,tr("7z not found"),tr("7z wasn't found in your PATH."));
break;
case QProcess::Crashed:
QMessageBox::critical(NULL,tr("7z crashed"),tr("7z crashed."));
break;
case QProcess::ReadError:
QMessageBox::critical(NULL,tr("7z reading"),tr("problem reading from 7z"));
break;
case QProcess::UnknownError:
QMessageBox::critical(NULL,tr("7z problem"),tr("Unknown error 7z"));
break;
default:
//TODO
break;
}
_loaded = false;
emit errorOpening();
}
int Comic2::nextPage()
{
if(_index<_pages.size()-1)
_index++;
emit pageChanged(_index);
return _index;
}
//-----------------------------------------------------------------------------
int Comic2::previousPage()
{
if(_index>0)
_index--;
emit pageChanged(_index);
return _index;
}
//-----------------------------------------------------------------------------
void Comic2::setIndex(unsigned int index)
{
if(static_cast<int>(index)<_pages.size()-1)
_index = index;
else
_index = _pages.size()-1;
emit pageChanged(_index);
}
//-----------------------------------------------------------------------------
QPixmap * Comic2::currentPage()
{
QPixmap * p = new QPixmap();
p->loadFromData(_pages[_index]);
return p;
}
//-----------------------------------------------------------------------------
QPixmap * Comic2::operator[](unsigned int index)
{
QPixmap * p = new QPixmap();
p->loadFromData(_pages[index]);
return p;
}
//-----------------------------------------------------------------------------
bool Comic2::loaded()
{
return _loaded;
}
//-----------------------------------------------------------------------------
void Comic2::loadFinished()
{
emit imagesLoaded();
}
//-----------------------------------------------------------------------------
void Comic2::setBookmark()
{
}
//-----------------------------------------------------------------------------
void Comic2::removeBookmark()
{
}
//-----------------------------------------------------------------------------
void Comic2::saveBookmarks()
{
}
//-----------------------------------------------------------------------------
void Comic2::checkIsBookmark(int index)
{
}
//-----------------------------------------------------------------------------
void Comic2::updateBookmarkImage(int index)
{
}
//-----------------------------------------------------------------------------
void Comic2::setPageLoaded(int page)
{
_loadedPages[page] = true;
}
//-----------------------------------------------------------------------------
QByteArray Comic2::getRawPage(int page)
{
if(page < 0 || page >= _pages.size())
return QByteArray();
return _pages[page];
}
//-----------------------------------------------------------------------------
bool Comic2::pageIsLoaded(int page)
{
if(page < 0 || page >= _pages.size())
return false;
return _loadedPages[page];
}

View File

@ -14,6 +14,7 @@
private:
//Comic pages, one QPixmap for each file.
QVector<QByteArray> _pages;
QVector<bool> _loadedPages;
QVector<uint> _sizes;
QStringList _fileNames;
QMap<QString,int> _newOrder;
@ -31,6 +32,7 @@
//Constructors
Comic();
Comic(const QString pathFile);
~Comic();
void setup();
//Load pages from file
bool load(const QString & path);
@ -45,7 +47,9 @@
bool loaded();
QPixmap * operator[](unsigned int index);
QVector<QByteArray> * getRawData(){return &_pages;};
QByteArray getRawPage(int page){return _pages[page];};
QByteArray getRawPage(int page);
bool pageIsLoaded(int page);
public slots:
void loadImages();
void loadSizes();
@ -55,7 +59,8 @@
void removeBookmark();
void saveBookmarks();
void checkIsBookmark(int index);
void updateBookmarkImage(int);
void updateBookmarkImage(int);
void setPageLoaded(int page);
signals:
void imagesLoaded();
void imageLoaded(int index);
@ -68,4 +73,69 @@
};
class Comic2 : public QObject
{
Q_OBJECT
private:
//Comic pages, one QPixmap for each file.
QVector<QByteArray> _pages;
QVector<bool> _loadedPages;
QVector<uint> _sizes;
QStringList _fileNames;
QMap<QString,int> _newOrder;
QVector<QString> _order;
int _index;
QString _path;
bool _loaded;
QProcess * _7z;
QProcess * _7ze;
int _cfi;
QString _pathDir;
public:
//Constructors
Comic2();
Comic2(const QString pathFile);
~Comic2();
void setup();
//Load pages from file
bool load(const QString & path);
void loadFromFile(const QString & pathFile);
int nextPage();
int previousPage();
void setIndex(unsigned int index);
unsigned int getIndex(){return _index;};
unsigned int numPages(){return _pages.size();}
QPixmap * currentPage();
bool loaded();
QPixmap * operator[](unsigned int index);
QVector<QByteArray> * getRawData(){return &_pages;};
QByteArray getRawPage(int page);
bool pageIsLoaded(int page);
public slots:
void loadImages();
void loadSizes();
void openingError(QProcess::ProcessError error);
void loadFinished();
void setBookmark();
void removeBookmark();
void saveBookmarks();
void checkIsBookmark(int index);
void updateBookmarkImage(int);
void setPageLoaded(int page);
signals:
void imagesLoaded();
void imageLoaded(int index);
void imageLoaded(int index,const QByteArray & image);
void pageChanged(int index);
void numPages(unsigned int numPages);
void errorOpening();
void isBookmark(bool);
void bookmarksLoaded(const Bookmarks &);
};
#endif

View File

@ -10,24 +10,68 @@ extern LibraryWindow * mw;
#include "comic_db.h"
#include "comic.h"
Synchronizer::Synchronizer(Comic2 * c,QString p,QThread * f)
:QThread(),comic(c),path(p),from(f)
{
}
void Synchronizer::run()
{
connect(comic,SIGNAL(numPages(unsigned int)),this,SLOT(waitedSignal()));
loaded = comic->load(path);
}
void Synchronizer::waitedSignal()
{
if(loaded)
{
comic->moveToThread(from);
quit();
}
else
{
exit(-1);
}
}
ComicController::ComicController() {}
void ComicController::service(HttpRequest& request, HttpResponse& response)
{
HttpSession session=Static::sessionStore->getSession(request,response);
QStringList pathElements = ((QString)request.getPath()).split('/');
QString libraryName = pathElements.at(2);
qulonglong comicId = pathElements.at(4).toULongLong();
//TODO
//if(pathElements.size() == 6)
//{
// QString action = pathElements.at(5);
// if(!action.isEmpty() && (action == "close"))
// {
// session.dismissCurrentComic();
// response.write("",true);
// return;
// }
//}
QMap<QString,QString> libraries = mw->getLibraries();
ComicDB comic = mw->getComicInfo(libraryName, comicId);
Comic * comicFile = new Comic;
Comic2 * comicFile = new Comic2;
//Synchronizer * synchronizer = new Synchronizer(comicFile,libraries.value(libraryName)+comic.path, this->thread());
//comicFile->moveToThread(synchronizer);
//synchronizer->start();
//QApplication::instance()->exec();
//synchronizer->wait(20000);
if(comicFile->load(libraries.value(libraryName)+comic.path))
{
session.setCurrentComic(comic.id, comicFile);
@ -45,10 +89,6 @@ void ComicController::service(HttpRequest& request, HttpResponse& response)
response.setStatus(404,"not found");
response.write("404 not found",true);
}
//response.write(t.toLatin1(),true);
}

View File

@ -5,11 +5,14 @@
#include "httpresponse.h"
#include "httprequesthandler.h"
#include <QThread>
class Comic2;
class QString;
class ComicController : public HttpRequestHandler {
Q_OBJECT
Q_DISABLE_COPY(ComicController);
public:
/** Constructor */
ComicController();
@ -17,4 +20,21 @@ public:
void service(HttpRequest& request, HttpResponse& response);
};
class Synchronizer : public QThread
{
Q_OBJECT
public:
Synchronizer(Comic2 * c, QString p, QThread * f);
bool loaded;
private:
Comic2 * comic;
QString path;
QThread * from;
void run();
public slots:
void waitedSignal();
};
#endif // COMICCONTROLLER_H

View File

@ -16,6 +16,8 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
HttpSession session=Static::sessionStore->getSession(request,response);
QString y = session.get("xxx").toString();
response.writeText(QString("session xxx : %1 <br/>").arg(y));
@ -29,16 +31,36 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
QList<LibraryItem *> folderComics = mw->getFolderComicsFromLibrary(libraryName,parentId);
qulonglong backId = mw->getParentFromComicFolderId(libraryName,parentId);
if(backId == 1 && parentId == 1)
t.setVariable(QString("upurl"),"/");
else
t.setVariable(QString("upurl"),"/library/" + libraryName + "/folder/" +QString("%1").arg(backId));
int page = 0;
QByteArray p = request.getParameter("page");
if(p.length() != 0)
page = p.toInt();
// /comicIdi/pagei/comicIdj/pagej/....../comicIdn/pagen
//QString currentPath = session.get("currentPath").toString();
//QStringList pathSize = currentPath.split("/").last().toInt;
if(backId == 1 && parentId == 1)
t.setVariable(QString("upurl"),"/?page=0");
else
t.setVariable(QString("upurl"),"/library/" + libraryName + "/folder/" +QString("%1").arg(backId));//.arg(upPage));
/*if(currentPath.length()>0)
{
if(currentPath.contains(QString("%1").arg(parentId))
{
}
else
{
session.set("currentPath",currentPath+QString("/%1/%2").arg(parentId).arg(page);
}
}*/
//t.loop("element",folderContent.length());
int elementsPerPage = 10;

View File

@ -3,37 +3,62 @@
#include "../static.h"
#include "comic.h"
#include "comiccontroller.h"
#include <QDataStream>
#include <QPointer>
PageController::PageController() {}
void PageController::service(HttpRequest& request, HttpResponse& response)
{
HttpSession session=Static::sessionStore->getSession(request,response);
QStringList pathElements = ((QString)request.getPath()).split('/');
QString libraryName = pathElements.at(2);
qulonglong comicId = pathElements.at(4).toULongLong();
quint16 page = pathElements.at(6).toUInt();
unsigned int page = pathElements.at(6).toUInt();
Comic * comicFile = session.getCurrentComic();
if((comicFile != 0) && comicId == session.getCurrentComicId())
Comic2 * comicFile = session.getCurrentComic();
if(session.getCurrentComicId() != 0 && !QPointer<Comic2>(comicFile).isNull())
{
response.setHeader("Content-Type", "image/page");
QByteArray pageData = comicFile->getRawPage(page);
response.write(pageData);
if(comicId == session.getCurrentComicId() && page < comicFile->numPages())
{
if(comicFile->pageIsLoaded(page))
{
response.setHeader("Content-Type", "yacreader/page");
QByteArray pageData = comicFile->getRawPage(page);
QDataStream data(pageData);
int i=0;
char buffer[65536];
while (!data.atEnd()) {
int len = data.readRawData(buffer,65536);
response.write(QByteArray(buffer,len));
}
//response.write(pageData);
}
else
{
response.setStatus(404,"not found"); //TODO qué mensaje enviar
response.write("404 not found",true);
}
}
else
{
if(comicId != session.getCurrentComicId())
{
//delete comicFile;
session.dismissCurrentComic();
}
response.setStatus(404,"not found"); //TODO qué mensaje enviar
response.write("404 not found",true);
}
}
else
{
delete comicFile;
response.setStatus(404,"not found");
response.write("404 not found",true);
}
//response.write(t.toLatin1(),true);
}

View File

@ -15,6 +15,7 @@ HttpSession::HttpSession(bool canStore) {
dataPtr->lastAccess=QDateTime::currentMSecsSinceEpoch();
dataPtr->id=QUuid::createUuid().toString().toAscii();
dataPtr->yacreaderSessionData.comic = 0;
dataPtr->yacreaderSessionData.comicId = 0;
#ifdef SUPERVERBOSE
qDebug("HttpSession: created new session data with id %s",dataPtr->id.data());
#endif
@ -180,7 +181,7 @@ qulonglong HttpSession::getCurrentComicId()
else
return 0;
}
Comic * HttpSession::getCurrentComic()
Comic2* HttpSession::getCurrentComic()
{
if(dataPtr)
{
@ -196,6 +197,7 @@ void HttpSession::dismissCurrentComic()
if(dataPtr->yacreaderSessionData.comic != 0)
{
delete dataPtr->yacreaderSessionData.comic;
dataPtr->yacreaderSessionData.comic = 0;
}
dataPtr->yacreaderSessionData.comicId = 0;
}
@ -215,7 +217,7 @@ void HttpSession::setDownloadedComic(const QString & hash)
dataPtr->yacreaderSessionData.downloadedComics.insert(hash);
}
}
void HttpSession::setCurrentComic(qulonglong id, Comic * comic)
void HttpSession::setCurrentComic(qulonglong id, Comic2 * comic)
{
if(dataPtr)
{

View File

@ -12,7 +12,7 @@
#include <QSet>
#include <QString>
class Comic;
#include "comic.h"
/**
This class stores data for a single HTTP session.
@ -96,12 +96,12 @@ public:
bool isComicOnDevice(const QString & hash);
bool isComicDownloaded(const QString & hash);
qulonglong getCurrentComicId();
Comic * getCurrentComic();
Comic2 * getCurrentComic();
void dismissCurrentComic();
void setComicsOnDevice(const QSet<QString> & set);
void setDownloadedComic(const QString & hash);
void setCurrentComic(qulonglong id, Comic * comic);
void setCurrentComic(qulonglong id, Comic2 * comic);
private:
@ -112,7 +112,7 @@ private:
QSet<QString> downloadedComics;
//cómic actual que está siendo descargado
qulonglong comicId;
Comic * comic;
Comic2 * comic;
};
struct HttpSessionData {

View File

@ -1,19 +1,32 @@
<html>
<body>
<h1>Folder</h1>
<a href="{upurl}">up</a>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<link rel="stylesheet" href="/css/reset.css" type="text/css" />
<link rel="stylesheet" href="/css/styles.css" type="text/css" />
<title>Login</title>
</head>
<body>
<div id="content">
<h1>BROWSE AND IMPORT</h1>
<h2>nombre folder?</h2>
<a href="/">Libraries</a> <a href="{upurl}">up</a>
<!--<a href="javascript:javascript:history.go(-1)">up</a>-->
<ul id="itemContainer">
{loop element}
<li><a href="{element.url}">{element.name}</a> - <a href="{element.downloadurl}">Download</a></li>
<li><img style="width: 92px" src="/images/f.png"/><a href="{element.url}">{element.name}</a> - <a href="{element.downloadurl}">Download</a></li>
{end element}
{loop elementcomic}
<li><img style="width: 100px" src="{elementcomic.coverulr}" /> <a href="{elementcomic.url}">{elementcomic.name}</a></li>
<li><img style="width: 80px" src="{elementcomic.coverulr}" /> <a href="{elementcomic.url}">{elementcomic.name}</a></li>
{end elementcomic}
</ul>
<div>{loop page} <a href="{page.url}"> {page.number} </a> {end page}</div>
</body>
</html>
</div>
<div class="sombra">&nbsp;</div>
</body>
</html>

View File

@ -1,7 +1,14 @@
<html>
<body>
<h1>Bibliotecas</h1>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<link rel="stylesheet" href="/css/reset.css" type="text/css" />
<link rel="stylesheet" href="/css/styles.css" type="text/css" />
<title>Login</title>
</head>
<body>
<div id="content">
<h1>BIBLIOTECAS</h1>
<h2>Selecciona una biblioteca</h2>
<p>
<ul>
{loop library}
@ -9,5 +16,7 @@
{end library}
</ul>
</p>
</div>
<div class="sombra">&nbsp;</div>
</body>
</html>

View File

@ -1,7 +1,14 @@
<html>
<body>
<h1>Libraries</h1>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<link rel="stylesheet" href="/css/reset.css" type="text/css" />
<link rel="stylesheet" href="/css/styles.css" type="text/css" />
<title>Login</title>
</head>
<body>
<div id="content">
<h1>LIBRARIES</h1>
<h2>Select a comic library</h2>
<p>
<ul>
{loop library}
@ -9,5 +16,7 @@
{end library}
</ul>
</p>
</div>
<div class="sombra">&nbsp;</div>
</body>
</html>