diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 15d78d9f..53db0a03 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -1,324 +1,332 @@ -###################################################################### -# Automatically generated by qmake (2.01a) dom 12. oct 20:47:48 2008 -###################################################################### - -TEMPLATE = app -TARGET = YACReaderLibrary -DEPENDPATH += . -INCLUDEPATH += . -INCLUDEPATH += ../common \ - ./server \ - ./db \ - ../custom_widgets \ - ./comic_vine \ - ./comic_vine/model - -DEFINES += SERVER_RELEASE NOMINMAX YACREADER_LIBRARY -QMAKE_MAC_SDK = macosx10.11 -#load default build flags -include (../config.pri) - -CONFIG(legacy_gl_widget) { - INCLUDEPATH += ../common/gl_legacy \ -} else { - INCLUDEPATH += ../common/gl \ -} - -#there are going to be two builds for windows, OpenGL based and ANGLE based -win32 { - CONFIG(force_angle) { - message("using ANGLE") - LIBS += -L../dependencies/poppler/lib -loleaut32 -lole32 -lshell32 -lopengl32 -lglu32 -luser32 - #linking extra libs are necesary for a successful compilation, a better approach should be - #to remove any OpenGL (desktop) dependencies - #the OpenGL stuff should be migrated to OpenGL ES - DEFINES += FORCE_ANGLE - } else { - LIBS += -L../dependencies/poppler/lib -loleaut32 -lole32 -lshell32 -lopengl32 -lglu32 -luser32 - } - - LIBS += -lpoppler-qt5 - INCLUDEPATH += ../dependencies/poppler/include/qt5 - - QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL - QMAKE_LFLAGS_RELEASE += /LTCG - CONFIG -= embed_manifest_exe -} - -unix:!macx{ - -INCLUDEPATH += /usr/include/poppler/qt5 -LIBS += -L/usr/lib -lpoppler-qt5 - -!CONFIG(no_opengl) { - LIBS += -lGLU - } -} - -macx{ -#INCLUDEPATH += "/Volumes/Mac OS X Lion/usr/X11/include" -#isEqual(QT_MAJOR_VERSION, 5) { -#INCLUDEPATH += /usr/local/include/poppler/qt5 -#LIBS += -L/usr/local/lib -lpoppler-qt5 -#} -#else { -#INCLUDEPATH += /usr/local/include/poppler/qt4 -#LIBS += -L/usr/local/lib -lpoppler-qt4 -#} -#QT += macextras - -LIBS += -framework Foundation -framework ApplicationServices -framework AppKit - -OBJECTIVE_SOURCES += $$PWD/../common/pdf_comic.mm -HEADERS += $$PWD/../common/pdf_comic.h -CONFIG += objective_c -QT += macextras gui-private -} - -unix{ -CONFIG += c++11 -} - -#CONFIG += release -CONFIG -= flat -QT += sql network widgets script -!CONFIG(no_opengl) { - QT += opengl -} - -# Input -HEADERS += comic_flow.h \ - create_library_dialog.h \ - library_creator.h \ - library_window.h \ - add_library_dialog.h \ - rename_library_dialog.h \ - properties_dialog.h \ - options_dialog.h \ - export_library_dialog.h \ - import_library_dialog.h \ - package_manager.h \ - bundle_creator.h \ - export_comics_info_dialog.h \ - import_comics_info_dialog.h \ - server_config_dialog.h \ - comic_flow_widget.h \ - db_helper.h \ - ./db/data_base_management.h \ - ./db/folder_item.h \ - ./db/folder_model.h \ - ./db/comic_model.h \ - ./db/comic_item.h \ - ../common/comic_db.h \ - ../common/folder.h \ - ../common/library_item.h \ - ../common/comic.h \ - ../common/bookmarks.h \ - ../common/pictureflow.h \ - ../common/custom_widgets.h \ - ../common/qnaturalsorting.h \ - ../common/yacreader_global.h \ - ../common/yacreader_global_gui.h \ - ../common/onstart_flow_selection_dialog.h \ - no_libraries_widget.h \ - import_widget.h \ - yacreader_local_server.h \ - yacreader_main_toolbar.h \ - comics_remover.h \ - ../common/http_worker.h \ - yacreader_libraries.h \ - ../common/exit_check.h \ - comics_view.h \ - classic_comics_view.h \ - empty_folder_widget.h \ - no_search_results_widget.h \ - comic_files_manager.h \ - db/reading_list_model.h \ - db/reading_list_item.h \ - yacreader_folders_view.h \ - yacreader_reading_lists_view.h \ - add_label_dialog.h \ - yacreader_history_controller.h \ - yacreader_navigation_controller.h \ - empty_label_widget.h \ - empty_container_info.h \ - empty_special_list.h \ - empty_reading_list_widget.h \ - ../common/scroll_management.h \ - ../common/opengl_checker.h - -!CONFIG(no_opengl) { - CONFIG(legacy_gl_widget) { - message("using legacy YACReaderFlowGL (QGLWidget) header") - HEADERS += ../common/gl_legacy/yacreader_flow_gl.h - } else { - HEADERS += ../common/gl/yacreader_flow_gl.h - } -} - -SOURCES += comic_flow.cpp \ - create_library_dialog.cpp \ - library_creator.cpp \ - library_window.cpp \ - main.cpp \ - add_library_dialog.cpp \ - rename_library_dialog.cpp \ - properties_dialog.cpp \ - options_dialog.cpp \ - export_library_dialog.cpp \ - import_library_dialog.cpp \ - package_manager.cpp \ - bundle_creator.cpp \ - export_comics_info_dialog.cpp \ - import_comics_info_dialog.cpp \ - server_config_dialog.cpp \ - comic_flow_widget.cpp \ - db_helper.cpp \ - ./db/data_base_management.cpp \ - ./db/folder_item.cpp \ - ./db/folder_model.cpp \ - ./db/comic_model.cpp \ - ./db/comic_item.cpp \ - ../common/comic_db.cpp \ - ../common/folder.cpp \ - ../common/library_item.cpp \ - ../common/comic.cpp \ - ../common/bookmarks.cpp \ - ../common/pictureflow.cpp \ - ../common/custom_widgets.cpp \ - ../common/qnaturalsorting.cpp \ - ../common/onstart_flow_selection_dialog.cpp \ - no_libraries_widget.cpp \ - import_widget.cpp \ - yacreader_local_server.cpp \ - yacreader_main_toolbar.cpp \ - comics_remover.cpp \ - ../common/http_worker.cpp \ - ../common/yacreader_global.cpp \ - ../common/yacreader_global_gui.cpp \ - yacreader_libraries.cpp \ - ../common/exit_check.cpp \ - comics_view.cpp \ - classic_comics_view.cpp \ - empty_folder_widget.cpp \ - no_search_results_widget.cpp \ - comic_files_manager.cpp \ - db/reading_list_model.cpp \ - db/reading_list_item.cpp \ - yacreader_folders_view.cpp \ - yacreader_reading_lists_view.cpp \ - add_label_dialog.cpp \ - yacreader_history_controller.cpp \ - yacreader_navigation_controller.cpp \ - empty_label_widget.cpp \ - empty_container_info.cpp \ - empty_special_list.cpp \ - empty_reading_list_widget.cpp \ - ../common/scroll_management.cpp \ - ../common/opengl_checker.cpp - -!CONFIG(no_opengl) { - CONFIG(legacy_gl_widget) { - message("using legacy YACReaderFlowGL (QGLWidget) source code") - SOURCES += ../common/gl_legacy/yacreader_flow_gl.cpp - } else { - SOURCES += ../common/gl/yacreader_flow_gl.cpp - } -} - - -include(./server/server.pri) -include(../custom_widgets/custom_widgets_yacreaderlibrary.pri) -CONFIG(7zip){ -include(../compressed_archive/wrapper.pri) -} else:CONFIG(unarr) { -include(../compressed_archive/unarr/unarr-wrapper.pri) -} else { - error(No compression backend specified. Did you mess with the build system?) -} - -include(./comic_vine/comic_vine.pri) -include(../QsLog/QsLog.pri) -include(../shortcuts_management/shortcuts_management.pri) - -RESOURCES += images.qrc files.qrc -win32:RESOURCES += images_win.qrc -unix:!macx:RESOURCES += images_win.qrc -macx:RESOURCES += images_osx.qrc - -RC_FILE = icon.rc - -macx { - ICON = YACReaderLibrary.icns -} - -TRANSLATIONS = yacreaderlibrary_es.ts \ - yacreaderlibrary_ru.ts \ - yacreaderlibrary_pt.ts \ - yacreaderlibrary_fr.ts \ - yacreaderlibrary_nl.ts \ - yacreaderlibrary_tr.ts \ - yacreaderlibrary_de.ts \ - yacreaderlibrary_source.ts - -CONFIG(force_angle) { - Release:DESTDIR = ../release_angle - Debug:DESTDIR = ../debug_angle -} else { - Release:DESTDIR = ../release - Debug:DESTDIR = ../debug -} - -#QML/GridView -QT += quick qml - -HEADERS += grid_comics_view.h \ - comics_view_transition.h - -SOURCES += grid_comics_view.cpp \ - comics_view_transition.cpp - -RESOURCES += qml.qrc -win32:RESOURCES += qml_win.qrc -unix:!macx:RESOURCES += qml_win.qrc -macx:RESOURCES += qml_osx.qrc - -unix:!macx { -#set install prefix if it's empty -isEmpty(PREFIX) { - PREFIX = /usr -} - -BINDIR = $$PREFIX/bin -LIBDIR = $$PREFIX/lib -DATADIR = $$PREFIX/share - -DEFINES += "LIBDIR=\\\"$$LIBDIR\\\"" "DATADIR=\\\"$$DATADIR\\\"" "BINDIR=\\\"$$BINDIR\\\"" - -#MAKE INSTALL -INSTALLS += bin icon desktop server translation manpage - -bin.path = $$BINDIR -isEmpty(DESTDIR) { - bin.files = YACReaderLibrary -} else { - bin.files = $$DESTDIR/YACReaderLibrary -} - -server.path = $$DATADIR/yacreader -server.files = ../release/server - -icon.path = $$DATADIR/yacreader -icon.files = ../images/iconLibrary.png ../images/db.png ../images/coversPackage.png - -desktop.path = $$DATADIR/applications -desktop.extra = desktop-file-edit --set-icon=$$DATADIR/yacreader/iconLibrary.png $$PWD/../YACReaderLibrary.desktop -desktop.files = ../YACReaderLibrary.desktop -#TODO: icons should be located at /usr/share/icons and have the same basename as their application - -translation.path = $$DATADIR/yacreader/languages -translation.files = ../release/languages/yacreaderlibrary_* - -manpage.path = $$DATADIR/man/man1 -manpage.files = ../YACReaderLibrary.1 -} +###################################################################### +# Automatically generated by qmake (2.01a) dom 12. oct 20:47:48 2008 +###################################################################### + +TEMPLATE = app +TARGET = YACReaderLibrary +DEPENDPATH += . +INCLUDEPATH += . +INCLUDEPATH += ../common \ + ./server \ + ./db \ + ../custom_widgets \ + ./comic_vine \ + ./comic_vine/model + +DEFINES += SERVER_RELEASE NOMINMAX YACREADER_LIBRARY +QMAKE_MAC_SDK = macosx10.11 +#load default build flags +include (../config.pri) + +CONFIG(legacy_gl_widget) { + INCLUDEPATH += ../common/gl_legacy \ +} else { + INCLUDEPATH += ../common/gl \ +} + +#there are going to be two builds for windows, OpenGL based and ANGLE based +win32 { + CONFIG(force_angle) { + message("using ANGLE") + LIBS += -L../dependencies/poppler/lib -loleaut32 -lole32 -lshell32 -lopengl32 -lglu32 -luser32 + #linking extra libs are necesary for a successful compilation, a better approach should be + #to remove any OpenGL (desktop) dependencies + #the OpenGL stuff should be migrated to OpenGL ES + DEFINES += FORCE_ANGLE + } else { + LIBS += -L../dependencies/poppler/lib -loleaut32 -lole32 -lshell32 -lopengl32 -lglu32 -luser32 + } + + LIBS += -lpoppler-qt5 + INCLUDEPATH += ../dependencies/poppler/include/qt5 + + QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL + QMAKE_LFLAGS_RELEASE += /LTCG + CONFIG -= embed_manifest_exe +} + +unix:!macx{ + +INCLUDEPATH += /usr/include/poppler/qt5 +LIBS += -L/usr/lib -lpoppler-qt5 + +!CONFIG(no_opengl) { + LIBS += -lGLU + } +} + +macx{ +#INCLUDEPATH += "/Volumes/Mac OS X Lion/usr/X11/include" +#isEqual(QT_MAJOR_VERSION, 5) { +#INCLUDEPATH += /usr/local/include/poppler/qt5 +#LIBS += -L/usr/local/lib -lpoppler-qt5 +#} +#else { +#INCLUDEPATH += /usr/local/include/poppler/qt4 +#LIBS += -L/usr/local/lib -lpoppler-qt4 +#} +#QT += macextras + +LIBS += -framework Foundation -framework ApplicationServices -framework AppKit + +OBJECTIVE_SOURCES += $$PWD/../common/pdf_comic.mm +HEADERS += $$PWD/../common/pdf_comic.h +CONFIG += objective_c +QT += macextras gui-private +} + +unix{ +CONFIG += c++11 +} + +#CONFIG += release +CONFIG -= flat +QT += sql network widgets script +!CONFIG(no_opengl) { + QT += opengl +} + +# Input +HEADERS += comic_flow.h \ + create_library_dialog.h \ + library_creator.h \ + library_window.h \ + add_library_dialog.h \ + rename_library_dialog.h \ + properties_dialog.h \ + options_dialog.h \ + export_library_dialog.h \ + import_library_dialog.h \ + package_manager.h \ + bundle_creator.h \ + export_comics_info_dialog.h \ + import_comics_info_dialog.h \ + server_config_dialog.h \ + comic_flow_widget.h \ + db_helper.h \ + ./db/data_base_management.h \ + ./db/folder_item.h \ + ./db/folder_model.h \ + ./db/comic_model.h \ + ./db/comic_item.h \ + ../common/comic_db.h \ + ../common/folder.h \ + ../common/library_item.h \ + ../common/comic.h \ + ../common/bookmarks.h \ + ../common/pictureflow.h \ + ../common/custom_widgets.h \ + ../common/qnaturalsorting.h \ + ../common/yacreader_global.h \ + ../common/yacreader_global_gui.h \ + ../common/onstart_flow_selection_dialog.h \ + no_libraries_widget.h \ + import_widget.h \ + yacreader_local_server.h \ + yacreader_main_toolbar.h \ + comics_remover.h \ + ../common/http_worker.h \ + yacreader_libraries.h \ + ../common/exit_check.h \ + comics_view.h \ + classic_comics_view.h \ + empty_folder_widget.h \ + no_search_results_widget.h \ + comic_files_manager.h \ + db/reading_list_model.h \ + db/reading_list_item.h \ + yacreader_folders_view.h \ + yacreader_reading_lists_view.h \ + add_label_dialog.h \ + yacreader_history_controller.h \ + yacreader_navigation_controller.h \ + empty_label_widget.h \ + empty_container_info.h \ + empty_special_list.h \ + empty_reading_list_widget.h \ + ../common/scroll_management.h \ + ../common/opengl_checker.h \ + yacreader_comics_views_manager.h \ + info_comics_view.h \ + yacreader_comics_selection_helper.h \ + yacreader_comic_info_helper.h + +!CONFIG(no_opengl) { + CONFIG(legacy_gl_widget) { + message("using legacy YACReaderFlowGL (QGLWidget) header") + HEADERS += ../common/gl_legacy/yacreader_flow_gl.h + } else { + HEADERS += ../common/gl/yacreader_flow_gl.h + } +} + +SOURCES += comic_flow.cpp \ + create_library_dialog.cpp \ + library_creator.cpp \ + library_window.cpp \ + main.cpp \ + add_library_dialog.cpp \ + rename_library_dialog.cpp \ + properties_dialog.cpp \ + options_dialog.cpp \ + export_library_dialog.cpp \ + import_library_dialog.cpp \ + package_manager.cpp \ + bundle_creator.cpp \ + export_comics_info_dialog.cpp \ + import_comics_info_dialog.cpp \ + server_config_dialog.cpp \ + comic_flow_widget.cpp \ + db_helper.cpp \ + ./db/data_base_management.cpp \ + ./db/folder_item.cpp \ + ./db/folder_model.cpp \ + ./db/comic_model.cpp \ + ./db/comic_item.cpp \ + ../common/comic_db.cpp \ + ../common/folder.cpp \ + ../common/library_item.cpp \ + ../common/comic.cpp \ + ../common/bookmarks.cpp \ + ../common/pictureflow.cpp \ + ../common/custom_widgets.cpp \ + ../common/qnaturalsorting.cpp \ + ../common/onstart_flow_selection_dialog.cpp \ + no_libraries_widget.cpp \ + import_widget.cpp \ + yacreader_local_server.cpp \ + yacreader_main_toolbar.cpp \ + comics_remover.cpp \ + ../common/http_worker.cpp \ + ../common/yacreader_global.cpp \ + ../common/yacreader_global_gui.cpp \ + yacreader_libraries.cpp \ + ../common/exit_check.cpp \ + comics_view.cpp \ + classic_comics_view.cpp \ + empty_folder_widget.cpp \ + no_search_results_widget.cpp \ + comic_files_manager.cpp \ + db/reading_list_model.cpp \ + db/reading_list_item.cpp \ + yacreader_folders_view.cpp \ + yacreader_reading_lists_view.cpp \ + add_label_dialog.cpp \ + yacreader_history_controller.cpp \ + yacreader_navigation_controller.cpp \ + empty_label_widget.cpp \ + empty_container_info.cpp \ + empty_special_list.cpp \ + empty_reading_list_widget.cpp \ + ../common/scroll_management.cpp \ + ../common/opengl_checker.cpp \ + yacreader_comics_views_manager.cpp \ + info_comics_view.cpp \ + yacreader_comics_selection_helper.cpp \ + yacreader_comic_info_helper.cpp + +!CONFIG(no_opengl) { + CONFIG(legacy_gl_widget) { + message("using legacy YACReaderFlowGL (QGLWidget) source code") + SOURCES += ../common/gl_legacy/yacreader_flow_gl.cpp + } else { + SOURCES += ../common/gl/yacreader_flow_gl.cpp + } +} + + +include(./server/server.pri) +include(../custom_widgets/custom_widgets_yacreaderlibrary.pri) +CONFIG(7zip){ +include(../compressed_archive/wrapper.pri) +} else:CONFIG(unarr) { +include(../compressed_archive/unarr/unarr-wrapper.pri) +} else { + error(No compression backend specified. Did you mess with the build system?) +} + +include(./comic_vine/comic_vine.pri) +include(../QsLog/QsLog.pri) +include(../shortcuts_management/shortcuts_management.pri) + +RESOURCES += images.qrc files.qrc +win32:RESOURCES += images_win.qrc +unix:!macx:RESOURCES += images_win.qrc +macx:RESOURCES += images_osx.qrc + +RC_FILE = icon.rc + +macx { + ICON = YACReaderLibrary.icns +} + +TRANSLATIONS = yacreaderlibrary_es.ts \ + yacreaderlibrary_ru.ts \ + yacreaderlibrary_pt.ts \ + yacreaderlibrary_fr.ts \ + yacreaderlibrary_nl.ts \ + yacreaderlibrary_tr.ts \ + yacreaderlibrary_de.ts \ + yacreaderlibrary_source.ts + +CONFIG(force_angle) { + Release:DESTDIR = ../release_angle + Debug:DESTDIR = ../debug_angle +} else { + Release:DESTDIR = ../release + Debug:DESTDIR = ../debug +} + +#QML/GridView +QT += quick qml + +HEADERS += grid_comics_view.h \ + comics_view_transition.h + +SOURCES += grid_comics_view.cpp \ + comics_view_transition.cpp + +RESOURCES += qml.qrc +win32:RESOURCES += qml_win.qrc +unix:!macx:RESOURCES += qml_win.qrc +macx:RESOURCES += qml_osx.qrc + +unix:!macx { +#set install prefix if it's empty +isEmpty(PREFIX) { + PREFIX = /usr +} + +BINDIR = $$PREFIX/bin +LIBDIR = $$PREFIX/lib +DATADIR = $$PREFIX/share + +DEFINES += "LIBDIR=\\\"$$LIBDIR\\\"" "DATADIR=\\\"$$DATADIR\\\"" "BINDIR=\\\"$$BINDIR\\\"" + +#MAKE INSTALL +INSTALLS += bin icon desktop server translation manpage + +bin.path = $$BINDIR +isEmpty(DESTDIR) { + bin.files = YACReaderLibrary +} else { + bin.files = $$DESTDIR/YACReaderLibrary +} + +server.path = $$DATADIR/yacreader +server.files = ../release/server + +icon.path = $$DATADIR/yacreader +icon.files = ../images/iconLibrary.png ../images/db.png ../images/coversPackage.png + +desktop.path = $$DATADIR/applications +desktop.extra = desktop-file-edit --set-icon=$$DATADIR/yacreader/iconLibrary.png $$PWD/../YACReaderLibrary.desktop +desktop.files = ../YACReaderLibrary.desktop +#TODO: icons should be located at /usr/share/icons and have the same basename as their application + +translation.path = $$DATADIR/yacreader/languages +translation.files = ../release/languages/yacreaderlibrary_* + +manpage.path = $$DATADIR/man/man1 +manpage.files = ../YACReaderLibrary.1 +} diff --git a/YACReaderLibrary/classic_comics_view.cpp b/YACReaderLibrary/classic_comics_view.cpp index 2da9845a..90a3736a 100644 --- a/YACReaderLibrary/classic_comics_view.cpp +++ b/YACReaderLibrary/classic_comics_view.cpp @@ -88,8 +88,6 @@ ClassicComicsView::ClassicComicsView(QWidget *parent) sVertical->restoreState(settings->value(COMICS_VIEW_FLOW_SPLITTER_STATUS).toByteArray()); //hide flow widgets - toolBarStretch = new YACReaderToolBarStretch(this); - hideFlowViewAction = new QAction(this); hideFlowViewAction->setText(tr("Hide comic flow")); hideFlowViewAction->setData(HIDE_COMIC_VIEW_ACTION_YL); @@ -127,6 +125,8 @@ void ClassicComicsView::setToolBar(QToolBar *toolBar) static_cast(comics->layout())->insertWidget(0,toolBar); this->toolbar = toolBar; + toolBarStretch = new YACReaderToolBarStretch(this); + toolBarStretchAction = toolBar->addWidget(toolBarStretch); toolBar->addAction(hideFlowViewAction); } diff --git a/YACReaderLibrary/comics_view.cpp b/YACReaderLibrary/comics_view.cpp index d23dcc53..96e46f75 100644 --- a/YACReaderLibrary/comics_view.cpp +++ b/YACReaderLibrary/comics_view.cpp @@ -1,11 +1,14 @@ #include "comics_view.h" #include "comic.h" #include "comic_files_manager.h" +#include "comic_db.h" #include "QsLog.h" +#include + ComicsView::ComicsView(QWidget *parent) : - QWidget(parent),model(NULL) + QWidget(parent),model(NULL),comicDB(nullptr) { setAcceptDrops(true); } @@ -15,6 +18,22 @@ void ComicsView::setModel(ComicModel *m) model = m; } +void ComicsView::updateInfoForIndex(int index) +{ + QQmlContext *ctxt = view->rootContext(); + + if(comicDB != nullptr) delete comicDB; + + comicDB = new ComicDB(model->getComic(this->model->index(index, 0))); + ComicInfo *comicInfo = &(comicDB->info); + comicInfo->isFavorite = model->isFavorite(model->index(index,0)); + + ctxt->setContextProperty("comic", comicDB); + ctxt->setContextProperty("comicInfo", comicInfo); + + ctxt->setContextProperty("comic_info_index", index); +} + void ComicsView::dragEnterEvent(QDragEnterEvent *event) { if(model->canDropMimeData(event->mimeData(),event->proposedAction(),0,0,QModelIndex())) diff --git a/YACReaderLibrary/comics_view.h b/YACReaderLibrary/comics_view.h index 2d4f1940..1876343c 100644 --- a/YACReaderLibrary/comics_view.h +++ b/YACReaderLibrary/comics_view.h @@ -10,6 +10,8 @@ class QSplitter; class ComicFlowWidget; class QToolBar; class ComicModel; +class QQuickView; + class ComicsView : public QWidget { Q_OBJECT @@ -27,6 +29,11 @@ public: virtual void enableFilterMode(bool enabled) = 0; virtual void selectIndex(int index) = 0; +public slots: + virtual void updateInfoForIndex(int index); + virtual void setShowMarks(bool show) = 0; + virtual void selectAll() = 0; + signals: void selected(unsigned int); void comicRated(int,QModelIndex); @@ -39,9 +46,6 @@ signals: void copyComicsToCurrentFolder(QList >); void moveComicsToCurrentFolder(QList >); -public slots: - virtual void setShowMarks(bool show) = 0; - virtual void selectAll() = 0; protected: ComicModel * model; @@ -49,6 +53,11 @@ protected: void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); + QQuickView *view; + QWidget *container; + + ComicDB *comicDB; + private: }; diff --git a/YACReaderLibrary/comics_view_transition.cpp b/YACReaderLibrary/comics_view_transition.cpp index a41e1070..08893d7d 100644 --- a/YACReaderLibrary/comics_view_transition.cpp +++ b/YACReaderLibrary/comics_view_transition.cpp @@ -11,42 +11,14 @@ #include "yacreader_global_gui.h" ComicsViewTransition::ComicsViewTransition(QWidget *parent) : - QWidget(parent),movie(0) + QWidget(parent) { - QVBoxLayout * layout = new QVBoxLayout; - - settings = new QSettings(YACReader::getSettingsPath()+"/YACReaderLibrary.ini",QSettings::IniFormat); - settings->beginGroup("libraryConfig"); - - movieLabel = new QLabel("Placeholder"); - movieLabel->setAlignment(Qt::AlignCenter); - QLabel * textLabel = new QLabel("Switching comics view"); - textLabel->setAlignment(Qt::AlignCenter); - #ifdef Q_OS_MAC - textLabel->setStyleSheet("QLabel {color:#888888; font-size:24px;font-family:Arial;font-weight:bold;}"); setStyleSheet("QWidget {background:#FFFFFF}"); #else - textLabel->setStyleSheet("QLabel {color:#CCCCCC; font-size:24px;font-family:Arial;font-weight:bold;}"); setStyleSheet("QWidget {background:#2A2A2A}"); #endif - //movieLabel->setFixedSize(450,350); - - layout->addSpacing(100); - layout->addWidget(movieLabel); - layout->addSpacing(20); - layout->addWidget(textLabel); - layout->addStretch(); - layout->setMargin(0); - layout->setSpacing(0); - - setContentsMargins(0,0,0,0); - - //QSizePolicy sp(); - setSizePolicy(QSizePolicy ::Expanding , QSizePolicy ::Expanding ); - //movieLabel->setSizePolicy(QSizePolicy ::Expanding , QSizePolicy ::Expanding ); - setLayout(layout); } QSize ComicsViewTransition::sizeHint() @@ -54,25 +26,6 @@ QSize ComicsViewTransition::sizeHint() return QSize(450,350); } -void ComicsViewTransition::startMovie() -{ - if(movie) - delete movie; - - if(settings->value(COMICS_VIEW_STATUS) == YACReader::Flow) - movie = new QMovie(":/images/flow_to_grid.gif"); - else - movie = new QMovie(":/images/grid_to_flow.gif"); - - connect(movie,SIGNAL(finished()),this,SIGNAL(transitionFinished())); - //connect(movie,SIGNAL(finished()),movie,SLOT(deleteLater()); - movie->setSpeed(200); - movie->jumpToFrame(0); - movieLabel->setMovie(movie); - - QTimer::singleShot(100,movie,SLOT(start())); -} - void ComicsViewTransition::paintEvent(QPaintEvent *) { QPainter painter (this); diff --git a/YACReaderLibrary/comics_view_transition.h b/YACReaderLibrary/comics_view_transition.h index ed8c55ba..774c53bd 100644 --- a/YACReaderLibrary/comics_view_transition.h +++ b/YACReaderLibrary/comics_view_transition.h @@ -3,10 +3,6 @@ #include -class QMovie; -class QSettings; -class QLabel; - class ComicsViewTransition : public QWidget { Q_OBJECT @@ -14,17 +10,7 @@ public: explicit ComicsViewTransition(QWidget *parent = 0); QSize sizeHint(); -signals: - void transitionFinished(); - -public slots: - void startMovie(); - protected: - QMovie * movie; - QSettings * settings; - QLabel * movieLabel; - void paintEvent(QPaintEvent *); }; diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index 80118626..cb9efa17 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -1107,8 +1107,8 @@ void ComicModel::deleteComicsFromFavorites(const QList &comicsList) db.close(); QSqlDatabase::removeDatabase(_databasePath); - deleteComicsFromModel(comicsList); - + if(mode == Favorites) + deleteComicsFromModel(comicsList); } void ComicModel::deleteComicsFromLabel(const QList &comicsList, qulonglong labelId) @@ -1155,6 +1155,19 @@ void ComicModel::deleteComicsFromModel(const QList &comicsList) emit isEmpty(); } +bool ComicModel::isFavorite(const QModelIndex &index) +{ + bool isFavorite; + + QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); + + isFavorite = DBHelper::isFavoriteComic(_data[index.row()]->data(Id).toLongLong(),db); + + db.close(); + QSqlDatabase::removeDatabase(_databasePath); + + return isFavorite; +} void ComicModel::updateRating(int rating, QModelIndex mi) { diff --git a/YACReaderLibrary/db/comic_model.h b/YACReaderLibrary/db/comic_model.h index ce0de290..bf517298 100644 --- a/YACReaderLibrary/db/comic_model.h +++ b/YACReaderLibrary/db/comic_model.h @@ -81,6 +81,8 @@ public: void deleteComicsFromModel(const QList &comicsList); + bool isFavorite(const QModelIndex &index); + QHash roleNames() const; enum Columns { diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index 9f784f91..6b1d995d 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -1062,3 +1062,18 @@ QList DBHelper::loadSubfoldersNames(qulonglong folderId, QSqlDatabase & } return result; } + +bool DBHelper::isFavoriteComic(qulonglong id, QSqlDatabase &db) +{ + QSqlQuery selectQuery(db); + selectQuery.prepare("SELECT * FROM comic_default_reading_list cl WHERE cl.comic_id = :comic_id AND cl.default_reading_list_id = 1"); + selectQuery.bindValue(":comic_id", id); + selectQuery.exec(); + + if(selectQuery.next()) + { + return true; + } + + return false; +} diff --git a/YACReaderLibrary/db_helper.h b/YACReaderLibrary/db_helper.h index 5eb2eae3..5dee01d6 100644 --- a/YACReaderLibrary/db_helper.h +++ b/YACReaderLibrary/db_helper.h @@ -76,6 +76,8 @@ public: static ComicDB loadComic(QString cname, QString cpath, QString chash, QSqlDatabase & database); static ComicInfo loadComicInfo(QString hash, QSqlDatabase & db); static QList loadSubfoldersNames(qulonglong folderId, QSqlDatabase & db); + //queries + static bool isFavoriteComic(qulonglong id, QSqlDatabase & db); }; #endif diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index 0643b498..250cf55a 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -8,6 +8,9 @@ #include "QsLog.h" #include "yacreader_global.h" #include "yacreader_tool_bar_stretch.h" +#include "comic_db.h" +#include "yacreader_comics_selection_helper.h" +#include "yacreader_comic_info_helper.h" //values relative to visible cells const unsigned int YACREADER_MIN_GRID_ZOOM_WIDTH = 156; @@ -27,12 +30,14 @@ const unsigned int YACREADER_MIN_ITEM_WIDTH = YACREADER_MIN_COVER_WIDTH; GridComicsView::GridComicsView(QWidget *parent) : - ComicsView(parent),_selectionModel(NULL) + ComicsView(parent) { settings = new QSettings(YACReader::getSettingsPath()+"/YACReaderLibrary.ini", QSettings::IniFormat, this); settings->beginGroup("libraryConfig"); - qmlRegisterType("comicModel",1,0,"TableModel"); + qmlRegisterType("com.yacreader.ComicModel",1,0,"ComicModel"); + qmlRegisterType("com.yacreader.ComicDB",1,0,"ComicDB"); + qmlRegisterType("com.yacreader.ComicInfo",1,0,"ComicInfo"); view = new QQuickView(); container = QWidget::createWindowContainer(view, this); @@ -40,12 +45,10 @@ GridComicsView::GridComicsView(QWidget *parent) : container->setMinimumSize(200, 200); container->setFocusPolicy(Qt::TabFocus); - createCoverSizeSliderWidget(); + selectionHelper = new YACReaderComicsSelectionHelper(this); + connect(selectionHelper, &YACReaderComicsSelectionHelper::selectionChanged, this, &GridComicsView::dummyUpdater); - int coverSize = settings->value(COMICS_GRID_COVER_SIZES, YACREADER_MIN_COVER_WIDTH).toInt(); - - coverSizeSlider->setValue(coverSize); - setCoversSize(coverSize); + comicInfoHelper = new YACReaderComicInfoHelper(this); QQmlContext *ctxt = view->rootContext(); @@ -86,18 +89,32 @@ GridComicsView::GridComicsView(QWidget *parent) : ctxt->setContextProperty("backgroundBlurVisible", false); ComicModel *model = new ComicModel(); - QItemSelectionModel *selectionModel = new QItemSelectionModel(model); + selectionHelper->setModel(model); ctxt->setContextProperty("comicsList", model); - ctxt->setContextProperty("comicsSelection", selectionModel); + ctxt->setContextProperty("comicsSelection", selectionHelper->selectionModel()); ctxt->setContextProperty("contextMenuHelper",this); - ctxt->setContextProperty("comicsSelectionHelper", this); + ctxt->setContextProperty("comicsSelectionHelper", selectionHelper); + ctxt->setContextProperty("currentIndexHelper", this); ctxt->setContextProperty("comicRatingHelper", this); ctxt->setContextProperty("dummyValue", true); ctxt->setContextProperty("dragManager", this); ctxt->setContextProperty("dropManager", this); + bool showInfo = settings->value(COMICS_GRID_SHOW_INFO, false).toBool(); + ctxt->setContextProperty("showInfo", showInfo); + view->setSource(QUrl("qrc:/qml/GridComicsView.qml")); + QObject *rootObject = dynamic_cast(view->rootObject()); + QObject *infoContainer = rootObject->findChild("infoContainer"); + + QQmlProperty(infoContainer, "width").write(settings->value(COMICS_GRID_INFO_WIDTH, 350)); + + showInfoAction = new QAction(tr("Show info"),this); + showInfoAction->setIcon(QIcon(":/images/comics_view_toolbar/show_comic_info.png")); + showInfoAction->setCheckable(true); + showInfoAction->setChecked(showInfo); + connect(showInfoAction, &QAction::toggled, this, &GridComicsView::showInfo); setShowMarks(true);//TODO save this in settings @@ -141,6 +158,11 @@ void GridComicsView::createCoverSizeSliderWidget() //TODO add shortcuts (ctrl-+ and ctrl-- for zooming in out, + ctrl-0 for reseting the zoom) connect(coverSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(setCoversSize(int))); + + int coverSize = settings->value(COMICS_GRID_COVER_SIZES, YACREADER_MIN_COVER_WIDTH).toInt(); + + coverSizeSlider->setValue(coverSize); + setCoversSize(coverSize); } void GridComicsView::setToolBar(QToolBar *toolBar) @@ -148,8 +170,12 @@ void GridComicsView::setToolBar(QToolBar *toolBar) static_cast(this->layout())->insertWidget(1,toolBar); this->toolbar = toolBar; - toolBarStretchAction = toolBar->addWidget(toolBarStretch); - coverSizeSliderAction = toolBar->addWidget(coverSizeSliderWidget); + createCoverSizeSliderWidget(); + + toolBarStretchAction = toolBar->addWidget(toolBarStretch); + toolBar->addAction(showInfoAction); + showInfoSeparatorAction = toolBar->addSeparator(); + coverSizeSliderAction = toolBar->addWidget(coverSizeSliderWidget); } void GridComicsView::setModel(ComicModel *model) @@ -159,27 +185,30 @@ void GridComicsView::setModel(ComicModel *model) ComicsView::setModel(model); + selectionHelper->setModel(model); + comicInfoHelper->setModel(model); + QQmlContext *ctxt = view->rootContext(); - if(_selectionModel != NULL) - delete _selectionModel; - - _selectionModel = new QItemSelectionModel(model); - - //TODO fix crash in the following line on comics views switch ctxt->setContextProperty("comicsList", model); - ctxt->setContextProperty("comicsSelection", _selectionModel); + ctxt->setContextProperty("comicsSelection", selectionHelper->selectionModel()); ctxt->setContextProperty("contextMenuHelper",this); - ctxt->setContextProperty("comicsSelectionHelper", this); + ctxt->setContextProperty("comicsSelectionHelper", selectionHelper); + ctxt->setContextProperty("currentIndexHelper", this); ctxt->setContextProperty("comicRatingHelper", this); ctxt->setContextProperty("dummyValue", true); ctxt->setContextProperty("dragManager", this); ctxt->setContextProperty("dropManager", this); + ctxt->setContextProperty("comicInfoHelper", comicInfoHelper); updateBackgroundConfig(); if(model->rowCount()>0) + { setCurrentIndex(model->index(0,0)); + if(showInfoAction->isChecked()) + updateInfoForIndex(0); + } } void GridComicsView::updateBackgroundConfig() @@ -192,7 +221,7 @@ void GridComicsView::updateBackgroundConfig() //backgroun image configuration bool useBackgroundImage = settings->value(USE_BACKGROUND_IMAGE_IN_GRID_VIEW, true).toBool(); - if(useBackgroundImage) + if(useBackgroundImage && this->model->rowCount() > 0) { float opacity = settings->value(OPACITY_BACKGROUND_IMAGE_IN_GRID_VIEW, 0.2).toFloat(); float blurRadius = settings->value(BLUR_RADIUS_BACKGROUND_IMAGE_IN_GRID_VIEW, 75).toInt(); @@ -221,41 +250,39 @@ void GridComicsView::updateBackgroundConfig() #endif } +void GridComicsView::showInfo() +{ + QQmlContext *ctxt = view->rootContext(); + ctxt->setContextProperty("showInfo", showInfoAction->isChecked()); + + updateInfoForIndex(currentIndex().row()); +} + void GridComicsView::setCurrentIndex(const QModelIndex &index) { - _selectionModel->clear(); - _selectionModel->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); - view->rootContext()->setContextProperty("dummyValue", true); + selectionHelper->clear(); + selectionHelper->selectIndex(index.row()); if(settings->value(USE_SELECTED_COMIC_COVER_AS_BACKGROUND_IMAGE_IN_GRID_VIEW, false).toBool()) updateBackgroundConfig(); + + if(showInfoAction->isChecked()) + updateInfoForIndex(index.row()); +} + +void GridComicsView::setCurrentIndex(int index) +{ + setCurrentIndex(model->index(index,0)); } QModelIndex GridComicsView::currentIndex() { - - if(!_selectionModel) - return QModelIndex(); - - QModelIndexList indexes = _selectionModel->selectedRows(); - if(indexes.length()>0) - return indexes[0]; - - this->selectIndex(0); - indexes = _selectionModel->selectedRows(); - if(indexes.length()>0) - return indexes[0]; - else - return QModelIndex(); + return selectionHelper->currentIndex(); } QItemSelectionModel *GridComicsView::selectionModel() { - QModelIndexList indexes = _selectionModel->selectedRows(); - if(indexes.length()==0) - this->selectIndex(0); - - return _selectionModel; + return selectionHelper->selectionModel(); } void GridComicsView::scrollTo(const QModelIndex &mi, QAbstractItemView::ScrollHint hint) @@ -286,11 +313,12 @@ void GridComicsView::enableFilterMode(bool enabled) void GridComicsView::selectAll() { - QModelIndex top = model->index(0, 0); - QModelIndex bottom = model->index(model->rowCount()-1, 0); - QItemSelection selection(top, bottom); - _selectionModel->select(selection, QItemSelectionModel::Select | QItemSelectionModel::Rows); - view->rootContext()->setContextProperty("dummyValue", true); + selectionHelper->selectAll(); +} + +void GridComicsView::selectIndex(int index) +{ + selectionHelper->selectIndex(index); } void GridComicsView::rate(int index, int rating) @@ -328,6 +356,12 @@ void GridComicsView::setCoversSize(int width) ctxt->setContextProperty("coverHeight", (width * YACREADER_MAX_COVER_HEIGHT) / YACREADER_MIN_COVER_WIDTH); } +void GridComicsView::dummyUpdater() +{ + QQmlContext *ctxt = view->rootContext(); + ctxt->setContextProperty("dummyValue", true); +} + QSize GridComicsView::sizeHint() { return QSize(1280,768); @@ -337,7 +371,7 @@ QByteArray GridComicsView::getMimeDataFromSelection() { QByteArray data; - QMimeData * mimeData = model->mimeData(_selectionModel->selectedIndexes()); + QMimeData * mimeData = model->mimeData(selectionHelper->selectedIndexes()); data = mimeData->data(YACReader::YACReaderLibrarComiscSelectionMimeDataFormat); delete mimeData; @@ -348,7 +382,7 @@ QByteArray GridComicsView::getMimeDataFromSelection() void GridComicsView::startDrag() { QDrag *drag = new QDrag(this); - drag->setMimeData(model->mimeData(_selectionModel->selectedRows())); + drag->setMimeData(model->mimeData(selectionHelper->selectedRows())); drag->setPixmap(QPixmap(":/images/comics_view_toolbar/openInYACReader.png")); //TODO add better image /*Qt::DropAction dropAction =*/ drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction); @@ -390,78 +424,12 @@ void GridComicsView::droppedComicsForResortingAt(const QString &data, int index) { Q_UNUSED(data); - model->dropMimeData(model->mimeData(_selectionModel->selectedRows()), Qt::MoveAction, index, 0, QModelIndex()); -} - -//helper -void GridComicsView::selectIndex(int index) -{ - if(_selectionModel != NULL && model!=NULL) - { - _selectionModel->select(model->index(index,0),QItemSelectionModel::Select | QItemSelectionModel::Rows); - view->rootContext()->setContextProperty("dummyValue", true); - } -} - -void GridComicsView::setCurrentIndex(int index) -{ - setCurrentIndex(model->index(index,0)); -} - -void GridComicsView::deselectIndex(int index) -{ - if(_selectionModel != NULL && model!=NULL) - { - _selectionModel->select(model->index(index,0),QItemSelectionModel::Deselect | QItemSelectionModel::Rows); - view->rootContext()->setContextProperty("dummyValue", true); - } -} - -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() -{ - if(_selectionModel != NULL) - { - _selectionModel->clear(); - - QQmlContext *ctxt = view->rootContext(); - ctxt->setContextProperty("dummyValue", true); - } - //model->forceClear(); + model->dropMimeData(model->mimeData(selectionHelper->selectedRows()), Qt::MoveAction, index, 0, QModelIndex()); } void GridComicsView::selectedItem(int index) { - emit doubleClicked(model->index(index,0)); -} - -int GridComicsView::numItemsSelected() -{ - if(_selectionModel != NULL) - { - return _selectionModel->selectedRows().length(); - } - - return 0; -} - -int GridComicsView::lastSelectedIndex() -{ - if(_selectionModel != NULL) - { - return _selectionModel->selectedRows().last().row(); - } - - return -1; + emit selected(index); } void GridComicsView::setShowMarks(bool show) @@ -473,15 +441,25 @@ void GridComicsView::setShowMarks(bool show) void GridComicsView::closeEvent(QCloseEvent *event) { toolbar->removeAction(toolBarStretchAction); + toolbar->removeAction(showInfoAction); + toolbar->removeAction(showInfoSeparatorAction); toolbar->removeAction(coverSizeSliderAction); - QObject *object = view->rootObject(); + QObject *rootObject = dynamic_cast(view->rootObject()); + QObject *infoContainer = rootObject->findChild("infoContainer"); + + int infoWidth = QQmlProperty(infoContainer, "width").read().toInt(); + + /*QObject *object = view->rootObject(); QMetaObject::invokeMethod(object, "exit"); container->close(); - view->close(); + view->close();*/ + event->accept(); ComicsView::closeEvent(event); //save settings settings->setValue(COMICS_GRID_COVER_SIZES, coverSizeSlider->value()); + settings->setValue(COMICS_GRID_SHOW_INFO, showInfoAction->isChecked()); + settings->setValue(COMICS_GRID_INFO_WIDTH, infoWidth); } diff --git a/YACReaderLibrary/grid_comics_view.h b/YACReaderLibrary/grid_comics_view.h index 8a876198..8d3348ce 100644 --- a/YACReaderLibrary/grid_comics_view.h +++ b/YACReaderLibrary/grid_comics_view.h @@ -5,12 +5,18 @@ #include + + class QAbstractListModel; class QItemSelectionModel; class QQuickView; class QQuickView; class YACReaderToolBarStretch; +class YACReaderComicsSelectionHelper; +class YACReaderComicInfoHelper; + + class GridComicsView : public ComicsView { @@ -31,44 +37,37 @@ public: QSize sizeHint(); QByteArray getMimeDataFromSelection(); - -signals: - void comicRated(int,QModelIndex); - void doubleClicked(QModelIndex); - public slots: - //selection helper - void selectIndex(int index); - void setCurrentIndex(int index); - void deselectIndex(int index); - bool isSelectedIndex(int index); - void clear(); - //double clicked item - void selectedItem(int index); - int numItemsSelected(); - int lastSelectedIndex(); - //ComicsView void setShowMarks(bool show); void selectAll(); + void selectIndex(int index); - //rating + void updateBackgroundConfig(); + + void showInfo(); + +protected slots: + void setCurrentIndex(int index); + //QML - double clicked item + void selectedItem(int index); + + //QML - rating void rate(int index, int rating); - - //dragManager + //QML - dragManager void startDrag(); - //dropManager + //QML - dropManager bool canDropUrls(const QList & urls, Qt::DropAction action); bool canDropFormats(const QString &formats); void droppedFiles(const QList & urls, Qt::DropAction action); void droppedComicsForResortingAt(const QString & data, int index); - - void updateBackgroundConfig(); - -protected slots: + //QML - context menu void requestedContextMenu(const QPoint & point); + void setCoversSize(int width); + void dummyUpdater(); //TODO remove this + private: QSettings * settings; QToolBar * toolbar; @@ -77,9 +76,12 @@ private: QWidget * coverSizeSliderWidget; QSlider * coverSizeSlider; QAction * coverSizeSliderAction; - QItemSelectionModel * _selectionModel; - QQuickView *view; - QWidget *container; + QAction * showInfoAction; + QAction * showInfoSeparatorAction; + + YACReaderComicsSelectionHelper * selectionHelper; + YACReaderComicInfoHelper * comicInfoHelper; + bool dummy; void closeEvent ( QCloseEvent * event ); void createCoverSizeSliderWidget(); diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index 3eb7b46c..07aa91bc 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -35,7 +35,9 @@ ../images/comics_view_toolbar/small_size_grid_zoom.png ../images/comics_view_toolbar/small_size_grid_zoom@2x.png ../images/comics_view_toolbar/trash.png - ../images/comics_view_toolbar/trash.png + ../images/comics_view_toolbar/trash@2x.png + ../images/comics_view_toolbar/show_comic_info.png + ../images/comics_view_toolbar/show_comic_info@2x.png ../images/coversPackage.png ../images/db.png ../images/defaultCover.png diff --git a/YACReaderLibrary/images_osx.qrc b/YACReaderLibrary/images_osx.qrc index 5f9106a3..4cac9ddc 100644 --- a/YACReaderLibrary/images_osx.qrc +++ b/YACReaderLibrary/images_osx.qrc @@ -15,13 +15,10 @@ ../images/main_toolbar/flow_osx@2x.png ../images/main_toolbar/grid_osx.png ../images/main_toolbar/grid_osx@2x.png - ../images/flow_to_grid_osx.gif - ../images/grid_to_flow_osx.gif ../images/empty_folder_osx.png ../images/empty_search_osx.png ../images/iconSearch.png ../images/clearSearch.png - ../images/lists/default_0_osx.png ../images/lists/default_1_osx.png ../images/lists/label_blue_osx.png @@ -38,7 +35,6 @@ ../images/lists/label_yellow_osx.png ../images/lists/list_osx.png ../images/empty_reading_list_osx.png - ../images/lists/default_0_osx@2x.png ../images/lists/default_1_osx@2x.png ../images/lists/label_blue_osx@2x.png @@ -54,7 +50,6 @@ ../images/lists/label_white_osx@2x.png ../images/lists/label_yellow_osx@2x.png ../images/lists/list_osx@2x.png - ../images/sidebar/libraryIcon_osx.png ../images/sidebar/setRoot_osx.png ../images/sidebar/expand_osx.png @@ -65,8 +60,6 @@ ../images/sidebar/delete_sidebar_osx.png ../images/sidebar/addLabelIcon_osx.png ../images/sidebar/renameListIcon_osx.png - - ../images/sidebar/setRoot_osx@2x.png ../images/sidebar/expand_osx@2x.png ../images/sidebar/colapse_osx@2x.png diff --git a/YACReaderLibrary/images_win.qrc b/YACReaderLibrary/images_win.qrc index 0e042c76..fdb1ea0b 100644 --- a/YACReaderLibrary/images_win.qrc +++ b/YACReaderLibrary/images_win.qrc @@ -16,8 +16,7 @@ ../images/sidebar/openLibraryIcon.png ../images/main_toolbar/flow.png ../images/main_toolbar/grid.png - ../images/flow_to_grid.gif - ../images/grid_to_flow.gif + ../images/main_toolbar/info.png ../images/empty_folder.png ../images/empty_search.png ../images/sidebar/addNew_sidebar.png @@ -26,7 +25,6 @@ ../images/clearSearchNew.png ../images/sidebar/addLabelIcon.png ../images/sidebar/renameListIcon.png - ../images/lists/default_0.png ../images/lists/default_1.png ../images/lists/label_blue.png @@ -44,4 +42,4 @@ ../images/lists/list.png ../images/empty_reading_list.png - \ No newline at end of file + diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp new file mode 100644 index 00000000..5912686b --- /dev/null +++ b/YACReaderLibrary/info_comics_view.cpp @@ -0,0 +1,203 @@ +#include "info_comics_view.h" + +#include + +#include "comic.h" +#include "comic_files_manager.h" +#include "comic_model.h" +#include "comic_db.h" +#include "yacreader_comic_info_helper.h" +#include "yacreader_comics_selection_helper.h" + +#include "QsLog.h" + +InfoComicsView::InfoComicsView(QWidget *parent) + :ComicsView(parent) +{ + qmlRegisterType("com.yacreader.ComicModel",1,0,"ComicModel"); + qmlRegisterType("com.yacreader.ComicDB",1,0,"ComicDB"); + qmlRegisterType("com.yacreader.ComicInfo",1,0,"ComicInfo"); + + view = new QQuickView(); + container = QWidget::createWindowContainer(view, this); + + container->setFocusPolicy(Qt::StrongFocus); + + view->setSource(QUrl("qrc:/qml/InfoComicsView.qml")); + + + QObject *rootObject = dynamic_cast(view->rootObject()); + flow = rootObject->findChild("flow"); + list = rootObject->findChild("list"); + + connect(flow, SIGNAL(currentCoverChanged(int)), this, SLOT(updateInfoForIndex(int))); + connect(flow, SIGNAL(currentCoverChanged(int)), this, SLOT(setCurrentIndex(int))); + + selectionHelper = new YACReaderComicsSelectionHelper(this); + comicInfoHelper = new YACReaderComicInfoHelper(this); + + QVBoxLayout * l = new QVBoxLayout; + l->addWidget(container); + this->setLayout(l); + + setContentsMargins(0,0,0,0); + l->setContentsMargins(0,0,0,0); + l->setSpacing(0); + + setShowMarks(true); + + QLOG_TRACE() << "GridComicsView"; +} + +InfoComicsView::~InfoComicsView() +{ + delete view; +} + +void InfoComicsView::setToolBar(QToolBar *toolBar) +{ + static_cast(this->layout())->insertWidget(1,toolBar); + this->toolbar = toolBar; +} + +void InfoComicsView::setModel(ComicModel *model) +{ + if(model == NULL) + return; + + selectionHelper->setModel(model); + comicInfoHelper->setModel(model); + + ComicsView::setModel(model); + + QQmlContext *ctxt = view->rootContext(); + + /*if(_selectionModel != NULL) + delete _selectionModel; + + _selectionModel = new QItemSelectionModel(model);*/ + + ctxt->setContextProperty("comicsList", model); + if(model->rowCount()>0) + ctxt->setContextProperty("backgroundImage", this->model->data(this->model->index(0, 0), ComicModel::CoverPathRole)); + else + ctxt->setContextProperty("backgroundImage", QUrl()); + + ctxt->setContextProperty("comicsSelection", selectionHelper->selectionModel()); + ctxt->setContextProperty("contextMenuHelper",this); + ctxt->setContextProperty("currentIndexHelper", this); + ctxt->setContextProperty("comicInfoHelper", comicInfoHelper); + /*ctxt->setContextProperty("comicsSelectionHelper", this); + ctxt->setContextProperty("dragManager", this);*/ + ctxt->setContextProperty("dropManager", this); + + + if(model->rowCount()>0) + { + setCurrentIndex(model->index(0,0)); + updateInfoForIndex(0); + } +} + +void InfoComicsView::setCurrentIndex(const QModelIndex &index) +{ + QQmlProperty(list, "currentIndex").write(index.row()); + + selectionHelper->clear(); + selectionHelper->selectIndex(index.row()); +} + +void InfoComicsView::setCurrentIndex(int index) +{ + selectionHelper->clear(); + selectionHelper->selectIndex(index); +} + +QModelIndex InfoComicsView::currentIndex() +{ + return selectionHelper->currentIndex(); +} + +QItemSelectionModel *InfoComicsView::selectionModel() +{ + return selectionHelper->selectionModel(); +} + +void InfoComicsView::scrollTo(const QModelIndex &mi, QAbstractItemView::ScrollHint hint) +{ + Q_UNUSED(mi); + Q_UNUSED(hint); +} + +void InfoComicsView::toFullScreen() +{ + toolbar->hide(); +} + +void InfoComicsView::toNormal() +{ + toolbar->show(); +} + +void InfoComicsView::updateConfig(QSettings *settings) +{ + Q_UNUSED(settings); +} + +void InfoComicsView::enableFilterMode(bool enabled) +{ + Q_UNUSED(enabled); +} + +void InfoComicsView::selectIndex(int index) +{ + selectionHelper->selectIndex(index); +} + +void InfoComicsView::setShowMarks(bool show) +{ + QQmlContext *ctxt = view->rootContext(); + ctxt->setContextProperty("show_marks", show); +} + +void InfoComicsView::selectAll() +{ + selectionHelper->selectAll(); +} + +bool InfoComicsView::canDropUrls(const QList &urls, Qt::DropAction action) +{ + if(action == Qt::CopyAction) + { + QString currentPath; + foreach (QUrl url, urls) + { + //comics or folders are accepted, folders' content is validate in dropEvent (avoid any lag before droping) + currentPath = url.toLocalFile(); + if(Comic::fileIsComic(currentPath) || QFileInfo(currentPath).isDir()) + return true; + } + } + return false; +} + +void InfoComicsView::droppedFiles(const QList &urls, Qt::DropAction action) +{ + bool validAction = action == Qt::CopyAction; //TODO add move + + if(validAction) + { + QList > droppedFiles = ComicFilesManager::getDroppedFiles(urls); + emit copyComicsToCurrentFolder(droppedFiles); + } +} + +void InfoComicsView::requestedContextMenu(const QPoint &point) +{ + emit customContextMenuViewRequested(point); +} + +void InfoComicsView::selectedItem(int index) +{ + emit selected(index); +} diff --git a/YACReaderLibrary/info_comics_view.h b/YACReaderLibrary/info_comics_view.h new file mode 100644 index 00000000..53699148 --- /dev/null +++ b/YACReaderLibrary/info_comics_view.h @@ -0,0 +1,56 @@ +#ifndef INFOCOMICSVIEW_H +#define INFOCOMICSVIEW_H + +#include "comics_view.h" + + + +class QQuickView; + +class YACReaderComicsSelectionHelper; +class YACReaderComicInfoHelper; + + + +class InfoComicsView : public ComicsView +{ + Q_OBJECT +public: + explicit InfoComicsView(QWidget *parent = 0); + ~InfoComicsView(); + void setToolBar(QToolBar * toolBar); + void setModel(ComicModel *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 enableFilterMode(bool enabled); + void selectIndex(int index); + +public slots: + void setShowMarks(bool show); + void selectAll(); + +protected slots: + void setCurrentIndex(int index); + + bool canDropUrls(const QList & urls, Qt::DropAction action); + void droppedFiles(const QList & urls, Qt::DropAction action); + + void requestedContextMenu(const QPoint & point); + + void selectedItem(int index); + +protected: + QToolBar * toolbar; + QObject *flow; + QObject *list; + + YACReaderComicsSelectionHelper * selectionHelper; + YACReaderComicInfoHelper * comicInfoHelper; +}; + +#endif // INFOCOMICSVIEW_H diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index e2f942b0..9def54cf 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -63,19 +63,11 @@ #include "api_key_dialog.h" //#include "yacreader_social_dialog.h" -#include "classic_comics_view.h" -#include "grid_comics_view.h" -#include "comics_view_transition.h" -#include "empty_folder_widget.h" -#include "empty_label_widget.h" -#include "empty_special_list.h" -#include "empty_reading_list_widget.h" +#include "comics_view.h" #include "edit_shortcuts_dialog.h" #include "shortcuts_manager.h" -#include "no_search_results_widget.h" - #include "comic_files_manager.h" #include "reading_list_model.h" @@ -88,6 +80,8 @@ #include "reading_list_item.h" #include "opengl_checker.h" +#include "yacreader_comics_views_manager.h" + #include "QsLog.h" #ifdef Q_OS_WIN @@ -140,7 +134,7 @@ void LibraryWindow::setupUI() createToolBars(); createMenus(); - navigationController = new YACReaderNavigationController(this); + navigationController = new YACReaderNavigationController(this, comicsViewsManager); createConnections(); @@ -237,37 +231,14 @@ void LibraryWindow::doLayout() readingListsTitle->addSpacing(3); //FINAL LAYOUT------------------------------------------------------------- - comicsViewStack = new QStackedWidget(); - if(!settings->contains(COMICS_VIEW_STATUS) || settings->value(COMICS_VIEW_STATUS) == Flow) { - comicsView = classicComicsView = new ClassicComicsView(); - comicsViewStatus = Flow; - //comicsViewStack->setCurrentIndex(Flow); - } else { - comicsView = gridComicsView = new GridComicsView(); - connect(optionsDialog, SIGNAL(optionsChanged()), gridComicsView, SLOT(updateBackgroundConfig())); - comicsViewStatus = Grid; - //comicsViewStack->setCurrentIndex(Grid); - } - - doComicsViewConnections(); - - comicsViewStack->addWidget(comicsViewTransition = new ComicsViewTransition()); - comicsViewStack->addWidget(emptyFolderWidget = new EmptyFolderWidget()); - comicsViewStack->addWidget(emptyLabelWidget = new EmptyLabelWidget()); - comicsViewStack->addWidget(emptySpecialList = new EmptySpecialListWidget()); - comicsViewStack->addWidget(emptyReadingList = new EmptyReadingListWidget()); - comicsViewStack->addWidget(noSearchResultsWidget = new NoSearchResultsWidget()); - - comicsViewStack->addWidget(comicsView); - - comicsViewStack->setCurrentWidget(comicsView); + comicsViewsManager = new YACReaderComicsViewsManager(settings, this); sHorizontal->addWidget(sideBar); #ifndef Q_OS_MAC QVBoxLayout * rightLayout = new QVBoxLayout; rightLayout->addWidget(libraryToolBar); - rightLayout->addWidget(comicsViewStack); + rightLayout->addWidget(comicsViewsManager->containerWidget()); rightLayout->setMargin(0); rightLayout->setSpacing(0); @@ -277,7 +248,7 @@ void LibraryWindow::doLayout() sHorizontal->addWidget(rightWidget); #else - sHorizontal->addWidget(comicsViewStack); + sHorizontal->addWidget(comicsViewsManager->containerWidget()); #endif sHorizontal->setStretchFactor(0,0); @@ -433,7 +404,7 @@ void LibraryWindow::doModels() foldersModelProxy = new FolderModelProxy(); //foldersModelProxy->setSourceModel(foldersModel); //comics - comicsModel = new ComicModel(); + comicsModel = new ComicModel(this); //lists listsModel = new ReadingListModel(); listsModelProxy = new ReadingListModelProxy(); @@ -441,34 +412,6 @@ void LibraryWindow::doModels() //setSearchFilter(YACReader::NoModifiers, ""); //clear search filter } -void LibraryWindow::disconnectComicsViewConnections(ComicsView * widget) -{ - disconnect(widget, SIGNAL(comicRated(int,QModelIndex)), comicsModel, SLOT(updateRating(int,QModelIndex))); - disconnect(showHideMarksAction,SIGNAL(toggled(bool)),widget,SLOT(setShowMarks(bool))); - disconnect(widget,SIGNAL(selected(unsigned int)),this,SLOT(openComic())); - disconnect(widget,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(openComic())); - disconnect(selectAllComicsAction,SIGNAL(triggered()),widget,SLOT(selectAll())); - disconnect(comicsView, SIGNAL(copyComicsToCurrentFolder(QList >)), this, SLOT(copyAndImportComicsToCurrentFolder(QList >))); - disconnect(comicsView, SIGNAL(moveComicsToCurrentFolder(QList >)), this, SLOT(moveAndImportComicsToCurrentFolder(QList >))); - disconnect(comicsView,SIGNAL(customContextMenuViewRequested(QPoint)),this,SLOT(showComicsViewContextMenu(QPoint))); - disconnect(comicsView,SIGNAL(customContextMenuItemRequested(QPoint)),this,SLOT(showComicsItemContextMenu(QPoint))); -} - -void LibraryWindow::doComicsViewConnections() -{ - connect(comicsView, SIGNAL(comicRated(int,QModelIndex)), comicsModel, SLOT(updateRating(int,QModelIndex))); - connect(showHideMarksAction,SIGNAL(toggled(bool)),comicsView,SLOT(setShowMarks(bool))); - connect(comicsView,SIGNAL(selected(unsigned int)),this,SLOT(openComic())); - connect(comicsView,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(openComic())); - connect(selectAllComicsAction,SIGNAL(triggered()),comicsView,SLOT(selectAll())); - - connect(comicsView,SIGNAL(customContextMenuViewRequested(QPoint)),this,SLOT(showComicsViewContextMenu(QPoint))); - connect(comicsView,SIGNAL(customContextMenuItemRequested(QPoint)),this,SLOT(showComicsItemContextMenu(QPoint))); - //Drops - connect(comicsView, SIGNAL(copyComicsToCurrentFolder(QList >)), this, SLOT(copyAndImportComicsToCurrentFolder(QList >))); - connect(comicsView, SIGNAL(moveComicsToCurrentFolder(QList >)), this, SLOT(moveAndImportComicsToCurrentFolder(QList >))); -} - void LibraryWindow::createActions() { backAction = new QAction(this); @@ -647,10 +590,14 @@ void LibraryWindow::createActions() toggleComicsViewAction = new QAction(tr("Change between comics views"),this); toggleComicsViewAction->setToolTip(tr("Change between comics views")); QIcon icoViewsButton; + if(!settings->contains(COMICS_VIEW_STATUS) || settings->value(COMICS_VIEW_STATUS) == Flow) icoViewsButton.addFile(":/images/main_toolbar/grid.png", QSize(), QIcon::Normal); + else if(settings->value(COMICS_VIEW_STATUS) == Grid) + icoViewsButton.addFile(":/images/main_toolbar/info.png", QSize(), QIcon::Normal); else icoViewsButton.addFile(":/images/main_toolbar/flow.png", QSize(), QIcon::Normal); + toggleComicsViewAction->setData(TOGGLE_COMICS_VIEW_ACTION_YL); toggleComicsViewAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(TOGGLE_COMICS_VIEW_ACTION_YL)); toggleComicsViewAction->setIcon(icoViewsButton); @@ -930,7 +877,7 @@ void LibraryWindow::createToolBars() editInfoToolBar->addAction(deleteComicsAction); - comicsView->setToolBar(editInfoToolBar); + comicsViewsManager->comicsView->setToolBar(editInfoToolBar); } void LibraryWindow::createMenus() @@ -1109,7 +1056,7 @@ void LibraryWindow::createConnections() #ifndef Q_OS_MAC connect(toggleFullScreenAction,SIGNAL(triggered()),this,SLOT(toggleFullScreen())); #endif - connect(toggleComicsViewAction,SIGNAL(triggered()),this,SLOT(toggleComicsView())); + connect(toggleComicsViewAction,SIGNAL(triggered()),comicsViewsManager,SLOT(toggleComicsView())); connect(optionsAction, SIGNAL(triggered()),optionsDialog,SLOT(show())); #ifdef SERVER_RELEASE connect(serverConfigAction, SIGNAL(triggered()), serverConfigDialog, SLOT(show())); @@ -1143,14 +1090,9 @@ void LibraryWindow::createConnections() //connect(socialAction,SIGNAL(triggered()),this,SLOT(showSocial())); - connect(comicsViewTransition,SIGNAL(transitionFinished()),this,SLOT(showComicsView())); - //connect(comicsModel,SIGNAL(isEmpty()),this,SLOT(showEmptyFolderView())); //connect(comicsModel,SIGNAL(searchNumResults(int)),this,SLOT(checkSearchNumResults(int))); //connect(emptyFolderWidget,SIGNAL(subfolderSelected(QModelIndex,int)),this,SLOT(selectSubfolder(QModelIndex,int))); - //Drops - connect(emptyFolderWidget, SIGNAL(copyComicsToCurrentFolder(QList >)), this, SLOT(copyAndImportComicsToCurrentFolder(QList >))); - connect(emptyFolderWidget, SIGNAL(moveComicsToCurrentFolder(QList >)), this, SLOT(moveAndImportComicsToCurrentFolder(QList >))); connect(showEditShortcutsAction,SIGNAL(triggered()),editShortcutsDialog,SLOT(show())); @@ -1200,7 +1142,7 @@ void LibraryWindow::loadLibrary(const QString & name) } else { - comicsView->setModel(NULL); + comicsViewsManager->comicsView->setModel(NULL); foldersView->setModel(NULL); listsView->setModel(NULL); disableAllActions();//TODO comprobar que se deben deshabilitar @@ -1257,7 +1199,7 @@ void LibraryWindow::loadLibrary(const QString & name) if(ret == QMessageBox::Yes) QDesktopServices::openUrl(QUrl("http://www.yacreader.com")); - comicsView->setModel(NULL); + comicsViewsManager->comicsView->setModel(NULL); foldersView->setModel(NULL); listsView->setModel(NULL); disableAllActions();//TODO comprobar que se deben deshabilitar @@ -1268,7 +1210,7 @@ void LibraryWindow::loadLibrary(const QString & name) } else { - comicsView->setModel(NULL); + comicsViewsManager->comicsView->setModel(NULL); foldersView->setModel(NULL); listsView->setModel(NULL); disableAllActions();//TODO comprobar que se deben deshabilitar @@ -1325,10 +1267,7 @@ void LibraryWindow::loadLibrary(const QString & name) void LibraryWindow::loadCoversFromCurrentModel() { - //TODO this is a workaround for the crash in GridComicsView::setModel crash on views switching - if(typeid(*comicsView) == typeid(GridComicsView)) - comicsView->setModel(new ComicModel()); - comicsView->setModel(comicsModel); + comicsViewsManager->comicsView->setModel(comicsModel); } void LibraryWindow::copyAndImportComicsToCurrentFolder(const QList > &comics) @@ -1521,7 +1460,7 @@ void LibraryWindow::addFolderToCurrentIndex() navigationController->loadFolderInfo(newIndex); historyController->updateHistory(YACReaderLibrarySourceContainer(newIndex,YACReaderLibrarySourceContainer::Folder)); //a new folder is always an empty folder - showEmptyFolderView(); + comicsViewsManager->showEmptyFolderView(); } } } @@ -1694,7 +1633,7 @@ void LibraryWindow::showComicsViewContextMenu(const QPoint &point) menu.addAction(toggleFullScreenAction); #endif - menu.exec(comicsView->mapToGlobal(point)); + menu.exec(comicsViewsManager->comicsView->mapToGlobal(point)); } void LibraryWindow::showComicsItemContextMenu(const QPoint &point) @@ -1722,7 +1661,7 @@ void LibraryWindow::showComicsItemContextMenu(const QPoint &point) QMenu subMenu; setupAddToSubmenu(subMenu); - menu.exec(comicsView->mapToGlobal(point)); + menu.exec(comicsViewsManager->comicsView->mapToGlobal(point)); } void LibraryWindow::setupAddToSubmenu(QMenu &menu) @@ -1819,7 +1758,7 @@ void LibraryWindow::openComic() { if(!importedCovers) { - ComicDB comic = comicsModel->getComic(comicsView->currentIndex()); + ComicDB comic = comicsModel->getComic(comicsViewsManager->comicsView->currentIndex()); QString path = currentPath(); QList siblings = comicsModel->getAllComics(); @@ -1972,7 +1911,7 @@ void LibraryWindow::deleteCurrentLibrary() d.removeRecursively(); if(libraries.isEmpty())//no more libraries available. { - comicsView->setModel(NULL); + comicsViewsManager->comicsView->setModel(NULL); foldersView->setModel(NULL); listsView->setModel(NULL); @@ -1997,7 +1936,7 @@ void LibraryWindow::removeLibrary() //selectedLibrary->setCurrentIndex(0); if(libraries.isEmpty())//no more libraries available. { - comicsView->setModel(NULL); + comicsViewsManager->comicsView->setModel(NULL); foldersView->setModel(NULL); listsView->setModel(NULL); @@ -2069,7 +2008,7 @@ void LibraryWindow::setRootIndex() } else { - comicsView->setModel(NULL); + comicsViewsManager->comicsView->setModel(NULL); } foldersView->selectionModel()->clear(); @@ -2090,7 +2029,7 @@ void LibraryWindow::toFullScreen() sideBar->hide(); libraryToolBar->hide(); - comicsView->toFullScreen(); + comicsViewsManager->comicsView->toFullScreen(); showFullScreen(); } @@ -2099,7 +2038,7 @@ void LibraryWindow::toNormal() { sideBar->show(); - comicsView->toNormal(); + comicsViewsManager->comicsView->toNormal(); if(fromMaximized) showMaximized(); @@ -2125,14 +2064,14 @@ void LibraryWindow::setSearchFilter(const YACReader::SearchModifiers modifier, Q status = LibraryWindow::Searching; foldersModelProxy->setFilter(modifier, filter, true);//includeComicsCheckBox->isChecked()); comicsModel->setupModelData(modifier, filter, foldersModel->getDatabase()); - comicsView->enableFilterMode(true); - comicsView->setModel(comicsModel); //TODO, columns are messed up after ResetModel some times, this shouldn't be necesary + comicsViewsManager->comicsView->enableFilterMode(true); + comicsViewsManager->comicsView->setModel(comicsModel); //TODO, columns are messed up after ResetModel some times, this shouldn't be necesary foldersView->expandAll(); if(comicsModel->rowCount() == 0) - showNoSearchResultsView(); + comicsViewsManager->showNoSearchResultsView(); else - showComicsView(); + comicsViewsManager->showComicsView(); } else if(status == LibraryWindow::Searching) {//if no searching, then ignore this @@ -2144,7 +2083,7 @@ void LibraryWindow::setSearchFilter(const YACReader::SearchModifiers modifier, Q void LibraryWindow::clearSearchFilter() { foldersModelProxy->clear(); - comicsView->enableFilterMode(false); + comicsViewsManager->comicsView->enableFilterMode(false); foldersView->collapseAll(); status = LibraryWindow::Normal; } @@ -2219,110 +2158,12 @@ void LibraryWindow::resetComicRating() comicsModel->finishTransaction(); } -void LibraryWindow::switchToComicsView(ComicsView * from, ComicsView * to) -{ - //setup views - disconnectComicsViewConnections(from); - from->close(); - - comicsView = to; - doComicsViewConnections(); - - comicsView->setToolBar(editInfoToolBar); - - comicsViewStack->removeWidget(from); - comicsViewStack->addWidget(comicsView); - - delete from; - - //load content into current view - loadCoversFromCurrentModel(); - - if(!searchEdit->text().isEmpty()) - { - comicsView->enableFilterMode(true); - } -} - -void LibraryWindow::showComicsViewTransition() -{ - comicsViewStack->setCurrentWidget(comicsViewTransition); - comicsViewTransition->startMovie(); -} - -void LibraryWindow::toggleComicsView_delayed() -{ - if(comicsViewStatus == Flow){ - QIcon icoViewsButton; - icoViewsButton.addFile(":/images/main_toolbar/flow.png", QSize(), QIcon::Normal); - toggleComicsViewAction->setIcon(icoViewsButton); -#ifdef Q_OS_MAC - libraryToolBar->updateViewSelectorIcon(icoViewsButton); -#endif - switchToComicsView(classicComicsView, gridComicsView = new GridComicsView()); - connect(optionsDialog, SIGNAL(optionsChanged()), gridComicsView, SLOT(updateBackgroundConfig())); - comicsViewStatus = Grid; - } - else{ - QIcon icoViewsButton; - icoViewsButton.addFile(":/images/main_toolbar/grid.png", QSize(), QIcon::Normal); - toggleComicsViewAction->setIcon(icoViewsButton); -#ifdef Q_OS_MAC - libraryToolBar->updateViewSelectorIcon(icoViewsButton); -#endif - switchToComicsView(gridComicsView, classicComicsView = new ClassicComicsView()); - comicsViewStatus = Flow; - } - - settings->setValue(COMICS_VIEW_STATUS, comicsViewStatus); -} - -void LibraryWindow::showComicsView() -{ - comicsViewStack->setCurrentWidget(comicsView); -} - -void LibraryWindow::showEmptyFolderView() -{ - comicsViewStack->setCurrentWidget(emptyFolderWidget); -} - -void LibraryWindow::showEmptyLabelView() -{ - comicsViewStack->setCurrentWidget(emptyLabelWidget); -} - -void LibraryWindow::showEmptySpecialList() -{ - comicsViewStack->setCurrentWidget(emptySpecialList); -} - -void LibraryWindow::showEmptyReadingListWidget() -{ - comicsViewStack->setCurrentWidget(emptyReadingList); -} - -void LibraryWindow::showNoSearchResultsView() -{ - comicsViewStack->setCurrentWidget(noSearchResultsWidget); -} - -//TODO recover the current comics selection and restore it in the destination -void LibraryWindow::toggleComicsView() -{ - if(comicsViewStack->currentWidget()==comicsView) { - QTimer::singleShot(0,this,SLOT(showComicsViewTransition())); - QTimer::singleShot(32,this,SLOT(toggleComicsView_delayed())); - } else - toggleComicsView_delayed(); -} - void LibraryWindow::checkSearchNumResults(int numResults) { if(numResults == 0) - showNoSearchResultsView(); + comicsViewsManager->showNoSearchResultsView(); else - showComicsView(); + comicsViewsManager->showComicsView(); } void LibraryWindow::asignNumbers() @@ -2348,14 +2189,14 @@ void LibraryWindow::asignNumbers() const QModelIndex & mi = comicsModel->getIndexFromId(edited); if(mi.isValid()) { - comicsView->scrollTo(mi,QAbstractItemView::PositionAtCenter); - comicsView->setCurrentIndex(mi); + comicsViewsManager->comicsView->scrollTo(mi,QAbstractItemView::PositionAtCenter); + comicsViewsManager->comicsView->setCurrentIndex(mi); } } void LibraryWindow::openContainingFolderComic() { -QModelIndex modelIndex = comicsView->currentIndex(); +QModelIndex modelIndex = comicsViewsManager->comicsView->currentIndex(); QFileInfo file = QDir::cleanPath(currentPath() + comicsModel->getComicPath(modelIndex)); #if defined Q_OS_UNIX && !defined Q_OS_MAC QString path = file.absolutePath(); @@ -2435,7 +2276,7 @@ void LibraryWindow::importLibrary(QString clc,QString destPath,QString name) void LibraryWindow::reloadOptions() { //comicFlow->setFlowType(flowType); - comicsView->updateConfig(settings); + comicsViewsManager->comicsView->updateConfig(settings); } QString LibraryWindow::currentPath() @@ -2475,7 +2316,7 @@ void LibraryWindow::closeEvent ( QCloseEvent * event ) s->stop(); settings->setValue(MAIN_WINDOW_GEOMETRY, saveGeometry()); - comicsView->close(); + comicsViewsManager->comicsView->close(); sideBar->close(); QApplication::instance()->processEvents(); @@ -2534,14 +2375,14 @@ 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 //avoid selection.count()==0 forcing selection in comicsView - QModelIndexList selection = comicsView->selectionModel()->selectedRows(); + QModelIndexList selection = comicsViewsManager->comicsView->selectionModel()->selectedRows(); QLOG_TRACE() << "selection count " << selection.length(); qSort(selection.begin(),selection.end(),lessThanModelIndexRow); if(selection.count()==0) { - comicsView->selectIndex(0); - selection = comicsView->selectionModel()->selectedRows(); + comicsViewsManager->comicsView->selectIndex(0); + selection = comicsViewsManager->comicsView->selectionModel()->selectedRows(); } return selection; } diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index 29ca0232..66588c41 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -71,6 +71,7 @@ class YACReaderHistoryController; class EmptyLabelWidget; class EmptySpecialListWidget; class EmptyReadingListWidget; +class YACReaderComicsViewsManager; #include "comic_db.h" @@ -81,7 +82,7 @@ class LibraryWindow : public QMainWindow friend class YACReaderNavigationController; Q_OBJECT -private: +public: YACReaderSideBar * sideBar; CreateLibraryDialog * createLibraryDialog; @@ -117,17 +118,7 @@ private: //------------- YACReaderNavigationController * navigationController; - - ComicsView * comicsView; - ClassicComicsView * classicComicsView; - GridComicsView * gridComicsView; - QStackedWidget * comicsViewStack; - ComicsViewTransition * comicsViewTransition; - EmptyFolderWidget * emptyFolderWidget; - EmptyLabelWidget * emptyLabelWidget; - EmptySpecialListWidget * emptySpecialList; - EmptyReadingListWidget * emptyReadingList; - NoSearchResultsWidget * noSearchResultsWidget; + YACReaderComicsViewsManager * comicsViewsManager; YACReaderFoldersView * foldersView; YACReaderReadingListsView * listsView; @@ -261,9 +252,6 @@ private: void doDialogs(); void setUpShortcutsManagement(); void doModels(); - void disconnectComicsViewConnections(ComicsView * widget); - void doComicsViewConnections(); - //ACTIONS MANAGEMENT void disableComicsActions(bool disabled); @@ -287,8 +275,6 @@ private: bool removeError; - ComicsViewStatus comicsViewStatus; - //QTBUG-41883 QSize _size; QPoint _pos; @@ -361,16 +347,6 @@ public slots: void setRemoveError(); void checkRemoveError(); void resetComicRating(); - void switchToComicsView(ComicsView *from, ComicsView *to); - void showComicsViewTransition(); - void toggleComicsView_delayed();//used in orther to avoid flickering; - void showComicsView(); - void showEmptyFolderView(); - void showEmptyLabelView(); - void showEmptySpecialList(); - void showEmptyReadingListWidget(); - void showNoSearchResultsView(); - void toggleComicsView(); void checkSearchNumResults(int numResults); void loadCoversFromCurrentModel(); void copyAndImportComicsToCurrentFolder(const QList > & comics); @@ -399,7 +375,6 @@ public slots: void onAddComicsToLabel(); void setToolbarTitle(const QModelIndex & modelIndex); void saveSelectedCoversTo(); - }; #endif diff --git a/YACReaderLibrary/qml.qrc b/YACReaderLibrary/qml.qrc index 9952ca07..69bcc0fd 100644 --- a/YACReaderLibrary/qml.qrc +++ b/YACReaderLibrary/qml.qrc @@ -6,5 +6,23 @@ qml/reading.png qml/star_menu.png qml/star_menu@2x.png + qml/InfoComicsView.qml + qml/FlowView.qml + qml/info-indicator.png + qml/info-shadow.png + qml/info-top-shadow.png + qml/ComicInfo.qml + qml/info-favorites.png + qml/info-favorites@2x.png + qml/info-rating.png + qml/info-rating@2x.png + qml/info-tag.png + qml/info-tag@2x.png + qml/info-tick.png + qml/info-tick@2x.png + qml/InfoTick.qml + qml/InfoFavorites.qml + qml/InfoRating.qml + qml/YACReaderScrollViewStyle.qml diff --git a/YACReaderLibrary/qml/ComicInfo.qml b/YACReaderLibrary/qml/ComicInfo.qml new file mode 100644 index 00000000..ce6f86e2 --- /dev/null +++ b/YACReaderLibrary/qml/ComicInfo.qml @@ -0,0 +1,528 @@ +import QtQuick 2.6 + +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.2 + +import QtGraphicalEffects 1.0 + +import com.yacreader.ComicInfo 1.0 +import com.yacreader.ComicDB 1.0 + +Rectangle { + + color : "transparent" + id: mainContainer + + height: info.height + 2 * topMargin + + property string infoColor: "#b0b0b0" + property font infoFont: Qt.font({ + + family: "Arial", + pixelSize: 14 + }); + + property int topMargin : 27 + + property bool compact : width <= 650 + + RowLayout + { + id:main_layout + anchors.fill: parent + + //READ------------------------------------------------------------ + ColumnLayout + { + Layout.topMargin: topMargin + Layout.maximumWidth: 61 + Layout.fillHeight: true + id: readStatus + + Layout.alignment: Qt.AlignTop | + Qt.AlignHCenter + + Rectangle { + color: "transparent" + width: 61 + height: 24 + + InfoTick { + x: 27 + y: 5 + + read: comicInfo.read + + onReadChangedByUser: { + comicInfo.read = read; + comicInfoHelper.setRead(comic_info_index, read); + } + } + } + + visible: !mainContainer.compact + } + + //INFO------------------------------------------------------------ + ColumnLayout + { + id: info + //width: parent.width + //Layout.fillWidth: true + + Layout.alignment: Qt.AlignTop | + Qt.AlignLeft + + Layout.maximumWidth: mainContainer.compact ? mainContainer.width : 960 + + Layout.leftMargin: mainContainer.compact ? 30 : 0 + + RowLayout + { + Layout.topMargin: topMargin + + InfoTick { + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + + read: comicInfo.read + + onReadChangedByUser: { + comicInfo.read = read; + comicInfoHelper.setRead(comic_info_index, read); + } + } + + Item { + Layout.fillWidth: true + } + + InfoFavorites { + Layout.topMargin: 1 + Layout.rightMargin: 17 + Layout.alignment: Qt.AlignTop + + active: comicInfo.isFavorite + + onActiveChangedByUser: { + if(active) + comicInfoHelper.addToFavorites(comic_info_index); + else + comicInfoHelper.removeFromFavorites(comic_info_index); + + comicInfo.isFavorite = active; + } + } + + InfoRating { + Layout.alignment: Qt.AlignTop + Layout.rightMargin: 30 + rating: comicInfo.rating + + onRatingChangedByUser: { + comicInfo.rating = rating; + comicInfoHelper.rate(comic_info_index, rating); + } + } + + visible: mainContainer.compact + } + + RowLayout + { + Text { + Layout.topMargin: mainContainer.compact ? 18 : topMargin + Layout.fillWidth: true + Layout.rightMargin: mainContainer.compact ? 30 : 0 + + id: title + + color: "#ffffff" + font.family: "Arial" + font.bold: true + font.pixelSize: mainContainer.compact ? 18 : 21; + wrapMode: Text.WordWrap + + text: comic.getTitleIncludingNumber() + } + + RowLayout + { + visible: !mainContainer.compact + + Layout.alignment: Qt.AlignTop + Layout.topMargin: topMargin + + InfoFavorites { + Layout.topMargin: 1 + Layout.rightMargin: 17 + Layout.alignment: Qt.AlignTop + + active: comicInfo.isFavorite + + onActiveChangedByUser: { + if(active) + comicInfoHelper.addToFavorites(comic_info_index); + else + comicInfoHelper.removeFromFavorites(comic_info_index); + + comicInfo.isFavorite = active; + } + } + + InfoRating { + Layout.alignment: Qt.AlignTop + Layout.rightMargin: 30 + rating: comicInfo.rating + + onRatingChangedByUser: { + comicInfo.rating = rating; + comicInfoHelper.rate(comic_info_index, rating); + } + } + } + } + + Flow { + spacing: 0 + + Layout.fillWidth: true + Text { + id: volume + color: infoColor + font: mainContainer.infoFont + text: comicInfo.volume + rightPadding: 20 + visible: comicInfo.volume + } + + Text { + id: numbering + color: infoColor + font: mainContainer.infoFont + text: comicInfo.number + "/" + comicInfo.count + rightPadding: 20 + visible : comicInfo.number + } + + Text { + id: genre + color: infoColor + font: mainContainer.infoFont + text: comicInfo.genere + rightPadding: 20 + visible: comicInfo.genere + } + + Text { + id: date + color: infoColor + font: mainContainer.infoFont + text: comicInfo.date + rightPadding: 20 + visible: comicInfo.date + } + + Text { + id: pages + color: infoColor + font: mainContainer.infoFont + text: comicInfo.numPages + " pages" + rightPadding: 20 + visible: comicInfo.numPages + } + + Text { + id: showInComicVinw + font: mainContainer.infoFont + color: "#ffcc00" + text: "Show in Comic Vine" + visible: comicInfo.comicVineID + MouseArea { + anchors.fill: parent + onClicked: { + Qt.openUrlExternally("http://www.comicvine.com/comic/4000-%1/".arg(comicInfo.comicVineID)); + } + } + } + } + + Text { + Layout.topMargin: 22 + Layout.rightMargin: 30 + Layout.bottomMargin: 5 + Layout.fillWidth: true + + id: sinopsis + color: "white" + font.family: "Arial" + font.pixelSize: 15 + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignJustify + text: comicInfo.synopsis + visible: comicInfo.synopsis + } + + Text { + Layout.topMargin: 25 + Layout.bottomMargin: 5 + + id: authors_title + color: "white" + font.family: "Arial" + font.pixelSize: 18 + font.bold: true + + text: "Authors" + + visible: comicInfo.getWriters().length + + comicInfo.getPencillers().length + + comicInfo.getInkers().length + + comicInfo.getColorists().length + + comicInfo.getLetterers().length + + comicInfo.getCoverArtists().length > 0 + } + + Flow { + Layout.fillWidth: true + spacing: 20 + Repeater { + id: writers + model: comicInfo.getWriters().length + Column{ + Text { + color: "white" + font.family: "Arial" + font.pixelSize: 15 + + text: comicInfo.getWriters()[index] + } + + Text { + color: "#b0b0b0" + font.family: "Arial" + font.pixelSize: 13 + font.italic: true + text: "writer" + } + } + } + + Repeater { + id: pencilllers + model: comicInfo.getPencillers().length + Column{ + Text { + color: "white" + font.family: "Arial" + font.pixelSize: 15 + + text: comicInfo.getPencillers()[index] + } + + Text { + color: "#b0b0b0" + font.family: "Arial" + font.pixelSize: 13 + font.italic: true + text: "penciller" + } + } + } + + Repeater { + id: inkers + model: comicInfo.getInkers().length + Column{ + Text { + color: "white" + font.family: "Arial" + font.pixelSize: 15 + + text: comicInfo.getInkers()[index] + } + + Text { + color: "#b0b0b0" + font.family: "Arial" + font.pixelSize: 13 + font.italic: true + text: "inker" + } + } + } + + Repeater { + id: colorist + model: comicInfo.getColorists().length + Column{ + Text { + color: "white" + font.family: "Arial" + font.pixelSize: 15 + + text: comicInfo.getColorists()[index] + } + + Text { + color: "#b0b0b0" + font.family: "Arial" + font.pixelSize: 13 + font.italic: true + text: "colorist" + } + } + } + + Repeater { + id: letterers + model: comicInfo.getLetterers().length + Column{ + Text { + color: "white" + font.family: "Arial" + font.pixelSize: 15 + + text: comicInfo.getLetterers()[index] + } + + Text { + color: "#b0b0b0" + font.family: "Arial" + font.pixelSize: 13 + font.italic: true + text: "letterer" + } + } + } + + Repeater { + id: cover_artist + model: comicInfo.getCoverArtists().length + Column{ + Text { + color: "white" + font.family: "Arial" + font.pixelSize: 15 + + text: comicInfo.getCoverArtists()[index] + } + + Text { + color: "#b0b0b0" + font.family: "Arial" + font.pixelSize: 13 + font.italic: true + text: "cover artist" + } + } + } + } + + Text { + Layout.topMargin: 25 + + id: publisher_title + color: "white" + font.family: "Arial" + font.pixelSize: 18 + font.bold: true + + text: "Publisher" + + visible: publisher.visible || format.visible || color.visible || age_rating.visible + } + + Flow { + Layout.fillWidth: true + spacing: 20 + + Text { + id: publisher + + color: "white" + font.family: "Arial" + font.pixelSize: 15 + + text: comicInfo.publisher + + visible: comicInfo.publisher + } + + Text { + id: format + + color: "white" + font.family: "Arial" + font.pixelSize: 15 + + text: comicInfo.format + + visible: comicInfo.format + } + + Text { + id: color + + color: "white" + font.family: "Arial" + font.pixelSize: 15 + + text: comicInfo.color ? "color" : "b/w" + + visible: comicInfo.color + } + + Text { + id: age_rating + + color: "white" + font.family: "Arial" + font.pixelSize: 15 + + text: comicInfo.ageRating + + visible: comicInfo.ageRating + } + } + + Text { + Layout.topMargin: 25 + Layout.bottomMargin: 5 + + id: characters_title + color: "white" + font.family: "Arial" + font.pixelSize: 18 + font.bold: true + + text: "Characters" + + visible: comicInfo.getCharacters().length > 0 + } + + Flow { + Layout.fillWidth: true + spacing: 20 + Repeater { + id: characters + model: comicInfo.getCharacters().length + + Text { + color: "white" + font.family: "Arial" + font.pixelSize: 15 + + text: comicInfo.getCharacters()[index] + } + } + } + } + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + Layout.minimumWidth: 0 + Layout.preferredWidth: 0 + } + } +} diff --git a/YACReaderLibrary/qml/FlowView.qml b/YACReaderLibrary/qml/FlowView.qml new file mode 100644 index 00000000..c0858f04 --- /dev/null +++ b/YACReaderLibrary/qml/FlowView.qml @@ -0,0 +1,211 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.4 + +import QtGraphicalEffects 1.0 + +import com.yacreader.ComicModel 1.0 + +Rectangle { + id: main + + property url backgroundImageURL; + + property real backgroundBlurRadius : 100; //85; + property real backgroundBlurOpacity : 0.25; //0.35; + property bool backgroundBlurVisible : true; + + property real additionalBottomSpace : 0; + + property real verticalPadding: 12 + + property real itemsSpacing: 17 + + signal currentCoverChanged(int index) + + Rectangle { + id: background + color: "#2A2A2A" + anchors.fill: backgroundImg + } + + Image { + id: backgroundImg + width: parent.width + height: parent.height + additionalBottomSpace + source: backgroundImage + fillMode: Image.PreserveAspectCrop + smooth: true + mipmap: true + asynchronous : true + cache: false //TODO clear cache only when it is needed + opacity: 0 + visible: false + } + + FastBlur { + anchors.fill: backgroundImg + source: backgroundImg + radius: backgroundBlurRadius + opacity: backgroundBlurOpacity + visible: backgroundBlurVisible + } + + anchors.margins: 0 + + MouseArea { + anchors.fill : list + onWheel: { + + if(list.moving) + return; + + var ci + if(wheel.angleDelta.y < 0) { + ci = Math.min(list.currentIndex+1, list.count - 1); + } + else if(wheel.angleDelta.y > 0) { + ci = Math.max(0,list.currentIndex-1); + } else { + return; + } + + list.currentIndex = ci; + } + } + + ListView { + id: list + objectName: "list" + anchors.fill: parent + + property int previousIndex; + + orientation: Qt.Horizontal + pixelAligned: true + + model: comicsList + + spacing: itemsSpacing + anchors.leftMargin: Math.floor(verticalPadding * 1.1) + + snapMode: ListView.SnapToItem + + highlightFollowsCurrentItem: true + highlightRangeMode: ListView.StrictlyEnforceRange + preferredHighlightEnd: 50 + + highlightMoveDuration: 250 + + onCurrentIndexChanged: { + currentCoverChanged(currentIndex); + } + + delegate: Component { + + //cover + Rectangle { + width: Math.floor((list.height - (verticalPadding * 2)) * 0.65); + height: list.height - (verticalPadding * 2); + anchors.verticalCenter: parent.verticalCenter + + color:"transparent" + + BusyIndicator { + scale: 0.5 + anchors.centerIn: parent + running: coverElement.status === Image.Loading + } + + DropShadow { + anchors.fill: coverElement + horizontalOffset: 0 + verticalOffset: 0 + radius: 6 + samples: 17 + color: "#BB000000" + source: coverElement + visible: (Qt.platform.os === "osx") ? false : true; + } + + Image { + id: coverElement + anchors.fill: parent + source: cover_path + fillMode: Image.PreserveAspectCrop + smooth: true + mipmap: true + asynchronous : true + cache: false + } + + //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: 9; rightMargin: 9} + asynchronous : true + } + + //border + Rectangle { + width: coverElement.width + height: coverElement.height + anchors.centerIn: coverElement + color: "transparent" + border { + color: "#30FFFFFF" + width: 1 + } + } + + MouseArea { + id: mouseArea + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + + hoverEnabled: true + + onDoubleClicked: { + list.currentIndex = index; + currentIndexHelper.selectedItem(index); + } + + onReleased: { + list.currentIndex = index; + + if(mouse.button === Qt.RightButton) // context menu is requested + { + var coordinates = main.mapFromItem(coverElement,mouseX,mouseY) + contextMenuHelper.requestedContextMenu(Qt.point(coordinates.x,coordinates.y)); + } + + mouse.accepted = true; + } + } + } + } + + focus: true + Keys.onPressed: { + + if (event.modifiers & Qt.ControlModifier || event.modifiers & Qt.ShiftModifier) + return; + var ci + if (event.key === Qt.Key_Right) { + ci = Math.min(list.currentIndex+1, list.count - 1); + } + else if (event.key === Qt.Key_Left) { + ci = Math.max(0,list.currentIndex-1); + } else { + return; + } + + list.currentIndex = ci; + + event.accepted = true; + } + + } +} diff --git a/YACReaderLibrary/qml/GridComicsView.qml b/YACReaderLibrary/qml/GridComicsView.qml index ff5eea38..dc24bf83 100644 --- a/YACReaderLibrary/qml/GridComicsView.qml +++ b/YACReaderLibrary/qml/GridComicsView.qml @@ -1,8 +1,21 @@ import QtQuick 2.3 -import QtQuick.Controls 1.2 -import comicModel 1.0 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.2 + import QtGraphicalEffects 1.0 +import QtQuick.Controls.Styles 1.4 + +import com.yacreader.ComicModel 1.0 + +SplitView { + anchors.fill: parent + orientation: Qt.Horizontal + handleDelegate:Rectangle { + width: 1 + height: 1 + color: "#202020" + } Rectangle { id: main @@ -30,18 +43,12 @@ Rectangle { } color: backgroundColor - width: parent.width + width: parent.width - (info_container.visible ? info_container.width : 0) + Layout.fillWidth: true + Layout.minimumWidth: coverWidth + 100 height: parent.height anchors.margins: 0 - function selectAll(from,to) - { - for(var i = from;i<=to;i++) - { - comicsSelectionHelper.selectIndex(i); - } - } - Component { id: appDelegate Rectangle @@ -121,7 +128,13 @@ Rectangle { } border.color: (Qt.platform.os === "osx") ? selectedBorderColor : "#ffcc00" - border.width: (dummyValue || !dummyValue) && (comicsSelectionHelper.isSelectedIndex(index) || mouseArea.containsMouse) ? 3 : 0 + border.width: 3 + + opacity: (dummyValue || !dummyValue) && (comicsSelectionHelper.isSelectedIndex(index) || mouseArea.containsMouse) ? 1 : 0 + + Behavior on opacity { + NumberAnimation { duration: 300 } + } radius : 2 } @@ -146,7 +159,15 @@ Rectangle { comicsSelectionHelper.selectIndex(index); grid.currentIndex = index; - comicsSelectionHelper.selectedItem(index); + currentIndexHelper.selectedItem(index); + } + + function selectAll(from,to) + { + for(var i = from;i<=to;i++) + { + comicsSelectionHelper.selectIndex(i); + } } onPressed: { @@ -177,7 +198,7 @@ Rectangle { { if(!comicsSelectionHelper.isSelectedIndex(index)) //the context menu is requested outside the current selection, the selection will be { - comicsSelectionHelper.setCurrentIndex(index) + currentIndexHelper.setCurrentIndex(index) grid.currentIndex = index; } @@ -214,7 +235,7 @@ Rectangle { } else { - comicsSelectionHelper.setCurrentIndex(index) + currentIndexHelper.setCurrentIndex(index) } grid.currentIndex = index; @@ -228,7 +249,7 @@ Rectangle { { if(comicsSelectionHelper.isSelectedIndex(index)) { - comicsSelectionHelper.setCurrentIndex(index) + currentIndexHelper.setCurrentIndex(index) grid.currentIndex = index; } } @@ -369,33 +390,49 @@ Rectangle { id: scrollView anchors.fill: parent anchors.margins: 0 - //QTBUG-39453 - //Another fu%$·#& bug in Qt - //https://bugreports.qt.io/browse/QTBUG-39453 - //To solve this I am going to accept any input drag, drops will be filtered in "onDropped" + + style: YACReaderScrollViewStyle { + transientScrollBars: false + incrementControl: Item {} + decrementControl: Item {} + handle: Item { + implicitWidth: 16 + implicitHeight: 26 + Rectangle { + color: "#88424242" + anchors.fill: parent + anchors.topMargin: 6 + anchors.leftMargin: 4 + anchors.rightMargin: 4 + anchors.bottomMargin: 6 + border.color: "#AA313131" + border.width: 1 + radius: 8 + } + } + scrollBarBackground: Item { + implicitWidth: 16 + implicitHeight: 26 + } + } + DropArea { anchors.fill: parent - /* onEntered: { - console.log("onEntered"); if(drag.hasUrls) { - console.log("HAS URLS -> ", drag.urls); if(dropManager.canDropUrls(drag.urls, drag.action)) { drag.accepted = true; - console.log("canDropUrls"); }else drag.accepted = false; } else if (dropManager.canDropFormats(drag.formats)) { drag.accepted = true; - console.log("canDropFormats"); } else drag.accepted = false; - }*/ - + } onDropped: { if(drop.hasUrls && dropManager.canDropUrls(drop.urls, drop.action)) @@ -434,7 +471,7 @@ Rectangle { anchors.rightMargin: 10 pixelAligned: true //flickDeceleration: -2000 - snapMode: GridView.SnapToRow + currentIndex: 0 cacheBuffer: 0 @@ -494,7 +531,7 @@ Rectangle { var numCells = grid.numCellsPerRow(); var ci if (event.key === Qt.Key_Right) { - ci = Math.min(grid.currentIndex+1,grid.count); + ci = Math.min(grid.currentIndex+1,grid.count - 1); } else if (event.key === Qt.Key_Left) { ci = Math.max(0,grid.currentIndex-1); @@ -503,14 +540,14 @@ Rectangle { ci = Math.max(0,grid.currentIndex-numCells); } else if (event.key === Qt.Key_Down) { - ci = Math.min(grid.currentIndex+numCells,grid.count); + ci = Math.min(grid.currentIndex+numCells,grid.count - 1); } event.accepted = true; //var ci = grid.currentIndex; grid.currentIndex = -1 comicsSelectionHelper.clear(); - comicsSelectionHelper.setCurrentIndex(ci); + currentIndexHelper.setCurrentIndex(ci); grid.currentIndex = ci; } //} @@ -539,7 +576,55 @@ Rectangle { height: 64 enabled: (dummyValue || !dummyValue) }*/ + } } +Rectangle { + id: info_container + objectName: "infoContainer" + Layout.preferredWidth: 350 + Layout.minimumWidth: 350 + Layout.maximumWidth: 960 + height: parent.height + + color: "#2e2e2e" + + visible: showInfo + + ScrollView { + __wheelAreaScrollSpeed: 75 + anchors.fill: parent + anchors.margins: 0 + + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + + style: ScrollViewStyle { + transientScrollBars: false + incrementControl: Item {} + decrementControl: Item {} + handle: Item { + implicitWidth: 10 + implicitHeight: 26 + Rectangle { + color: "#424246" + anchors.fill: parent + anchors.topMargin: 6 + anchors.leftMargin: 4 + anchors.rightMargin: 4 + anchors.bottomMargin: 6 + } + } + scrollBarBackground: Item { + implicitWidth: 14 + implicitHeight: 26 + } + } + + ComicInfo { + width: info_container.width + } + } +} +} diff --git a/YACReaderLibrary/qml/InfoComicsView.qml b/YACReaderLibrary/qml/InfoComicsView.qml new file mode 100644 index 00000000..6ffb35c3 --- /dev/null +++ b/YACReaderLibrary/qml/InfoComicsView.qml @@ -0,0 +1,121 @@ +import QtQuick 2.5 + +import QtQuick.Controls 1.2 +import QtGraphicalEffects 1.0 +import QtQuick.Controls.Styles 1.4 + +import com.yacreader.ComicModel 1.0 + +Rectangle { + id: main + + color: "#2e2e2e" + + width: parent.width + height: parent.height + anchors.margins: 0 + + FlowView { + id: flow + objectName: "flow" + height: 256 //TODO dynamic size? + + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + + additionalBottomSpace: indicator.height + } + + Image { + id: top_shadow + source: "info-top-shadow.png" + width: parent.width + fillMode: Image.TileHorizontally + } + + Rectangle { + id: indicator_container + width: parent.width + y: 250 + + Image { + id: indicator + source: "info-indicator.png" + } + + Image { + id: bottom_shadow + x: indicator.width + width: parent.width - indicator.width + source: "info-shadow.png" + fillMode: Image.TileHorizontally + } + } + + Rectangle { + id: info_container + width: parent.width + y: flow.height + flow.additionalBottomSpace - 6 + height: parent.height - y + + color: "#2e2e2e" + + ScrollView { + __wheelAreaScrollSpeed: 75 + anchors.fill: parent + anchors.margins: 0 + + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + + style: ScrollViewStyle { + transientScrollBars: false + incrementControl: Item {} + decrementControl: Item {} + handle: Item { + implicitWidth: 10 + implicitHeight: 26 + Rectangle { + color: "#424246" + anchors.fill: parent + anchors.topMargin: 6 + anchors.leftMargin: 4 + anchors.rightMargin: 4 + anchors.bottomMargin: 6 + } + } + + scrollBarBackground: Item { + implicitWidth: 14 + implicitHeight: 26 + } + } + + ComicInfo { + width: info_container.width - 14 + } + } + } + + DropArea { + anchors.fill: parent + + onEntered: { + if(drag.hasUrls) + { + if(dropManager.canDropUrls(drag.urls, drag.action)) + { + drag.accepted = true; + }else + drag.accepted = false; + } + } + + onDropped: { + if(drop.hasUrls && dropManager.canDropUrls(drop.urls, drop.action)) + { + dropManager.droppedFiles(drop.urls, drop.action); + } + } + } +} diff --git a/YACReaderLibrary/qml/InfoFavorites.qml b/YACReaderLibrary/qml/InfoFavorites.qml new file mode 100644 index 00000000..daf6b956 --- /dev/null +++ b/YACReaderLibrary/qml/InfoFavorites.qml @@ -0,0 +1,32 @@ +import QtQuick 2.6 + +import QtGraphicalEffects 1.0 + +Item { + width: 20 + height: 20 + + property bool active + + signal activeChangedByUser(bool active) + + MouseArea { + anchors.fill: favorites_button_compact + onClicked: { + activeChangedByUser(!active); + } + } + + Image { + anchors.centerIn: parent + id: favorites_button_compact + source: "info-favorites.png" + } + + ColorOverlay { + anchors.fill: favorites_button_compact + source: favorites_button_compact + color: active ? "#e84852" : "#1c1c1c" + } +} + diff --git a/YACReaderLibrary/qml/InfoRating.qml b/YACReaderLibrary/qml/InfoRating.qml new file mode 100644 index 00000000..9a2e5e76 --- /dev/null +++ b/YACReaderLibrary/qml/InfoRating.qml @@ -0,0 +1,50 @@ +import QtQuick 2.6 + +import QtGraphicalEffects 1.0 + +Row { + spacing: 0 + property int rating : 0 + property int mouseIndex : 0 + + signal ratingChangedByUser(int rating) + + Repeater { + id: rating_compact + model: 5 + Item { + width: 25 + height: 20 + + Image { + id: star + source: "info-rating.png" + } + + ColorOverlay { + anchors.fill: star + source: star + color: index < (mouseIndex > 0 ? mouseIndex : rating) ? "#ffffff" : "#1c1c1c" + } + + MouseArea { + anchors.fill: parent + hoverEnabled: true + + onPositionChanged: { + mouseIndex = index + 1; + } + + onClicked: { + ratingChangedByUser(mouseIndex); + } + + onExited: { + mouseIndex = 0; + } + } + } + } + + +} diff --git a/YACReaderLibrary/qml/InfoTick.qml b/YACReaderLibrary/qml/InfoTick.qml new file mode 100644 index 00000000..f52e5402 --- /dev/null +++ b/YACReaderLibrary/qml/InfoTick.qml @@ -0,0 +1,29 @@ +import QtQuick 2.6 + +import QtGraphicalEffects 1.0 + +Item { + + property bool read + + signal readChangedByUser(bool read) + + MouseArea { + anchors.fill: read_compact + onClicked: { + readChangedByUser(!read); + } + } + + Image { + id: read_compact + source: "info-tick.png" + } + + ColorOverlay { + anchors.fill: read_compact + source: read_compact + color: read ? "#e84852" : "#1c1c1c" + } +} + diff --git a/YACReaderLibrary/qml/YACReaderScrollView.qml b/YACReaderLibrary/qml/YACReaderScrollView.qml index c71c9cbc..ad26d4b3 100644 --- a/YACReaderLibrary/qml/YACReaderScrollView.qml +++ b/YACReaderLibrary/qml/YACReaderScrollView.qml @@ -44,6 +44,7 @@ import QtQuick.Controls.Styles 1.1 \inqmlmodule QtQuick.Controls \since 5.1 \ingroup views + \ingroup controls \brief Provides a scrolling view within another Item. \image scrollview.png @@ -163,7 +164,9 @@ FocusScope { default property Item contentItem /*! \internal */ - property Item __scroller: scroller + property alias __scroller: scroller + /*! \internal */ + property alias __verticalScrollbarOffset: scroller.verticalScrollbarOffset /*! \internal */ property alias __wheelAreaScrollSpeed: wheelArea.scrollSpeed /*! \internal */ @@ -237,13 +240,13 @@ FocusScope { onContentYChanged: { scroller.blockUpdates = true - scroller.verticalScrollBar.value = flickableItem.contentY + scroller.verticalScrollBar.value = flickableItem.contentY - flickableItem.originY scroller.blockUpdates = false } onContentXChanged: { scroller.blockUpdates = true - scroller.horizontalScrollBar.value = flickableItem.contentX + scroller.horizontalScrollBar.value = flickableItem.contentX - flickableItem.originX scroller.blockUpdates = false } @@ -273,42 +276,43 @@ FocusScope { property bool horizontalRecursionGuard: false property bool verticalRecursionGuard: false - horizontalMinimumValue: flickableItem ? flickableItem.originX : 0 - horizontalMaximumValue: flickableItem ? flickableItem.originX + flickableItem.contentWidth - viewport.width : 0 + horizontalMinimumValue: 0 + horizontalMaximumValue: flickableItem ? flickableItem.contentWidth - viewport.width : 0 - verticalMinimumValue: flickableItem ? flickableItem.originY : 0 - verticalMaximumValue: flickableItem ? flickableItem.originY + flickableItem.contentHeight - viewport.height + __viewTopMargin : 0 + verticalMinimumValue: 0 + verticalMaximumValue: flickableItem ? flickableItem.contentHeight - viewport.height + __viewTopMargin : 0 // The default scroll speed for typical angle-based mouse wheels. The value // comes originally from QTextEdit, which sets 20px steps by default, as well as // QQuickWheelArea. // TODO: centralize somewhere, QPlatformTheme? - scrollSpeed: 20 * (__style.__wheelScrollLines || 1) + scrollSpeed: 20 * (__style && __style.__wheelScrollLines || 1) Connections { target: flickableItem onContentYChanged: { wheelArea.verticalRecursionGuard = true - wheelArea.verticalValue = flickableItem.contentY + wheelArea.verticalValue = flickableItem.contentY - flickableItem.originY wheelArea.verticalRecursionGuard = false } onContentXChanged: { wheelArea.horizontalRecursionGuard = true - wheelArea.horizontalValue = flickableItem.contentX + wheelArea.horizontalValue = flickableItem.contentX - flickableItem.originX wheelArea.horizontalRecursionGuard = false } } onVerticalValueChanged: { if (!verticalRecursionGuard) { - if (flickableItem.contentY < flickThreshold && verticalDelta > speedThreshold) { + var effectiveContentY = flickableItem.contentY - flickableItem.originY + if (effectiveContentY < flickThreshold && verticalDelta > speedThreshold) { flickableItem.flick(ignored, Math.min(maxFlick, acceleration * verticalDelta)) - } else if (flickableItem.contentY > flickableItem.contentHeight - - flickThreshold - viewport.height && verticalDelta < -speedThreshold) { + } else if (effectiveContentY > flickableItem.contentHeight - flickThreshold - viewport.height + && verticalDelta < -speedThreshold) { flickableItem.flick(ignored, Math.max(-maxFlick, acceleration * verticalDelta)) } else { - flickableItem.contentY = verticalValue + flickableItem.contentY = verticalValue + flickableItem.originY } flickableItem.contentY = Math.min(verticalMaximumValue, Math.max(0, flickableItem.contentY)); } @@ -316,7 +320,7 @@ FocusScope { onHorizontalValueChanged: { if (!horizontalRecursionGuard) - flickableItem.contentX = horizontalValue + flickableItem.contentX = horizontalValue + flickableItem.originX } } @@ -327,9 +331,9 @@ FocusScope { 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 + verticalScrollBar.width + scrollBarSpacing : 0 property int horizontalScrollbarOffset: horizontalScrollBar.visible && !horizontalScrollBar.isTransient ? - horizontalScrollBar.height + scrollBarSpacing : 0 + horizontalScrollBar.height + scrollBarSpacing : 0 Loader { id: frameLoader sourceComponent: __style ? __style.frame : null diff --git a/YACReaderLibrary/qml/YACReaderScrollViewStyle.qml b/YACReaderLibrary/qml/YACReaderScrollViewStyle.qml new file mode 100644 index 00000000..e9a0e787 --- /dev/null +++ b/YACReaderLibrary/qml/YACReaderScrollViewStyle.qml @@ -0,0 +1,403 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Controls module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Private 1.0 + +/*! + \qmltype ScrollViewStyle + \inqmlmodule QtQuick.Controls.Styles + \since 5.1 + \ingroup viewsstyling + \ingroup controlsstyling + \brief Provides custom styling for ScrollView +*/ +Style { + id: root + + /*! The \l ScrollView this style is attached to. */ + readonly property YACReaderScrollView control: __control + + /*! This property controls the frame border padding of the scrollView. */ + padding {left: 1; top: 1; right: 1; bottom: 1} + + /*! This Component paints the corner area between scroll bars */ + property Component corner: Rectangle { color: "#ccc" } + + /*! This component determines if the flickable should reposition itself at the + mouse location when clicked. */ + property bool scrollToClickedPosition: true + + /*! This property holds whether the scroll bars are transient. Transient scroll bars + appear when the content is scrolled and disappear when they are no longer needed. + + The default value is platform dependent. */ + property bool transientScrollBars: Settings.isMobile && Settings.hasTouchScreen + + /*! This Component paints the frame around scroll bars. */ + property Component frame: Rectangle { + color: control["backgroundVisible"] ? "white": "transparent" + border.color: "#999" + border.width: 1 + radius: 1 + visible: control.frameVisible + } + + /*! This is the minimum extent of the scroll bar handle. + + The default value is \c 30. + */ + + property int minimumHandleLength: 30 + + /*! This property controls the edge overlap + between the handle and the increment/decrement buttons. + + The default value is \c 30. + */ + + property int handleOverlap: 1 + + /*! This component controls the appearance of the + scroll bar background. + + You can access the following state properties: + + \table + \row \li property bool \b styleData.hovered + \row \li property bool \b styleData.horizontal + \endtable + */ + + property Component scrollBarBackground: Item { + property bool sticky: false + property bool hovered: styleData.hovered + implicitWidth: Math.round(TextSingleton.implicitHeight) + implicitHeight: Math.round(TextSingleton.implicitHeight) + clip: true + opacity: transientScrollBars ? 0.5 : 1.0 + visible: !Settings.hasTouchScreen && (!transientScrollBars || sticky) + Rectangle { + anchors.fill: parent + color: "#ddd" + border.color: "#aaa" + anchors.rightMargin: styleData.horizontal ? -2 : -1 + anchors.leftMargin: styleData.horizontal ? -2 : 0 + anchors.topMargin: styleData.horizontal ? 0 : -2 + anchors.bottomMargin: styleData.horizontal ? -1 : -2 + } + onHoveredChanged: if (hovered) sticky = true + onVisibleChanged: if (!visible) sticky = false + } + + /*! This component controls the appearance of the + scroll bar handle. + + You can access the following state properties: + + \table + \row \li property bool \b styleData.hovered + \row \li property bool \b styleData.pressed + \row \li property bool \b styleData.horizontal + \endtable + */ + + property Component handle: Item { + property bool sticky: false + property bool hovered: __activeControl !== "none" + implicitWidth: Math.round(TextSingleton.implicitHeight) + 1 + implicitHeight: Math.round(TextSingleton.implicitHeight) + 1 + BorderImage { + id: img + opacity: styleData.pressed && !transientScrollBars ? 0.5 : styleData.hovered ? 1 : 0.8 + source: "images/scrollbar-handle-" + (transientScrollBars ? "transient" : styleData.horizontal ? "horizontal" : "vertical") + ".png" + border.left: transientScrollBars ? 5 : 2 + border.top: transientScrollBars ? 5 : 2 + border.right: transientScrollBars ? 5 : 2 + border.bottom: transientScrollBars ? 5 : 2 + anchors.top: !styleData.horizontal ? parent.top : undefined + anchors.margins: transientScrollBars ? 2 : 0 + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.left: styleData.horizontal ? parent.left : undefined + width: !styleData.horizontal && transientScrollBars ? sticky ? 13 : 10 : parent.width + height: styleData.horizontal && transientScrollBars ? sticky ? 13 : 10 : parent.height + Behavior on width { enabled: !styleData.horizontal && transientScrollBars; NumberAnimation { duration: 100 } } + Behavior on height { enabled: styleData.horizontal && transientScrollBars; NumberAnimation { duration: 100 } } + } + onHoveredChanged: if (hovered) sticky = true + onVisibleChanged: if (!visible) sticky = false + } + + /*! This component controls the appearance of the + scroll bar increment button. + + You can access the following state properties: + + \table + \row \li property bool \b styleData.hovered + \row \li property bool \b styleData.pressed + \row \li property bool \b styleData.horizontal + \endtable + */ + property Component incrementControl: Rectangle { + visible: !transientScrollBars + implicitWidth: transientScrollBars ? 0 : Math.round(TextSingleton.implicitHeight) + implicitHeight: transientScrollBars ? 0 : Math.round(TextSingleton.implicitHeight) + Rectangle { + anchors.fill: parent + anchors.bottomMargin: -1 + anchors.rightMargin: -1 + border.color: "#aaa" + Rectangle { + anchors.fill: parent + anchors.margins: 1 + color: "transparent" + border.color: "#44ffffff" + } + Image { + source: styleData.horizontal ? "images/arrow-right.png" : "images/arrow-down.png" + anchors.centerIn: parent + opacity: control.enabled ? 0.6 : 0.5 + } + gradient: Gradient { + GradientStop {color: styleData.pressed ? "lightgray" : "white" ; position: 0} + GradientStop {color: styleData.pressed ? "lightgray" : "lightgray" ; position: 1} + } + } + } + + /*! This component controls the appearance of the + scroll bar decrement button. + + You can access the following state properties: + + \table + \row \li property bool \b styleData.hovered + \row \li property bool \b styleData.pressed + \row \li property bool \b styleData.horizontal + \endtable + */ + property Component decrementControl: Rectangle { + visible: !transientScrollBars + implicitWidth: transientScrollBars ? 0 : Math.round(TextSingleton.implicitHeight) + implicitHeight: transientScrollBars ? 0 : Math.round(TextSingleton.implicitHeight) + Rectangle { + anchors.fill: parent + anchors.topMargin: styleData.horizontal ? 0 : -1 + anchors.leftMargin: styleData.horizontal ? -1 : 0 + anchors.bottomMargin: styleData.horizontal ? -1 : 0 + anchors.rightMargin: styleData.horizontal ? 0 : -1 + color: "lightgray" + Rectangle { + anchors.fill: parent + anchors.margins: 1 + color: "transparent" + border.color: "#44ffffff" + } + Image { + source: styleData.horizontal ? "images/arrow-left.png" : "images/arrow-up.png" + anchors.centerIn: parent + anchors.verticalCenterOffset: styleData.horizontal ? 0 : -1 + anchors.horizontalCenterOffset: styleData.horizontal ? -1 : 0 + opacity: control.enabled ? 0.6 : 0.5 + } + gradient: Gradient { + GradientStop {color: styleData.pressed ? "lightgray" : "white" ; position: 0} + GradientStop {color: styleData.pressed ? "lightgray" : "lightgray" ; position: 1} + } + border.color: "#aaa" + } + } + + /*! \internal */ + property Component __scrollbar: Item { + id: panel + property string activeControl: "none" + property bool scrollToClickPosition: true + property bool isTransient: transientScrollBars + + property bool on: false + property bool raised: false + property bool sunken: __styleData.upPressed | __styleData.downPressed | __styleData.handlePressed + + states: State { + name: "out" + when: isTransient + && (!__stickyScrollbars || !flickableItem.moving) + && panel.activeControl === "none" + && !panel.on + && !panel.raised + PropertyChanges { target: panel; opacity: 0 } + } + + transitions: Transition { + to: "out" + SequentialAnimation { + PauseAnimation { duration: root.__scrollBarFadeDelay } + NumberAnimation { properties: "opacity"; duration: root.__scrollBarFadeDuration } + PropertyAction { target: panel; property: "visible"; value: false } + } + } + + implicitWidth: __styleData.horizontal ? 200 : bg.implicitWidth + implicitHeight: __styleData.horizontal ? bg.implicitHeight : 200 + + function pixelMetric(arg) { + if (arg === "scrollbarExtent") + return (__styleData.horizontal ? bg.height : bg.width); + return 0; + } + + function styleHint(arg) { + return false; + } + + function hitTest(argX, argY) { + if (itemIsHit(handleControl, argX, argY)) + return "handle" + else if (itemIsHit(incrementLoader, argX, argY)) + return "up"; + else if (itemIsHit(decrementLoader, argX, argY)) + return "down"; + else if (itemIsHit(bg, argX, argY)) { + if (__styleData.horizontal && argX < handleControl.x || !__styleData.horizontal && argY < handleControl.y) + return "upPage" + else + return "downPage" + } + + return "none"; + } + + function subControlRect(arg) { + if (arg === "handle") { + return Qt.rect(handleControl.x, handleControl.y, handleControl.width, handleControl.height); + } else if (arg === "groove") { + if (__styleData.horizontal) { + return Qt.rect(incrementLoader.width - handleOverlap, + 0, + __control.width - (incrementLoader.width + decrementLoader.width - handleOverlap * 2), + __control.height); + } else { + return Qt.rect(0, + incrementLoader.height - handleOverlap, + __control.width, + __control.height - (incrementLoader.height + decrementLoader.height - handleOverlap * 2)); + } + } + return Qt.rect(0,0,0,0); + } + + function itemIsHit(argItem, argX, argY) { + var pos = argItem.mapFromItem(__control, argX, argY); + return (pos.x >= 0 && pos.x <= argItem.width && pos.y >= 0 && pos.y <= argItem.height); + } + + Loader { + id: incrementLoader + anchors.top: parent.top + anchors.left: parent.left + sourceComponent: decrementControl + property QtObject styleData: QtObject { + readonly property bool hovered: activeControl === "up" + readonly property bool pressed: __styleData.upPressed + readonly property bool horizontal: __styleData.horizontal + } + } + + Loader { + id: bg + anchors.top: __styleData.horizontal ? undefined : incrementLoader.bottom + anchors.bottom: __styleData.horizontal ? undefined : decrementLoader.top + anchors.left: __styleData.horizontal ? incrementLoader.right : undefined + anchors.right: __styleData.horizontal ? decrementLoader.left : undefined + sourceComponent: scrollBarBackground + property QtObject styleData: QtObject { + readonly property bool horizontal: __styleData.horizontal + readonly property bool hovered: activeControl !== "none" + } + } + + Loader { + id: decrementLoader + anchors.bottom: __styleData.horizontal ? undefined : parent.bottom + anchors.right: __styleData.horizontal ? parent.right : undefined + sourceComponent: incrementControl + property QtObject styleData: QtObject { + readonly property bool hovered: activeControl === "down" + readonly property bool pressed: __styleData.downPressed + readonly property bool horizontal: __styleData.horizontal + } + } + + property var flickableItem: control.flickableItem + property int extent: Math.max(minimumHandleLength, __styleData.horizontal ? + (flickableItem ? flickableItem.width/flickableItem.contentWidth : 0 ) * bg.width : + (flickableItem ? flickableItem.height/flickableItem.contentHeight : 0) * bg.height) + readonly property real range: __control.maximumValue - __control.minimumValue + readonly property real begin: __control.value - __control.minimumValue + + Loader { + id: handleControl + height: __styleData.horizontal ? implicitHeight : extent + width: __styleData.horizontal ? extent : implicitWidth + anchors.top: bg.top + anchors.left: bg.left + anchors.topMargin: __styleData.horizontal || range === 0 ? 0 : -handleOverlap + (2 * begin * (bg.height + (2 * handleOverlap) - extent) + range) / (2 * range) + anchors.leftMargin: __styleData.horizontal && range !== 0 ? -handleOverlap + (2 * begin * (bg.width + (2 * handleOverlap) - extent) + range) / (2 * range) : 0 + sourceComponent: handle + property QtObject styleData: QtObject { + readonly property bool hovered: activeControl === "handle" + readonly property bool pressed: __styleData.handlePressed + readonly property bool horizontal: __styleData.horizontal + } + readonly property alias __activeControl: panel.activeControl + } + } + + /*! \internal */ + property bool __externalScrollBars: false + /*! \internal */ + property int __scrollBarSpacing: 4 + /*! \internal */ + property int __scrollBarFadeDelay: 450 + /*! \internal */ + property int __scrollBarFadeDuration: 200 + /*! \internal */ + property bool __stickyScrollbars: false +} diff --git a/YACReaderLibrary/qml/info-favorites.png b/YACReaderLibrary/qml/info-favorites.png new file mode 100644 index 00000000..f8b61395 Binary files /dev/null and b/YACReaderLibrary/qml/info-favorites.png differ diff --git a/YACReaderLibrary/qml/info-favorites@2x.png b/YACReaderLibrary/qml/info-favorites@2x.png new file mode 100644 index 00000000..19aedd32 Binary files /dev/null and b/YACReaderLibrary/qml/info-favorites@2x.png differ diff --git a/YACReaderLibrary/qml/info-indicator.png b/YACReaderLibrary/qml/info-indicator.png new file mode 100644 index 00000000..af4a616a Binary files /dev/null and b/YACReaderLibrary/qml/info-indicator.png differ diff --git a/YACReaderLibrary/qml/info-rating.png b/YACReaderLibrary/qml/info-rating.png new file mode 100644 index 00000000..d65cf2ab Binary files /dev/null and b/YACReaderLibrary/qml/info-rating.png differ diff --git a/YACReaderLibrary/qml/info-rating@2x.png b/YACReaderLibrary/qml/info-rating@2x.png new file mode 100644 index 00000000..01048c80 Binary files /dev/null and b/YACReaderLibrary/qml/info-rating@2x.png differ diff --git a/YACReaderLibrary/qml/info-shadow.png b/YACReaderLibrary/qml/info-shadow.png new file mode 100644 index 00000000..3508da2e Binary files /dev/null and b/YACReaderLibrary/qml/info-shadow.png differ diff --git a/YACReaderLibrary/qml/info-tag.png b/YACReaderLibrary/qml/info-tag.png new file mode 100644 index 00000000..b7209c58 Binary files /dev/null and b/YACReaderLibrary/qml/info-tag.png differ diff --git a/YACReaderLibrary/qml/info-tag@2x.png b/YACReaderLibrary/qml/info-tag@2x.png new file mode 100644 index 00000000..04a995f8 Binary files /dev/null and b/YACReaderLibrary/qml/info-tag@2x.png differ diff --git a/YACReaderLibrary/qml/info-tick.png b/YACReaderLibrary/qml/info-tick.png new file mode 100644 index 00000000..aa6b80b9 Binary files /dev/null and b/YACReaderLibrary/qml/info-tick.png differ diff --git a/YACReaderLibrary/qml/info-tick@2x.png b/YACReaderLibrary/qml/info-tick@2x.png new file mode 100644 index 00000000..46455b1d Binary files /dev/null and b/YACReaderLibrary/qml/info-tick@2x.png differ diff --git a/YACReaderLibrary/qml/info-top-shadow.png b/YACReaderLibrary/qml/info-top-shadow.png new file mode 100644 index 00000000..1fd60281 Binary files /dev/null and b/YACReaderLibrary/qml/info-top-shadow.png differ diff --git a/YACReaderLibrary/server/lib/bfLogging/filelogger.cpp b/YACReaderLibrary/server/lib/bfLogging/filelogger.cpp index 64bdbd69..06cf122d 100644 --- a/YACReaderLibrary/server/lib/bfLogging/filelogger.cpp +++ b/YACReaderLibrary/server/lib/bfLogging/filelogger.cpp @@ -37,7 +37,7 @@ void FileLogger::refreshSettings() { maxBackups=settings->value("maxBackups",1).toInt(); msgFormat=settings->value("msgFormat","{timestamp} {type} {msg}").toString(); timestampFormat=settings->value("timestampFormat","yyyy-MM-dd hh:mm:ss.zzz").toString(); - minLevel=static_cast(settings->value("minLevel",QtWarningMsg).toInt()); + minLevel=static_cast(settings->value("minLevel",QtCriticalMsg).toInt()); bufferSize=settings->value("bufferSize",0).toInt(); // Create new file if the filename has been changed diff --git a/YACReaderLibrary/yacreader_comic_info_helper.cpp b/YACReaderLibrary/yacreader_comic_info_helper.cpp new file mode 100644 index 00000000..45ee091f --- /dev/null +++ b/YACReaderLibrary/yacreader_comic_info_helper.cpp @@ -0,0 +1,45 @@ +#include "yacreader_comic_info_helper.h" + + + +#include "comic_model.h" + + + +YACReaderComicInfoHelper::YACReaderComicInfoHelper(QObject *parent) + : QObject(parent), model(nullptr) +{ + +} + +void YACReaderComicInfoHelper::setModel(ComicModel *model) +{ + this->model = model; +} + +void YACReaderComicInfoHelper::rate(int index, int rating) +{ + if(model != nullptr) + model->updateRating(rating,model->index(index,0)); +} + +void YACReaderComicInfoHelper::setRead(int index, bool read) +{ + YACReaderComicReadStatus status; + read ? (status = YACReaderComicReadStatus::Read) : (status = YACReaderComicReadStatus::Unread); + + if(model != nullptr) + model->setComicsRead(QModelIndexList() << model->index(index, 0), status); +} + +void YACReaderComicInfoHelper::addToFavorites(int index) +{ + if(model != nullptr) + model->addComicsToFavorites(QModelIndexList() << model->index(index, 0)); +} + +void YACReaderComicInfoHelper::removeFromFavorites(int index) +{ + if(model != nullptr) + model->deleteComicsFromFavorites(QModelIndexList() << model->index(index, 0)); +} diff --git a/YACReaderLibrary/yacreader_comic_info_helper.h b/YACReaderLibrary/yacreader_comic_info_helper.h new file mode 100644 index 00000000..13bd85b4 --- /dev/null +++ b/YACReaderLibrary/yacreader_comic_info_helper.h @@ -0,0 +1,31 @@ +#ifndef YACREADERCOMICINFOHELPER_H +#define YACREADERCOMICINFOHELPER_H + +#include + + +class ComicModel; + + +class YACReaderComicInfoHelper : public QObject +{ + Q_OBJECT +public: + explicit YACReaderComicInfoHelper(QObject *parent = 0); + + void setModel(ComicModel *model); + + Q_INVOKABLE void rate(int index, int rating); + Q_INVOKABLE void setRead(int index, bool read); + Q_INVOKABLE void addToFavorites(int index); + Q_INVOKABLE void removeFromFavorites(int index); + +signals: + +public slots: + +protected: + ComicModel *model; +}; + +#endif // YACREADERCOMICINFOHELPER_H diff --git a/YACReaderLibrary/yacreader_comics_selection_helper.cpp b/YACReaderLibrary/yacreader_comics_selection_helper.cpp new file mode 100644 index 00000000..14798c0c --- /dev/null +++ b/YACReaderLibrary/yacreader_comics_selection_helper.cpp @@ -0,0 +1,127 @@ +#include "yacreader_comics_selection_helper.h" + +#include "comic_model.h" + +YACReaderComicsSelectionHelper::YACReaderComicsSelectionHelper(QObject *parent) : QObject(parent), _selectionModel(nullptr) +{ + +} + +void YACReaderComicsSelectionHelper::setModel(ComicModel *model) +{ + if(model == NULL) + return; + + this->model = model; + + if(_selectionModel != nullptr) + delete _selectionModel; + + _selectionModel = new QItemSelectionModel(model); +} + +void YACReaderComicsSelectionHelper::selectIndex(int index) +{ + if(_selectionModel != nullptr && model!=NULL) + { + _selectionModel->select(model->index(index,0),QItemSelectionModel::Select | QItemSelectionModel::Rows); + + emit selectionChanged(); + } +} + +void YACReaderComicsSelectionHelper::deselectIndex(int index) +{ + if(_selectionModel != nullptr && model!=NULL) + { + _selectionModel->select(model->index(index,0),QItemSelectionModel::Deselect | QItemSelectionModel::Rows); + + emit selectionChanged(); + } +} + +bool YACReaderComicsSelectionHelper::isSelectedIndex(int index) const +{ + if(_selectionModel != nullptr && model!=NULL) + { + QModelIndex mi = model->index(index,0); + return _selectionModel->isSelected(mi); + } + return false; +} + +void YACReaderComicsSelectionHelper::clear() +{ + if(_selectionModel != nullptr) + { + _selectionModel->clear(); + + emit selectionChanged(); + } +} + +QModelIndex YACReaderComicsSelectionHelper::currentIndex() +{ + if(!_selectionModel) + return QModelIndex(); + + QModelIndexList indexes = _selectionModel->selectedRows(); + if(indexes.length()>0) + return indexes[0]; + + this->selectIndex(0); + indexes = _selectionModel->selectedRows(); + if(indexes.length()>0) + return indexes[0]; + else + return QModelIndex(); +} + +void YACReaderComicsSelectionHelper::selectAll() +{ + QModelIndex top = model->index(0, 0); + QModelIndex bottom = model->index(model->rowCount()-1, 0); + QItemSelection selection(top, bottom); + _selectionModel->select(selection, QItemSelectionModel::Select | QItemSelectionModel::Rows); + + emit selectionChanged(); +} + +QModelIndexList YACReaderComicsSelectionHelper::selectedRows(int column) const +{ + return _selectionModel->selectedRows(column); +} + +QList YACReaderComicsSelectionHelper::selectedIndexes() const +{ + return _selectionModel->selectedIndexes(); +} + +int YACReaderComicsSelectionHelper::numItemsSelected() const +{ + if(_selectionModel != nullptr) + { + return _selectionModel->selectedRows().length(); + } + + return 0; +} + +int YACReaderComicsSelectionHelper::lastSelectedIndex() const +{ + if(_selectionModel != nullptr) + { + return _selectionModel->selectedRows().last().row(); + } + + return -1; +} + +QItemSelectionModel *YACReaderComicsSelectionHelper::selectionModel() +{ + QModelIndexList indexes = _selectionModel->selectedRows(); + if(indexes.length()==0) + this->selectIndex(0); + + return _selectionModel; +} diff --git a/YACReaderLibrary/yacreader_comics_selection_helper.h b/YACReaderLibrary/yacreader_comics_selection_helper.h new file mode 100644 index 00000000..b33c63ee --- /dev/null +++ b/YACReaderLibrary/yacreader_comics_selection_helper.h @@ -0,0 +1,41 @@ +#ifndef YACREADERCOMICSSELECTIONHELPER_H +#define YACREADERCOMICSSELECTIONHELPER_H + +#include +#include + +class ComicModel; + +class YACReaderComicsSelectionHelper : public QObject +{ + Q_OBJECT +public: + explicit YACReaderComicsSelectionHelper(QObject *parent = 0); + + void setModel(ComicModel *model); + + Q_INVOKABLE void selectIndex(int index); + Q_INVOKABLE void deselectIndex(int index); + Q_INVOKABLE bool isSelectedIndex(int index) const; + Q_INVOKABLE void clear(); + Q_INVOKABLE int numItemsSelected() const; + Q_INVOKABLE int lastSelectedIndex() const; + Q_INVOKABLE QModelIndex currentIndex(); + Q_INVOKABLE void selectAll(); + Q_INVOKABLE QModelIndexList selectedIndexes() const; + Q_INVOKABLE QModelIndexList selectedRows(int column = 0) const; + + QItemSelectionModel * selectionModel(); + +signals: + void selectionChanged(); + +public slots: + +protected: + QItemSelectionModel * _selectionModel; + + ComicModel * model; +}; + +#endif // YACREADERCOMICSSELECTIONHELPER_H diff --git a/YACReaderLibrary/yacreader_comics_views_manager.cpp b/YACReaderLibrary/yacreader_comics_views_manager.cpp new file mode 100644 index 00000000..36991443 --- /dev/null +++ b/YACReaderLibrary/yacreader_comics_views_manager.cpp @@ -0,0 +1,232 @@ +#include "yacreader_comics_views_manager.h" + +#include "library_window.h" + +#include "classic_comics_view.h" +#include "grid_comics_view.h" +#include "info_comics_view.h" +#include "comics_view_transition.h" +#include "empty_folder_widget.h" +#include "empty_label_widget.h" +#include "empty_special_list.h" +#include "empty_reading_list_widget.h" +#include "no_search_results_widget.h" + +//-- +#include "yacreader_search_line_edit.h" +#include "options_dialog.h" + +YACReaderComicsViewsManager::YACReaderComicsViewsManager(QSettings *settings, LibraryWindow *parent) + : QObject(parent), libraryWindow(parent), classicComicsView(nullptr), gridComicsView(nullptr), infoComicsView(nullptr) +{ + comicsViewStack = new QStackedWidget(); + + switch ((YACReader::ComicsViewStatus)settings->value(COMICS_VIEW_STATUS).toInt()) + { + case Flow: + comicsView = classicComicsView = new ClassicComicsView(); + comicsViewStatus = Flow; + break; + + case Grid: + comicsView = gridComicsView = new GridComicsView(); + connect(libraryWindow->optionsDialog, SIGNAL(optionsChanged()), gridComicsView, SLOT(updateBackgroundConfig())); + comicsViewStatus = Grid; + break; + + case Info: + comicsView = infoComicsView = new InfoComicsView(); + comicsViewStatus = Info; + break; + + default: + comicsView = classicComicsView = new ClassicComicsView(); + comicsViewStatus = Flow; + } + + doComicsViewConnections(); + + comicsViewStack->addWidget(comicsViewTransition = new ComicsViewTransition()); + comicsViewStack->addWidget(emptyFolderWidget = new EmptyFolderWidget()); + comicsViewStack->addWidget(emptyLabelWidget = new EmptyLabelWidget()); + comicsViewStack->addWidget(emptySpecialList = new EmptySpecialListWidget()); + comicsViewStack->addWidget(emptyReadingList = new EmptyReadingListWidget()); + comicsViewStack->addWidget(noSearchResultsWidget = new NoSearchResultsWidget()); + + comicsViewStack->addWidget(comicsView); + + comicsViewStack->setCurrentWidget(comicsView); + + //connections + + connect(emptyFolderWidget, SIGNAL(copyComicsToCurrentFolder(QList >)), libraryWindow, SLOT(copyAndImportComicsToCurrentFolder(QList >))); + connect(emptyFolderWidget, SIGNAL(moveComicsToCurrentFolder(QList >)), libraryWindow, SLOT(moveAndImportComicsToCurrentFolder(QList >))); +} + +QWidget * YACReaderComicsViewsManager::containerWidget() +{ + return comicsViewStack; +} + +void YACReaderComicsViewsManager::showComicsView() +{ + comicsViewStack->setCurrentWidget(comicsView); +} + +void YACReaderComicsViewsManager::showEmptyFolderView() +{ + comicsViewStack->setCurrentWidget(emptyFolderWidget); +} + +void YACReaderComicsViewsManager::showEmptyLabelView() +{ + comicsViewStack->setCurrentWidget(emptyLabelWidget); +} + +void YACReaderComicsViewsManager::showEmptySpecialList() +{ + comicsViewStack->setCurrentWidget(emptySpecialList); +} + +void YACReaderComicsViewsManager::showEmptyReadingListWidget() +{ + comicsViewStack->setCurrentWidget(emptyReadingList); +} + +void YACReaderComicsViewsManager::showNoSearchResultsView() +{ + comicsViewStack->setCurrentWidget(noSearchResultsWidget); +} + +//TODO recover the current comics selection and restore it in the destination +void YACReaderComicsViewsManager::toggleComicsView() +{ + if(comicsViewStack->currentWidget()==comicsView) { + QTimer::singleShot(0,this,SLOT(showComicsViewTransition())); + QTimer::singleShot(100,this,SLOT(_toggleComicsView())); + } else + { + _toggleComicsView(); + } +} + +//PROTECTED + +void YACReaderComicsViewsManager::disconnectComicsViewConnections(ComicsView * widget) +{ + disconnect(widget, SIGNAL(comicRated(int,QModelIndex)), libraryWindow->comicsModel, SLOT(updateRating(int,QModelIndex))); + disconnect(libraryWindow->showHideMarksAction,SIGNAL(toggled(bool)),widget,SLOT(setShowMarks(bool))); + disconnect(widget,SIGNAL(selected(unsigned int)),libraryWindow,SLOT(openComic())); + disconnect(libraryWindow->selectAllComicsAction,SIGNAL(triggered()),widget,SLOT(selectAll())); + disconnect(comicsView, SIGNAL(copyComicsToCurrentFolder(QList >)), libraryWindow, SLOT(copyAndImportComicsToCurrentFolder(QList >))); + disconnect(comicsView, SIGNAL(moveComicsToCurrentFolder(QList >)), libraryWindow, SLOT(moveAndImportComicsToCurrentFolder(QList >))); + disconnect(comicsView,SIGNAL(customContextMenuViewRequested(QPoint)),libraryWindow,SLOT(showComicsViewContextMenu(QPoint))); + disconnect(comicsView,SIGNAL(customContextMenuItemRequested(QPoint)),libraryWindow,SLOT(showComicsItemContextMenu(QPoint))); +} + +void YACReaderComicsViewsManager::doComicsViewConnections() +{ + connect(comicsView, SIGNAL(comicRated(int,QModelIndex)), libraryWindow->comicsModel, SLOT(updateRating(int,QModelIndex))); + connect(libraryWindow->showHideMarksAction,SIGNAL(toggled(bool)),comicsView,SLOT(setShowMarks(bool))); + connect(comicsView,SIGNAL(selected(unsigned int)),libraryWindow,SLOT(openComic())); + connect(libraryWindow->selectAllComicsAction,SIGNAL(triggered()),comicsView,SLOT(selectAll())); + + connect(comicsView,SIGNAL(customContextMenuViewRequested(QPoint)),libraryWindow,SLOT(showComicsViewContextMenu(QPoint))); + connect(comicsView,SIGNAL(customContextMenuItemRequested(QPoint)),libraryWindow,SLOT(showComicsItemContextMenu(QPoint))); + //Drops + connect(comicsView, SIGNAL(copyComicsToCurrentFolder(QList >)), libraryWindow, SLOT(copyAndImportComicsToCurrentFolder(QList >))); + connect(comicsView, SIGNAL(moveComicsToCurrentFolder(QList >)), libraryWindow, SLOT(moveAndImportComicsToCurrentFolder(QList >))); +} + +void YACReaderComicsViewsManager::switchToComicsView(ComicsView * from, ComicsView * to) +{ + //setup views + disconnectComicsViewConnections(from); + from->close(); + + comicsView = to; + doComicsViewConnections(); + + comicsView->setToolBar(libraryWindow->editInfoToolBar); + + comicsViewStack->removeWidget(from); + comicsViewStack->addWidget(comicsView); + + //delete from; No need to delete the previews view, because all views are going to be kept in memory + + //load content into current view + libraryWindow->loadCoversFromCurrentModel(); + + if(!libraryWindow->searchEdit->text().isEmpty()) + { + comicsView->enableFilterMode(true); + } +} + +void YACReaderComicsViewsManager::showComicsViewTransition() +{ + comicsViewStack->setCurrentWidget(comicsViewTransition); +} + +void YACReaderComicsViewsManager::_toggleComicsView() +{ + switch(comicsViewStatus) + { + case Flow: + { + QIcon icoViewsButton; + icoViewsButton.addFile(":/images/main_toolbar/info.png", QSize(), QIcon::Normal); + libraryWindow->toggleComicsViewAction->setIcon(icoViewsButton); +#ifdef Q_OS_MAC + libraryWindow->libraryToolBar->updateViewSelectorIcon(icoViewsButton); +#endif + if(gridComicsView == nullptr) + gridComicsView = new GridComicsView(); + + switchToComicsView(classicComicsView, gridComicsView); + connect(libraryWindow->optionsDialog, SIGNAL(optionsChanged()), gridComicsView, SLOT(updateBackgroundConfig())); + comicsViewStatus = Grid; + + break; + } + + case Grid: + { + QIcon icoViewsButton; + icoViewsButton.addFile(":/images/main_toolbar/flow.png", QSize(), QIcon::Normal); + libraryWindow->toggleComicsViewAction->setIcon(icoViewsButton); +#ifdef Q_OS_MAC + libraryWindow->libraryToolBar->updateViewSelectorIcon(icoViewsButton); +#endif + if(infoComicsView == nullptr) + infoComicsView = new InfoComicsView(); + + switchToComicsView(gridComicsView, infoComicsView); + comicsViewStatus = Info; + + break; + } + + case Info: + { + QIcon icoViewsButton; + icoViewsButton.addFile(":/images/main_toolbar/grid.png", QSize(), QIcon::Normal); + libraryWindow->toggleComicsViewAction->setIcon(icoViewsButton); +#ifdef Q_OS_MAC + libraryWindow->libraryToolBar->updateViewSelectorIcon(icoViewsButton); +#endif + if(classicComicsView == nullptr) + classicComicsView = new ClassicComicsView(); + + switchToComicsView(infoComicsView, classicComicsView); + comicsViewStatus = Flow; + + break; + } + } + + libraryWindow->settings->setValue(COMICS_VIEW_STATUS, comicsViewStatus); + + if(comicsViewStack->currentWidget()==comicsViewTransition) + showComicsView(); +} diff --git a/YACReaderLibrary/yacreader_comics_views_manager.h b/YACReaderLibrary/yacreader_comics_views_manager.h new file mode 100644 index 00000000..62136ca9 --- /dev/null +++ b/YACReaderLibrary/yacreader_comics_views_manager.h @@ -0,0 +1,75 @@ +#ifndef YACREADERCOMICSVIEWSMANAGER_H +#define YACREADERCOMICSVIEWSMANAGER_H + +#include + +#include "yacreader_global_gui.h" + +class LibraryWindow; + +class ComicsView; +class ClassicComicsView; +class GridComicsView; +class InfoComicsView; +class ComicsViewTransition; +class EmptyFolderWidget; +class EmptyLabelWidget; +class EmptySpecialListWidget; +class EmptyReadingListWidget; +class NoSearchResultsWidget; + +using namespace YACReader; + +class YACReaderComicsViewsManager : public QObject +{ + Q_OBJECT +public: + explicit YACReaderComicsViewsManager(QSettings *settings, LibraryWindow *parent = 0); + + QWidget * containerWidget(); + + ComicsView * comicsView; + + ComicsViewTransition * comicsViewTransition; + + EmptyFolderWidget * emptyFolderWidget; + EmptyLabelWidget * emptyLabelWidget; + EmptySpecialListWidget * emptySpecialList; + EmptyReadingListWidget * emptyReadingList; + + NoSearchResultsWidget * noSearchResultsWidget; + +protected: + QStackedWidget * comicsViewStack; + LibraryWindow * libraryWindow; + + ComicsViewStatus comicsViewStatus; + + ClassicComicsView * classicComicsView; + GridComicsView * gridComicsView; + InfoComicsView *infoComicsView; + +signals: + +public slots: + void toggleComicsView(); + + void showComicsView(); + void showEmptyFolderView(); + void showEmptyLabelView(); + void showEmptySpecialList(); + void showEmptyReadingListWidget(); + void showNoSearchResultsView(); + +protected slots: + void showComicsViewTransition(); + void _toggleComicsView(); + + void disconnectComicsViewConnections(ComicsView * widget); + void doComicsViewConnections(); + + void switchToComicsView(ComicsView *from, ComicsView *to); + +}; + +#endif // COMICSVIEWSMANAGER_H diff --git a/YACReaderLibrary/yacreader_navigation_controller.cpp b/YACReaderLibrary/yacreader_navigation_controller.cpp index 3996932b..ab1afd33 100644 --- a/YACReaderLibrary/yacreader_navigation_controller.cpp +++ b/YACReaderLibrary/yacreader_navigation_controller.cpp @@ -16,11 +16,12 @@ #include "yacreader_global.h" #include "empty_label_widget.h" #include "empty_special_list.h" +#include "yacreader_comics_views_manager.h" #include "QsLog.h" -YACReaderNavigationController::YACReaderNavigationController(LibraryWindow *parent) : - QObject(parent),libraryWindow(parent) +YACReaderNavigationController::YACReaderNavigationController(LibraryWindow *parent, YACReaderComicsViewsManager *comicsViewsManager) : + QObject(parent),libraryWindow(parent),comicsViewsManager(comicsViewsManager) { setupConnections(); } @@ -59,19 +60,19 @@ void YACReaderNavigationController::loadFolderInfo(const QModelIndex &modelIndex //check comics in folder with id = folderId libraryWindow->comicsModel->setupFolderModelData(folderId,libraryWindow->foldersModel->getDatabase()); - libraryWindow->comicsView->setModel(libraryWindow->comicsModel); + comicsViewsManager->comicsView->setModel(libraryWindow->comicsModel); //configure views if(libraryWindow->comicsModel->rowCount() > 0) { //updateView - libraryWindow->showComicsView(); + comicsViewsManager->showComicsView(); libraryWindow->disableComicsActions(false); } else{ //showEmptyFolder loadEmptyFolderInfo(modelIndex); - libraryWindow->showEmptyFolderView(); + comicsViewsManager->showEmptyFolderView(); libraryWindow->disableComicsActions(true); } @@ -116,11 +117,11 @@ void YACReaderNavigationController::loadSpecialListInfo(const QModelIndex &model break; } - libraryWindow->comicsView->setModel(libraryWindow->comicsModel); + comicsViewsManager->comicsView->setModel(libraryWindow->comicsModel); if(libraryWindow->comicsModel->rowCount() > 0) { - libraryWindow->showComicsView(); + comicsViewsManager->showComicsView(); libraryWindow->disableComicsActions(false); } else @@ -129,16 +130,16 @@ void YACReaderNavigationController::loadSpecialListInfo(const QModelIndex &model switch(type) { case ReadingListModel::Favorites: - libraryWindow->emptySpecialList->setPixmap(QPixmap(":/images/empty_favorites.png")); - libraryWindow->emptySpecialList->setText(tr("No favorites")); + comicsViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_favorites.png")); + comicsViewsManager->emptySpecialList->setText(tr("No favorites")); break; case ReadingListModel::Reading: - libraryWindow->emptySpecialList->setPixmap(QPixmap(":/images/empty_current_readings.png")); - libraryWindow->emptySpecialList->setText(tr("You are not reading anything yet, come on!!")); + comicsViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_current_readings.png")); + comicsViewsManager->emptySpecialList->setText(tr("You are not reading anything yet, come on!!")); break; } - libraryWindow->showEmptySpecialList(); + comicsViewsManager->showEmptySpecialList(); libraryWindow->disableComicsActions(true); } } @@ -148,20 +149,20 @@ void YACReaderNavigationController::loadLabelInfo(const QModelIndex &modelIndex) qulonglong id = modelIndex.data(ReadingListModel::IDRole).toULongLong(); //check comics in label with id = id libraryWindow->comicsModel->setupLabelModelData(id,libraryWindow->foldersModel->getDatabase()); - libraryWindow->comicsView->setModel(libraryWindow->comicsModel); + comicsViewsManager->comicsView->setModel(libraryWindow->comicsModel); //configure views if(libraryWindow->comicsModel->rowCount() > 0) { //updateView - libraryWindow->showComicsView(); + comicsViewsManager->showComicsView(); libraryWindow->disableComicsActions(false); } else{ //showEmptyFolder //loadEmptyLabelInfo(); //there is no info in an empty label by now, TODO design something - libraryWindow->emptyLabelWidget->setColor((YACReader::LabelColors)modelIndex.data(ReadingListModel::LabelColorRole).toInt()); - libraryWindow->showEmptyLabelView(); + comicsViewsManager->emptyLabelWidget->setColor((YACReader::LabelColors)modelIndex.data(ReadingListModel::LabelColorRole).toInt()); + comicsViewsManager->showEmptyLabelView(); libraryWindow->disableComicsActions(true); } } @@ -171,17 +172,17 @@ void YACReaderNavigationController::loadReadingListInfo(const QModelIndex &model qulonglong id = modelIndex.data(ReadingListModel::IDRole).toULongLong(); //check comics in label with id = id libraryWindow->comicsModel->setupReadingListModelData(id,libraryWindow->foldersModel->getDatabase()); - libraryWindow->comicsView->setModel(libraryWindow->comicsModel); + comicsViewsManager->comicsView->setModel(libraryWindow->comicsModel); //configure views if(libraryWindow->comicsModel->rowCount() > 0) { //updateView - libraryWindow->showComicsView(); + comicsViewsManager->showComicsView(); libraryWindow->disableComicsActions(false); } else{ - libraryWindow->showEmptyReadingListWidget(); + comicsViewsManager->showEmptyReadingListWidget(); libraryWindow->disableComicsActions(true); } } @@ -273,7 +274,7 @@ void YACReaderNavigationController::loadEmptyFolderInfo(const QModelIndex &model { QStringList subfolders; subfolders = libraryWindow->foldersModel->getSubfoldersNames(modelIndex); - libraryWindow->emptyFolderWidget->setSubfolders(modelIndex,subfolders); + comicsViewsManager->emptyFolderWidget->setSubfolders(modelIndex,subfolders); } void YACReaderNavigationController::loadPreviousStatus() @@ -287,7 +288,7 @@ void YACReaderNavigationController::setupConnections() connect(libraryWindow->foldersView,SIGNAL(clicked(QModelIndex)),this,SLOT(selectedFolder(QModelIndex))); connect(libraryWindow->listsView,SIGNAL(clicked(QModelIndex)),this,SLOT(selectedList(QModelIndex))); connect(libraryWindow->historyController,SIGNAL(modelIndexSelected(YACReaderLibrarySourceContainer)),this,SLOT(selectedIndexFromHistory(YACReaderLibrarySourceContainer))); - connect(libraryWindow->emptyFolderWidget,SIGNAL(subfolderSelected(QModelIndex,int)),this,SLOT(selectSubfolder(QModelIndex,int))); + connect(comicsViewsManager->emptyFolderWidget,SIGNAL(subfolderSelected(QModelIndex,int)),this,SLOT(selectSubfolder(QModelIndex,int))); connect(libraryWindow->comicsModel,SIGNAL(isEmpty()),this,SLOT(reselectCurrentSource())); } diff --git a/YACReaderLibrary/yacreader_navigation_controller.h b/YACReaderLibrary/yacreader_navigation_controller.h index 2dbeac28..6463dbfa 100644 --- a/YACReaderLibrary/yacreader_navigation_controller.h +++ b/YACReaderLibrary/yacreader_navigation_controller.h @@ -4,13 +4,14 @@ #include class LibraryWindow; class YACReaderLibrarySourceContainer; +class YACReaderComicsViewsManager; class YACReaderNavigationController : public QObject { Q_OBJECT public: - explicit YACReaderNavigationController(LibraryWindow * parent); + explicit YACReaderNavigationController(LibraryWindow * parent, YACReaderComicsViewsManager * comicsViewsManager); signals: @@ -45,6 +46,7 @@ private: void setupConnections(); LibraryWindow * libraryWindow; + YACReaderComicsViewsManager * comicsViewsManager; //convenience methods qulonglong folderModelIndexToID(const QModelIndex & mi); diff --git a/common/comic_db.cpp b/common/comic_db.cpp index 6e92b85a..2f88ee58 100644 --- a/common/comic_db.cpp +++ b/common/comic_db.cpp @@ -11,6 +11,11 @@ ComicDB::ComicDB() } +ComicDB::ComicDB(const ComicDB &comicDB) +{ + operator=(comicDB); +} + bool ComicDB::isDir() { return false; @@ -105,7 +110,18 @@ QString ComicDB::toTXT() if(!info.notes.isNull()) txt.append(QString("notes:%1\r\n").arg(info.notes.toString())); - return txt; + return txt; +} + +ComicDB &ComicDB::operator=(const ComicDB &other) +{ + LibraryItem::operator =(other); + + this->_hasCover = other._hasCover; + + this->info = other.info; + + return *this; } QString ComicDB::getFileName() const @@ -136,6 +152,16 @@ qulonglong ComicDB::getFileSize() const return info.hash.right(info.hash.length()-40).toLongLong(); } +QString ComicDB::getTitleIncludingNumber() const +{ + if(!info.number.isNull()) + { + return "#" + info.number.toString() + " - " + getTitleOrFileName(); + } + + return getTitleOrFileName(); +} + //----------------------------------------------------------------------------- //COMIC_INFO------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -346,8 +372,106 @@ QPixmap ComicInfo::getCover(const QString & basePath) } QPixmap c; c.convertFromImage(cover); - return c; + return c; } + +QStringList ComicInfo::getWriters() +{ + if(writer.toString().length()>0) + { + return writer.toString().split("\n"); + } + + return QStringList(); +} + +QStringList ComicInfo::getPencillers() +{ + if(penciller.toString().length()>0) + { + return penciller.toString().split("\n"); + } + + return QStringList(); +} + +QStringList ComicInfo::getInkers() +{ + if(inker.toString().length()>0) + { + return inker.toString().split("\n"); + } + + return QStringList(); +} + +QStringList ComicInfo::getColorists() +{ + if(colorist.toString().length()>0) + { + return colorist.toString().split("\n"); + } + + return QStringList(); +} + +QStringList ComicInfo::getLetterers() +{ + if(letterer.toString().length()>0) + { + return letterer.toString().split("\n"); + } + + return QStringList(); +} + +QStringList ComicInfo::getCoverArtists() +{ + if(coverArtist.toString().length()>0) + { + return coverArtist.toString().split("\n"); + } + + return QStringList(); +} + +QStringList ComicInfo::getCharacters() +{ + if(characters.toString().length()>0) + { + return characters.toString().split("\n"); + } + + return QStringList(); +} + +void ComicInfo::setRead(bool r) +{ + if(r != read) + { + read = r; + emit readChanged(); + } +} + +void ComicInfo::setRating(int r) +{ + if(r != rating) + { + rating = r; + emit ratingChanged(); + } +} + +void ComicInfo::setFavorite(bool f) +{ + if(f != isFavorite) + { + isFavorite = f; + emit favoriteChanged(); + } +} + QDataStream &operator<<(QDataStream & stream, const ComicDB & comic) { stream << comic.id; diff --git a/common/comic_db.h b/common/comic_db.h index 417efa4d..5850de65 100644 --- a/common/comic_db.h +++ b/common/comic_db.h @@ -8,8 +8,12 @@ #include #include -class ComicInfo +typedef QPair YACReaderComicInfoPair; +Q_DECLARE_METATYPE(YACReaderComicInfoPair) + +class ComicInfo : public QObject { + Q_OBJECT public: ComicInfo(); ComicInfo(const ComicInfo & comicInfo); @@ -17,6 +21,9 @@ public: ComicInfo & operator=(const ComicInfo & comicInfo); + bool operator==(const ComicInfo & other){return id == other.id;} + bool operator!=(const ComicInfo & other){return id != other.id;} + //mandatory fields qulonglong id; bool read; @@ -111,47 +118,131 @@ public: QPixmap getCover(const QString & basePath); + Q_INVOKABLE QStringList getWriters(); + Q_INVOKABLE QStringList getPencillers(); + Q_INVOKABLE QStringList getInkers(); + Q_INVOKABLE QStringList getColorists(); + Q_INVOKABLE QStringList getLetterers(); + Q_INVOKABLE QStringList getCoverArtists(); + + Q_INVOKABLE QStringList getCharacters(); + friend QDataStream &operator<<(QDataStream & stream, const ComicInfo & comicInfo); friend QDataStream &operator>>(QDataStream & stream, ComicInfo & comicInfo); + Q_PROPERTY(qulonglong id MEMBER id CONSTANT) + Q_PROPERTY(bool read MEMBER read WRITE setRead NOTIFY readChanged) + Q_PROPERTY(bool edited MEMBER edited CONSTANT) + Q_PROPERTY(QString hash MEMBER hash CONSTANT) + Q_PROPERTY(bool existOnDb MEMBER existOnDb CONSTANT) + + Q_PROPERTY(int rating MEMBER rating WRITE setRating NOTIFY ratingChanged) + + Q_PROPERTY(bool hasBeenOpened MEMBER hasBeenOpened CONSTANT) + + Q_PROPERTY(int currentPage MEMBER currentPage CONSTANT) + Q_PROPERTY(int bookmark1 MEMBER bookmark1 CONSTANT) + Q_PROPERTY(int bookmark2 MEMBER bookmark2 CONSTANT) + Q_PROPERTY(int bookmark3 MEMBER bookmark3 CONSTANT) + Q_PROPERTY(int brightness MEMBER brightness CONSTANT) + Q_PROPERTY(int contrast MEMBER contrast CONSTANT) + Q_PROPERTY(int gamma MEMBER gamma CONSTANT) + + Q_PROPERTY(QVariant title MEMBER title CONSTANT) + + Q_PROPERTY(QVariant coverPage MEMBER coverPage CONSTANT) + Q_PROPERTY(QVariant numPages MEMBER numPages CONSTANT) + + Q_PROPERTY(QVariant number MEMBER number CONSTANT) + Q_PROPERTY(QVariant isBis MEMBER isBis CONSTANT) + Q_PROPERTY(QVariant count MEMBER count CONSTANT) + + Q_PROPERTY(QVariant volume MEMBER volume CONSTANT) + Q_PROPERTY(QVariant storyArc MEMBER storyArc CONSTANT) + Q_PROPERTY(QVariant arcNumber MEMBER arcNumber CONSTANT) + Q_PROPERTY(QVariant arcCount MEMBER arcCount CONSTANT) + + Q_PROPERTY(QVariant genere MEMBER genere CONSTANT) + + Q_PROPERTY(QVariant writer MEMBER writer CONSTANT) + Q_PROPERTY(QVariant penciller MEMBER penciller CONSTANT) + Q_PROPERTY(QVariant inker MEMBER inker CONSTANT) + Q_PROPERTY(QVariant colorist MEMBER colorist CONSTANT) + Q_PROPERTY(QVariant letterer MEMBER letterer CONSTANT) + Q_PROPERTY(QVariant coverArtist MEMBER coverArtist CONSTANT) + + Q_PROPERTY(QVariant date MEMBER date CONSTANT) + Q_PROPERTY(QVariant publisher MEMBER publisher CONSTANT) + Q_PROPERTY(QVariant format MEMBER format CONSTANT) + Q_PROPERTY(QVariant color MEMBER color CONSTANT) + Q_PROPERTY(QVariant ageRating MEMBER ageRating CONSTANT) + + Q_PROPERTY(QVariant synopsis MEMBER synopsis CONSTANT) + Q_PROPERTY(QVariant characters MEMBER characters CONSTANT) + Q_PROPERTY(QVariant notes MEMBER notes CONSTANT) + + Q_PROPERTY(QVariant comicVineID MEMBER comicVineID CONSTANT) + + Q_PROPERTY(QImage cover MEMBER cover CONSTANT) + + //-new properties, not loaded from the DB automatically + bool isFavorite; + Q_PROPERTY(bool isFavorite MEMBER isFavorite WRITE setFavorite NOTIFY favoriteChanged) + + //setters, used in QML only by now + void setRead(bool r); + void setRating(int r); + void setFavorite(bool f); private: +signals: + void readChanged(); + void ratingChanged(); + void favoriteChanged(); + }; class ComicDB : public LibraryItem { + Q_OBJECT public: ComicDB(); + ComicDB(const ComicDB & comicDB); bool isDir(); bool _hasCover; - bool hasCover() {return _hasCover;}; + bool hasCover() {return _hasCover;} //return comic file name QString getFileName() const; //returns comic title if it isn't null or empty, in other case returns fileName - QString getTitleOrFileName() const; + Q_INVOKABLE QString getTitleOrFileName() const; //returns parent folder name QString getParentFolderName() const; //return the size of the file in bytes - qulonglong getFileSize() const; + Q_INVOKABLE qulonglong getFileSize() const; - QString toTXT(); - - ComicInfo info; + Q_INVOKABLE QString getTitleIncludingNumber() const; - bool operator==(const ComicDB & other){return id == other.id;}; + QString toTXT(); + + ComicInfo info; + Q_PROPERTY(ComicInfo info MEMBER info) + + ComicDB & operator=(const ComicDB & other); + bool operator==(const ComicDB & other){return id == other.id;} friend QDataStream &operator<<(QDataStream &, const ComicDB &); - friend QDataStream &operator>>(QDataStream &, ComicDB &); + friend QDataStream &operator>>(QDataStream &, ComicDB &); + }; -Q_DECLARE_METATYPE(ComicDB); +Q_DECLARE_METATYPE(ComicDB) #endif diff --git a/common/folder.cpp b/common/folder.cpp index e69de29b..4f08207e 100644 --- a/common/folder.cpp +++ b/common/folder.cpp @@ -0,0 +1,19 @@ + +#include "folder.h" + +Folder::Folder(const Folder &folder) +{ + operator=(folder); +} + +Folder &Folder::operator =(const Folder &other) +{ + LibraryItem::operator =(other); + + this->knownParent = other.knownParent; + this->knownId = other.knownId; + this->finished = other.finished; + this->completed = other.completed; + + return *this; +} diff --git a/common/folder.h b/common/folder.h index 862c05de..2dc7002a 100644 --- a/common/folder.h +++ b/common/folder.h @@ -11,16 +11,18 @@ public: bool knownParent; bool knownId; - Folder():knownParent(false), knownId(false){}; - Folder(qulonglong sid, qulonglong pid,QString fn, QString fp):knownParent(true), knownId(true){id = sid; parentId = pid;name = fn; path = fp;}; - Folder(QString fn, QString fp):knownParent(false), knownId(false){name = fn; path = fp;}; - void setId(qulonglong sid){id = sid;knownId = true;}; - void setFather(qulonglong pid){parentId = pid;knownParent = true;}; - bool isDir() {return true;}; - bool isFinished() const {return finished;}; - bool isCompleted() const {return completed;}; - void setFinished(bool b) {finished = b;}; - void setCompleted(bool b) {completed = b;}; + Folder():knownParent(false), knownId(false){} + Folder(qulonglong sid, qulonglong pid,QString fn, QString fp):knownParent(true), knownId(true){id = sid; parentId = pid;name = fn; path = fp;} + Folder(QString fn, QString fp):knownParent(false), knownId(false){name = fn; path = fp;} + Folder(const Folder &folder); + Folder &operator =(const Folder & other); + void setId(qulonglong sid){id = sid;knownId = true;} + void setFather(qulonglong pid){parentId = pid;knownParent = true;} + bool isDir() {return true;} + bool isFinished() const {return finished;} + bool isCompleted() const {return completed;} + void setFinished(bool b) {finished = b;} + void setCompleted(bool b) {completed = b;} private: bool finished; diff --git a/common/library_item.cpp b/common/library_item.cpp index e69de29b..3d92a6ee 100644 --- a/common/library_item.cpp +++ b/common/library_item.cpp @@ -0,0 +1,12 @@ + +#include "library_item.h" + +LibraryItem &LibraryItem::operator=(const LibraryItem &other) +{ + this->name = other.name; + this->path = other.path; + this->parentId = other.parentId; + this->id = other.id; + + return *this; +} diff --git a/common/library_item.h b/common/library_item.h index 2f6b8d9f..5ca1958e 100644 --- a/common/library_item.h +++ b/common/library_item.h @@ -3,14 +3,16 @@ #include -class LibraryItem +class LibraryItem : public QObject { + Q_OBJECT public: virtual bool isDir() = 0; + LibraryItem & operator=(const LibraryItem & other); QString name; QString path; qulonglong parentId; qulonglong id; }; -#endif \ No newline at end of file +#endif diff --git a/common/yacreader_global_gui.h b/common/yacreader_global_gui.h index 672971a7..f3858958 100644 --- a/common/yacreader_global_gui.h +++ b/common/yacreader_global_gui.h @@ -53,6 +53,8 @@ #define COMICS_VIEW_FLOW_SPLITTER_STATUS "COMICS_VIEW_FLOW_SPLITTER_STATUS" #define SIDEBAR_SPLITTER_STATUS "SIDEBAR_SPLITTER_STATUS" #define COMICS_GRID_COVER_SIZES "COMICS_GRID_COVER_SIZES" +#define COMICS_GRID_SHOW_INFO "COMICS_GRID_SHOW_INFO" +#define COMICS_GRID_INFO_WIDTH "COMICS_GRID_INFO_WIDTH" #define COMIC_VINE_API_KEY "COMIC_VINE_API_KEY" #define COMIC_VINE_BASE_URL "COMIC_VINE_BASE_URL" @@ -76,7 +78,8 @@ static const QString YACReaderLibrarSubReadingListMimeDataFormat = "application/ enum ComicsViewStatus { Flow, - Grid + Grid, + Info }; enum FitMode{ diff --git a/images/comics_view_toolbar/show_comic_info.png b/images/comics_view_toolbar/show_comic_info.png new file mode 100644 index 00000000..277dbc23 Binary files /dev/null and b/images/comics_view_toolbar/show_comic_info.png differ diff --git a/images/comics_view_toolbar/show_comic_info@2x.png b/images/comics_view_toolbar/show_comic_info@2x.png new file mode 100644 index 00000000..530d1f93 Binary files /dev/null and b/images/comics_view_toolbar/show_comic_info@2x.png differ diff --git a/images/flow_to_grid.gif b/images/flow_to_grid.gif deleted file mode 100644 index f78228cf..00000000 Binary files a/images/flow_to_grid.gif and /dev/null differ diff --git a/images/flow_to_grid_osx.gif b/images/flow_to_grid_osx.gif deleted file mode 100644 index 99a73ed6..00000000 Binary files a/images/flow_to_grid_osx.gif and /dev/null differ diff --git a/images/grid_to_flow.gif b/images/grid_to_flow.gif deleted file mode 100644 index 10bc6d23..00000000 Binary files a/images/grid_to_flow.gif and /dev/null differ diff --git a/images/grid_to_flow_osx.gif b/images/grid_to_flow_osx.gif deleted file mode 100644 index 7bf2fbc4..00000000 Binary files a/images/grid_to_flow_osx.gif and /dev/null differ diff --git a/images/main_toolbar/info.png b/images/main_toolbar/info.png new file mode 100644 index 00000000..09d12542 Binary files /dev/null and b/images/main_toolbar/info.png differ