From 79fe9a3f2d7c4f258ec9e71386972a26d0ab644a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 21 Jul 2013 23:18:50 +0200 Subject: [PATCH] Reading status added sending comic info to yacreaderlibrary on openNext/openPrevious --- YACReader/main_window_viewer.cpp | 23 ++- YACReader/main_window_viewer.h | 1 + YACReaderLibrary/comic_flow_widget.cpp | 12 +- YACReaderLibrary/comic_flow_widget.h | 12 +- YACReaderLibrary/db/tablemodel.cpp | 166 ++++++++++++-------- YACReaderLibrary/db/tablemodel.h | 8 +- YACReaderLibrary/images.qrc | 1 + YACReaderLibrary/library_window.cpp | 30 ++-- YACReaderLibrary/library_window.h | 6 +- YACReaderLibrary/main.cpp | 2 +- YACReaderLibrary/yacreader_local_server.cpp | 2 +- YACReaderLibrary/yacreader_local_server.h | 2 +- common/pictureflow.cpp | 14 +- common/pictureflow.h | 7 +- common/yacreader_flow_gl.cpp | 17 +- common/yacreader_flow_gl.h | 7 +- common/yacreader_global.h | 7 + images/readRibbon.png | Bin 8481 -> 7963 bytes images/readingRibbon.png | Bin 0 -> 6603 bytes 19 files changed, 196 insertions(+), 121 deletions(-) create mode 100644 images/readingRibbon.png diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 8be8be79..8d9d2aa4 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -171,7 +171,7 @@ void MainWindowViewer::setupUI() QString pathFile = QCoreApplication::arguments().at(1); currentDirectory = pathFile; quint64 comicId = QCoreApplication::arguments().at(2).toULongLong(); - quint64 libraryId = QCoreApplication::arguments().at(3).toULongLong(); + libraryId = QCoreApplication::arguments().at(3).toULongLong(); int page = QCoreApplication::arguments().at(4).toULongLong(); enableActions(); @@ -848,7 +848,7 @@ void MainWindowViewer::closeEvent ( QCloseEvent * event ) currentComicDB.info.currentPage = viewer->getCurrentPageNumber()+1; currentComicDB.info.hasBeenOpened = true; //viewer->getBookmarks(); - client.sendComicInfo(0,currentComicDB); + client.sendComicInfo(libraryId,currentComicDB); } viewer->save(); @@ -865,8 +865,18 @@ void MainWindowViewer::closeEvent ( QCloseEvent * event ) void MainWindowViewer::openPreviousComic() { + YACReaderLocalClient client; if(!siblingComics.isEmpty()) { + + if(isClient) + { + currentComicDB.info.currentPage = viewer->getCurrentPageNumber()+1; + currentComicDB.info.hasBeenOpened = true; + //viewer->getBookmarks(); + client.sendComicInfo(libraryId,currentComicDB); + } + int currentIndex = siblingComics.indexOf(currentComicDB); if (currentIndex == -1) return; @@ -889,8 +899,17 @@ void MainWindowViewer::openPreviousComic() void MainWindowViewer::openNextComic() { + YACReaderLocalClient client; if(!siblingComics.isEmpty()) { + if(isClient) + { + currentComicDB.info.currentPage = viewer->getCurrentPageNumber()+1; + currentComicDB.info.hasBeenOpened = true; + //viewer->getBookmarks(); + client.sendComicInfo(libraryId,currentComicDB); + } + int currentIndex = siblingComics.indexOf(currentComicDB); if (currentIndex == -1) return; diff --git a/YACReader/main_window_viewer.h b/YACReader/main_window_viewer.h index ea762dca..cf832924 100644 --- a/YACReader/main_window_viewer.h +++ b/YACReader/main_window_viewer.h @@ -122,6 +122,7 @@ class YACReaderSliderAction; ComicDB currentComicDB; QList siblingComics; bool isClient; + quint64 libraryId; signals: void closed(); protected: diff --git a/YACReaderLibrary/comic_flow_widget.cpp b/YACReaderLibrary/comic_flow_widget.cpp index 2a2263c6..4e2b101a 100644 --- a/YACReaderLibrary/comic_flow_widget.cpp +++ b/YACReaderLibrary/comic_flow_widget.cpp @@ -47,7 +47,7 @@ void ComicFlowWidgetSW::setShowMarks(bool value) { flow->setShowMarks(value); } -void ComicFlowWidgetSW::setMarks(QVector marks) +void ComicFlowWidgetSW::setMarks(QVector marks) { flow->setMarks(marks); } @@ -55,9 +55,9 @@ void ComicFlowWidgetSW::setMarkImage(QImage & image) { flow->setMarkImage(image); } -void ComicFlowWidgetSW::markSlide(int index) +void ComicFlowWidgetSW::markSlide(int index, YACReaderComicReadStatus status) { - flow->markSlide(index); + flow->markSlide(index,status); } void ComicFlowWidgetSW::unmarkSlide(int index) { @@ -181,7 +181,7 @@ void ComicFlowWidgetGL::setShowMarks(bool value) { flow->setShowMarks(value); } -void ComicFlowWidgetGL::setMarks(QVector marks) +void ComicFlowWidgetGL::setMarks(QVector marks) { flow->setMarks(marks); } @@ -189,9 +189,9 @@ void ComicFlowWidgetGL::setMarkImage(QImage & image) { flow->setMarkImage(image); } -void ComicFlowWidgetGL::markSlide(int index) +void ComicFlowWidgetGL::markSlide(int index, YACReaderComicReadStatus status) { - flow->markSlide(index); + flow->markSlide(index,status); } void ComicFlowWidgetGL::unmarkSlide(int index) { diff --git a/YACReaderLibrary/comic_flow_widget.h b/YACReaderLibrary/comic_flow_widget.h index bbea3503..028d9177 100644 --- a/YACReaderLibrary/comic_flow_widget.h +++ b/YACReaderLibrary/comic_flow_widget.h @@ -16,9 +16,9 @@ public: public slots: virtual void setShowMarks(bool value) = 0; - virtual void setMarks(QVector marks) = 0; + virtual void setMarks(QVector marks) = 0; virtual void setMarkImage(QImage & image) = 0; - virtual void markSlide(int index) = 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; @@ -46,9 +46,9 @@ public: ComicFlowWidgetSW(QWidget * parent = 0); void setShowMarks(bool value); - void setMarks(QVector marks); + void setMarks(QVector marks); void setMarkImage(QImage & image); - void markSlide(int index); + void markSlide(int index, YACReaderComicReadStatus status); void unmarkSlide(int index); void setSlideSize(QSize size); void clear(); @@ -82,9 +82,9 @@ public: ComicFlowWidgetGL(QWidget * parent = 0); void setShowMarks(bool value); - void setMarks(QVector marks); + void setMarks(QVector marks); void setMarkImage(QImage & image); - void markSlide(int index); + void markSlide(int index, YACReaderComicReadStatus status); void unmarkSlide(int index); void setSlideSize(QSize size); void clear(); diff --git a/YACReaderLibrary/db/tablemodel.cpp b/YACReaderLibrary/db/tablemodel.cpp index 01b72710..b8154751 100644 --- a/YACReaderLibrary/db/tablemodel.cpp +++ b/YACReaderLibrary/db/tablemodel.cpp @@ -10,19 +10,22 @@ #include "db_helper.h" //ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read -#define NUMBER 0 -#define TITLE 1 -#define FILE_NAME 2 -#define NUM_PAGES 3 -#define ID 4 -#define PARENT_ID 5 -#define PATH 6 -#define HASH 7 -#define READ 8 -#define IS_BIS 9 -#define CURRENT_PAGE 10 -#define RATING 11 -#define HAS_BEEN_OPENED 12 +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 +}; + TableModel::TableModel(QObject *parent) : QAbstractItemModel(parent) @@ -61,7 +64,7 @@ QVariant TableModel::data(const QModelIndex &index, int role) const if (!index.isValid()) return QVariant(); - if (index.column() == RATING && role == Qt::DecorationRole) + if (index.column() == Columns::Rating && role == Qt::DecorationRole) { TableItem *item = static_cast(index.internalPointer()); return QPixmap(QString(":/images/rating%1.png").arg(item->data(index.column()).toInt())); @@ -82,7 +85,7 @@ QVariant TableModel::data(const QModelIndex &index, int role) const return QVariant(Qt::AlignRight | Qt::AlignVCenter); case 7: return QVariant(Qt::AlignRight | Qt::AlignVCenter); - case CURRENT_PAGE: + case Columns::CurrentPage: return QVariant(Qt::AlignRight | Qt::AlignVCenter); default: return QVariant(Qt::AlignLeft | Qt::AlignVCenter); @@ -94,14 +97,14 @@ QVariant TableModel::data(const QModelIndex &index, int role) const return QVariant(); TableItem *item = static_cast(index.internalPointer()); - if(index.column() == HASH) + if(index.column() == Columns::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() == READ) - return item->data(index.column()).toBool()?QVariant(tr("yes")):QVariant(tr("no")); - if(index.column() == CURRENT_PAGE) - return item->data(HAS_BEEN_OPENED).toBool()?item->data(index.column()):QVariant("-"); + if(index.column() == Columns::ReadColumn) + return (item->data(Columns::CurrentPage).toInt()==item->data(Columns::NumPages).toInt() || item->data(Columns::ReadColumn).toBool())?QVariant(tr("yes")):QVariant(tr("no")); + if(index.column() == Columns::CurrentPage) + return item->data(Columns::HasBeenOpened).toBool()?item->data(index.column()):QVariant("-"); - if (index.column() == RATING) + if (index.column() == Columns::Rating) return QVariant(); return item->data(index.column()); @@ -138,9 +141,9 @@ QVariant TableModel::headerData(int section, Qt::Orientation orientation, return QVariant(QString(tr("Size"))); case 8: return QVariant(QString(tr("Read"))); - case CURRENT_PAGE: + case Columns::CurrentPage: return QVariant(QString(tr("Current Page"))); - case RATING: + case Columns::Rating: return QVariant(QString(tr("Rating"))); } } @@ -155,7 +158,7 @@ QVariant TableModel::headerData(int section, Qt::Orientation orientation, return QVariant(Qt::AlignRight | Qt::AlignVCenter); case 7: return QVariant(Qt::AlignRight | Qt::AlignVCenter); - case CURRENT_PAGE: + case Columns::CurrentPage: return QVariant(Qt::AlignRight | Qt::AlignVCenter); default: return QVariant(Qt::AlignLeft | Qt::AlignVCenter); @@ -165,7 +168,7 @@ QVariant TableModel::headerData(int section, Qt::Orientation orientation, if(orientation == Qt::Vertical && role == Qt::DecorationRole) { - QString fileName = _data.value(section)->data(FILE_NAME).toString(); + QString fileName = _data.value(section)->data(Columns::FileName).toString(); QFileInfo fi(fileName); QString ext = fi.suffix(); @@ -233,7 +236,7 @@ QStringList TableModel::getPaths(const QString & _source) QList::ConstIterator itr; for(itr = _data.constBegin();itr != _data.constEnd();itr++) { - QString hash = (*itr)->data(HASH).toString(); + QString hash = (*itr)->data(Columns::Hash).toString(); paths << source+ hash +".jpg"; } @@ -276,7 +279,7 @@ void TableModel::setupModelData(unsigned long long int folderId,const QString & QString TableModel::getComicPath(QModelIndex mi) { if(mi.isValid()) - return _data.at(mi.row())->data(PATH).toString(); + return _data.at(mi.row())->data(Columns::Path).toString(); return ""; } #define NUMBER_MAX 99999999 @@ -297,16 +300,16 @@ void TableModel::setupModelData(QSqlQuery &sqlquery) else { TableItem * last = _data.back(); - QString nameLast = last->data(FILE_NAME).toString(); - QString nameCurrent = currentItem->data(FILE_NAME).toString(); + QString nameLast = last->data(Columns::FileName).toString(); + QString nameCurrent = currentItem->data(Columns::FileName).toString(); int numberLast,numberCurrent; numberLast = numberCurrent = NUMBER_MAX; //TODO change by std limit - if(!last->data(NUMBER).isNull()) - numberLast = last->data(NUMBER).toInt(); + if(!last->data(Columns::Number).isNull()) + numberLast = last->data(Columns::Number).toInt(); - if(!currentItem->data(NUMBER).isNull()) - numberCurrent = currentItem->data(NUMBER).toInt(); + if(!currentItem->data(Columns::Number).isNull()) + numberCurrent = currentItem->data(Columns::Number).toInt(); QList::iterator i; i = _data.end(); @@ -319,8 +322,8 @@ void TableModel::setupModelData(QSqlQuery &sqlquery) i--; numberLast = NUMBER_MAX; //TODO change by std limit - if(!(*i)->data(NUMBER).isNull()) - numberLast = (*i)->data(NUMBER).toInt(); + if(!(*i)->data(Columns::Number).isNull()) + numberLast = (*i)->data(Columns::Number).toInt(); } } else @@ -328,11 +331,11 @@ void TableModel::setupModelData(QSqlQuery &sqlquery) while ((lessThan = naturalSortLessThanCI(nameCurrent,nameLast)) && i != _data.begin() && numberLast == 99999999) { i--; - nameLast = (*i)->data(FILE_NAME).toString(); + nameLast = (*i)->data(Columns::FileName).toString(); numberLast = NUMBER_MAX; //TODO change by std limit - if(!(*i)->data(NUMBER).isNull()) - numberLast = (*i)->data(NUMBER).toInt(); + if(!(*i)->data(Columns::Number).isNull()) + numberLast = (*i)->data(Columns::Number).toInt(); } } @@ -341,7 +344,7 @@ void TableModel::setupModelData(QSqlQuery &sqlquery) if(numberCurrent != NUMBER_MAX) { if(numberCurrent == numberLast) - if(currentItem->data(IS_BIS).toBool()) + if(currentItem->data(Columns::IsBis).toBool()) { _data.insert(++i,currentItem); } @@ -365,7 +368,7 @@ void TableModel::setupModelData(QSqlQuery &sqlquery) ComicDB TableModel::getComic(const QModelIndex & mi) { QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); - ComicDB c = DBHelper::loadComic(_data.at(mi.row())->data(ID).toULongLong(),db); + ComicDB c = DBHelper::loadComic(_data.at(mi.row())->data(Columns::Id).toULongLong(),db); db.close(); QSqlDatabase::removeDatabase(_databasePath); @@ -375,7 +378,7 @@ ComicDB TableModel::getComic(const QModelIndex & mi) ComicDB TableModel::_getComic(const QModelIndex & mi) { QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); - ComicDB c = DBHelper::loadComic(_data.at(mi.row())->data(ID).toULongLong(),db); + ComicDB c = DBHelper::loadComic(_data.at(mi.row())->data(Columns::Id).toULongLong(),db); db.close(); QSqlDatabase::removeDatabase(_databasePath); @@ -383,36 +386,53 @@ ComicDB TableModel::_getComic(const QModelIndex & mi) } -QVector TableModel::getReadList() +QVector TableModel::getReadList() { int numComics = _data.count(); - QVector readList(numComics); + QVector readList(numComics); for(int i=0;idata(READ).toBool(); + if(_data.value(i)->data(Columns::ReadColumn).toBool()) + readList[i] = YACReaderComicReadStatus::Read; + else if (_data.value(i)->data(Columns::CurrentPage).toInt() == _data.value(i)->data(Columns::NumPages).toInt()) + readList[i] = YACReaderComicReadStatus::Read; + else if (_data.value(i)->data(Columns::HasBeenOpened).toBool()) + readList[i] = YACReaderComicReadStatus::Opened; + else + readList[i] = YACReaderComicReadStatus::Unread; } return readList; } - -QVector TableModel::setAllComicsRead(bool read) +//TODO check other read status +QVector TableModel::setAllComicsRead(YACReaderComicReadStatus read) { QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); db.transaction(); int numComics = _data.count(); - QVector readList(numComics); + QVector readList(numComics); for(int i=0;isetData(READ,QVariant(read)); - ComicDB c = DBHelper::loadComic(_data.value(i)->data(ID).toULongLong(),db); - c.info.read = read; - DBHelper::update(&(c.info),db); + readList[i] = read; + if(read == YACReaderComicReadStatus::Read) + { + _data.value(i)->setData(Columns::ReadColumn,QVariant(true)); + ComicDB c = DBHelper::loadComic(_data.value(i)->data(Columns::Id).toULongLong(),db); + c.info.read = true; + DBHelper::update(&(c.info),db); + } + if(read == YACReaderComicReadStatus::Unread) + { + _data.value(i)->setData(Columns::ReadColumn,QVariant(false)); + ComicDB c = DBHelper::loadComic(_data.value(i)->data(Columns::Id).toULongLong(),db); + c.info.read = false; + DBHelper::update(&(c.info),db); + } } db.commit(); db.close(); QSqlDatabase::removeDatabase(_databasePath); - emit dataChanged(index(0,READ),index(numComics-1,READ)); + emit dataChanged(index(0,Columns::ReadColumn),index(numComics-1,Columns::ReadColumn)); return readList; } @@ -426,7 +446,7 @@ QList TableModel::getAllComics() int numComics = _data.count(); for(int i=0;idata(ID).toULongLong(),db)); + comics.append(DBHelper::loadComic(_data.value(i)->data(Columns::Id).toULongLong(),db)); } db.commit(); @@ -452,23 +472,33 @@ QList TableModel::getComics(QList list) QSqlDatabase::removeDatabase(_databasePath); return comics; } - -QVector TableModel::setComicsRead(QList list,bool read) +//TODO +QVector TableModel::setComicsRead(QList list,YACReaderComicReadStatus read) { QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); db.transaction(); foreach (QModelIndex mi, list) { - _data.value(mi.row())->setData(READ, QVariant(read)); - ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ID).toULongLong(),db); - c.info.read = read; + if(read == YACReaderComicReadStatus::Read) + { + _data.value(mi.row())->setData(Columns::ReadColumn, QVariant(true)); + ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(Columns::Id).toULongLong(),db); + c.info.read = true; DBHelper::update(&(c.info),db); + } + if(read == YACReaderComicReadStatus::Unread) + { + _data.value(mi.row())->setData(Columns::ReadColumn, QVariant(false)); + ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(Columns::Id).toULongLong(),db); + c.info.read = false; + DBHelper::update(&(c.info),db); + } } db.commit(); db.close(); QSqlDatabase::removeDatabase(_databasePath); - emit dataChanged(index(list.first().row(),READ),index(list.last().row(),READ)); + emit dataChanged(index(list.first().row(),Columns::ReadColumn),index(list.last().row(),Columns::ReadColumn)); return getReadList(); } @@ -476,11 +506,11 @@ qint64 TableModel::asignNumbers(QList list,int startingNumber) { QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); db.transaction(); - qint64 idFirst = _data.value(list[0].row())->data(ID).toULongLong(); + qint64 idFirst = _data.value(list[0].row())->data(Columns::Id).toULongLong(); int i = 0; foreach (QModelIndex mi, list) { - ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ID).toULongLong(),db); + ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(Columns::Id).toULongLong(),db); c.info.setNumber(startingNumber+i); c.info.edited = true; DBHelper::update(&(c.info),db); @@ -501,7 +531,7 @@ QModelIndex TableModel::getIndexFromId(quint64 id) int i=0; for(itr = _data.constBegin();itr != _data.constEnd();itr++) { - if((*itr)->data(ID).toULongLong() == id) + if((*itr)->data(Columns::Id).toULongLong() == id) break; i++; } @@ -527,7 +557,7 @@ void TableModel::finishTransaction() void TableModel::removeInTransaction(int row) { - ComicDB c = DBHelper::loadComic(_data.at(row)->data(ID).toULongLong(),dbTransaction); + ComicDB c = DBHelper::loadComic(_data.at(row)->data(Columns::Id).toULongLong(),dbTransaction); DBHelper::removeFromDB(&c,dbTransaction); beginRemoveRows(QModelIndex(),row,row); @@ -570,16 +600,16 @@ void TableModel::reload(const ComicDB & comic) bool found = false; foreach(TableItem * item,_data) { - if(item->data(ID).toULongLong() == comic.id) + if(item->data(Columns::Id).toULongLong() == comic.id) { found = true; - item->setData(CURRENT_PAGE,comic.info.currentPage); - item->setData(HAS_BEEN_OPENED,true); + item->setData(Columns::CurrentPage,comic.info.currentPage); + item->setData(Columns::HasBeenOpened,true); break; } row++; } if(found) - emit dataChanged(index(row,CURRENT_PAGE),index(row,CURRENT_PAGE)); + emit dataChanged(index(row,Columns::CurrentPage),index(row,Columns::CurrentPage)); } \ No newline at end of file diff --git a/YACReaderLibrary/db/tablemodel.h b/YACReaderLibrary/db/tablemodel.h index 90902009..76dd4e9b 100644 --- a/YACReaderLibrary/db/tablemodel.h +++ b/YACReaderLibrary/db/tablemodel.h @@ -7,6 +7,8 @@ #include #include +#include "yacreader_global.h" + class ComicDB; class TableItem; @@ -38,15 +40,15 @@ public: QString getComicPath(QModelIndex mi); ComicDB getComic(const QModelIndex & mi); //--> para la edición ComicDB getComic(int row); - QVector getReadList(); - QVector setAllComicsRead(bool read); + QVector getReadList(); + QVector setAllComicsRead(YACReaderComicReadStatus readStatus); QList getComics(QList list); //--> recupera la información común a los comics seleccionados QList getAllComics(); QModelIndex getIndexFromId(quint64 id); //setcomicInfo(QModelIndex & mi); --> inserta en la base datos //setComicInfoForAllComics(); --> inserta la información común a todos los cómics de una sola vez. //setComicInfoForSelectedComis(QList list); -->inserta la información común para los comics seleccionados - QVector setComicsRead(QList list,bool read); + QVector setComicsRead(QList list,YACReaderComicReadStatus read); qint64 asignNumbers(QList list,int startingNumber); void remove(ComicDB * comic, int row); void removeInTransaction(int row); diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index 7014df9d..1ca334b3 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -53,6 +53,7 @@ ../images/clearSearch.png ../images/iconSearch.png ../images/readRibbon.png + ../images/readingRibbon.png ../images/shownCovers.png ../images/hiddenCovers.png ../images/trash.png diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index e7d516f8..5c1507b8 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -1017,42 +1017,47 @@ void LibraryWindow::openComic() #ifdef Q_OS_MAC QProcess::startDetached("open", QStringList() << "-n" << QDir::cleanPath(QCoreApplication::applicationDirPath()+"/../../../YACReader.app") << "--args" << path << comicId << libraryId << page);//,QStringList() << path); - //Comic is readed #else QProcess::startDetached(QDir::cleanPath(QCoreApplication::applicationDirPath())+QString("/YACReader \"%1\" \"%2\" \"%3\" \"%4\"").arg(path).arg(comicId).arg(libraryId).arg(page),QStringList()); #endif //Comic is readed - setCurrentComicReaded(); + //setCurrentComicReaded(); + setCurrentComicOpened(); } } -void LibraryWindow::setCurrentComicsStatusReaded(bool readed) +void LibraryWindow::setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus) { - comicFlow->setMarks(dmCV->setComicsRead(getSelectedComics(),readed)); + comicFlow->setMarks(dmCV->setComicsRead(getSelectedComics(),readStatus)); comicFlow->updateMarks(); } void LibraryWindow::setCurrentComicReaded() { - this->setCurrentComicsStatusReaded(true); + this->setCurrentComicsStatusReaded(YACReaderComicReadStatus::Read); +} + +void LibraryWindow::setCurrentComicOpened() +{ + } void LibraryWindow::setComicsReaded() { - comicFlow->setMarks(dmCV->setAllComicsRead(true)); + comicFlow->setMarks(dmCV->setAllComicsRead(YACReaderComicReadStatus::Read)); comicFlow->updateMarks(); } void LibraryWindow::setCurrentComicUnreaded() { - this->setCurrentComicsStatusReaded(false); + this->setCurrentComicsStatusReaded(YACReaderComicReadStatus::Unread); } void LibraryWindow::setComicsUnreaded() { - comicFlow->setMarks(dmCV->setAllComicsRead(false)); + comicFlow->setMarks(dmCV->setAllComicsRead(YACReaderComicReadStatus::Unread)); comicFlow->updateMarks(); } @@ -1689,7 +1694,12 @@ void LibraryWindow::importLibraryPackage() importLibraryDialog->show(libraries); } -void LibraryWindow::updateComicsView(const ComicDB & comic) +void LibraryWindow::updateComicsView(quint64 libraryId, const ComicDB & comic) { - dmCV->reload(comic); + //TODO comprobar la biblioteca.... + if(libraryId == selectedLibrary->currentIndex()) + { + dmCV->reload(comic); + comicFlow->setMarks(dmCV->getReadList()); + } } \ No newline at end of file diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index cd570b98..7081302b 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -5,6 +5,7 @@ #include #include #include +#include "yacreader_global.h" class QTreeView; class QDirModel; @@ -238,7 +239,7 @@ public: void exportLibrary(QString destPath); void importLibrary(QString clc,QString destPath,QString name); void reloadOptions(); - void setCurrentComicsStatusReaded(bool readed); + void setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus); void setCurrentComicReaded(); void setCurrentComicUnreaded(); void setComicsReaded(); @@ -261,7 +262,8 @@ public: void updateHistory(const QModelIndex & mi); void libraryAlreadyExists(const QString & name); void importLibraryPackage(); - void updateComicsView(const ComicDB & comic); + void updateComicsView(quint64 libraryId, const ComicDB & comic); + void setCurrentComicOpened(); }; diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index 0f5f6e31..22875a11 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -49,7 +49,7 @@ int main( int argc, char ** argv ) LibraryWindow * mw = new LibraryWindow(); - mw->connect(localServer,SIGNAL(comicUpdated(const ComicDB &)),mw,SLOT(updateComicsView(const ComicDB &))); + mw->connect(localServer,SIGNAL(comicUpdated(quint64, const ComicDB &)),mw,SLOT(updateComicsView(quint64, const ComicDB &))); //connections to localServer diff --git a/YACReaderLibrary/yacreader_local_server.cpp b/YACReaderLibrary/yacreader_local_server.cpp index eab24fa8..52e18ca7 100644 --- a/YACReaderLibrary/yacreader_local_server.cpp +++ b/YACReaderLibrary/yacreader_local_server.cpp @@ -97,7 +97,7 @@ void YACReaderLocalServer::getComicInfo(quint64 libraryId, ComicDB & comic, QLis void YACReaderLocalServer::updateComic(quint64 libraryId, ComicDB & comic) { DBHelper::update(DBHelper::getLibrariesNames().at(libraryId), comic.info); - emit comicUpdated(comic); + emit comicUpdated(libraryId, comic); } bool YACReaderLocalServer::isRunning() diff --git a/YACReaderLibrary/yacreader_local_server.h b/YACReaderLibrary/yacreader_local_server.h index b6b65a7f..9d7225c1 100644 --- a/YACReaderLibrary/yacreader_local_server.h +++ b/YACReaderLibrary/yacreader_local_server.h @@ -13,7 +13,7 @@ public: explicit YACReaderLocalServer(QObject *parent = 0); signals: - void comicUpdated(const ComicDB & comic); + void comicUpdated(quint64 libraryId, const ComicDB & comic); public slots: bool isListening(); void sendResponse(); diff --git a/common/pictureflow.cpp b/common/pictureflow.cpp index 351543eb..3946d08c 100644 --- a/common/pictureflow.cpp +++ b/common/pictureflow.cpp @@ -192,7 +192,7 @@ public: PictureFlow::ReflectionEffect reflectionEffect; QVector slideImages; - QVector marks; + QVector marks; bool showMarks; QImage mark; @@ -1076,7 +1076,7 @@ void PictureFlow::addSlide(const QImage& image) d->state->slideImages.resize(c+1); d->state->slideImages[c] = new QImage(image); d->state->marks.resize(c+1); - d->state->marks[c] = false; + d->state->marks[c] = YACReaderComicReadStatus::Unread; triggerRender(); } @@ -1345,10 +1345,10 @@ void PictureFlow::setMarkImage(const QImage & m) d->state->mark = m; } -void PictureFlow::markSlide(int index) +void PictureFlow::markSlide(int index, YACReaderComicReadStatus readStatus) { if(indexstate->marks.size()) - d->state->marks[index] = true; + d->state->marks[index] = readStatus; } void PictureFlow::updateMarks() @@ -1361,10 +1361,10 @@ void PictureFlow::updateMarks() void PictureFlow::unmarkSlide(int index) { if(indexstate->marks.size()) - d->state->marks[index] = false; + d->state->marks[index] = YACReaderComicReadStatus::Unread; } -void PictureFlow::setMarks(const QVector & m) +void PictureFlow::setMarks(const QVector & m) { d->state->marks = m; updateMarks(); @@ -1376,7 +1376,7 @@ void PictureFlow::setShowMarks(bool enable) updateMarks(); } -QVector PictureFlow::getMarks() +QVector PictureFlow::getMarks() { return d->state->marks; } diff --git a/common/pictureflow.h b/common/pictureflow.h index 51cfe257..28c05307 100644 --- a/common/pictureflow.h +++ b/common/pictureflow.h @@ -189,17 +189,17 @@ public slots: void setMarkImage(const QImage & mark); - void markSlide(int index); + void markSlide(int index, YACReaderComicReadStatus readStatus = Read); void updateMarks(); void unmarkSlide(int index); - void setMarks(const QVector & marks); + void setMarks(const QVector & marks); void setShowMarks(bool enable); - QVector getMarks(); + QVector getMarks(); signals: @@ -218,7 +218,6 @@ private slots: private: PictureFlowPrivate* d; QImage mark; - QVector marks; int framesSkip; }; diff --git a/common/yacreader_flow_gl.cpp b/common/yacreader_flow_gl.cpp index 16e2d4b1..801af4a2 100644 --- a/common/yacreader_flow_gl.cpp +++ b/common/yacreader_flow_gl.cpp @@ -280,7 +280,7 @@ void YACReaderFlowGL::initializeGL() defaultTexture = bindTexture(QImage(":/images/defaultCover.png"),GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption); markTexture = bindTexture(QImage(":/images/readRibbon.png"),GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption); - + readingTexture = bindTexture(QImage(":/images/readingRibbon.png"),GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption); if(lazyPopulateObjects!=-1) populate(lazyPopulateObjects); @@ -454,10 +454,13 @@ void YACReaderFlowGL::drawCover(CFImage *CF) glEnd(); glDisable(GL_TEXTURE_2D); - if(showMarks && loaded[CF->index] && marks[CF->index]) + if(showMarks && loaded[CF->index] && marks[CF->index] != Unread) { glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, markTexture); + if(marks[CF->index] == Read) + glBindTexture(GL_TEXTURE_2D, markTexture); + else + glBindTexture(GL_TEXTURE_2D, readingTexture); glBegin(GL_QUADS); //esquina inferior izquierda @@ -866,7 +869,7 @@ void YACReaderFlowGL::setShowMarks(bool value) { showMarks = value; } -void YACReaderFlowGL::setMarks(QVector marks) +void YACReaderFlowGL::setMarks(QVector marks) { this->marks = marks; } @@ -876,13 +879,13 @@ void YACReaderFlowGL::setMarkImage(QImage & image) //deleteTexture(markTexture); //markTexture = bindTexture(image,GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption); } -void YACReaderFlowGL::markSlide(int index) +void YACReaderFlowGL::markSlide(int index, YACReaderComicReadStatus status) { - marks[index] = true; + marks[index] = status; } void YACReaderFlowGL::unmarkSlide(int index) { - marks[index] = false; + marks[index] = YACReaderComicReadStatus::Unread; } void YACReaderFlowGL::setSlideSize(QSize size) { diff --git a/common/yacreader_flow_gl.h b/common/yacreader_flow_gl.h index 323db5a5..9be46610 100644 --- a/common/yacreader_flow_gl.h +++ b/common/yacreader_flow_gl.h @@ -127,6 +127,7 @@ protected: GLuint defaultTexture; GLuint markTexture; + GLuint readingTexture; void initializeGL(); void paintGL(); void timerEvent(QTimerEvent *); @@ -136,7 +137,7 @@ protected: int lazyPopulateObjects; bool showMarks; QVector loaded; - QVector marks; + QVector marks; QList paths; CFImage * cfImages; bool hasBeenInitialized; @@ -247,9 +248,9 @@ public: //interface with yacreaderlibrary, compatibility void setShowMarks(bool value); - void setMarks(QVector marks); + void setMarks(QVector marks); void setMarkImage(QImage & image); - void markSlide(int index); + void markSlide(int index, YACReaderComicReadStatus status); void unmarkSlide(int index); void setSlideSize(QSize size); void clear(); diff --git a/common/yacreader_global.h b/common/yacreader_global.h index 9186a716..d9975cb9 100644 --- a/common/yacreader_global.h +++ b/common/yacreader_global.h @@ -67,5 +67,12 @@ SendComicInfo, }; + enum YACReaderComicReadStatus + { + Unread = 0, + Read = 1, + Opened = 2 + }; + #endif diff --git a/images/readRibbon.png b/images/readRibbon.png index f1a862c012e937292710ed9eed923017cb05507e..43bbdf7ad980239ba986a4a4323a1fa3f3b6b942 100644 GIT binary patch delta 7960 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 JPDHLkV1g_<{O