From 664dac34010c946db4477065abd077a7f7145bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sun, 6 Jul 2014 14:50:28 +0200 Subject: [PATCH] code refactoring for adding support to multiple "comics views" two "comics views" added, classic (flow+table_view) and grid (based on qml/qtquick) TODO: the views are only interchangeable in compilation time, some more work is needed for doing it in run time. fixed reloadCovers --- YACReaderLibrary/YACReaderLibrary.pro | 16 + YACReaderLibrary/classic_comics_view.cpp | 233 ++++++++++++ YACReaderLibrary/classic_comics_view.h | 49 +++ YACReaderLibrary/comics_view.cpp | 11 + YACReaderLibrary/comics_view.h | 46 +++ YACReaderLibrary/db/tablemodel.cpp | 80 ++-- YACReaderLibrary/db/tablemodel.h | 9 +- YACReaderLibrary/db_helper.cpp | 1 + YACReaderLibrary/grid_comics_view.cpp | 200 ++++++++++ YACReaderLibrary/grid_comics_view.h | 58 +++ YACReaderLibrary/library_window.cpp | 377 ++++++++----------- YACReaderLibrary/library_window.h | 13 +- YACReaderLibrary/main.cpp | 5 +- YACReaderLibrary/qml/GridComicsView.qml | 288 ++++++++++++++ YACReaderLibrary/qml/YACReaderScrollView.qml | 336 +++++++++++++++++ YACReaderLibrary/qml/page.png | Bin 0 -> 155 bytes YACReaderLibrary/qml/reading.png | Bin 0 -> 374 bytes YACReaderLibrary/qml/star.png | Bin 0 -> 242 bytes YACReaderLibrary/qml/tick.png | Bin 0 -> 488 bytes YACReaderLibrary/server/startup.cpp | 13 +- YACReaderLibrary/yacreader_local_server.cpp | 7 +- YACReaderLibrary/yacreader_local_server.h | 1 + common/yacreader_global.cpp | 8 + common/yacreader_global.h | 1 + 24 files changed, 1473 insertions(+), 279 deletions(-) create mode 100644 YACReaderLibrary/classic_comics_view.cpp create mode 100644 YACReaderLibrary/classic_comics_view.h create mode 100644 YACReaderLibrary/comics_view.cpp create mode 100644 YACReaderLibrary/comics_view.h create mode 100644 YACReaderLibrary/grid_comics_view.cpp create mode 100644 YACReaderLibrary/grid_comics_view.h create mode 100644 YACReaderLibrary/qml/GridComicsView.qml create mode 100644 YACReaderLibrary/qml/YACReaderScrollView.qml create mode 100644 YACReaderLibrary/qml/page.png create mode 100644 YACReaderLibrary/qml/reading.png create mode 100644 YACReaderLibrary/qml/star.png create mode 100644 YACReaderLibrary/qml/tick.png diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index a97ade55..ccf4566e 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -113,6 +113,9 @@ HEADERS += comic_flow.h \ ../common/http_worker.h \ yacreader_libraries.h \ ../common/exit_check.h \ + comics_view.h \ + classic_comics_view.h + SOURCES += comic_flow.cpp \ create_library_dialog.cpp \ @@ -156,6 +159,9 @@ SOURCES += comic_flow.cpp \ ../common/yacreader_global.cpp \ yacreader_libraries.cpp \ ../common/exit_check.cpp \ + comics_view.cpp \ + classic_comics_view.cpp + include(./server/server.pri) @@ -186,6 +192,16 @@ TRANSLATIONS = yacreaderlibrary_es.ts \ isEqual(QT_MAJOR_VERSION, 5) { Release:DESTDIR = ../release5 Debug:DESTDIR = ../debug5 + +#QML/GridView +QT += quick qml + +HEADERS += grid_comics_view.h + +SOURCES += grid_comics_view.cpp + +RESOURCES += qml.qrc + } else { Release:DESTDIR = ../release Debug:DESTDIR = ../debug diff --git a/YACReaderLibrary/classic_comics_view.cpp b/YACReaderLibrary/classic_comics_view.cpp new file mode 100644 index 00000000..26ee326f --- /dev/null +++ b/YACReaderLibrary/classic_comics_view.cpp @@ -0,0 +1,233 @@ +#include "classic_comics_view.h" + +#include "yacreader_table_view.h" + +#include "comic_flow_widget.h" +#include "QsLog.h" + +ClassicComicsView::ClassicComicsView(QWidget *parent) + :ComicsView(parent) +{ + QHBoxLayout * layout = new QHBoxLayout; + + settings = new QSettings(YACReader::getSettingsPath()+"/YACReaderLibrary.ini",QSettings::IniFormat); //TODO unificar la creación del fichero de config con el servidor + settings->beginGroup("libraryConfig"); + //FLOW----------------------------------------------------------------------- + //--------------------------------------------------------------------------- + + if(QGLFormat::hasOpenGL() && (settings->value(USE_OPEN_GL).toBool() == true)) + comicFlow = new ComicFlowWidgetGL(0); + else + comicFlow = new ComicFlowWidgetSW(0); + + comicFlow->updateConfig(settings); + comicFlow->setFocusPolicy(Qt::StrongFocus); + comicFlow->setShowMarks(true); + setFocusProxy(comicFlow); + + comicFlow->setFocus(Qt::OtherFocusReason); + + comicFlow->setContextMenuPolicy(Qt::ActionsContextMenu); + + //TODO!!! set actions.... + //comicFlow->addAction(toggleFullScreenAction); + //comicFlow->addAction(openComicAction); + + //END FLOW---- + + + //layout----------------------------------------------- + sVertical = new QSplitter(Qt::Vertical); //spliter derecha + + sVertical->addWidget(comicFlow); + comics = new QWidget; + QVBoxLayout * comicsLayout = new QVBoxLayout; + comicsLayout->setSpacing(0); + comicsLayout->setContentsMargins(0,0,0,0); + //TODO ComicsView:(set toolbar) comicsLayout->addWidget(editInfoToolBar); + + tableView = new YACReaderTableView; + tableView->verticalHeader()->hide(); + comicsLayout->addWidget(tableView); + comics->setLayout(comicsLayout); + sVertical->addWidget(comics); + + //config-------------------------------------------------- + if(settings->contains(COMICS_VIEW_HEADERS)) + tableView->horizontalHeader()->restoreState(settings->value(COMICS_VIEW_HEADERS).toByteArray()); + + //connections--------------------------------------------- + connect(tableView, SIGNAL(clicked(QModelIndex)), this, SLOT(centerComicFlow(QModelIndex))); + connect(comicFlow, SIGNAL(centerIndexChanged(int)), this, SLOT(updateTableView(int))); + connect(tableView, SIGNAL(comicRated(int,QModelIndex)), this, SIGNAL(comicRated(int,QModelIndex))); + connect(comicFlow, SIGNAL(selected(uint)), this, SIGNAL(selected(uint))); + connect(tableView->horizontalHeader(), SIGNAL(sectionMoved(int,int,int)), this, SLOT(saveTableHeadersStatus())); + + layout->addWidget(sVertical); + setLayout(layout); + + layout->setMargin(0); +} + +void ClassicComicsView::setToolBar(QToolBar *toolBar) +{ + static_cast(comics->layout())->insertWidget(0,toolBar); +} + +void ClassicComicsView::setModel(TableModel *model) +{ + + ComicsView::setModel(model); + + if(model == NULL) + { + comicFlow->clear(); + } + else + { + connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector)), this, SLOT(applyModelChanges(QModelIndex,QModelIndex,QVector))); + connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(removeItemsFromFlow(QModelIndex,int,int))); + + tableView->setModel(model); + + tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); + #if QT_VERSION >= 0x050000 + tableView->horizontalHeader()->setSectionsMovable(true); + #else + tableView->horizontalHeader()->setMovable(true); + #endif + //TODO parametrizar la configuración de las columnas + for(int i = 0;ihorizontalHeader()->count();i++) + tableView->horizontalHeader()->hideSection(i); + + tableView->horizontalHeader()->showSection(TableModel::Number); + tableView->horizontalHeader()->showSection(TableModel::Title); + tableView->horizontalHeader()->showSection(TableModel::FileName); + tableView->horizontalHeader()->showSection(TableModel::NumPages); + tableView->horizontalHeader()->showSection(TableModel::Hash); //Size is part of the Hash...TODO add Columns::Size to Columns + tableView->horizontalHeader()->showSection(TableModel::ReadColumn); + tableView->horizontalHeader()->showSection(TableModel::CurrentPage); + tableView->horizontalHeader()->showSection(TableModel::Rating); + + //debido a un bug, qt4 no es capaz de ajustar el ancho teniendo en cuenta todas la filas (no sólo las visibles) + //así que se ecala la primera vez y después se deja el control al usuario. + //if(!settings->contains(COMICS_VIEW_HEADERS)) + tableView->resizeColumnsToContents(); + tableView->horizontalHeader()->setStretchLastSection(true); + + QStringList paths = model->getPaths(model->getCurrentPath());//TODO ComicsView: get currentpath from somewhere currentPath()); + comicFlow->setImagePaths(paths); + comicFlow->setMarks(model->getReadList()); + comicFlow->setFocus(Qt::OtherFocusReason); + } + + if(settings->contains(COMICS_VIEW_HEADERS)) + tableView->horizontalHeader()->restoreState(settings->value(COMICS_VIEW_HEADERS).toByteArray()); + + +} + +void ClassicComicsView::setCurrentIndex(const QModelIndex &index) +{ + tableView->setCurrentIndex(index); + //TODO ComicsView: scroll comicFlow to index +} + +QModelIndex ClassicComicsView::currentIndex() +{ + return tableView->currentIndex(); +} + +QItemSelectionModel *ClassicComicsView::selectionModel() +{ + return tableView->selectionModel(); +} + +void ClassicComicsView::scrollTo(const QModelIndex & mi, QAbstractItemView::ScrollHint hint) +{ + comicFlow->setCenterIndex(mi.row()); +} + +void ClassicComicsView::toFullScreen() +{ + comicFlow->hide(); + comicFlow->setCenterIndex(comicFlow->centerIndex()); + comics->hide(); + + //showFullScreen() //parent windows + + comicFlow->show(); + comicFlow->setFocus(Qt::OtherFocusReason); +} + +void ClassicComicsView::toNormal() +{ + comicFlow->hide(); + comicFlow->setCenterIndex(comicFlow->centerIndex()); + comicFlow->render(); + comics->show(); + comicFlow->show(); +} + +void ClassicComicsView::updateConfig(QSettings *settings) +{ + comicFlow->updateConfig(settings); +} + +void ClassicComicsView::setItemActions(const QList &actions) +{ + tableView->addActions(actions); +} + +void ClassicComicsView::setViewActions(const QList &actions) +{ + comicFlow->addActions(actions); +} + +void ClassicComicsView::setShowMarks(bool show) +{ + comicFlow->setShowMarks(show); +} + +void ClassicComicsView::centerComicFlow(const QModelIndex & mi) +{ + comicFlow->showSlide(mi.row()); + comicFlow->setFocus(Qt::OtherFocusReason); +} + +void ClassicComicsView::updateTableView(int i) +{ + QModelIndex mi = model->index(i,2); + tableView->setCurrentIndex(mi); + tableView->scrollTo(mi,QAbstractItemView::EnsureVisible); +} + +void ClassicComicsView::saveTableHeadersStatus() +{ + settings->setValue(COMICS_VIEW_HEADERS,tableView->horizontalHeader()->saveState()); +} + +void ClassicComicsView::applyModelChanges(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) +{ + Q_UNUSED(topLeft); + Q_UNUSED(bottomRight); + if(roles.contains(TableModel::ReadColumnRole)) + { + comicFlow->setMarks(model->getReadList()); + comicFlow->updateMarks(); + } +} + +void ClassicComicsView::removeItemsFromFlow(const QModelIndex &parent, int from, int to) +{ + Q_UNUSED(parent); + for(int i = from; i<=to; i++) + comicFlow->remove(i); +} + +void ClassicComicsView::closeEvent(QCloseEvent *event) +{ + saveTableHeadersStatus(); + ComicsView::closeEvent(event); +} + diff --git a/YACReaderLibrary/classic_comics_view.h b/YACReaderLibrary/classic_comics_view.h new file mode 100644 index 00000000..9ecb9e3e --- /dev/null +++ b/YACReaderLibrary/classic_comics_view.h @@ -0,0 +1,49 @@ +#ifndef CLASSIC_COMICS_VIEW_H +#define CLASSIC_COMICS_VIEW_H + +#include "comics_view.h" + +#include +#include + +class YACReaderTableView; +class QSplitter; +class ComicFlowWidget; +class QToolBar; +class TableModel; + +class ClassicComicsView : public ComicsView +{ + Q_OBJECT +public: + ClassicComicsView(QWidget *parent = 0); + void setToolBar(QToolBar * toolBar); + void setModel(TableModel *model); + void setCurrentIndex(const QModelIndex &index); + QModelIndex currentIndex(); + QItemSelectionModel * selectionModel(); + void scrollTo(const QModelIndex & mi, QAbstractItemView::ScrollHint hint ); + void toFullScreen(); + void toNormal(); + void updateConfig(QSettings * settings); + void setItemActions(const QList & actions); + void setViewActions(const QList & actions); + +public slots: + void centerComicFlow(const QModelIndex & mi); + void updateTableView(int i); + void saveTableHeadersStatus(); + void applyModelChanges(const QModelIndex & topLeft,const QModelIndex & bottomRight,const QVector & roles); + void removeItemsFromFlow(const QModelIndex & parent, int from, int to); + //ComicsView + void setShowMarks(bool show); +private: + YACReaderTableView * tableView; + QWidget *comics; + QSplitter * sVertical; + ComicFlowWidget * comicFlow; + QSettings * settings; + void closeEvent ( QCloseEvent * event ); +}; + +#endif // CLASSIC_COMICS_VIEW_H diff --git a/YACReaderLibrary/comics_view.cpp b/YACReaderLibrary/comics_view.cpp new file mode 100644 index 00000000..5c5e7725 --- /dev/null +++ b/YACReaderLibrary/comics_view.cpp @@ -0,0 +1,11 @@ +#include "comics_view.h" + +ComicsView::ComicsView(QWidget *parent) : + QWidget(parent),model(NULL) +{ +} + +void ComicsView::setModel(TableModel *m) +{ + model = m; +} diff --git a/YACReaderLibrary/comics_view.h b/YACReaderLibrary/comics_view.h new file mode 100644 index 00000000..4076e114 --- /dev/null +++ b/YACReaderLibrary/comics_view.h @@ -0,0 +1,46 @@ +#ifndef COMICS_VIEW_H +#define COMICS_VIEW_H + +#include + +#include "tablemodel.h" +#include +#include +#include +#include + +class YACReaderTableView; +class QSplitter; +class ComicFlowWidget; +class QToolBar; +class TableModel; +class ComicsView : public QWidget +{ + Q_OBJECT +public: + explicit ComicsView(QWidget *parent = 0); + virtual void setToolBar(QToolBar * toolBar) = 0; + virtual void setModel(TableModel *model); + virtual void setCurrentIndex(const QModelIndex &index) = 0; + virtual QModelIndex currentIndex() = 0; + virtual QItemSelectionModel * selectionModel() = 0; + virtual void scrollTo(const QModelIndex & mi, QAbstractItemView::ScrollHint hint ) = 0; + virtual void toFullScreen() = 0; + virtual void toNormal() = 0; + virtual void updateConfig(QSettings * settings) = 0; + //Actions for tableviews + virtual void setItemActions(const QList & actions) = 0; + //actions for visual-oriented views + virtual void setViewActions(const QList & actions) = 0; + //virtual selectItem(int index) = 0; +signals: + void selected(unsigned int); + void comicRated(int,QModelIndex); +public slots: + virtual void setShowMarks(bool show) = 0; +protected: + TableModel * model; + +}; + +#endif // COMICS_VIEW_H diff --git a/YACReaderLibrary/db/tablemodel.cpp b/YACReaderLibrary/db/tablemodel.cpp index e04bed06..08f996cc 100644 --- a/YACReaderLibrary/db/tablemodel.cpp +++ b/YACReaderLibrary/db/tablemodel.cpp @@ -15,7 +15,7 @@ TableModel::TableModel(QObject *parent) - : QAbstractItemModel(parent) + : QAbstractItemModel(parent) { connect(this,SIGNAL(beforeReset()),this,SIGNAL(modelAboutToBeReset())); connect(this,SIGNAL(reset()),this,SIGNAL(modelReset())); @@ -23,7 +23,7 @@ TableModel::TableModel(QObject *parent) //! [0] TableModel::TableModel( QSqlQuery &sqlquery, QObject *parent) - : QAbstractItemModel(parent) + : QAbstractItemModel(parent) { setupModelData(sqlquery); } @@ -46,6 +46,27 @@ int TableModel::columnCount(const QModelIndex &parent) const } //! [2] +QHash TableModel::roleNames() const { + QHash roles; + + roles[NumberRole] = "number"; + roles[TitleRole] = "title"; + roles[FileNameRole] = "file_name"; + roles[NumPagesRole] = "num_pages"; + roles[IdRole] = "id"; + roles[Parent_IdRole] = "parent_id"; + roles[PathRole] = "path"; + roles[HashRole] = "hash"; + roles[ReadColumnRole] = "read_column"; + roles[IsBisRole] = "is_bis"; + roles[CurrentPageRole] = "current_page"; + roles[RatingRole] = "rating"; + roles[HasBeenOpenedRole] = "has_been_opened"; + roles[CoverPathRole] = "cover_path"; + + return roles; +} + //! [3] QVariant TableModel::data(const QModelIndex &index, int role) const { @@ -84,10 +105,28 @@ QVariant TableModel::data(const QModelIndex &index, int role) const //TODO check here if any view is asking for TableModel::Roles //these roles will be used from QML/GridView - if (role != Qt::DisplayRole) - return QVariant(); - TableItem *item = static_cast(index.internalPointer()); + + if (role == NumberRole) + return item->data(Number); + else if (role == TitleRole) + return item->data(Title).isNull()?item->data(FileName):item->data(Title); + else if (role == RatingRole) + return item->data(Rating); + else if (role == CoverPathRole) + return "file:///"+_databasePath+"/covers/"+item->data(Hash).toString()+".jpg"; + else if (role == NumPagesRole) + return item->data(NumPages); + else if (role == CurrentPageRole) + return item->data(CurrentPage); + else if (role == ReadColumnRole) + return item->data(ReadColumn).toBool(); + else if (role == HasBeenOpenedRole) + return item->data(TableModel::HasBeenOpened); + + if (role != Qt::DisplayRole) + return QVariant(); + if(index.column() == TableModel::Hash) return QString::number(item->data(index.column()).toString().right(item->data(index.column()).toString().length()-40).toInt()/1024.0/1024.0,'f',2)+"Mb"; if(index.column() == TableModel::ReadColumn) @@ -467,7 +506,7 @@ QVector TableModel::setComicsRead(QList l db.close(); QSqlDatabase::removeDatabase(_databasePath); - emit dataChanged(index(list.first().row(),TableModel::ReadColumn),index(list.last().row(),TableModel::CurrentPage+1)); + emit dataChanged(index(list.first().row(),TableModel::ReadColumn),index(list.last().row(),TableModel::HasBeenOpened),QVector() = {ReadColumnRole,CurrentPageRole,HasBeenOpenedRole}); return getReadList(); } @@ -553,10 +592,10 @@ void TableModel::remove(ComicDB * comic, int row) endRemoveRows(); } -ComicDB TableModel::getComic(int row) +/*ComicDB TableModel::getComic(int row) { return getComic(index(row,0)); -} +}*/ void TableModel::remove(int row) { @@ -580,8 +619,8 @@ void TableModel::reload(const ComicDB & comic) } row++; } - if(found) - emit dataChanged(index(row,TableModel::CurrentPage),index(row,TableModel::CurrentPage)); + if(found) + emit dataChanged(index(row,ReadColumn),index(row,HasBeenOpened), QVector() = {ReadColumnRole,CurrentPageRole,HasBeenOpenedRole}); } void TableModel::resetComicRating(const QModelIndex &mi) @@ -600,27 +639,6 @@ void TableModel::resetComicRating(const QModelIndex &mi) QSqlDatabase::removeDatabase(_databasePath); } -QHash TableModel::roleNames() -{ - QHash roles; - - roles[NumberRole] = "number"; - roles[TitleRole] = "title"; - roles[FileNameRole] = "file_name"; - roles[NumPagesRole] = "num_pages"; - roles[IdRole] = "id"; - roles[Parent_IdRole] = "parent_id"; - roles[PathRole] = "path"; - roles[HashRole] = "hash"; - roles[ReadColumnRole] = "read"; - roles[IsBisRole] = "is_bis"; - roles[CurrentPageRole] = "current_page"; - roles[RatingRole] = "rating"; - roles[HasBeenOpenedRole] = "has_been_opened"; - roles[CoverPathRole] = "cover_path"; - - return roles; -} void TableModel::updateRating(int rating, QModelIndex mi) { diff --git a/YACReaderLibrary/db/tablemodel.h b/YACReaderLibrary/db/tablemodel.h index 88913bc4..7bfff95b 100644 --- a/YACReaderLibrary/db/tablemodel.h +++ b/YACReaderLibrary/db/tablemodel.h @@ -24,7 +24,7 @@ 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, @@ -39,8 +39,9 @@ public: //Métodos de conveniencia QStringList getPaths(const QString & _source); QString getComicPath(QModelIndex mi); + QString getCurrentPath(){return QString(_databasePath).remove("/.yacreaderlibrary");}; ComicDB getComic(const QModelIndex & mi); //--> para la edición - ComicDB getComic(int row); + //ComicDB getComic(int row); QVector getReadList(); QVector setAllComicsRead(YACReaderComicReadStatus readStatus); QList getComics(QList list); //--> recupera la información común a los comics seleccionados @@ -56,7 +57,7 @@ public: void reload(const ComicDB & comic); void resetComicRating(const QModelIndex & mi); - QHash roleNames(); + QHash roleNames() const; enum Columns { Number = 0, @@ -98,6 +99,8 @@ public slots: void finishTransaction(); void updateRating(int rating, QModelIndex mi); +protected: + private: void setupModelData( QSqlQuery &sqlquery); ComicDB _getComic(const QModelIndex & mi); diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index 648477d4..417d8d4d 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -253,6 +253,7 @@ void DBHelper::update(ComicInfo * comicInfo, QSqlDatabase & db) updateComicInfo.bindValue(":notes",comicInfo->notes); bool read = comicInfo->read || comicInfo->currentPage == comicInfo->numPages.toInt(); //if current page is the las page, the comic is read(completed) + comicInfo->read = read; updateComicInfo.bindValue(":read", read?1:0); updateComicInfo.bindValue(":id", comicInfo->id); updateComicInfo.bindValue(":edited", comicInfo->edited?1:0); diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp new file mode 100644 index 00000000..c8da3b20 --- /dev/null +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -0,0 +1,200 @@ +#include "grid_comics_view.h" + +#include +#include + +#include "QsLog.h" + +GridComicsView::GridComicsView(QWidget *parent) : + ComicsView(parent),_selectionModel(NULL) +{ + qmlRegisterType("comicModel",1,0,"TableModel"); + + view = new QQuickView(); + container = QWidget::createWindowContainer(view, this); + + container->setMinimumSize(200, 200); + container->setFocusPolicy(Qt::TabFocus); + view->setSource(QUrl("qrc:/qml/GridComicsView.qml")); + + setShowMarks(true);//TODO save this in settings + + QVBoxLayout * l = new QVBoxLayout; + l->addWidget(container); + this->setLayout(l); + + setContentsMargins(0,0,0,0); + l->setContentsMargins(0,0,0,0); + + QLOG_INFO() << "GridComicsView"; +} + +GridComicsView::~GridComicsView() +{ + delete view; +} + +void GridComicsView::setToolBar(QToolBar *toolBar) +{ +QLOG_INFO() << "setToolBar"; +static_cast(this->layout())->insertWidget(1,toolBar); +} + +void GridComicsView::setModel(TableModel *model) +{ + QLOG_INFO() << "setModel"; + + QQmlContext *ctxt = view->rootContext(); + + //there is only one mothel in the system + ComicsView::setModel(model); + if(this->model != NULL) + { + QLOG_INFO() << "xxx"; + + if(_selectionModel != NULL) + delete _selectionModel; + _selectionModel = new QItemSelectionModel(this->model); + + ctxt->setContextProperty("comicsList", this->model); + ctxt->setContextProperty("comicsSelection", _selectionModel); + ctxt->setContextProperty("comicsSelectionHelper", this); + ctxt->setContextProperty("dummyValue", true); + } + +#ifdef Q_OS_MAC + ctxt->setContextProperty("backgroundColor", "#FAFAFA"); + ctxt->setContextProperty("cellColor", "#EDEDED"); + ctxt->setContextProperty("selectedColor", "#DDDDDD"); + ctxt->setContextProperty("titleColor", "#121212"); + ctxt->setContextProperty("textColor", "#636363"); + ctxt->setContextProperty("dropShadow",true); +#else + ctxt->setContextProperty("backgroundColor", "#2A2A2A"); + ctxt->setContextProperty("cellColor", "#212121"); + ctxt->setContextProperty("selectedColor", "#121212"); + ctxt->setContextProperty("titleColor", "#E6E6E6"); + ctxt->setContextProperty("textColor", "#E6E6E6"); + ctxt->setContextProperty("dropShadow",false); +#endif + + +} + +void GridComicsView::setCurrentIndex(const QModelIndex &index) +{ + QLOG_INFO() << "setCurrentIndex"; +} + +QModelIndex GridComicsView::currentIndex() +{ + QLOG_INFO() << "currentIndex"; + QModelIndexList indexes = _selectionModel->selectedRows(); + if(indexes.length()>0) + return indexes[0]; + + this->selectIndex(0); + return _selectionModel->selectedRows()[0]; +} + +QItemSelectionModel *GridComicsView::selectionModel() +{ + QLOG_INFO() << "selectionModel"; + QModelIndexList indexes = _selectionModel->selectedRows(); + if(indexes.length()==0) + this->selectIndex(0); + + return _selectionModel; +} + +void GridComicsView::scrollTo(const QModelIndex &mi, QAbstractItemView::ScrollHint hint) +{ + QLOG_INFO() << "scrollTo"; +} + +void GridComicsView::toFullScreen() +{ + QLOG_INFO() << "toFullScreen"; +} + +void GridComicsView::toNormal() +{ + QLOG_INFO() << "toNormal"; +} + +void GridComicsView::updateConfig(QSettings *settings) +{ + QLOG_INFO() << "updateConfig"; +} + +void GridComicsView::setItemActions(const QList &actions) +{ + QLOG_INFO() << "setItemActions"; +} + +void GridComicsView::setViewActions(const QList &actions) +{ + //TODO generate QML Menu from actions + QLOG_INFO() << "setViewActions"; + this->addActions(actions); +} + +QSize GridComicsView::sizeHint() +{ + QLOG_INFO() << "sizeHint"; + return QSize(1280,768); +} + +//helper +void GridComicsView::selectIndex(int index) +{ + QLOG_INFO() << "selectIndex" << index; + if(_selectionModel != NULL && model!=NULL) + _selectionModel->select(model->index(index,0),QItemSelectionModel::Select | QItemSelectionModel::Rows); +} + +bool GridComicsView::isSelectedIndex(int index) +{ + if(_selectionModel != NULL && model!=NULL) + { + QModelIndex mi = model->index(index,0); + return _selectionModel->isSelected(mi); + } + return false; +} + +void GridComicsView::clear() +{ + QLOG_INFO() << "clear"; + if(_selectionModel != NULL) + { + _selectionModel->clear(); + + QQmlContext *ctxt = view->rootContext(); + ctxt->setContextProperty("dummyValue", true); + } + //model->forceClear(); +} + +void GridComicsView::selectedItem(int index) +{ + emit doubleClicked(model->index(index,0)); +} + +void GridComicsView::setShowMarks(bool show) +{ + QLOG_INFO() << "setShowMarks"; + QQmlContext *ctxt = view->rootContext(); + ctxt->setContextProperty("show_marks", show); +} + +void GridComicsView::closeEvent(QCloseEvent *event) +{ + QLOG_INFO() << "closeEvent"; + QObject *object = view->rootObject(); + QMetaObject::invokeMethod(object, "exit"); + container->close(); + view->close(); + event->accept(); + ComicsView::closeEvent(event); +} diff --git a/YACReaderLibrary/grid_comics_view.h b/YACReaderLibrary/grid_comics_view.h new file mode 100644 index 00000000..1012679f --- /dev/null +++ b/YACReaderLibrary/grid_comics_view.h @@ -0,0 +1,58 @@ +#ifndef GRID_COMICS_VIEW_H +#define GRID_COMICS_VIEW_H + +#include "comics_view.h" + +#include + +class QAbstractListModel; +class QItemSelectionModel; +class QQuickView; +class QQuickView; + + +class GridComicsView : public ComicsView +{ + Q_OBJECT +public: + explicit GridComicsView(QWidget *parent = 0); + virtual ~GridComicsView(); + void setToolBar(QToolBar * toolBar); + void setModel(TableModel *model); + void setCurrentIndex(const QModelIndex &index); + QModelIndex currentIndex(); + QItemSelectionModel * selectionModel(); + void scrollTo(const QModelIndex & mi, QAbstractItemView::ScrollHint hint ); + void toFullScreen(); + void toNormal(); + void updateConfig(QSettings * settings); + void setItemActions(const QList & actions); + void setViewActions(const QList & actions); + + QSize sizeHint(); +signals: +signals: + void comicRated(int,QModelIndex); + void doubleClicked(QModelIndex); + +public slots: + //selection helper + void selectIndex(int index); + bool isSelectedIndex(int index); + void clear(); + //double clicked item + void selectedItem(int index); + + //ComicsView + void setShowMarks(bool show); + +private: + QItemSelectionModel * _selectionModel; + QQuickView *view; + QWidget *container; + bool dummy; + void closeEvent ( QCloseEvent * event ); + +}; + +#endif // GRID_COMICS_VIEW_H diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 66debab4..b6e32a6b 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -60,6 +60,9 @@ #include "comic_vine_dialog.h" //#include "yacreader_social_dialog.h" +#include "classic_comics_view.h" +#include "grid_comics_view.h" + #include "QsLog.h" #ifdef Q_OS_WIN @@ -118,10 +121,9 @@ void LibraryWindow::setupUI() else //if(settings->value(USE_OPEN_GL).toBool() == false) showMaximized(); - if(settings->contains(COMICS_VIEW_HEADERS)) - comicView->horizontalHeader()->restoreState(settings->value(COMICS_VIEW_HEADERS).toByteArray()); + /*if(settings->contains(COMICS_VIEW_HEADERS_GEOMETRY)) - comicView->horizontalHeader()->restoreGeometry(settings->value(COMICS_VIEW_HEADERS_GEOMETRY).toByteArray());*/ + comicsView->horizontalHeader()->restoreGeometry(settings->value(COMICS_VIEW_HEADERS_GEOMETRY).toByteArray());*/ /*socialDialog = new YACReaderSocialDialog(this); socialDialog->setHidden(true);*/ @@ -131,7 +133,7 @@ void LibraryWindow::doLayout() { //LAYOUT ELEMENTS------------------------------------------------------------ //--------------------------------------------------------------------------- - sVertical = new QSplitter(Qt::Vertical); //spliter derecha + QSplitter * sHorizontal = new QSplitter(Qt::Horizontal); //spliter principal #ifdef Q_OS_MAC sHorizontal->setStyleSheet("QSplitter::handle{image:none;background-color:#B8B8B8;} QSplitter::handle:vertical {height:1px;}"); @@ -142,49 +144,29 @@ void LibraryWindow::doLayout() //TOOLBARS------------------------------------------------------------------- //--------------------------------------------------------------------------- editInfoToolBar = new QToolBar(); + editInfoToolBar->setStyleSheet("QToolBar {border: none;}"); + #ifdef Q_OS_MAC libraryToolBar = addToolBar(tr("Library")); #else libraryToolBar = new YACReaderMainToolBar(this); #endif - //FLOW----------------------------------------------------------------------- - //--------------------------------------------------------------------------- - if(QGLFormat::hasOpenGL() && !settings->contains(USE_OPEN_GL)) - { - OnStartFlowSelectionDialog * flowSelDialog = new OnStartFlowSelectionDialog(); - flowSelDialog->exec(); - if(flowSelDialog->result() == QDialog::Accepted) - settings->setValue(USE_OPEN_GL,2); - else - settings->setValue(USE_OPEN_GL,0); + //FLOW----------------------------------------------------------------------- + //--------------------------------------------------------------------------- + if(QGLFormat::hasOpenGL() && !settings->contains(USE_OPEN_GL)) + { + OnStartFlowSelectionDialog * flowSelDialog = new OnStartFlowSelectionDialog(); - delete flowSelDialog; - } + flowSelDialog->exec(); + if(flowSelDialog->result() == QDialog::Accepted) + settings->setValue(USE_OPEN_GL,2); + else + settings->setValue(USE_OPEN_GL,0); - if(QGLFormat::hasOpenGL() && (settings->value(USE_OPEN_GL).toBool() == true)) - comicFlow = new ComicFlowWidgetGL(0); - else - comicFlow = new ComicFlowWidgetSW(0); - - comicFlow->updateConfig(settings); - comicFlow->setFocusPolicy(Qt::StrongFocus); - comicFlow->setShowMarks(true); - setFocusProxy(comicFlow); - - fullScreenToolTip = new QLabel(comicFlow); - fullScreenToolTip->setText(tr(" press 'F' to close fullscreen mode ")); - fullScreenToolTip->setPalette(QPalette(QColor(0,0,0))); - fullScreenToolTip->setFont(QFont("courier new",15,234)); - fullScreenToolTip->setAutoFillBackground(true); - fullScreenToolTip->hide(); - fullScreenToolTip->adjustSize(); - - comicFlow->setFocus(Qt::OtherFocusReason); - - comicFlow->addAction(toggleFullScreenAction); - comicFlow->addAction(openComicAction); + delete flowSelDialog; + } //SIDEBAR----------------------------------------------------------------------- //--------------------------------------------------------------------------- @@ -207,25 +189,23 @@ void LibraryWindow::doLayout() foldersTitle->addAction(colapseAllNodesAction); //FINAL LAYOUT------------------------------------------------------------- - sVertical->addWidget(comicFlow); - comics = new QWidget; - QVBoxLayout * comicsLayout = new QVBoxLayout; - comicsLayout->setSpacing(0); - comicsLayout->setContentsMargins(0,0,0,0); - comicsLayout->addWidget(editInfoToolBar); - editInfoToolBar->setStyleSheet("QToolBar {border: none;}"); - - comicView = new YACReaderTableView; - comicView->verticalHeader()->hide(); - comicsLayout->addWidget(comicView); - comics->setLayout(comicsLayout); - sVertical->addWidget(comics); + comicsView = new ClassicComicsView(); + comicsView->setToolBar(editInfoToolBar); + + fullScreenToolTip = new QLabel(comicsView); + fullScreenToolTip->setText(tr(" press 'F' to close fullscreen mode ")); + fullScreenToolTip->setPalette(QPalette(QColor(0,0,0))); + fullScreenToolTip->setFont(QFont("courier new",15,234)); + fullScreenToolTip->setAutoFillBackground(true); + fullScreenToolTip->hide(); + fullScreenToolTip->adjustSize(); + sHorizontal->addWidget(sideBar); #ifndef Q_OS_MAC QVBoxLayout * rightLayout = new QVBoxLayout; rightLayout->addWidget(libraryToolBar); - rightLayout->addWidget(sVertical); + rightLayout->addWidget(comicsView); rightLayout->setMargin(0); rightLayout->setSpacing(0); @@ -257,10 +237,7 @@ void LibraryWindow::doLayout() connect(noLibrariesWidget,SIGNAL(createNewLibrary()),this,SLOT(createLibrary())); connect(noLibrariesWidget,SIGNAL(addExistingLibrary()),this,SLOT(showAddLibrary())); - comicFlow->addAction(toggleFullScreenAction); - comicFlow->addAction(openComicAction); - comicFlow->setContextMenuPolicy(Qt::ActionsContextMenu); //collapsible disabled in macosx (only temporaly) #ifdef Q_OS_MAC @@ -489,11 +466,11 @@ void LibraryWindow::createActions() deleteComicsAction->setText(tr("Delete selected comics")); deleteComicsAction->setIcon(QIcon(":/images/trash.png")); - hideComicViewAction = new QAction(this); - hideComicViewAction->setText(tr("Hide comic flow")); - hideComicViewAction->setIcon(QIcon(":/images/hideComicFlow.png")); - hideComicViewAction->setCheckable(true); - hideComicViewAction->setChecked(false); + hideComicViewAction = new QAction(this); + hideComicViewAction->setText(tr("Hide comic flow")); + hideComicViewAction->setIcon(QIcon(":/images/hideComicFlow.png")); + hideComicViewAction->setCheckable(true); + hideComicViewAction->setChecked(false); getInfoAction = new QAction(this); getInfoAction->setText(tr("Download tags from Comic Vine")); @@ -634,28 +611,49 @@ void LibraryWindow::createToolBars() editInfoToolBar->addAction(deleteComicsAction); editInfoToolBar->addWidget(new QToolBarStretch()); - editInfoToolBar->addAction(hideComicViewAction); + editInfoToolBar->addAction(hideComicViewAction); } void LibraryWindow::createMenus() { - comicView->addAction(openContainingFolderComicAction); - YACReader::addSperator(comicView); + QList itemActions; + itemActions << openContainingFolderComicAction + << YACReader::createSeparator() + << resetComicRatingAction + << YACReader::createSeparator() + << editSelectedComicsAction + << getInfoAction + << asignOrderActions + << YACReader::createSeparator() + << setAsReadAction + << setAsNonReadAction + << YACReader::createSeparator() + << deleteComicsAction; - comicView->addAction(resetComicRatingAction); - YACReader::addSperator(comicView); + QList viewActions; + viewActions << openComicAction + << YACReader::createSeparator() + << openContainingFolderComicAction + << YACReader::createSeparator() + << resetComicRatingAction + << YACReader::createSeparator() + << editSelectedComicsAction + << getInfoAction + << asignOrderActions + << YACReader::createSeparator() + << selectAllComicsAction + << YACReader::createSeparator() + << setAsReadAction + << setAsNonReadAction + << showHideMarksAction + << YACReader::createSeparator() + << deleteComicsAction + << YACReader::createSeparator() + << toggleFullScreenAction; - comicView->addAction(editSelectedComicsAction); - comicView->addAction(getInfoAction); - comicView->addAction(asignOrderActions); - YACReader::addSperator(comicView); - - comicView->addAction(setAsReadAction); - comicView->addAction(setAsNonReadAction); - YACReader::addSperator(comicView); - - comicView->addAction(deleteComicsAction); + comicsView->setItemActions(itemActions); + comicsView->setViewActions(viewActions); foldersView->addAction(openContainingFolderAction); YACReader::addSperator(foldersView); @@ -678,6 +676,9 @@ void LibraryWindow::createMenus() selectedLibrary->addAction(exportLibraryAction); selectedLibrary->addAction(importLibraryAction); + + + //MacOSX app menus #ifdef Q_OS_MACX @@ -776,9 +777,8 @@ void LibraryWindow::createConnections() connect(foldersView, SIGNAL(clicked(QModelIndex)), this, SLOT(loadCovers(QModelIndex))); connect(foldersView, SIGNAL(clicked(QModelIndex)), this, SLOT(updateHistory(QModelIndex))); - connect(comicView, SIGNAL(clicked(QModelIndex)), this, SLOT(centerComicFlow(QModelIndex))); - connect(comicFlow, SIGNAL(centerIndexChanged(int)), this, SLOT(updateComicView(int))); - connect(comicView, SIGNAL(comicRated(int,QModelIndex)), dmCV, SLOT(updateRating(int,QModelIndex))); + connect(comicsView, SIGNAL(comicRated(int,QModelIndex)), dmCV, SLOT(updateRating(int,QModelIndex))); + connect(showHideMarksAction,SIGNAL(toggled(bool)),comicsView,SLOT(setShowMarks(bool))); //actions connect(createLibraryAction,SIGNAL(triggered()),this,SLOT(createLibrary())); @@ -791,8 +791,7 @@ void LibraryWindow::createConnections() //connect(setAllAsReadAction,SIGNAL(triggered()),this,SLOT(setComicsReaded())); //connect(setAllAsNonReadAction,SIGNAL(triggered()),this,SLOT(setComicsUnreaded())); - connect(showHideMarksAction,SIGNAL(toggled(bool)),comicFlow,SLOT(setShowMarks(bool))); - + //comicsInfoManagement connect(exportComicsInfo,SIGNAL(triggered()),this,SLOT(showExportComicsInfo())); connect(importComicsInfo,SIGNAL(triggered()),this,SLOT(showImportComicsInfo())); @@ -819,8 +818,8 @@ void LibraryWindow::createConnections() #endif connect(optionsDialog, SIGNAL(optionsChanged()),this,SLOT(reloadOptions())); //ComicFlow - connect(comicFlow,SIGNAL(selected(unsigned int)),this,SLOT(openComic())); - connect(comicView,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(openComic())); + connect(comicsView,SIGNAL(selected(unsigned int)),this,SLOT(openComic())); + connect(comicsView,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(openComic())); //Folders filter //connect(clearFoldersFilter,SIGNAL(clicked()),foldersFilter,SLOT(clear())); connect(foldersFilter,SIGNAL(textChanged(QString)),this,SLOT(setFoldersFilter(QString))); @@ -838,13 +837,13 @@ void LibraryWindow::createConnections() //connect(dm,SIGNAL(directoryLoaded(QString)),foldersView,SLOT(expandAll())); //connect(dm,SIGNAL(directoryLoaded(QString)),this,SLOT(updateFoldersView(QString))); //Comicts edition - connect(selectAllComicsAction,SIGNAL(triggered()),comicView,SLOT(selectAll())); + connect(selectAllComicsAction,SIGNAL(triggered()),comicsView,SLOT(selectAll())); connect(editSelectedComicsAction,SIGNAL(triggered()),this,SLOT(showProperties())); connect(asignOrderActions,SIGNAL(triggered()),this,SLOT(asignNumbers())); connect(deleteComicsAction,SIGNAL(triggered()),this,SLOT(deleteComics())); - connect(hideComicViewAction, SIGNAL(toggled(bool)),this, SLOT(hideComicFlow(bool))); + connect(hideComicViewAction, SIGNAL(toggled(bool)),this, SLOT(hideComicFlow(bool))); connect(getInfoAction,SIGNAL(triggered()),this,SLOT(showComicVineScraper())); @@ -875,16 +874,14 @@ void LibraryWindow::loadLibrary(const QString & name) int ret = QMessageBox::question(this,tr("Update needed"),tr("This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now?"),QMessageBox::Yes,QMessageBox::No); if(ret == QMessageBox::Yes) { - //TODO update to new version updated = DataBaseManagement::updateToCurrentVersion(path+"/library.ydb"); if(!updated) QMessageBox::critical(this,tr("Update failed"), tr("The current library can't be udpated. Check for write write permissions on: ") + path+"/library.ydb"); } else { - comicView->setModel(NULL); + comicsView->setModel(NULL); foldersView->setModel(NULL); - comicFlow->clear(); disableAllActions();//TODO comprobar que se deben deshabilitar //será posible renombrar y borrar estas bibliotecas renameLibraryAction->setEnabled(true); @@ -935,9 +932,8 @@ void LibraryWindow::loadLibrary(const QString & name) if(ret == QMessageBox::Yes) QDesktopServices::openUrl(QUrl("http://www.yacreader.com")); - comicView->setModel(NULL); + comicsView->setModel(NULL); foldersView->setModel(NULL); - comicFlow->clear(); disableAllActions();//TODO comprobar que se deben deshabilitar //será posible renombrar y borrar estas bibliotecas renameLibraryAction->setEnabled(true); @@ -946,9 +942,8 @@ void LibraryWindow::loadLibrary(const QString & name) } else { - comicView->setModel(NULL); + comicsView->setModel(NULL); foldersView->setModel(NULL); - comicFlow->clear(); disableAllActions();//TODO comprobar que se deben deshabilitar //si la librería no existe en disco, se ofrece al usuario la posibiliad de eliminarla @@ -1035,45 +1030,15 @@ void LibraryWindow::loadCovers(const QModelIndex & mi) column = mi.column(); } - //comicView->setModel(NULL); + //comicsView->setModel(NULL); dmCV->setupModelData(folderId,dm->getDatabase()); - comicView->setModel(dmCV); - comicView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); -#if QT_VERSION >= 0x050000 - comicView->horizontalHeader()->setSectionsMovable(true); -#else - comicView->horizontalHeader()->setMovable(true); -#endif - //TODO parametrizar la configuración de las columnas - for(int i = 0;ihorizontalHeader()->count();i++) - comicView->horizontalHeader()->hideSection(i); - - comicView->horizontalHeader()->showSection(0); - comicView->horizontalHeader()->showSection(1); - comicView->horizontalHeader()->showSection(2); - comicView->horizontalHeader()->showSection(3); - comicView->horizontalHeader()->showSection(7); - comicView->horizontalHeader()->showSection(8); - comicView->horizontalHeader()->showSection(10); - comicView->horizontalHeader()->showSection(11); - - - //debido a un bug, qt4 no es capaz de ajustar el ancho teniendo en cuenta todas la filas (no sólo las visibles) - //así que se ecala la primera vez y después se deja el control al usuario. - //if(!settings->contains(COMICS_VIEW_HEADERS)) - comicView->resizeColumnsToContents(); - comicView->horizontalHeader()->setStretchLastSection(true); - - QStringList paths = dmCV->getPaths(currentPath()); - comicFlow->setImagePaths(paths); - comicFlow->setMarks(dmCV->getReadList()); - comicFlow->setFocus(Qt::OtherFocusReason); - + comicsView->setModel(dmCV); + QStringList paths = dmCV->getPaths(currentPath()); checkEmptyFolder(&paths); if(paths.size()>0) - comicView->setCurrentIndex(dmCV->index(0,0)); + comicsView->setCurrentIndex(dmCV->index(0,0)); } void LibraryWindow::checkEmptyFolder(QStringList * paths) @@ -1098,33 +1063,22 @@ void LibraryWindow::checkEmptyFolder(QStringList * paths) void LibraryWindow::reloadCovers() { - loadCovers(foldersView->currentIndex()); - + if(foldersView->selectionModel()->selectedRows().length()>0) + loadCovers(foldersView->currentIndex()); + else + loadCovers(QModelIndex()); +QLOG_INFO() << "reloaded covers at row : " << foldersView->currentIndex().row(); QModelIndex mi = dmCV->getIndexFromId(_comicIdEdited); - comicView->scrollTo(mi,QAbstractItemView::PositionAtCenter); - comicView->setCurrentIndex(mi); + comicsView->scrollTo(mi,QAbstractItemView::PositionAtCenter); + comicsView->setCurrentIndex(mi); //centerComicFlow(mi); - comicFlow->setCenterIndex(mi.row()); -} - -void LibraryWindow::centerComicFlow(const QModelIndex & mi) -{ - comicFlow->showSlide(mi.row()); - comicFlow->setFocus(Qt::OtherFocusReason); -} - -void LibraryWindow::updateComicView(int i) -{ - QModelIndex mi = dmCV->index(i,2); - comicView->setCurrentIndex(mi); - comicView->scrollTo(mi,QAbstractItemView::EnsureVisible); } void LibraryWindow::openComic() { if(!importedCovers) { - ComicDB comic = dmCV->getComic(comicView->currentIndex()); + ComicDB comic = dmCV->getComic(comicsView->currentIndex()); QString path = currentPath(); QList siblings = dmCV->getAllComics(); @@ -1159,42 +1113,24 @@ void LibraryWindow::openComic() } } -void LibraryWindow::setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus) -{ - - comicFlow->setMarks(dmCV->setComicsRead(getSelectedComics(),readStatus)); - comicFlow->updateMarks(); +void LibraryWindow::setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus) { + dmCV->setComicsRead(getSelectedComics(),readStatus); } -void LibraryWindow::setCurrentComicReaded() -{ +void LibraryWindow::setCurrentComicReaded() { this->setCurrentComicsStatusReaded(YACReader::Read); } void LibraryWindow::setCurrentComicOpened() { - + //TODO: remove? } -void LibraryWindow::setComicsReaded() -{ - comicFlow->setMarks(dmCV->setAllComicsRead(YACReader::Read)); - comicFlow->updateMarks(); -} - -void LibraryWindow::setCurrentComicUnreaded() -{ +void LibraryWindow::setCurrentComicUnreaded() { this->setCurrentComicsStatusReaded(YACReader::Unread); } -void LibraryWindow::setComicsUnreaded() -{ - comicFlow->setMarks(dmCV->setAllComicsRead(YACReader::Unread)); - comicFlow->updateMarks(); -} - -void LibraryWindow::createLibrary() -{ +void LibraryWindow::createLibrary() { createLibraryDialog->show(libraries); } @@ -1211,8 +1147,7 @@ void LibraryWindow::create(QString source, QString dest, QString name) } -void LibraryWindow::reloadCurrentLibrary() -{ +void LibraryWindow::reloadCurrentLibrary() { loadLibrary(selectedLibrary->currentText()); } @@ -1268,24 +1203,8 @@ void LibraryWindow::loadLibraries() } -void LibraryWindow::saveLibraries() -{ - +void LibraryWindow::saveLibraries() { libraries.save(); - /*QFile f(QCoreApplication::applicationDirPath()+"/libraries.yacr"); - if(!f.open(QIODevice::WriteOnly)) - { - QMessageBox::critical(NULL,tr("Saving libraries file...."),tr("There was a problem saving YACReaderLibrary libraries file. Please, check if you have enough permissions in the YACReader root folder.")); - } - else - { - QTextStream txtS(&f); - for(QMap::iterator i = libraries.begin();i!=libraries.end();i++) - { - txtS << i.key() << "\n"; - txtS << i.value() << "\n"; - } - }*/ } void LibraryWindow::updateLibrary() @@ -1313,9 +1232,9 @@ void LibraryWindow::deleteCurrentLibrary() d.rmdir(path); if(libraries.isEmpty())//no more libraries avaliable. { - comicView->setModel(NULL); + comicsView->setModel(NULL); foldersView->setModel(NULL); - comicFlow->clear(); + disableAllActions(); showNoLibrariesWidget(); } @@ -1335,9 +1254,9 @@ void LibraryWindow::removeLibrary() //selectedLibrary->setCurrentIndex(0); if(libraries.isEmpty())//no more libraries avaliable. { - comicView->setModel(NULL); + comicsView->setModel(NULL); foldersView->setModel(NULL); - comicFlow->clear(); + disableAllActions(); showNoLibrariesWidget(); } @@ -1408,11 +1327,10 @@ void LibraryWindow::setRootIndex() } else { - comicView->setModel(NULL); - comicFlow->clear(); + comicsView->setModel(NULL); } - foldersView->clearSelection(); + foldersView->selectionModel()->clear(); } setFolderAsNotCompletedAction->setVisible(false); @@ -1432,17 +1350,12 @@ void LibraryWindow::toFullScreen() { fromMaximized = this->isMaximized(); - comicFlow->hide(); - //comicFlow->setSlideSize(slideSizeF); - comicFlow->setCenterIndex(comicFlow->centerIndex()); - comics->hide(); - sideBar->hide(); + sideBar->hide(); libraryToolBar->hide(); - showFullScreen(); + comicsView->toFullScreen(); - comicFlow->show(); - comicFlow->setFocus(Qt::OtherFocusReason); + showFullScreen(); fullScreenToolTip->move((width()-fullScreenToolTip->width())/2,0); fullScreenToolTip->adjustSize(); @@ -1452,14 +1365,10 @@ void LibraryWindow::toFullScreen() void LibraryWindow::toNormal() { fullScreenToolTip->hide(); - comicFlow->hide(); - //comicFlow->setSlideSize(slideSizeW); - comicFlow->setCenterIndex(comicFlow->centerIndex()); - comicFlow->render(); - comics->show(); + sideBar->show(); - comicFlow->show(); + comicsView->toNormal(); if(fromMaximized) showMaximized(); @@ -1580,7 +1489,7 @@ void LibraryWindow::asignNumbers() void LibraryWindow::openContainingFolderComic() { -QModelIndex modelIndex = comicView->currentIndex(); +QModelIndex modelIndex = comicsView->currentIndex(); QFileInfo file = QDir::cleanPath(currentPath() + dmCV->getComicPath(modelIndex)); #ifdef Q_OS_LINUX QString path = file.absolutePath(); @@ -1656,7 +1565,7 @@ void LibraryWindow::importLibrary(QString clc,QString destPath,QString name) void LibraryWindow::reloadOptions() { //comicFlow->setFlowType(flowType); - comicFlow->updateConfig(settings); + comicsView->updateConfig(settings); } QString LibraryWindow::currentPath() @@ -1664,8 +1573,11 @@ QString LibraryWindow::currentPath() return libraries.getPath(selectedLibrary->currentText()); } +//TODO ComicsView: some actions in the comics toolbar can be relative to a certain view +//show/hide actions on show/hide widget void LibraryWindow::hideComicFlow(bool hide) { + /* if(hide) { QList sizes; @@ -1682,7 +1594,7 @@ void LibraryWindow::hideComicFlow(bool hide) sizes.append(total/3); sVertical->setSizes(sizes); } - +*/ } void LibraryWindow::showExportComicsInfo() @@ -1696,13 +1608,17 @@ void LibraryWindow::showImportComicsInfo() importComicsInfoDialog->dest = currentPath() + "/.yacreaderlibrary/library.ydb"; importComicsInfoDialog->show(); } - +#include "startup.h" +extern Startup * s; void LibraryWindow::closeEvent ( QCloseEvent * event ) { - settings->setValue(MAIN_WINDOW_GEOMETRY, saveGeometry()); - settings->setValue(COMICS_VIEW_HEADERS,comicView->horizontalHeader()->saveState()); - event->accept(); - //settings->setValue(COMICS_VIEW_HEADERS_GEOMETRY,comicView->horizontalHeader()->saveGeometry()); + s->stop(); + settings->setValue(MAIN_WINDOW_GEOMETRY, saveGeometry()); + + comicsView->close(); + QApplication::instance()->processEvents(); + event->accept(); + QMainWindow::closeEvent(event); } void LibraryWindow::showNoLibrariesWidget() @@ -1751,15 +1667,16 @@ bool lessThanModelIndexRow(const QModelIndex & m1, const QModelIndex & m2) QModelIndexList LibraryWindow::getSelectedComics() { //se fuerza a que haya almenos una fila seleccionada TODO comprobar se se puede forzar a la tabla a que lo haga automáticamente - QModelIndexList selection = comicView->selectionModel()->selectedRows(); - + //avoid selection.count()==0 forcing selection in comicsView + QModelIndexList selection = comicsView->selectionModel()->selectedRows(); + QLOG_INFO() << "selection count " << selection.length(); qSort(selection.begin(),selection.end(),lessThanModelIndexRow); - if(selection.count()==0) + /*if(selection.count()==0) { - comicView->selectRow(comicFlow->centerIndex()); - selection = comicView->selectionModel()->selectedRows(); - } + comicsView->selectRow(comicFlow->centerIndex()); + selection = comicsView->selectionModel()->selectedRows(); + }*/ return selection; } @@ -1778,19 +1695,21 @@ void LibraryWindow::deleteComics() QString libraryPath = currentPath(); foreach(ComicDB comic, comics) { - paths.append(libraryPath + comic.path); + paths.append(libraryPath + comic.path); + QLOG_INFO() << comic.path; + QLOG_INFO() << comic.id; + QLOG_INFO() << comic.parentId; } ComicsRemover * remover = new ComicsRemover(indexList,paths); - //comicView->showDeleteProgress(); + //comicsView->showDeleteProgress(); dmCV->startTransaction(); - connect(remover, SIGNAL(remove(int)), dmCV, SLOT(remove(int))); - connect(remover, SIGNAL(remove(int)), comicFlow, SLOT(remove(int))); + connect(remover, SIGNAL(remove(int)), dmCV, SLOT(remove(int))); connect(remover,SIGNAL(removeError()),this,SLOT(setRemoveError())); connect(remover, SIGNAL(finished()), dmCV, SLOT(finishTransaction())); - //connect(remover, SIGNAL(finished()), comicView, SLOT(hideDeleteProgress())); + //connect(remover, SIGNAL(finished()), comicsView, SLOT(hideDeleteProgress())); connect(remover, SIGNAL(finished()),this,SLOT(checkEmptyFolder())); connect(remover, SIGNAL(finished()),this,SLOT(checkRemoveError())); connect(remover, SIGNAL(finished()), remover, SLOT(deleteLater())); @@ -1895,9 +1814,7 @@ void LibraryWindow::importLibraryPackage() void LibraryWindow::updateComicsView(quint64 libraryId, const ComicDB & comic) { //TODO comprobar la biblioteca.... - if(libraryId == selectedLibrary->currentIndex()) - { + if(libraryId == selectedLibrary->currentIndex()) { dmCV->reload(comic); - comicFlow->setMarks(dmCV->getReadList()); } } diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index 5925d897..d100212c 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -27,7 +27,6 @@ class HelpAboutDialog; class RenameLibraryDialog; class PropertiesDialog; class PackageManager; -class ComicFlowWidget; class QCheckBox; class QPushButton; class TableModel; @@ -50,6 +49,7 @@ class YACReaderLibraryListWidget; class YACReaderTreeView; class YACReaderMainToolBar; class ComicVineDialog; +class ComicsView; #include "comic_db.h" using namespace YACReader; @@ -59,7 +59,7 @@ class LibraryWindow : public QMainWindow Q_OBJECT private: YACReaderSideBar * sideBar; - QSplitter * sVertical; + CreateLibraryDialog * createLibraryDialog; ExportLibraryDialog * exportLibraryDialog; ImportLibraryDialog * importLibraryDialog; @@ -80,7 +80,6 @@ private: //YACReaderSortComics * proxySort; PackageManager * packageManager; - ComicFlowWidget * comicFlow; QSize slideSizeW; QSize slideSizeF; //search filter @@ -91,8 +90,8 @@ private: QPushButton * clearFoldersFilter; QCheckBox * includeComicsCheckBox; //------------- - QWidget *comics; - YACReaderTableView * comicView; + + ComicsView * comicsView; YACReaderTreeView * foldersView; YACReaderLibraryListWidget * selectedLibrary; TreeModel * dm; @@ -224,8 +223,6 @@ public: void loadCovers(const QModelIndex & mi); void checkEmptyFolder(QStringList * paths = 0); void reloadCovers(); - void centerComicFlow(const QModelIndex & mi); - void updateComicView(int i); void openComic(); void createLibrary(); void create(QString source,QString dest, QString name); @@ -261,8 +258,6 @@ public: void setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus); void setCurrentComicReaded(); void setCurrentComicUnreaded(); - void setComicsReaded(); - void setComicsUnreaded(); void hideComicFlow(bool hide); void showExportComicsInfo(); void showImportComicsInfo(); diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index 951356fb..1b90312a 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -213,9 +213,12 @@ int main( int argc, char ** argv ) YACReader::exitCheck(ret); - //server shutdown + //shutdown s->stop(); delete s; + localServer->close(); + delete localServer; + delete mw; QsLogging::Logger::destroyInstance(); diff --git a/YACReaderLibrary/qml/GridComicsView.qml b/YACReaderLibrary/qml/GridComicsView.qml new file mode 100644 index 00000000..c3e4e515 --- /dev/null +++ b/YACReaderLibrary/qml/GridComicsView.qml @@ -0,0 +1,288 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.0 +import QtQuick.Controls 1.1 +import QtGraphicalEffects 1.0 +import comicModel 1.0 + +Rectangle { + id: main + color: backgroundColor + width: parent.width + height: parent.height + anchors.margins: 0 + + function selectAll(from,to) + { + for(var i = from+1;i ci) + selectAll(ci,index); + + mouse.accepted = true; + + comicsSelectionHelper.selectIndex(index) + grid.currentIndex = index; + + } + } + + + Menu { + id: myContextMenu + MenuItem { text: "Open containing folder..."; onTriggered: display.setRandomName() } + MenuSeparator{} + MenuItem { text: "Reset comic rating"; onTriggered: model1.removeRows(index, 1) } + MenuSeparator{} + MenuItem { text: "Edit"; onTriggered: model1.removeRows(index, 1) } + MenuItem { text: "Download tags from Comic Vine"; onTriggered: model1.removeRows(index, 1) } + MenuItem { text: "Asign current order to comics"; onTriggered: model1.removeRows(index, 1) } + MenuSeparator{} + MenuItem { text: "Set as read"; onTriggered: model1.removeRows(index, 1) } + MenuItem { text: "Set as unread"; onTriggered: model1.removeRows(index, 1) } + MenuSeparator{} + MenuItem { text: "Delete selected comics"; onTriggered: model1.removeRows(index, 1) } + //MenuItem { text: "Show details"; onTriggered: cell.state = 'Details'; + } + + + } + + DropShadow { + anchors.fill: source + horizontalOffset: 0 + verticalOffset: 0 + radius: 3 + samples: 24 + color: "#40000000" + transparentBorder: true; + source: realCell; + enabled: dropShadow; + visible: dropShadow; + } + + /**/ + + //cover + Image { + id: coverElement + width: 148 + height: 224 + anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 4} + source: cover_path + fillMode: Image.PreserveAspectCrop + //smooth: true + mipmap: true + //antialiasing: true + asynchronous : true + cache: false //TODO clear cache only when it is neede + } + //mark + Image { + id: mark + width: 23 + height: 23 + source: read_column&&show_marks?"tick.png":has_been_opened&&show_marks?"reading.png":"" + anchors {right: coverElement.right; top: coverElement.top; topMargin: 11; rightMargin: 11} + asynchronous : true + } + + //title + Text { + anchors { top: realCell.top; left: realCell.left; leftMargin: 4; rightMargin: 4; topMargin: 234; } + width: 148 + maximumLineCount: 2 + wrapMode: Text.WordWrap + text: title + elide: Text.ElideRight + color: titleColor + clip: true + font.letterSpacing: 0.5 + } + //number + Text { + anchors {bottom: realCell.bottom; left: realCell.left; margins: 4} + text: number?"#"+number:"" + color: textColor + font.letterSpacing: 0.5 + } + //page icon + Image { + id: pageImage + anchors {bottom: realCell.bottom; right: realCell.right; bottomMargin: 5; rightMargin: 4; leftMargin: 4} + source: "page.png" + } + //numPages + Text { + id: pages + anchors {bottom: realCell.bottom; right: pageImage.left; margins: 4} + text: has_been_opened?current_page+"/"+num_pages:num_pages + color: textColor + font.letterSpacing: 0.5 + } + //rating icon + Image { + id: ratingImage + anchors {bottom: realCell.bottom; right: pageImage.left; bottomMargin: 5; rightMargin: Math.floor(pages.width)+12} + source: "star.png" + } + //comic rating + Text { + id: comicRating + anchors {bottom: realCell.bottom; right: ratingImage.left; margins: 4} + text: rating>0?rating:"-" + color: textColor + } + } + } + + YACReaderScrollView{ + id: scrollView + anchors.fill: parent + anchors.margins: 0 + + + GridView { + id:grid + anchors.fill: parent + cellHeight: 295 + highlight: appHighlight + focus: true + model: comicsList + delegate: appDelegate + anchors.topMargin: 20 + anchors.bottomMargin: 20 + anchors.leftMargin: 10 + anchors.rightMargin: 10 + pixelAligned: true + //flickDeceleration: -2000 + snapMode: GridView.SnapToRow + currentIndex: 0 + cacheBuffer: 0 + + + function numCellsPerRow() { + return Math.floor(width / 190); + } + + onWidthChanged: { + var numCells = numCellsPerRow(); + var rest = width % 190; + + if(numCells > 0) + { + cellWidth = Math.floor(width / numCells) ; + //console.log("numCells=",numCells,"rest=",rest,"cellWidth=",cellWidth,"width=",width); + } + } + } + focus: true + Keys.onPressed: { + if (event.modifiers & Qt.ControlModifier || event.modifiers & Qt.ShiftModifier) + return; + var numCells = grid.numCellsPerRow(); + var ci + if (event.key === Qt.Key_Right) { + ci = Math.min(grid.currentIndex+1,grid.count); + } + else if (event.key === Qt.Key_Left) { + ci = Math.max(0,grid.currentIndex-1); + } + else if (event.key === Qt.Key_Up) { + ci = Math.max(0,grid.currentIndex-numCells); + } + else if (event.key === Qt.Key_Down) { + ci = Math.min(grid.currentIndex+numCells,grid.count); + } + + event.accepted = true; + //var ci = grid.currentIndex; + grid.currentIndex = -1 + comicsSelectionHelper.clear(); + comicsSelectionHelper.selectIndex(ci); + grid.currentIndex = ci; + } + //} + + /*MouseArea { + anchors.fill: parent + onClicked: { + clicked.accepted = false; + console.log("xx"); + } + + onWheel: { + var newValue = Math.max(0,scrollView.flickableItem.contentY - wheel.angleDelta.y) + scrollView.flickableItem.contentY = newValue + + } + }*/ + /*ScrollBar { + flickable: grid; + } + + PerformanceMeter { + anchors {top: parent.top; left: parent.left; margins: 4} + id: performanceMeter + width: 128 + height: 64 + enabled: (dummyValue || !dummyValue) + }*/ + } +} + + diff --git a/YACReaderLibrary/qml/YACReaderScrollView.qml b/YACReaderLibrary/qml/YACReaderScrollView.qml new file mode 100644 index 00000000..a8dc57ad --- /dev/null +++ b/YACReaderLibrary/qml/YACReaderScrollView.qml @@ -0,0 +1,336 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Quick Controls module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Private 1.0 +import QtQuick.Controls.Styles 1.1 + +/*! + \qmltype ScrollView + \inqmlmodule QtQuick.Controls + \since 5.1 + \ingroup views + \brief Provides a scrolling view within another Item. + + A ScrollView can be used either to replace a \l Flickable or decorate an + existing \l Flickable. Depending on the platform, it will add scroll bars and + a content frame. + + Only one Item can be a direct child of the ScrollView and the child is implicitly anchored + to fill the scroll view. + + Example: + \code + ScrollView { + Image { source: "largeImage.png" } + } + \endcode + + In the previous example the Image item will implicitly get scroll behavior as if it was + used within a \l Flickable. The width and height of the child item will be used to + define the size of the content area. + + Example: + \code + ScrollView { + ListView { + ... + } + } + \endcode + + In this case the content size of the ScrollView will simply mirror that of its contained + \l flickableItem. + + You can create a custom appearance for a ScrollView by + assigning a \l {QtQuick.Controls.Styles::ScrollViewStyle}{ScrollViewStyle}. +*/ + +FocusScope { + id: root + + implicitWidth: 240 + implicitHeight: 150 + + /*! + This property tells the ScrollView if it should render + a frame around its content. + + The default value is \c false. + */ + property bool frameVisible: false + + /*! + This property controls if there should be a highlight + around the frame when the ScrollView has input focus. + + The default value is \c false. + + \note This property is only applicable on some platforms, such + as Mac OS. + */ + property bool highlightOnFocus: false + + /*! + \qmlproperty Item ScrollView::viewport + + The viewport determines the current "window" on the contentItem. + In other words, it clips it and the size of the viewport tells you + how much of the content area is visible. + */ + property alias viewport: viewportItem + + /*! + \qmlproperty Item ScrollView::flickableItem + + The flickableItem of the ScrollView. If the contentItem provided + to the ScrollView is a Flickable, it will be the \l contentItem. + */ + readonly property alias flickableItem: internal.flickableItem + + /*! + The contentItem of the ScrollView. This is set by the user. + + Note that the definition of contentItem is somewhat different to that + of a Flickable, where the contentItem is implicitly created. + */ + default property Item contentItem + + /*! \internal */ + property Item __scroller: scroller + /*! \internal */ + property alias __wheelAreaScrollSpeed: wheelArea.scrollSpeed + /*! \internal */ + property int __scrollBarTopMargin: 0 + /*! \internal */ + property int __viewTopMargin: 0 + /*! \internal */ + property alias __horizontalScrollBar: scroller.horizontalScrollBar + /*! \internal */ + property alias __verticalScrollBar: scroller.verticalScrollBar + /*! \qmlproperty Component ScrollView::style + + The style Component for this control. + \sa {Qt Quick Controls Styles QML Types} + + */ + property Component style: Qt.createComponent(Settings.style + "/ScrollViewStyle.qml", root) + + /*! \internal */ + property Style __style: styleLoader.item + + activeFocusOnTab: true + + onContentItemChanged: { +//console.log("onContentItemChanged"); + if (contentItem.hasOwnProperty("contentY") && // Check if flickable + contentItem.hasOwnProperty("contentHeight")) { + internal.flickableItem = contentItem // "Use content if it is a flickable + internal.flickableItem.parent = viewportItem + } else { + internal.flickableItem = flickableComponent.createObject(viewportItem) + contentItem.parent = internal.flickableItem.contentItem + } + internal.flickableItem.anchors.fill = viewportItem + if (!Settings.hasTouchScreen) + internal.flickableItem.interactive = false + } + + + children: Item { + id: internal + + property Flickable flickableItem + + Loader { + id: styleLoader + sourceComponent: style + onStatusChanged: { + if (status === Loader.Error) + console.error("Failed to load Style for", root) + } + property alias __control: root + } + + Binding { + target: flickableItem + property: "contentHeight" + when: contentItem !== flickableItem + value: contentItem ? contentItem.height : 0 + } + + Binding { + target: flickableItem + when: contentItem !== flickableItem + property: "contentWidth" + value: contentItem ? contentItem.width : 0 + } + + Connections { + target: flickableItem + + onContentYChanged: { + //console.log("onContentYChanged2"); + scroller.blockUpdates = true + scroller.verticalScrollBar.value = flickableItem.contentY + scroller.blockUpdates = false + } + + onContentXChanged: { + //console.log("onContentXChanged2"); + scroller.blockUpdates = true + scroller.horizontalScrollBar.value = flickableItem.contentX + scroller.blockUpdates = false + } + + } + + anchors.fill: parent + + Component { + id: flickableComponent + Flickable {} + } + + WheelArea { + id: wheelArea + parent: flickableItem + + // ### Note this is needed due to broken mousewheel behavior in Flickable. + + anchors.fill: parent + + property int stepSize: 295 + + property int acceleration: 40 + property int flickThreshold: Settings.dragThreshold + property real speedThreshold: 3 + property real ignored: 0.001 // ## flick() does not work with 0 yVelocity + property int maxFlick: 400 + + property bool horizontalRecursionGuard: false + property bool verticalRecursionGuard: false + + horizontalMinimumValue: flickableItem ? flickableItem.originX : 0 + horizontalMaximumValue: flickableItem ? flickableItem.originX + flickableItem.contentWidth - viewport.width : 0 + + verticalMinimumValue: flickableItem ? flickableItem.originY : 0 + verticalMaximumValue: flickableItem ? flickableItem.originY + flickableItem.contentHeight - viewport.height + __viewTopMargin : 0 + + Connections { + target: flickableItem + + onContentYChanged: { + //console.log("onContentYChanged"); + wheelArea.verticalRecursionGuard = true + wheelArea.verticalValue = flickableItem.contentY + wheelArea.verticalRecursionGuard = false + } + onContentXChanged: { + //console.log("onContentXChanged"); + wheelArea.horizontalRecursionGuard = true + wheelArea.horizontalValue = flickableItem.contentX + wheelArea.horizontalRecursionGuard = false + } + } + + onVerticalValueChanged: { + if (!verticalRecursionGuard) { + //console.log(verticalDelta); + + if (flickableItem.contentY < flickThreshold && verticalDelta > speedThreshold) { + flickableItem.flick(ignored, Math.min(maxFlick, acceleration * verticalDelta)) + } else if (flickableItem.contentY > flickableItem.contentHeight + - flickThreshold - viewport.height && verticalDelta < -speedThreshold) { + flickableItem.flick(ignored, Math.max(-maxFlick, acceleration * verticalDelta)) + } else { + var absDelta = Math.abs(verticalDelta); + + if(verticalDelta < 0) + flickableItem.contentY = verticalValue + Math.min(98,0.93*absDelta+4.5); + else + flickableItem.contentY = verticalValue - Math.min(98,0.93*absDelta+4.5); +} + + + //TODO: snap to row + + } + + } + + onHorizontalValueChanged: { + if (!horizontalRecursionGuard) + flickableItem.contentX = horizontalValue + } + } + + ScrollViewHelper { + id: scroller + anchors.fill: parent + active: wheelArea.active + property bool outerFrame: !frameVisible || !(__style ? __style.__externalScrollBars : 0) + property int scrollBarSpacing: outerFrame ? 0 : (__style ? __style.__scrollBarSpacing : 0) + property int verticalScrollbarOffset: verticalScrollBar.visible && !verticalScrollBar.isTransient ? + verticalScrollBar.width + scrollBarSpacing : 0 + property int horizontalScrollbarOffset: horizontalScrollBar.visible && !horizontalScrollBar.isTransient ? + horizontalScrollBar.height + scrollBarSpacing : 0 + Loader { + id: frameLoader + sourceComponent: __style ? __style.frame : null + anchors.fill: parent + anchors.rightMargin: scroller.outerFrame ? 0 : scroller.verticalScrollbarOffset + anchors.bottomMargin: scroller.outerFrame ? 0 : scroller.horizontalScrollbarOffset + } + + Item { + id: viewportItem + anchors.fill: frameLoader + anchors.topMargin: frameVisible ? __style.padding.top : 0 + anchors.leftMargin: frameVisible ? __style.padding.left : 0 + anchors.rightMargin: (frameVisible ? __style.padding.right : 0) + (scroller.outerFrame ? scroller.verticalScrollbarOffset : 0) + anchors.bottomMargin: (frameVisible ? __style.padding.bottom : 0) + (scroller.outerFrame ? scroller.horizontalScrollbarOffset : 0) + clip: true + } + } + FocusFrame { visible: highlightOnFocus && root.activeFocus } + } +} diff --git a/YACReaderLibrary/qml/page.png b/YACReaderLibrary/qml/page.png new file mode 100644 index 0000000000000000000000000000000000000000..100db8a07ce55af57e69d58fd70c3ec37690e1ed GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MYf(Ujv*Ddl795dN*Ekq=s4cMvViLzb0Jg5`9lq|Doh`1 z7AP^gO(=3xIFPEejA53HFf*eAJF8BM43|IxgRqEQ=BZ0eSwMprJYD@<);T3K0RU%2 BE8+kE literal 0 HcmV?d00001 diff --git a/YACReaderLibrary/qml/reading.png b/YACReaderLibrary/qml/reading.png new file mode 100644 index 0000000000000000000000000000000000000000..a26a81d63a321ff8c73407b041c96b3c22c3576b GIT binary patch literal 374 zcmV-+0g3*JP)+7*9lVSQEwMA4ff7z&p)DoQSkRc@A2T3PiBWd_$!B1)`!d-qGqS2G(IqLR zi?D!Q_7E=NlpSM#+PVK79MCDk2DZd!6>tE~=_4HA6@n+eR|M9f6Amy{I~Ttz0WYXO z)KkTMz@#~I9&kQmPw0`yyr%Mv(5pL7@pZE_!!6<3cmIAa4Ep2b$qQ(_6UFN1DJ6iGx9CTxW#|uyQ7I> zD^q~9RKpKj0d0quY%6v!>}vZQ@Vw#0R|gpeQT~Qc4?n%w_NLv7E1~dU<%&HFX6onI zXZEPEZOXLUBq2O&U$?^_##IrFTHhG8`hq9h2yi<%^NLk51r*Mi#nT`mV$R+eA?Ri8 naI}!EnyIhB!$FLh!+>GZiKSU*Paew!x{txr)z4*}Q$iB}nx9l& literal 0 HcmV?d00001 diff --git a/YACReaderLibrary/qml/tick.png b/YACReaderLibrary/qml/tick.png new file mode 100644 index 0000000000000000000000000000000000000000..78a20644c27b468c50767aa4a44597662f7253de GIT binary patch literal 488 zcmVP)wXM;%Yz~3&g? zC_;UD5u4#56c~&gN1%AQ2I4Rwg|QO@b$}DpJhgt^2k28-cbAj1Q&xen-6dqYD*IeUA1 zMJ6Vu&map(Fc<__K{>P+nl>?9e*E}xKTw#0_9*{be eYPCN=fB^su{-6g#-^-l<0000beginGroup("debugLogFile"); Logger* logger=new FileLogger(mainLogSettings,10000,app); - logger->installMsgHandler(); + logger->installMsgHandler(); // Configure template loader and cache QSettings* templateSettings=new QSettings(configFileName,QSettings::IniFormat,app); @@ -65,9 +65,14 @@ void Startup::start() { void Startup::stop() { - qDebug("ServiceHelper: Service has been stopped"); - // QCoreApplication destroys all objects that have been created in start(). - delete listener; + qDebug("ServiceHelper: Service has been stopped"); + // QCoreApplication destroys all objects that have been created in start(). + if(listener!=nullptr) + { + listener->close(); + delete listener; + listener = nullptr; + } } diff --git a/YACReaderLibrary/yacreader_local_server.cpp b/YACReaderLibrary/yacreader_local_server.cpp index a24c184f..8d6d7c82 100644 --- a/YACReaderLibrary/yacreader_local_server.cpp +++ b/YACReaderLibrary/yacreader_local_server.cpp @@ -64,7 +64,12 @@ bool YACReaderLocalServer::isRunning() socket.connectToServer(YACREADERLIBRARY_GUID); if (socket.waitForConnected(500)) return true; // Server is running (another instance of YACReaderLibrary has been launched) - return false; + return false; +} + +void YACReaderLocalServer::close() +{ + localServer->close(); } diff --git a/YACReaderLibrary/yacreader_local_server.h b/YACReaderLibrary/yacreader_local_server.h index d6c8832b..d5432e60 100644 --- a/YACReaderLibrary/yacreader_local_server.h +++ b/YACReaderLibrary/yacreader_local_server.h @@ -21,6 +21,7 @@ public slots: bool isListening(); void sendResponse(); static bool isRunning(); + void close(); private: //void run(); QLocalServer * localServer; diff --git a/common/yacreader_global.cpp b/common/yacreader_global.cpp index 0ac9c43e..c8ad06c3 100644 --- a/common/yacreader_global.cpp +++ b/common/yacreader_global.cpp @@ -19,3 +19,11 @@ void YACReader::addSperator(QWidget *w) separator->setSeparator(true); w->addAction(separator); } + + +QAction * YACReader::createSeparator() +{ + QAction * a = new QAction(0); + a->setSeparator(true); + return a; +} diff --git a/common/yacreader_global.h b/common/yacreader_global.h index f92952c4..4f3ac6d0 100644 --- a/common/yacreader_global.h +++ b/common/yacreader_global.h @@ -96,6 +96,7 @@ namespace YACReader QString getSettingsPath(); void addSperator(QWidget * w); +QAction * createSeparator(); } #endif