mirror of
https://github.com/YACReader/yacreader
synced 2025-07-18 04:54:29 -04:00
Merged luisangelsm/yacreader into default
This commit is contained in:
@ -1,3 +1,34 @@
|
||||
8.0.0
|
||||
Reading lists
|
||||
Tags
|
||||
'Favorites' and 'being read' lists
|
||||
New search engine, now you can filter folders and comics
|
||||
New grid view
|
||||
Add and delete folders
|
||||
Update a single folder (no need for updating the whole library to rescan a single folder)
|
||||
Drag and drop for adding new comics and folders
|
||||
Customizable shorcuts
|
||||
Manga mode (thank you Felix)
|
||||
Spread page detection for double page mode (including manga mode)(thank you again Felix :) )
|
||||
New view for folders not containing comics (only subfolders)
|
||||
Save selected covers to disk
|
||||
Comics in Reading Lists and Tags can be sorted by drag&drop
|
||||
Sublist in Reading Lists can by sorted by drag&drop
|
||||
Added WebP image format support
|
||||
The user has to provide its own Comic Vine API key to prevent usage limit errors from Comic Vine
|
||||
New unarr decompression backend for Linux and Unix systems
|
||||
Fixed memory and filedescriptor leaks in 7zip wrapper
|
||||
Dropped support for Qt4
|
||||
Lots of smaller bugfixes
|
||||
|
||||
7.2.0
|
||||
Added support for the new "remote read" feature in iOS devices.
|
||||
Improved stability
|
||||
Fixed broken compatibility with Windows XP
|
||||
Improved Linux "packageability" (thanks to Felix, Alexander and Yoann)**
|
||||
German translation (thanks to Gerhard Joeken)
|
||||
Bug fixes.
|
||||
|
||||
7.1.0
|
||||
A<EFBFBD>adida opci<63>n para resetear el rating de un comics
|
||||
Corregidos bugs que afectaban a la informaci<63>n de p<>gina.
|
||||
|
49
INSTALL.txt
49
INSTALL.txt
@ -2,14 +2,57 @@ COMPILATION GUIDE FOR LINUX/UNIX USERS
|
||||
**********************************
|
||||
YACReader and YACReaderLibrary are build using qmake. To build and install the program, run:
|
||||
|
||||
qmake
|
||||
qmake-qt5 CONFIG+=[Options]
|
||||
make
|
||||
make install
|
||||
|
||||
from the source dir. For seperate builds of YACReader or YACReaderLibrary, enter their respective subfolders and run the commands from there.
|
||||
|
||||
Build options:
|
||||
Dependencies:
|
||||
-----------------------
|
||||
|
||||
- Qt >= 5.3 with the following modules:
|
||||
- declarative
|
||||
- sql
|
||||
- script
|
||||
- multimedia
|
||||
- imageformats
|
||||
- opengl
|
||||
- sql-sqlite
|
||||
|
||||
- poppler-qt5
|
||||
- qrencode
|
||||
- sqllite
|
||||
- glu
|
||||
- a decompression backend, either 7zip or unarr (see below)
|
||||
|
||||
|
||||
Decompression backend:
|
||||
---------------------------------------
|
||||
|
||||
YACReader supports two decompression backends:
|
||||
|
||||
- unarr
|
||||
- p7zip=9.20.1
|
||||
|
||||
These can be selected at build time by adding either CONFIG+=unarr or CONFIG+=7zip as an option when running qmake.
|
||||
If none of these is provided, the build system will default to unarr on Linux/Unix and [p]7zip on Windows and OS X.
|
||||
|
||||
The decompression backends have their own dependencies and require additional steps like downloading additional source code
|
||||
for setup. Please consult the README files provided in the compressed_archive and compressed_archive/unarr folders for details.
|
||||
|
||||
If you chose to build YACReader with p7zip as a backend on Linux/Unix, please take notice that this backend has some problems:
|
||||
|
||||
- p7zip > 9.20.1 is not supported
|
||||
- p7zip 9.20.1 has known bugs that are fixed only in the later versions
|
||||
- a system update that replaces p7zip 9.20.1 with a later version will make YACReader unusable
|
||||
|
||||
If your system already ships with p7zip > 9.20.1 you can place 7z.so and the Codecs folder with the Rar29.so from p7zip 9.20.1 in /usr/lib/yacreader
|
||||
YACReader will check this folder first and can thus continue using 7zip as a backend with p7zip > 9.20.1 installed on your system.
|
||||
|
||||
Other build options:
|
||||
---------------------
|
||||
|
||||
You can adjust the installation prefix as well als the path make install uses to install the files.
|
||||
Use "qmake PREFIX=DIR" to configure YACReader for your systems default prefix (for example "/", "/usr", "/usr/local").
|
||||
|
||||
@ -24,7 +67,7 @@ On embedded devices that don't support desktop OpenGL, it is recommended to use
|
||||
|
||||
qmake CONFIG+=no_opengl
|
||||
|
||||
This will remove any dependency on desktop OpenGL.
|
||||
This will remove any dependency on desktop OpenGL and hardlock rendering to software.
|
||||
|
||||
|
||||
DO YOU WANT TO HELP YACREADER?
|
||||
|
@ -1,164 +0,0 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
DEPENDPATH += $$PWD
|
||||
INCLUDEPATH += .
|
||||
INCLUDEPATH += $$PWD/../common \
|
||||
$$PWD/../custom_widgets
|
||||
|
||||
CONFIG(legacy_gl_widget) {
|
||||
INCLUDEPATH += ../common/gl_legacy \
|
||||
} else {
|
||||
INCLUDEPATH += ../common/gl \
|
||||
}
|
||||
|
||||
win32 {
|
||||
LIBS += -L$$PWD/../dependencies/poppler/lib -loleaut32 -lole32
|
||||
|
||||
LIBS += -lpoppler-qt5
|
||||
INCLUDEPATH += ../dependencies/poppler/include/qt5
|
||||
|
||||
QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT
|
||||
!CONFIG(no_opengl) {
|
||||
QMAKE_CXXFLAGS_RELEASE += /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
|
||||
#}
|
||||
CONFIG += objective_c
|
||||
QT += macextras gui-private
|
||||
|
||||
|
||||
LIBS += -framework Foundation -framework ApplicationServices -framework AppKit
|
||||
|
||||
OBJECTIVE_SOURCES += $$PWD/../common/pdf_comic.mm
|
||||
HEADERS += $$PWD/../common/pdf_comic.h
|
||||
}
|
||||
|
||||
QT += network widgets core
|
||||
!CONFIG(no_opengl) {
|
||||
QT += opengl
|
||||
}
|
||||
|
||||
#CONFIG += release
|
||||
CONFIG -= flat
|
||||
|
||||
QT += multimedia
|
||||
|
||||
# Input
|
||||
HEADERS += $$PWD/../common/comic.h \
|
||||
$$PWD/configuration.h \
|
||||
$$PWD/goto_dialog.h \
|
||||
$$PWD/magnifying_glass.h \
|
||||
$$PWD/main_window_viewer.h \
|
||||
$$PWD/viewer.h \
|
||||
$$PWD/goto_flow.h \
|
||||
$$PWD/options_dialog.h \
|
||||
$$PWD/../common/bookmarks.h \
|
||||
$$PWD/bookmarks_dialog.h \
|
||||
$$PWD/render.h \
|
||||
$$PWD/shortcuts_dialog.h \
|
||||
$$PWD/translator.h \
|
||||
$$PWD/goto_flow_widget.h \
|
||||
$$PWD/page_label_widget.h \
|
||||
$$PWD/goto_flow_toolbar.h \
|
||||
$$PWD/goto_flow_decorationbar.h \
|
||||
$$PWD/width_slider.h \
|
||||
$$PWD/notifications_label_widget.h \
|
||||
$$PWD/../common/pictureflow.h \
|
||||
$$PWD/../common/custom_widgets.h \
|
||||
$$PWD/../common/check_new_version.h \
|
||||
$$PWD/../common/qnaturalsorting.h \
|
||||
$$PWD/../common/yacreader_global.h \
|
||||
$$PWD/../common/onstart_flow_selection_dialog.h \
|
||||
$$PWD/../common/comic_db.h \
|
||||
$$PWD/../common/folder.h \
|
||||
$$PWD/../common/library_item.h \
|
||||
$$PWD/yacreader_local_client.h \
|
||||
$$PWD/../common/http_worker.h \
|
||||
$$PWD/../common/exit_check.h \
|
||||
$$PWD/../common/scroll_management.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
|
||||
}
|
||||
HEADERS += $$PWD/goto_flow_gl.h
|
||||
}
|
||||
|
||||
SOURCES += $$PWD/../common/comic.cpp \
|
||||
$$PWD/configuration.cpp \
|
||||
$$PWD/goto_dialog.cpp \
|
||||
$$PWD/magnifying_glass.cpp \
|
||||
$$PWD/main_window_viewer.cpp \
|
||||
$$PWD/viewer.cpp \
|
||||
$$PWD/goto_flow.cpp \
|
||||
$$PWD/options_dialog.cpp \
|
||||
$$PWD/../common/bookmarks.cpp \
|
||||
$$PWD/bookmarks_dialog.cpp \
|
||||
$$PWD/render.cpp \
|
||||
$$PWD/shortcuts_dialog.cpp \
|
||||
$$PWD/translator.cpp \
|
||||
$$PWD/goto_flow_widget.cpp \
|
||||
$$PWD/page_label_widget.cpp \
|
||||
$$PWD/goto_flow_toolbar.cpp \
|
||||
$$PWD/goto_flow_decorationbar.cpp \
|
||||
$$PWD/width_slider.cpp \
|
||||
$$PWD/notifications_label_widget.cpp \
|
||||
$$PWD/../common/pictureflow.cpp \
|
||||
$$PWD/../common/custom_widgets.cpp \
|
||||
$$PWD/../common/check_new_version.cpp \
|
||||
$$PWD/../common/qnaturalsorting.cpp \
|
||||
$$PWD/../common/onstart_flow_selection_dialog.cpp \
|
||||
$$PWD/../common/comic_db.cpp \
|
||||
$$PWD/../common/folder.cpp \
|
||||
$$PWD/../common/library_item.cpp \
|
||||
$$PWD/yacreader_local_client.cpp \
|
||||
$$PWD/../common/http_worker.cpp \
|
||||
$$PWD/../common/yacreader_global.cpp \
|
||||
$$PWD/../common/exit_check.cpp \
|
||||
$$PWD/../common/scroll_management.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
|
||||
}
|
||||
SOURCES += $$PWD/goto_flow_gl.cpp
|
||||
}
|
||||
|
||||
include($$PWD/../custom_widgets/custom_widgets_yacreader.pri)
|
||||
include($$PWD/../compressed_archive/wrapper.pri)
|
||||
include($$PWD/../shortcuts_management/shortcuts_management.pri)
|
||||
|
||||
RESOURCES += $$PWD/yacreader_images.qrc \
|
||||
$$PWD/yacreader_files.qrc
|
||||
|
||||
win32:RESOURCES += $$PWD/yacreader_images_win.qrc
|
||||
unix:!macx:RESOURCES += $$PWD/yacreader_images_win.qrc
|
||||
macx:RESOURCES += $$PWD/yacreader_images_osx.qrc
|
@ -8,41 +8,51 @@ DEPENDPATH += . \
|
||||
|
||||
DEFINES += NOMINMAX YACREADER
|
||||
|
||||
CONFIG(no_opengl) {
|
||||
DEFINES += NO_OPENGL
|
||||
#load default build flags
|
||||
include (../config.pri)
|
||||
|
||||
unix:!macx{
|
||||
QMAKE_CXXFLAGS += -std=c++11
|
||||
}
|
||||
|
||||
|
||||
unix:!macx{
|
||||
QMAKE_CXXFLAGS += -std=c++11
|
||||
CONFIG(force_angle) {
|
||||
Release:DESTDIR = ../release_angle
|
||||
Debug:DESTDIR = ../debug_angle
|
||||
} else {
|
||||
Release:DESTDIR = ../release
|
||||
Debug:DESTDIR = ../debug
|
||||
}
|
||||
|
||||
Release:DESTDIR = ../release
|
||||
Debug:DESTDIR = ../debug
|
||||
|
||||
SOURCES += main.cpp
|
||||
|
||||
INCLUDEPATH += ../common \
|
||||
../custom_widgets
|
||||
|
||||
CONFIG(legacy_gl_widget) {
|
||||
!CONFIG(no_opengl):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 {
|
||||
LIBS += -L../dependencies/poppler/lib -loleaut32 -lole32
|
||||
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
|
||||
LIBS += -lpoppler-qt5
|
||||
INCLUDEPATH += ../dependencies/poppler/include/qt5
|
||||
|
||||
QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT
|
||||
!CONFIG(no_opengl) {
|
||||
QMAKE_CXXFLAGS_RELEASE += /GL
|
||||
}
|
||||
QMAKE_LFLAGS_RELEASE += /LTCG
|
||||
CONFIG -= embed_manifest_exe
|
||||
QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL
|
||||
QMAKE_LFLAGS_RELEASE += /LTCG
|
||||
CONFIG -= embed_manifest_exe
|
||||
}
|
||||
|
||||
unix:!macx{
|
||||
@ -118,7 +128,8 @@ HEADERS += ../common/comic.h \
|
||||
yacreader_local_client.h \
|
||||
../common/http_worker.h \
|
||||
../common/exit_check.h \
|
||||
../common/scroll_management.h
|
||||
../common/scroll_management.h \
|
||||
../common/opengl_checker.h
|
||||
|
||||
!CONFIG(no_opengl) {
|
||||
CONFIG(legacy_gl_widget) {
|
||||
@ -161,7 +172,8 @@ SOURCES += ../common/comic.cpp \
|
||||
../common/http_worker.cpp \
|
||||
../common/yacreader_global.cpp \
|
||||
../common/exit_check.cpp \
|
||||
../common/scroll_management.cpp
|
||||
../common/scroll_management.cpp \
|
||||
../common/opengl_checker.cpp
|
||||
|
||||
!CONFIG(no_opengl) {
|
||||
CONFIG(legacy_gl_widget) {
|
||||
@ -174,7 +186,13 @@ SOURCES += ../common/comic.cpp \
|
||||
}
|
||||
|
||||
include(../custom_widgets/custom_widgets_yacreader.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(../shortcuts_management/shortcuts_management.pri)
|
||||
|
||||
RESOURCES += yacreader_images.qrc \
|
||||
@ -202,24 +220,6 @@ TRANSLATIONS = yacreader_es.ts \
|
||||
yacreader_de.ts \
|
||||
yacreader_source.ts
|
||||
|
||||
|
||||
win32 {
|
||||
!exists (../compressed_archive/lib7zip) {
|
||||
error(You\'ll need 7zip source code to compile YACReader. \
|
||||
Please check the compressed_archive folder for further instructions.)
|
||||
}
|
||||
}
|
||||
|
||||
unix {
|
||||
exists (../compressed_archive/libp7zip) {
|
||||
message(Found p7zip source code...)
|
||||
system(patch -d ../compressed_archive -N -p0 -i libp7zip.patch)
|
||||
} else {
|
||||
error(You\'ll need 7zip source code to compile YACReader. \
|
||||
Please check the compressed_archive folder for further instructions.)
|
||||
}
|
||||
}
|
||||
|
||||
unix:!macx {
|
||||
#set install prefix if it's empty
|
||||
isEmpty(PREFIX) {
|
||||
|
@ -59,6 +59,7 @@ class YACReaderApplication: public QApplication
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
|
||||
#if defined(_MSC_VER) && defined(_DEBUG)
|
||||
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
|
||||
#endif
|
||||
@ -78,9 +79,13 @@ int main(int argc, char * argv[])
|
||||
QApplication app(argc, argv);
|
||||
#endif
|
||||
|
||||
#ifdef FORCE_ANGLE
|
||||
app.setAttribute(Qt::AA_UseOpenGLES);
|
||||
#endif
|
||||
|
||||
app.setApplicationName("YACReader");
|
||||
app.setOrganizationName("YACReader");
|
||||
qApp->setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
app.setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
//simple command line parser
|
||||
//will be replaced by QCommandLineParser in the future
|
||||
QStringList optlist;
|
||||
|
@ -354,7 +354,7 @@ void MainWindowViewer::createActions()
|
||||
setBookmarkAction->setCheckable(true);
|
||||
setBookmarkAction->setData(SET_BOOKMARK_ACTION_Y);
|
||||
setBookmarkAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_BOOKMARK_ACTION_Y));
|
||||
connect(setBookmarkAction,SIGNAL(triggered (bool)),viewer,SLOT(setBookmarkAction(bool)));
|
||||
connect(setBookmarkAction,SIGNAL(triggered (bool)),viewer,SLOT(setBookmark(bool)));
|
||||
connect(viewer,SIGNAL(pageAvailable(bool)),setBookmarkAction,SLOT(setEnabled(bool)));
|
||||
connect(viewer,SIGNAL(pageIsBookmark(bool)),setBookmarkAction,SLOT(setChecked(bool)));
|
||||
|
||||
@ -578,7 +578,7 @@ void MainWindowViewer::createToolBars()
|
||||
#ifdef Q_OS_MAC
|
||||
comicToolBar->addStretch();
|
||||
#else
|
||||
comicToolBar->addWidget(new QToolBarStretch());
|
||||
comicToolBar->addWidget(new YACReaderToolBarStretch());
|
||||
#endif
|
||||
|
||||
|
||||
@ -671,7 +671,11 @@ void MainWindowViewer::reloadOptions()
|
||||
void MainWindowViewer::open()
|
||||
{
|
||||
QFileDialog openDialog;
|
||||
#ifndef use_unarr
|
||||
QString pathFile = openDialog.getOpenFileName(this,tr("Open Comic"),currentDirectory,tr("Comic files") + "(*.cbr *.cbz *.rar *.zip *.tar *.pdf *.7z *.cb7 *.arj *.cbt)");
|
||||
#else
|
||||
QString pathFile = openDialog.getOpenFileName(this,tr("Open Comic"),currentDirectory,tr("Comic files") + "(*.cbr *.cbz *.rar *.zip *.tar *.pdf *.cbt)");
|
||||
#endif
|
||||
if (!pathFile.isEmpty())
|
||||
{
|
||||
openComicFromPath(pathFile);
|
||||
@ -1315,7 +1319,11 @@ void MainWindowViewer::getSiblingComics(QString path,QString currentComic)
|
||||
{
|
||||
QDir d(path);
|
||||
d.setFilter(QDir::Files|QDir::NoDotAndDotDot);
|
||||
#ifndef use_unarr
|
||||
d.setNameFilters(QStringList() << "*.cbr" << "*.cbz" << "*.rar" << "*.zip" << "*.tar" << "*.pdf" << "*.7z" << "*.cb7" << "*.arj" << "*.cbt");
|
||||
#else
|
||||
d.setNameFilters(QStringList() << "*.cbr" << "*.cbz" << "*.rar" << "*.zip" << "*.tar" << "*.pdf" << "*.cbt");
|
||||
#endif
|
||||
d.setSorting(QDir::Name|QDir::IgnoreCase|QDir::LocaleAware);
|
||||
QStringList list = d.entryList();
|
||||
qSort(list.begin(),list.end(),naturalSortLessThanCI);
|
||||
|
@ -431,9 +431,9 @@ Render::~Render()
|
||||
delete pr;
|
||||
}
|
||||
}
|
||||
//Este m<EFBFBD>todo se encarga de forzar el renderizado de las p<EFBFBD>ginas.
|
||||
//Actualiza el buffer seg<EFBFBD>n es necesario.
|
||||
//si la pagina actual no est<EFBFBD> renderizada, se lanza un hilo que la renderize (double or single page mode) y se emite una se<EFBFBD>al que indica que se est<EFBFBD> renderizando.
|
||||
//Este método se encarga de forzar el renderizado de las páginas.
|
||||
//Actualiza el buffer según es necesario.
|
||||
//si la pagina actual no está renderizada, se lanza un hilo que la renderize (double or single page mode) y se emite una señal que indica que se está renderizando.
|
||||
void Render::render()
|
||||
{
|
||||
updateBuffer();
|
||||
@ -446,30 +446,30 @@ void Render::render()
|
||||
pageRenders[currentPageBufferedIndex] = new PageRender(this,currentIndex,comic->getRawData()->at(currentIndex),buffer[currentPageBufferedIndex],imageRotation,filters);
|
||||
}
|
||||
else
|
||||
//las p<EFBFBD>ginas no est<EFBFBD>n listas, y se est<EFBFBD>n cargando en el c<EFBFBD>mic
|
||||
emit processingPage(); //para evitar confusiones esta se<EFBFBD>al deber<EFBFBD>a llamarse de otra forma
|
||||
//las páginas no están listas, y se están cargando en el cómic
|
||||
emit processingPage(); //para evitar confusiones esta señal debería llamarse de otra forma
|
||||
|
||||
//si se ha creado un hilo para renderizar la p<EFBFBD>gina actual, se arranca
|
||||
//si se ha creado un hilo para renderizar la página actual, se arranca
|
||||
if(pageRenders[currentPageBufferedIndex]!=0)
|
||||
{
|
||||
//se conecta la se<EFBFBD>al pageReady del hilo, con el SLOT prepareAvailablePage
|
||||
//se conecta la señal pageReady del hilo, con el SLOT prepareAvailablePage
|
||||
connect(pageRenders[currentPageBufferedIndex],SIGNAL(pageReady(int)),this,SLOT(prepareAvailablePage(int)));
|
||||
//se emite la se<EFBFBD>al de procesando, debido a que los hilos se arrancan aqu<EFBFBD>
|
||||
//se emite la señal de procesando, debido a que los hilos se arrancan aquí
|
||||
if(filters.size()>0)
|
||||
emit processingPage();
|
||||
pageRenders[currentPageBufferedIndex]->start();
|
||||
pageRenders[currentPageBufferedIndex]->setPriority(QThread::TimeCriticalPriority);
|
||||
}
|
||||
else
|
||||
//en qu<EFBFBD> caso ser<EFBFBD>a necesario hacer esto??? //TODO: IMPORTANTE, puede que no sea necesario.
|
||||
//en qué caso sería necesario hacer esto??? //TODO: IMPORTANTE, puede que no sea necesario.
|
||||
emit processingPage();
|
||||
}
|
||||
else
|
||||
//no hay ninguna p<EFBFBD>gina lista para ser renderizada, es necesario esperar.
|
||||
//no hay ninguna página lista para ser renderizada, es necesario esperar.
|
||||
emit processingPage();
|
||||
}
|
||||
else
|
||||
// la p<EFBFBD>gina actual est<EFBFBD> lista
|
||||
// la página actual está lista
|
||||
{
|
||||
//emit currentPageReady();
|
||||
//make prepareAvailablePage the only function that emits currentPageReady()
|
||||
@ -768,7 +768,7 @@ void Render::createComic(const QString & path)
|
||||
comic = FactoryComic::newComic(path);
|
||||
|
||||
|
||||
if(comic == NULL)//archivo no encontrado o no v<EFBFBD>lido
|
||||
if(comic == NULL)//archivo no encontrado o no válido
|
||||
{
|
||||
emit errorOpening();
|
||||
reset();
|
||||
@ -788,7 +788,6 @@ void Render::createComic(const QString & path)
|
||||
connect(comic,SIGNAL(numPages(unsigned int)),this,SLOT(setNumPages(unsigned int)));
|
||||
connect(comic,SIGNAL(imageLoaded(int,QByteArray)),this,SIGNAL(imageLoaded(int,QByteArray)));
|
||||
connect(comic,SIGNAL(isBookmark(bool)),this,SIGNAL(currentPageIsBookmark(bool)));
|
||||
connect(comic,SIGNAL(isBookmark(bool)),this,SLOT(pageIsBookmark(bool)));
|
||||
|
||||
connect(comic,SIGNAL(bookmarksUpdated()),this,SIGNAL(bookmarksUpdated()));
|
||||
|
||||
@ -814,6 +813,9 @@ void Render::startLoad()
|
||||
|
||||
comic->moveToThread(thread);
|
||||
|
||||
connect(comic, SIGNAL(errorOpening()), thread, SLOT(quit()));
|
||||
connect(comic, SIGNAL(errorOpening(QString)), thread, SLOT(quit()));
|
||||
connect(comic, SIGNAL(imagesLoaded()), thread, SLOT(quit()));
|
||||
connect(thread, SIGNAL(started()), comic, SLOT(process()));
|
||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||
|
||||
@ -836,13 +838,13 @@ void Render::reset()
|
||||
loadedComic = false;
|
||||
invalidate();
|
||||
}
|
||||
//si se solicita la siguiente p<EFBFBD>gina, se calcula cu<EFBFBD>l debe ser en funci<EFBFBD>n de si se lee en modo a doble p<EFBFBD>gina o no.
|
||||
//la p<EFBFBD>gina s<EFBFBD>lo se renderiza, si realmente ha cambiado.
|
||||
//si se solicita la siguiente página, se calcula cuál debe ser en función de si se lee en modo a doble página o no.
|
||||
//la página sólo se renderiza, si realmente ha cambiado.
|
||||
void Render::nextPage()
|
||||
{
|
||||
int nextPage; //indica cu<EFBFBD>l ser<EFBFBD> la pr<EFBFBD>xima p<EFBFBD>gina
|
||||
int nextPage; //indica cuál será la próxima página
|
||||
nextPage = comic->nextPage();
|
||||
//se fuerza renderizado si la p<EFBFBD>gina ha cambiado
|
||||
//se fuerza renderizado si la página ha cambiado
|
||||
if(currentIndex != nextPage)
|
||||
{
|
||||
previousIndex = currentIndex;
|
||||
@ -880,14 +882,14 @@ void Render::nextDoublePage()
|
||||
}
|
||||
}
|
||||
|
||||
//si se solicita la p<EFBFBD>gina anterior, se calcula cu<EFBFBD>l debe ser en funci<EFBFBD>n de si se lee en modo a doble p<EFBFBD>gina o no.
|
||||
//la p<EFBFBD>gina s<EFBFBD>lo se renderiza, si realmente ha cambiado.
|
||||
//si se solicita la página anterior, se calcula cuál debe ser en función de si se lee en modo a doble página o no.
|
||||
//la página sólo se renderiza, si realmente ha cambiado.
|
||||
void Render::previousPage()
|
||||
{
|
||||
int previousPage; //indica cu<EFBFBD>l ser<EFBFBD> la pr<EFBFBD>xima p<EFBFBD>gina
|
||||
int previousPage; //indica cuál será la próxima página
|
||||
previousPage = comic->previousPage();
|
||||
|
||||
//se fuerza renderizado si la p<EFBFBD>gina ha cambiado
|
||||
//se fuerza renderizado si la página ha cambiado
|
||||
if(currentIndex != previousPage)
|
||||
{
|
||||
previousIndex = currentIndex;
|
||||
@ -903,7 +905,7 @@ void Render::previousPage()
|
||||
|
||||
void Render::previousDoublePage()
|
||||
{
|
||||
int previousPage; //indica cu<EFBFBD>l ser<EFBFBD> la pr<EFBFBD>xima p<EFBFBD>gina
|
||||
int previousPage; //indica cuál será la próxima página
|
||||
previousPage = qMax(currentIndex-2,0);
|
||||
if(currentIndex != previousPage)
|
||||
{
|
||||
@ -965,7 +967,7 @@ void Render::pageRawDataReady(int page)
|
||||
}
|
||||
}
|
||||
|
||||
//s<EFBFBD>lo se renderiza la p<EFBFBD>gina, si ha habido un cambio de p<EFBFBD>gina
|
||||
//sólo se renderiza la página, si ha habido un cambio de página
|
||||
void Render::goTo(int index)
|
||||
{
|
||||
|
||||
@ -993,9 +995,9 @@ void Render::rotateLeft()
|
||||
reload();
|
||||
}
|
||||
|
||||
//Actualiza el buffer, a<EFBFBD>adiendo las im<EFBFBD>genes (vac<EFBFBD>as) necesarias para su posterior renderizado y
|
||||
//eliminado aquellas que ya no sean necesarias. Tambi<EFBFBD>n libera los hilos (no estoy seguro de que sea responsabilidad suya)
|
||||
//Calcula el n<EFBFBD>mero de nuevas p<EFBFBD>ginas que hay que buferear y si debe hacerlo por la izquierda o la derecha (seg<EFBFBD>n sea el sentido de la lectura)
|
||||
//Actualiza el buffer, añadiendo las imágenes (vacías) necesarias para su posterior renderizado y
|
||||
//eliminado aquellas que ya no sean necesarias. También libera los hilos (no estoy seguro de que sea responsabilidad suya)
|
||||
//Calcula el número de nuevas páginas que hay que buferear y si debe hacerlo por la izquierda o la derecha (según sea el sentido de la lectura)
|
||||
void Render::updateBuffer()
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
@ -1081,8 +1083,8 @@ void Render::fillBuffer()
|
||||
}
|
||||
|
||||
|
||||
//M<EFBFBD>todo que debe ser llamado cada vez que la estructura del buffer se vuelve inconsistente con el modo de lectura actual.
|
||||
//se terminan todos los hilos en ejecuci<EFBFBD>n y se libera la memoria (de hilos e im<EFBFBD>genes)
|
||||
//Método que debe ser llamado cada vez que la estructura del buffer se vuelve inconsistente con el modo de lectura actual.
|
||||
//se terminan todos los hilos en ejecución y se libera la memoria (de hilos e imágenes)
|
||||
void Render::invalidate()
|
||||
{
|
||||
for(int i=0;i<pageRenders.size();i++)
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "comic_db.h"
|
||||
#include "shortcuts_manager.h"
|
||||
|
||||
#include "opengl_checker.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
|
||||
@ -72,10 +74,15 @@ shouldOpenPrevious(false)
|
||||
|
||||
//CONFIG GOTO_FLOW--------------------------------------------------------
|
||||
#ifndef NO_OPENGL
|
||||
if(!settings->contains(USE_OPEN_GL))
|
||||
{
|
||||
|
||||
OpenGLChecker openGLChecker;
|
||||
bool openGLAvailable = openGLChecker.hasCompatibleOpenGLVersion();
|
||||
|
||||
if(openGLAvailable && !settings->contains(USE_OPEN_GL))
|
||||
settings->setValue(USE_OPEN_GL,2);
|
||||
}
|
||||
else
|
||||
if(!openGLAvailable)
|
||||
settings->setValue(USE_OPEN_GL,0);
|
||||
|
||||
if((settings->value(USE_OPEN_GL).toBool() == true))
|
||||
goToFlow = new GoToFlowGL(this,Configuration::getConfiguration().getFlowType());
|
||||
|
@ -15,9 +15,8 @@ INCLUDEPATH += ../common \
|
||||
|
||||
DEFINES += SERVER_RELEASE NOMINMAX YACREADER_LIBRARY
|
||||
|
||||
CONFIG(no_opengl) {
|
||||
DEFINES += NO_OPENGL
|
||||
}
|
||||
#load default build flags
|
||||
include (../config.pri)
|
||||
|
||||
CONFIG(legacy_gl_widget) {
|
||||
INCLUDEPATH += ../common/gl_legacy \
|
||||
@ -25,19 +24,25 @@ CONFIG(legacy_gl_widget) {
|
||||
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 += -L../dependencies/poppler/lib -loleaut32 -lole32 -lshell32
|
||||
LIBS += -lpoppler-qt5
|
||||
INCLUDEPATH += ../dependencies/poppler/include/qt5
|
||||
|
||||
LIBS += -lpoppler-qt5
|
||||
INCLUDEPATH += ../dependencies/poppler/include/qt5
|
||||
|
||||
QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT
|
||||
!CONFIG(no_opengl) {
|
||||
QMAKE_CXXFLAGS_RELEASE += /GL
|
||||
}
|
||||
QMAKE_LFLAGS_RELEASE += /LTCG
|
||||
CONFIG -= embed_manifest_exe
|
||||
QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL
|
||||
QMAKE_LFLAGS_RELEASE += /LTCG
|
||||
CONFIG -= embed_manifest_exe
|
||||
}
|
||||
|
||||
unix:!macx{
|
||||
@ -71,7 +76,7 @@ QT += macextras gui-private
|
||||
}
|
||||
|
||||
unix{
|
||||
QMAKE_CXXFLAGS += -std=c++11
|
||||
CONFIG += c++11
|
||||
}
|
||||
|
||||
#CONFIG += release
|
||||
@ -138,7 +143,8 @@ HEADERS += comic_flow.h \
|
||||
empty_container_info.h \
|
||||
empty_special_list.h \
|
||||
empty_reading_list_widget.h \
|
||||
../common/scroll_management.h
|
||||
../common/scroll_management.h \
|
||||
../common/opengl_checker.h
|
||||
|
||||
!CONFIG(no_opengl) {
|
||||
CONFIG(legacy_gl_widget) {
|
||||
@ -206,7 +212,8 @@ SOURCES += comic_flow.cpp \
|
||||
empty_container_info.cpp \
|
||||
empty_special_list.cpp \
|
||||
empty_reading_list_widget.cpp \
|
||||
../common/scroll_management.cpp
|
||||
../common/scroll_management.cpp \
|
||||
../common/opengl_checker.cpp
|
||||
|
||||
!CONFIG(no_opengl) {
|
||||
CONFIG(legacy_gl_widget) {
|
||||
@ -220,7 +227,14 @@ SOURCES += comic_flow.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)
|
||||
@ -245,9 +259,13 @@ TRANSLATIONS = yacreaderlibrary_es.ts \
|
||||
yacreaderlibrary_de.ts \
|
||||
yacreaderlibrary_source.ts
|
||||
|
||||
|
||||
Release:DESTDIR = ../release
|
||||
Debug:DESTDIR = ../debug
|
||||
CONFIG(force_angle) {
|
||||
Release:DESTDIR = ../release_angle
|
||||
Debug:DESTDIR = ../debug_angle
|
||||
} else {
|
||||
Release:DESTDIR = ../release
|
||||
Debug:DESTDIR = ../debug
|
||||
}
|
||||
|
||||
#QML/GridView
|
||||
QT += quick qml
|
||||
@ -263,23 +281,6 @@ win32:RESOURCES += qml_win.qrc
|
||||
unix:!macx:RESOURCES += qml_win.qrc
|
||||
macx:RESOURCES += qml_osx.qrc
|
||||
|
||||
win32 {
|
||||
!exists(../compressed_archive/lib7zip){
|
||||
error(You\'ll need 7zip source code to compile YACReader. \
|
||||
Please check the compressed_archive folder for further instructions.)
|
||||
}
|
||||
}
|
||||
|
||||
unix {
|
||||
exists (../compressed_archive/libp7zip) {
|
||||
message(Found p7zip source code...)
|
||||
system(patch -d ../compressed_archive -N -p0 -i libp7zip.patch)
|
||||
} else {
|
||||
error(You\'ll need 7zip source code to compile YACReader. \
|
||||
Please check the compressed_archive folder for further instructions.)
|
||||
}
|
||||
}
|
||||
|
||||
unix:!macx {
|
||||
#set install prefix if it's empty
|
||||
isEmpty(PREFIX) {
|
||||
|
@ -1,11 +1,12 @@
|
||||
#include "classic_comics_view.h"
|
||||
|
||||
#include "yacreader_table_view.h"
|
||||
#include "QStackedWidget"
|
||||
|
||||
#include "comic_flow_widget.h"
|
||||
#include "QsLog.h"
|
||||
|
||||
#include "QStackedWidget"
|
||||
#include "shortcuts_manager.h"
|
||||
#include "yacreader_table_view.h"
|
||||
#include "yacreader_tool_bar_stretch.h"
|
||||
|
||||
ClassicComicsView::ClassicComicsView(QWidget *parent)
|
||||
:ComicsView(parent),searching(false)
|
||||
@ -16,6 +17,7 @@ ClassicComicsView::ClassicComicsView(QWidget *parent)
|
||||
settings->beginGroup("libraryConfig");
|
||||
//FLOW-----------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
//FORCE_ANGLE is not used here, because ComicFlowWidgetGL will use OpenGL ES in the future
|
||||
#ifndef NO_OPENGL
|
||||
if((settings->value(USE_OPEN_GL).toBool() == true))
|
||||
comicFlow = new ComicFlowWidgetGL(0);
|
||||
@ -70,6 +72,7 @@ ClassicComicsView::ClassicComicsView(QWidget *parent)
|
||||
connect(tableView, SIGNAL(comicRated(int,QModelIndex)), this, SIGNAL(comicRated(int,QModelIndex)));
|
||||
connect(comicFlow, SIGNAL(selected(uint)), this, SIGNAL(selected(uint)));
|
||||
connect(tableView->horizontalHeader(), SIGNAL(sectionMoved(int,int,int)), this, SLOT(saveTableHeadersStatus()));
|
||||
connect(tableView->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(saveTableHeadersStatus()));
|
||||
connect(comicFlow, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(requestedViewContextMenu(QPoint)));
|
||||
connect(tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(requestedItemContextMenu(QPoint)));
|
||||
layout->addWidget(sVertical);
|
||||
@ -83,11 +86,49 @@ ClassicComicsView::ClassicComicsView(QWidget *parent)
|
||||
|
||||
if(settings->contains(COMICS_VIEW_FLOW_SPLITTER_STATUS))
|
||||
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);
|
||||
hideFlowViewAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HIDE_COMIC_VIEW_ACTION_YL));
|
||||
hideFlowViewAction->setIcon(QIcon(":/images/hideComicFlow.png"));
|
||||
hideFlowViewAction->setCheckable(true);
|
||||
hideFlowViewAction->setChecked(false);
|
||||
|
||||
connect(hideFlowViewAction, SIGNAL(toggled(bool)),this, SLOT(hideComicFlow(bool)));
|
||||
}
|
||||
|
||||
void ClassicComicsView::hideComicFlow(bool hide)
|
||||
{
|
||||
if(hide)
|
||||
{
|
||||
QList<int> sizes;
|
||||
sizes.append(0);
|
||||
int total = sVertical->sizes().at(0) + sVertical->sizes().at(1);
|
||||
sizes.append(total);
|
||||
sVertical->setSizes(sizes);
|
||||
}
|
||||
else
|
||||
{
|
||||
QList<int> sizes;
|
||||
int total = sVertical->sizes().at(0) + sVertical->sizes().at(1);
|
||||
sizes.append(2*total/3);
|
||||
sizes.append(total/3);
|
||||
sVertical->setSizes(sizes);
|
||||
}
|
||||
}
|
||||
|
||||
//the toolbar has to be populated
|
||||
void ClassicComicsView::setToolBar(QToolBar *toolBar)
|
||||
{
|
||||
static_cast<QVBoxLayout *>(comics->layout())->insertWidget(0,toolBar);
|
||||
this->toolbar = toolBar;
|
||||
|
||||
toolBarStretchAction = toolBar->addWidget(toolBarStretch);
|
||||
toolBar->addAction(hideFlowViewAction);
|
||||
}
|
||||
|
||||
void ClassicComicsView::setModel(ComicModel *model)
|
||||
@ -118,23 +159,25 @@ void ClassicComicsView::setModel(ComicModel *model)
|
||||
tableView->horizontalHeader()->setMovable(true);
|
||||
#endif
|
||||
//TODO parametrizar la configuración de las columnas
|
||||
for(int i = 0;i<tableView->horizontalHeader()->count();i++)
|
||||
tableView->horizontalHeader()->hideSection(i);
|
||||
/*if(!settings->contains(COMICS_VIEW_HEADERS))
|
||||
{*/
|
||||
for(int i = 0;i<tableView->horizontalHeader()->count();i++)
|
||||
tableView->horizontalHeader()->hideSection(i);
|
||||
|
||||
tableView->horizontalHeader()->showSection(ComicModel::Number);
|
||||
tableView->horizontalHeader()->showSection(ComicModel::Title);
|
||||
tableView->horizontalHeader()->showSection(ComicModel::FileName);
|
||||
tableView->horizontalHeader()->showSection(ComicModel::NumPages);
|
||||
tableView->horizontalHeader()->showSection(ComicModel::Hash); //Size is part of the Hash...TODO add Columns::Size to Columns
|
||||
tableView->horizontalHeader()->showSection(ComicModel::ReadColumn);
|
||||
tableView->horizontalHeader()->showSection(ComicModel::CurrentPage);
|
||||
tableView->horizontalHeader()->showSection(ComicModel::Rating);
|
||||
tableView->horizontalHeader()->showSection(ComicModel::Number);
|
||||
tableView->horizontalHeader()->showSection(ComicModel::Title);
|
||||
tableView->horizontalHeader()->showSection(ComicModel::FileName);
|
||||
tableView->horizontalHeader()->showSection(ComicModel::NumPages);
|
||||
tableView->horizontalHeader()->showSection(ComicModel::Hash); //Size is part of the Hash...TODO add Columns::Size to Columns
|
||||
tableView->horizontalHeader()->showSection(ComicModel::ReadColumn);
|
||||
tableView->horizontalHeader()->showSection(ComicModel::CurrentPage);
|
||||
tableView->horizontalHeader()->showSection(ComicModel::Rating);
|
||||
//}
|
||||
|
||||
//debido a un bug, qt4 no es capaz de ajustar el ancho teniendo en cuenta todas la filas (no sólo las visibles)
|
||||
//así que se ecala la primera vez y después se deja el control al usuario.
|
||||
//if(!settings->contains(COMICS_VIEW_HEADERS))
|
||||
tableView->resizeColumnsToContents();
|
||||
tableView->horizontalHeader()->setStretchLastSection(true);
|
||||
|
||||
|
||||
QStringList paths = model->getPaths(model->getCurrentPath());//TODO ComicsView: get currentpath from somewhere currentPath());
|
||||
comicFlow->setImagePaths(paths);
|
||||
@ -143,6 +186,10 @@ void ClassicComicsView::setModel(ComicModel *model)
|
||||
|
||||
if(settings->contains(COMICS_VIEW_HEADERS))
|
||||
tableView->horizontalHeader()->restoreState(settings->value(COMICS_VIEW_HEADERS).toByteArray());
|
||||
|
||||
tableView->resizeColumnsToContents();
|
||||
|
||||
tableView->horizontalHeader()->setStretchLastSection(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -264,8 +311,10 @@ void ClassicComicsView::saveTableHeadersStatus()
|
||||
|
||||
void ClassicComicsView::saveSplitterStatus()
|
||||
{
|
||||
settingsMutex.lock();
|
||||
if(!searching)
|
||||
settings->setValue(COMICS_VIEW_FLOW_SPLITTER_STATUS, sVertical->saveState());
|
||||
settingsMutex.unlock();
|
||||
}
|
||||
|
||||
void ClassicComicsView::applyModelChanges(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
|
||||
@ -291,6 +340,9 @@ void ClassicComicsView::closeEvent(QCloseEvent *event)
|
||||
saveTableHeadersStatus();
|
||||
saveSplitterStatus();
|
||||
ComicsView::closeEvent(event);
|
||||
|
||||
toolbar->removeAction(toolBarStretchAction);
|
||||
toolbar->removeAction(hideFlowViewAction);
|
||||
}
|
||||
|
||||
void ClassicComicsView::setupSearchingIcon()
|
||||
|
@ -6,12 +6,14 @@
|
||||
#include <QModelIndex>
|
||||
#include <QModelIndexList>
|
||||
|
||||
class YACReaderTableView;
|
||||
class QSplitter;
|
||||
class ComicFlowWidget;
|
||||
class QToolBar;
|
||||
class ComicModel;
|
||||
class QStackedWidget;
|
||||
class QToolBar;
|
||||
|
||||
class ComicFlowWidget;
|
||||
class ComicModel;
|
||||
class YACReaderTableView;
|
||||
class YACReaderToolBarStretch;
|
||||
|
||||
class ClassicComicsView : public ComicsView
|
||||
{
|
||||
@ -44,16 +46,22 @@ public slots:
|
||||
void selectedComicForOpening(const QModelIndex & mi);
|
||||
|
||||
protected slots:
|
||||
void hideComicFlow(bool hide);
|
||||
void requestedViewContextMenu(const QPoint & point);
|
||||
void requestedItemContextMenu(const QPoint & point);
|
||||
|
||||
|
||||
private:
|
||||
YACReaderTableView * tableView;
|
||||
YACReaderToolBarStretch * toolBarStretch;
|
||||
QAction * toolBarStretchAction;
|
||||
QToolBar * toolbar;
|
||||
QWidget *comics;
|
||||
QSplitter * sVertical;
|
||||
ComicFlowWidget * comicFlow;
|
||||
QSettings * settings;
|
||||
void closeEvent ( QCloseEvent * event );
|
||||
QAction * hideFlowViewAction;
|
||||
|
||||
QStackedWidget * stack;
|
||||
|
||||
@ -64,6 +72,8 @@ private:
|
||||
void showSearchingIcon();
|
||||
void hideSearchingIcon();
|
||||
void updateSearchingIconPosition();
|
||||
|
||||
QMutex settingsMutex;
|
||||
};
|
||||
|
||||
#endif // CLASSIC_COMICS_VIEW_H
|
||||
|
@ -169,10 +169,12 @@ void SortVolumeComics::moveDownCL()
|
||||
QList<QModelIndex> selection = tableFiles->selectionModel()->selectedIndexes();
|
||||
|
||||
if(selection.count() > 0)
|
||||
{
|
||||
localComicsModel->moveSelectionDown(selection);
|
||||
|
||||
selection = tableFiles->selectionModel()->selectedIndexes();
|
||||
tableFiles->scrollTo(selection.last());
|
||||
selection = tableFiles->selectionModel()->selectedIndexes();
|
||||
tableFiles->scrollTo(selection.last());
|
||||
}
|
||||
}
|
||||
|
||||
void SortVolumeComics::moveUpIL()
|
||||
|
@ -47,7 +47,7 @@ bool ComicModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, i
|
||||
return data->formats().contains(YACReader::YACReaderLibrarComiscSelectionMimeDataFormat);
|
||||
}
|
||||
|
||||
//TODO: optimize this method
|
||||
//TODO: optimize this method (seriously)
|
||||
bool ComicModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
|
||||
{
|
||||
|
||||
@ -118,9 +118,26 @@ bool ComicModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int
|
||||
|
||||
QLOG_INFO() << newSorting;
|
||||
|
||||
if(!beginMoveRows(parent,currentIndexes.first(),currentIndexes.last(),parent,row))
|
||||
return false;
|
||||
_data = resortedData;
|
||||
int tempRow = row;
|
||||
foreach(qulonglong id, comicIds)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (ComicItem *item, _data) {
|
||||
if(item->data(Id) == id)
|
||||
{
|
||||
beginMoveRows(parent,i,i,parent,tempRow);
|
||||
_data.removeAll(item);
|
||||
_data.insert(tempRow++, item);
|
||||
endMoveRows();
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/*if(!beginMoveRows(parent,currentIndexes.first(),currentIndexes.last(),parent,row))
|
||||
return false;*/
|
||||
_data = resortedData; //TODO No longer needed
|
||||
|
||||
|
||||
//TODO emit signals
|
||||
@ -145,7 +162,7 @@ bool ComicModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int
|
||||
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
|
||||
endMoveRows();
|
||||
//endMoveRows();
|
||||
|
||||
emit resortedIndexes(newSorting);
|
||||
int destSelectedIndex = row<0?_data.length():row;
|
||||
@ -262,7 +279,7 @@ QVariant ComicModel::data(const QModelIndex &index, int role) const
|
||||
else if (role == RatingRole)
|
||||
return item->data(Rating);
|
||||
else if (role == CoverPathRole)
|
||||
return "file:///"+_databasePath+"/covers/"+item->data(Hash).toString()+".jpg";
|
||||
return QUrl("file:"+_databasePath+"/covers/"+item->data(Hash).toString()+".jpg");
|
||||
else if (role == NumPagesRole)
|
||||
return item->data(NumPages);
|
||||
else if (role == CurrentPageRole)
|
||||
@ -361,11 +378,13 @@ QVariant ComicModel::headerData(int section, Qt::Orientation orientation,
|
||||
return QVariant(QIcon(":/images/zip.png"));
|
||||
else if(ext.compare("rar",Qt::CaseInsensitive) == 0)
|
||||
return QVariant(QIcon(":/images/rar.png"));
|
||||
#ifndef use_unarr
|
||||
else if (ext.compare("7z",Qt::CaseInsensitive) == 0)
|
||||
return QVariant(QIcon(":/images/7z.png"));
|
||||
else if (ext.compare("cb7",Qt::CaseInsensitive) == 0)
|
||||
return QVariant(QIcon(":/images/comic7z.png"));
|
||||
else if (ext.compare("cb7",Qt::CaseInsensitive) == 0)
|
||||
#endif
|
||||
else if (ext.compare("cbt",Qt::CaseInsensitive) == 0)
|
||||
return QVariant(QIcon(":/images/comicTar.png"));
|
||||
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ void DBHelper::update(ComicInfo * comicInfo, QSqlDatabase & db)
|
||||
|
||||
updateComicInfo.bindValue(":comicVineID", comicInfo->comicVineID);
|
||||
|
||||
updateComicInfo.exec();
|
||||
updateComicInfo.exec();
|
||||
}
|
||||
|
||||
void DBHelper::updateRead(ComicInfo * comicInfo, QSqlDatabase & db)
|
||||
@ -391,6 +391,44 @@ void DBHelper::updateProgress(qulonglong libraryId, const ComicInfo &comicInfo)
|
||||
QSqlDatabase::removeDatabase(libraryPath);
|
||||
}
|
||||
|
||||
void DBHelper::updateReadingRemoteProgress(const ComicInfo &comicInfo, QSqlDatabase &db)
|
||||
{
|
||||
QSqlQuery updateComicInfo(db);
|
||||
updateComicInfo.prepare("UPDATE comic_info SET "
|
||||
"read = :read, "
|
||||
"currentPage = :currentPage, "
|
||||
"hasBeenOpened = :hasBeenOpened"
|
||||
" WHERE id = :id ");
|
||||
|
||||
updateComicInfo.bindValue(":read", comicInfo.read?1:0);
|
||||
updateComicInfo.bindValue(":currentPage", comicInfo.currentPage);
|
||||
updateComicInfo.bindValue(":hasBeenOpened", comicInfo.hasBeenOpened?1:0);
|
||||
updateComicInfo.bindValue(":id", comicInfo.id);
|
||||
updateComicInfo.exec();
|
||||
}
|
||||
|
||||
|
||||
void DBHelper::updateFromRemoteClient(qulonglong libraryId,const ComicInfo & comicInfo)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
|
||||
|
||||
ComicDB comic = DBHelper::loadComic(comicInfo.id,db);
|
||||
|
||||
if(comic.info.hash == comicInfo.hash)
|
||||
{
|
||||
if(comic.info.currentPage == comic.info.numPages)
|
||||
comic.info.read = true;
|
||||
comic.info.currentPage = comicInfo.currentPage;
|
||||
comic.info.hasBeenOpened = true;
|
||||
|
||||
DBHelper::updateReadingRemoteProgress(comic.info,db);
|
||||
}
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(libraryPath);
|
||||
}
|
||||
|
||||
void DBHelper::renameLabel(qulonglong id, const QString &name, QSqlDatabase &db)
|
||||
{
|
||||
QSqlQuery renameLabelQuery(db);
|
||||
@ -566,16 +604,21 @@ qulonglong DBHelper::insertReadingSubList(const QString &name, qulonglong parent
|
||||
|
||||
void DBHelper::insertComicsInFavorites(const QList<ComicDB> &comicsList, QSqlDatabase &db)
|
||||
{
|
||||
QSqlQuery getNumComicsInFavoritesQuery("SELECT count(*) FROM comic_default_reading_list WHERE default_reading_list_id = 1;",db);
|
||||
getNumComicsInFavoritesQuery.next();
|
||||
QSqlRecord record = getNumComicsInFavoritesQuery.record();
|
||||
int numComics = record.value(0).toInt();
|
||||
|
||||
db.transaction();
|
||||
|
||||
QSqlQuery query(db);
|
||||
query.prepare("INSERT INTO comic_default_reading_list (default_reading_list_id, comic_id) "
|
||||
"VALUES (1, :comic_id)");
|
||||
query.prepare("INSERT INTO comic_default_reading_list (default_reading_list_id, comic_id, ordering) "
|
||||
"VALUES (1, :comic_id, :ordering)");
|
||||
|
||||
foreach(ComicDB comic, comicsList)
|
||||
{
|
||||
query.bindValue(":comic_id", comic.id);
|
||||
//query.bindValue(":order", numComics++);
|
||||
query.bindValue(":ordering", numComics++);
|
||||
query.exec();
|
||||
}
|
||||
|
||||
@ -584,16 +627,22 @@ void DBHelper::insertComicsInFavorites(const QList<ComicDB> &comicsList, QSqlDat
|
||||
|
||||
void DBHelper::insertComicsInLabel(const QList<ComicDB> &comicsList, qulonglong labelId, QSqlDatabase &db)
|
||||
{
|
||||
QSqlQuery getNumComicsInFavoritesQuery(QString("SELECT count(*) FROM comic_label WHERE label_id = %1;").arg(labelId) ,db);
|
||||
getNumComicsInFavoritesQuery.next();
|
||||
QSqlRecord record = getNumComicsInFavoritesQuery.record();
|
||||
int numComics = record.value(0).toInt();
|
||||
|
||||
db.transaction();
|
||||
|
||||
QSqlQuery query(db);
|
||||
query.prepare("INSERT INTO comic_label (label_id, comic_id) "
|
||||
"VALUES (:label_id, :comic_id)");
|
||||
query.prepare("INSERT INTO comic_label (label_id, comic_id, ordering) "
|
||||
"VALUES (:label_id, :comic_id, :ordering)");
|
||||
|
||||
foreach(ComicDB comic, comicsList)
|
||||
{
|
||||
query.bindValue(":label_id", labelId);
|
||||
query.bindValue(":comic_id", comic.id);
|
||||
query.bindValue(":ordering", numComics++);
|
||||
query.exec();
|
||||
}
|
||||
|
||||
@ -602,7 +651,7 @@ void DBHelper::insertComicsInLabel(const QList<ComicDB> &comicsList, qulonglong
|
||||
|
||||
void DBHelper::insertComicsInReadingList(const QList<ComicDB> &comicsList, qulonglong readingListId, QSqlDatabase &db)
|
||||
{
|
||||
QSqlQuery getNumComicsInFavoritesQuery("SELECT count(*) from comic_reading_list;",db);
|
||||
QSqlQuery getNumComicsInFavoritesQuery("SELECT count(*) FROM comic_reading_list;",db);
|
||||
getNumComicsInFavoritesQuery.next();
|
||||
QSqlRecord record = getNumComicsInFavoritesQuery.record();
|
||||
int numComics = record.value(0).toInt();
|
||||
|
@ -57,6 +57,8 @@ public:
|
||||
static void updateRead(ComicInfo * comicInfo, QSqlDatabase & db);
|
||||
static void update(const Folder & folder, QSqlDatabase & db);
|
||||
static void updateProgress(qulonglong libraryId,const ComicInfo & comicInfo);
|
||||
static void updateReadingRemoteProgress(const ComicInfo & comicInfo, QSqlDatabase & db);
|
||||
static void updateFromRemoteClient(qulonglong libraryId,const ComicInfo & comicInfo);
|
||||
static void renameLabel(qulonglong id, const QString & name, QSqlDatabase & db);
|
||||
static void renameList(qulonglong id, const QString & name, QSqlDatabase & db);
|
||||
static void reasignOrderToSublists(QList<qulonglong> ids, QSqlDatabase & db);
|
||||
|
@ -84,7 +84,7 @@ void GridComicsView::setModel(ComicModel *model)
|
||||
ctxt->setContextProperty("textColor", "#636363");
|
||||
//fonts settings
|
||||
ctxt->setContextProperty("fontSize", 11);
|
||||
ctxt->setContextProperty("fontFamily", "none");
|
||||
ctxt->setContextProperty("fontFamily", QApplication::font().family());
|
||||
ctxt->setContextProperty("fontSpacing", 0.5);
|
||||
|
||||
#else
|
||||
@ -93,12 +93,15 @@ void GridComicsView::setModel(ComicModel *model)
|
||||
ctxt->setContextProperty("selectedColor", "#121212");
|
||||
ctxt->setContextProperty("selectedBorderColor", "#121212");
|
||||
ctxt->setContextProperty("borderColor", "#121212");
|
||||
ctxt->setContextProperty("titleColor", "#E6E6E6");
|
||||
ctxt->setContextProperty("textColor", "#E6E6E6");
|
||||
ctxt->setContextProperty("titleColor", "#FFFFFF");
|
||||
ctxt->setContextProperty("textColor", "#A8A8A8");
|
||||
ctxt->setContextProperty("dropShadow",false);
|
||||
//fonts settings
|
||||
ctxt->setContextProperty("fontSize", "none");
|
||||
ctxt->setContextProperty("fontFamily", "none");
|
||||
int fontSize = QApplication::font().pointSize();
|
||||
if(fontSize == -1)
|
||||
fontSize = QApplication::font().pixelSize();
|
||||
ctxt->setContextProperty("fontSize", fontSize);
|
||||
ctxt->setContextProperty("fontFamily", QApplication::font().family());
|
||||
ctxt->setContextProperty("fontSpacing", 0.5);
|
||||
#endif
|
||||
|
||||
|
@ -127,11 +127,14 @@ ImportWidget::ImportWidget(QWidget *parent) :
|
||||
coversView->setMaximumHeight(300);
|
||||
coversView->setStyleSheet("QGraphicsView {background-color: #E6E6E6;border:none;}");
|
||||
|
||||
coversScene = new QGraphicsScene();
|
||||
coversScene->setSceneRect(0,0,coversView->width(),coversView->height());
|
||||
coversScene = new QGraphicsScene();
|
||||
coversView->setAlignment(Qt::AlignLeft);
|
||||
coversView->setScene(coversScene);
|
||||
coversView->setScene(coversScene);
|
||||
coversView->setFixedHeight(300);
|
||||
|
||||
coversView->setInteractive(false);
|
||||
|
||||
scrollAnimation = new QPropertyAnimation(coversView->horizontalScrollBar(), "value");
|
||||
|
||||
QLabel * topDecorator = new QLabel();
|
||||
QLabel * bottomDecorator = new QLabel();
|
||||
@ -208,7 +211,7 @@ ImportWidget::ImportWidget(QWidget *parent) :
|
||||
connect(stop,SIGNAL(clicked()),this,SIGNAL(stop()));
|
||||
//connect(stop,SIGNAL(clicked()),this,SLOT(addCoverTest()));
|
||||
|
||||
previousWidth = 10;
|
||||
previousWidth = 0;
|
||||
updatingCovers = false;
|
||||
elapsedTimer = new QElapsedTimer();
|
||||
elapsedTimer->start();
|
||||
@ -216,70 +219,49 @@ ImportWidget::ImportWidget(QWidget *parent) :
|
||||
|
||||
void ImportWidget::newComic(const QString & path, const QString & coverPath)
|
||||
{
|
||||
currentComicLabel->setText("<font color=\"#565959\">"+path+"</font>");
|
||||
if(!this->isVisible())
|
||||
return;
|
||||
|
||||
if(((elapsedTimer->elapsed()>=1000) || ((previousWidth < coversView->width()) && (elapsedTimer->elapsed()>=500))) && !updatingCovers)//todo elapsed time
|
||||
{
|
||||
currentComicLabel->setText("<font color=\"#565959\">"+path+"</font>");
|
||||
|
||||
QPixmap p(coverPath);
|
||||
p = p.scaledToHeight(300,Qt::SmoothTransformation);
|
||||
QGraphicsPixmapItem * item = new QGraphicsPixmapItem(p);
|
||||
item->setPos(previousWidth,0);
|
||||
item->setZValue(i/10000.0);
|
||||
previousWidth += 10 + p.width();
|
||||
coversScene->addItem(item);
|
||||
if( ((elapsedTimer->elapsed()>=1100) || ((previousWidth < coversView->width()) && (elapsedTimer->elapsed()>=500))) && scrollAnimation->state() != QAbstractAnimation::Running)//todo elapsed time
|
||||
{
|
||||
updatingCovers = true;
|
||||
elapsedTimer->start();
|
||||
|
||||
elapsedTimer->start();
|
||||
if(previousWidth >= coversView->width()+200 && !updatingCovers)
|
||||
{
|
||||
updatingCovers = true;
|
||||
QPixmap p(coverPath);
|
||||
p = p.scaledToHeight(300,Qt::SmoothTransformation);
|
||||
|
||||
foreach(QGraphicsItem * itemToRemove, coversScene->items())
|
||||
{
|
||||
QGraphicsPixmapItem * last = dynamic_cast<QGraphicsPixmapItem *>(itemToRemove);
|
||||
QGraphicsPixmapItem * item = new QGraphicsPixmapItem(p);
|
||||
item->setPos(previousWidth, 0);
|
||||
coversScene->addItem(item);
|
||||
|
||||
if((last->pos().x()+last->pixmap().width())<=0)
|
||||
{
|
||||
coversScene->removeItem(last);
|
||||
delete last;
|
||||
}
|
||||
//else
|
||||
// break;
|
||||
}
|
||||
previousWidth += 10 + p.width();
|
||||
|
||||
int width = p.width();
|
||||
foreach(QGraphicsItem * itemToRemove, coversScene->items())
|
||||
{
|
||||
QGraphicsPixmapItem * last = dynamic_cast<QGraphicsPixmapItem *>(itemToRemove);
|
||||
|
||||
foreach(QGraphicsItem * itemToMove, coversScene->items())
|
||||
{
|
||||
QTimeLine *timer = new QTimeLine(400);
|
||||
timer->setFrameRange(0, 24);
|
||||
timer->setUpdateInterval(17);
|
||||
if((last->pos().x()+last->pixmap().width()) < coversView->horizontalScrollBar()->value()) //TODO check this
|
||||
{
|
||||
coversScene->removeItem(last);
|
||||
delete last;
|
||||
}
|
||||
}
|
||||
|
||||
QGraphicsItemAnimation *animation = new QGraphicsItemAnimation;
|
||||
animation->setItem(itemToMove);
|
||||
animation->setTimeLine(timer);
|
||||
QScrollBar * scrollBar = coversView->horizontalScrollBar();
|
||||
|
||||
QPointF point = itemToMove->scenePos();
|
||||
float step = (width+10)/24.0;
|
||||
for (int i = 0; i < 24; ++i)
|
||||
animation->setPosAt(i / 24.0, QPointF(point.x()-((i+1)*step), point.y()));
|
||||
float speedFactor = 2.5;
|
||||
int origin = scrollBar->value();
|
||||
int dest = origin + 10 + p.width();
|
||||
|
||||
timer->start();
|
||||
connect(timer,SIGNAL(finished()),timer,SLOT(deleteLater()));
|
||||
connect(timer,SIGNAL(finished()),animation,SLOT(deleteLater()));
|
||||
}
|
||||
|
||||
QTimer::singleShot(400,this,SLOT(finishedUpdatingCover()));
|
||||
|
||||
previousWidth -= 10+width;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ImportWidget::finishedUpdatingCover()
|
||||
{
|
||||
updatingCovers = false;
|
||||
scrollAnimation->setDuration((dest-origin)*speedFactor);
|
||||
scrollAnimation->setStartValue(origin);
|
||||
scrollAnimation->setEndValue(dest);
|
||||
QEasingCurve easing(QEasingCurve::OutQuad);
|
||||
scrollAnimation->setEasingCurve(easing);
|
||||
scrollAnimation->start();
|
||||
}
|
||||
}
|
||||
|
||||
void ImportWidget::newCover(const QPixmap & image)
|
||||
@ -335,7 +317,7 @@ void ImportWidget::addCoverTest()
|
||||
|
||||
void ImportWidget::clear()
|
||||
{
|
||||
previousWidth = 10;
|
||||
previousWidth = 0;
|
||||
|
||||
//nos aseguramos de que las animaciones han finalizado antes de borrar
|
||||
QList<QGraphicsItem*> all = coversScene->items();
|
||||
@ -347,7 +329,12 @@ void ImportWidget::clear()
|
||||
}
|
||||
coversScene->clear();
|
||||
|
||||
updatingCovers = false;
|
||||
delete coversScene;
|
||||
coversScene = new QGraphicsScene;
|
||||
|
||||
coversView->setScene(coversScene);
|
||||
|
||||
updatingCovers = false;
|
||||
|
||||
currentComicLabel->setText("<font color=\"#565959\">...</font>");
|
||||
|
||||
@ -377,7 +364,7 @@ void ImportWidget::clearScene()
|
||||
void ImportWidget::showCovers(bool hide)
|
||||
{
|
||||
portadasLabel->setHidden(hide);
|
||||
coversViewContainer->setHidden(hide);
|
||||
coversViewContainer->setHidden(hide);
|
||||
}
|
||||
|
||||
void ImportWidget::resizeEvent(QResizeEvent * event)
|
||||
|
@ -10,42 +10,45 @@ class QElapsedTimer;
|
||||
class QVBoxLayout;
|
||||
class QToolButton;
|
||||
class QResizeEvent;
|
||||
class QPropertyAnimation;
|
||||
|
||||
class ImportWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ImportWidget(QWidget *parent = 0);
|
||||
explicit ImportWidget(QWidget *parent = 0);
|
||||
|
||||
signals:
|
||||
void stop();
|
||||
void stop();
|
||||
public slots:
|
||||
void newComic(const QString & path, const QString & coverPath);
|
||||
void newCover(const QPixmap & image);
|
||||
void clear();
|
||||
void addCoverTest();
|
||||
void finishedUpdatingCover();
|
||||
void clearScene();
|
||||
void setImportLook();
|
||||
void setUpdateLook();
|
||||
void showCovers(bool hide);
|
||||
void newComic(const QString & path, const QString & coverPath);
|
||||
void newCover(const QPixmap & image);
|
||||
void clear();
|
||||
void addCoverTest();
|
||||
void clearScene();
|
||||
void setImportLook();
|
||||
void setUpdateLook();
|
||||
void showCovers(bool hide);
|
||||
|
||||
private:
|
||||
QLabel * currentComicLabel;
|
||||
QLabel * portadasLabel;
|
||||
QLabel * iconLabel;
|
||||
QLabel * text;
|
||||
QLabel * textDescription;
|
||||
QWidget * coversViewContainer;
|
||||
QGraphicsView * coversView;
|
||||
QGraphicsScene * coversScene;
|
||||
int previousWidth;
|
||||
bool updatingCovers;
|
||||
QElapsedTimer * elapsedTimer;
|
||||
quint64 i;
|
||||
QLabel * currentComicLabel;
|
||||
QLabel * portadasLabel;
|
||||
QLabel * iconLabel;
|
||||
QLabel * text;
|
||||
QLabel * textDescription;
|
||||
QWidget * coversViewContainer;
|
||||
QGraphicsView * coversView;
|
||||
QGraphicsScene * coversScene;
|
||||
QPropertyAnimation * scrollAnimation;
|
||||
|
||||
QToolButton * hideButton;
|
||||
int previousWidth;
|
||||
bool updatingCovers;
|
||||
QElapsedTimer * elapsedTimer;
|
||||
quint64 i;
|
||||
|
||||
void resizeEvent(QResizeEvent * event);
|
||||
QToolButton * hideButton;
|
||||
|
||||
void resizeEvent(QResizeEvent * event);
|
||||
|
||||
};
|
||||
|
||||
|
@ -122,8 +122,8 @@ void LibraryCreator::processLibrary(const QString & source, const QString & targ
|
||||
void LibraryCreator::run()
|
||||
{
|
||||
stopRunning = false;
|
||||
|
||||
//check for 7z lib
|
||||
#ifndef use_unarr
|
||||
//check for 7z lib
|
||||
#if defined Q_OS_UNIX && !defined Q_OS_MAC
|
||||
QLibrary *sevenzLib = new QLibrary(QString(LIBDIR)+"/p7zip/7z.so");
|
||||
#else
|
||||
@ -137,7 +137,7 @@ void LibraryCreator::run()
|
||||
exit();
|
||||
}
|
||||
sevenzLib->deleteLater();
|
||||
|
||||
#endif
|
||||
if(_mode == CREATOR)
|
||||
{
|
||||
QLOG_INFO() << "Starting to create new library ( " << _source << "," << _target << ")";
|
||||
|
@ -86,6 +86,7 @@
|
||||
#include "db_helper.h"
|
||||
|
||||
#include "reading_list_item.h"
|
||||
#include "opengl_checker.h"
|
||||
|
||||
#include "QsLog.h"
|
||||
|
||||
@ -187,10 +188,15 @@ void LibraryWindow::doLayout()
|
||||
#ifndef NO_OPENGL
|
||||
//FLOW-----------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
if(QGLFormat::hasOpenGL() && !settings->contains(USE_OPEN_GL))
|
||||
{
|
||||
|
||||
OpenGLChecker openGLChecker;
|
||||
bool openGLAvailable = openGLChecker.hasCompatibleOpenGLVersion();
|
||||
|
||||
if(openGLAvailable && !settings->contains(USE_OPEN_GL))
|
||||
settings->setValue(USE_OPEN_GL,2);
|
||||
}
|
||||
else
|
||||
if(!openGLAvailable)
|
||||
settings->setValue(USE_OPEN_GL,0);
|
||||
#endif
|
||||
//FOLDERS FILTER-------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
@ -245,7 +251,6 @@ void LibraryWindow::doLayout()
|
||||
|
||||
doComicsViewConnections();
|
||||
|
||||
comicsView->setToolBar(editInfoToolBar);
|
||||
comicsViewStack->addWidget(comicsViewTransition = new ComicsViewTransition());
|
||||
comicsViewStack->addWidget(emptyFolderWidget = new EmptyFolderWidget());
|
||||
comicsViewStack->addWidget(emptyLabelWidget = new EmptyLabelWidget());
|
||||
@ -413,8 +418,7 @@ void LibraryWindow::setUpShortcutsManagement()
|
||||
#ifndef Q_OS_MAC
|
||||
<< toggleFullScreenAction
|
||||
#endif
|
||||
<< toggleComicsViewAction
|
||||
<< hideComicViewAction);
|
||||
<< toggleComicsViewAction);
|
||||
|
||||
allActions << tmpList;
|
||||
|
||||
@ -570,7 +574,7 @@ void LibraryWindow::createActions()
|
||||
setAllAsNonReadAction->setIcon(QIcon(":/images/setAllUnread.png"));*/
|
||||
|
||||
showHideMarksAction = new QAction(tr("Show/Hide marks"),this);
|
||||
showHideMarksAction->setToolTip(tr("Show or hide readed marks"));
|
||||
showHideMarksAction->setToolTip(tr("Show or hide read marks"));
|
||||
showHideMarksAction->setData(SHOW_HIDE_MARKS_ACTION_YL);
|
||||
showHideMarksAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_HIDE_MARKS_ACTION_YL));
|
||||
showHideMarksAction->setCheckable(true);
|
||||
@ -719,14 +723,6 @@ void LibraryWindow::createActions()
|
||||
deleteComicsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(DELETE_COMICS_ACTION_YL));
|
||||
deleteComicsAction->setIcon(QIcon(":/images/trash.png"));
|
||||
|
||||
hideComicViewAction = new QAction(this);
|
||||
hideComicViewAction->setText(tr("Hide comic flow"));
|
||||
hideComicViewAction->setData(HIDE_COMIC_VIEW_ACTION_YL);
|
||||
hideComicViewAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HIDE_COMIC_VIEW_ACTION_YL));
|
||||
hideComicViewAction->setIcon(QIcon(":/images/hideComicFlow.png"));
|
||||
hideComicViewAction->setCheckable(true);
|
||||
hideComicViewAction->setChecked(false);
|
||||
|
||||
getInfoAction = new QAction(this);
|
||||
getInfoAction->setData(GET_INFO_ACTION_YL);
|
||||
getInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(GET_INFO_ACTION_YL));
|
||||
@ -932,8 +928,8 @@ void LibraryWindow::createToolBars()
|
||||
|
||||
editInfoToolBar->addAction(deleteComicsAction);
|
||||
|
||||
/*editInfoToolBar->addWidget(new QToolBarStretch());
|
||||
editInfoToolBar->addAction(hideComicViewAction);*/
|
||||
|
||||
comicsView->setToolBar(editInfoToolBar);
|
||||
}
|
||||
|
||||
void LibraryWindow::createMenus()
|
||||
@ -1142,8 +1138,6 @@ void LibraryWindow::createConnections()
|
||||
|
||||
connect(deleteComicsAction,SIGNAL(triggered()),this,SLOT(deleteComics()));
|
||||
|
||||
connect(hideComicViewAction, SIGNAL(toggled(bool)),this, SLOT(hideComicFlow(bool)));
|
||||
|
||||
connect(getInfoAction,SIGNAL(triggered()),this,SLOT(showComicVineScraper()));
|
||||
|
||||
//connect(socialAction,SIGNAL(triggered()),this,SLOT(showSocial()));
|
||||
@ -2458,30 +2452,6 @@ QString LibraryWindow::currentFolderPath()
|
||||
return QDir::cleanPath(currentPath()+path);
|
||||
}
|
||||
|
||||
//TODO ComicsView: some actions in the comics toolbar can be relative to a certain view
|
||||
//show/hide actions on show/hide widget
|
||||
void LibraryWindow::hideComicFlow(bool hide)
|
||||
{
|
||||
/*
|
||||
if(hide)
|
||||
{
|
||||
QList<int> sizes;
|
||||
sizes.append(0);
|
||||
int total = sVertical->sizes().at(0) + sVertical->sizes().at(1);
|
||||
sizes.append(total);
|
||||
sVertical->setSizes(sizes);
|
||||
}
|
||||
else
|
||||
{
|
||||
QList<int> sizes;
|
||||
int total = sVertical->sizes().at(0) + sVertical->sizes().at(1);
|
||||
sizes.append(2*total/3);
|
||||
sizes.append(total/3);
|
||||
sVertical->setSizes(sizes);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void LibraryWindow::showExportComicsInfo()
|
||||
{
|
||||
exportComicsInfoDialog->source = currentPath() + "/.yacreaderlibrary/library.ydb";
|
||||
|
@ -205,7 +205,6 @@ private:
|
||||
QAction * asignOrderAction;
|
||||
QAction * forceCoverExtractedAction;
|
||||
QAction * deleteComicsAction;
|
||||
QAction * hideComicViewAction;
|
||||
|
||||
QAction *showEditShortcutsAction;
|
||||
|
||||
@ -339,7 +338,6 @@ public slots:
|
||||
void setCurrentComicsStatusReaded(YACReaderComicReadStatus readStatus);
|
||||
void setCurrentComicReaded();
|
||||
void setCurrentComicUnreaded();
|
||||
void hideComicFlow(bool hide);
|
||||
void showExportComicsInfo();
|
||||
void showImportComicsInfo();
|
||||
void asignNumbers();
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "db_helper.h"
|
||||
#include "yacreader_libraries.h"
|
||||
#include "exit_check.h"
|
||||
#include "opengl_checker.h"
|
||||
|
||||
#include "QsLog.h"
|
||||
#include "QsLogDest.h"
|
||||
@ -92,6 +93,7 @@ void logSystemAndConfig()
|
||||
QLOG_INFO() << "SO : Unknown";
|
||||
#endif
|
||||
|
||||
#ifndef use_unarr
|
||||
#ifdef Q_OS_WIN
|
||||
if(QLibrary::isLibrary(QApplication::applicationDirPath()+"/utils/7z.dll"))
|
||||
#elif defined Q_OS_UNIX && !defined Q_OS_MAC
|
||||
@ -102,6 +104,9 @@ void logSystemAndConfig()
|
||||
QLOG_INFO() << "7z : found";
|
||||
else
|
||||
QLOG_ERROR() << "7z : not found";
|
||||
#else
|
||||
QLOG_INFO() << "using unarr decompression backend";
|
||||
#endif
|
||||
#if defined Q_OS_UNIX && !defined Q_OS_MAC
|
||||
if(QFileInfo(QString(BINDIR)+"/qrencode").exists())
|
||||
#else
|
||||
@ -123,12 +128,16 @@ void logSystemAndConfig()
|
||||
else
|
||||
QLOG_INFO() << "OpenGL : disabled";
|
||||
|
||||
OpenGLChecker checker;
|
||||
QLOG_INFO() << "OpenGL version : " << checker.textVersionDescription();
|
||||
|
||||
QLOG_INFO() << "Libraries: " << DBHelper::getLibraries().getLibraries();
|
||||
QLOG_INFO() << "--------------------------------------------";
|
||||
}
|
||||
|
||||
int main( int argc, char ** argv )
|
||||
{
|
||||
|
||||
//fix for misplaced text in Qt4.8 and Mavericks
|
||||
#ifdef Q_OS_MAC
|
||||
#if QT_VERSION < 0x050000
|
||||
@ -140,9 +149,13 @@ int main( int argc, char ** argv )
|
||||
|
||||
QApplication app( argc, argv );
|
||||
|
||||
#ifdef FORCE_ANGLE
|
||||
app.setAttribute(Qt::AA_UseOpenGLES);
|
||||
#endif
|
||||
|
||||
app.setApplicationName("YACReaderLibrary");
|
||||
app.setOrganizationName("YACReader");
|
||||
qApp->setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
app.setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
//simple command line parser
|
||||
//will be replaced by QCommandLineParser in the future
|
||||
//TODO: --headless, --server=[on|off], support for file and directory arguments
|
||||
@ -208,7 +221,6 @@ int main( int argc, char ** argv )
|
||||
|
||||
if(settings->value(SERVER_ON,true).toBool())
|
||||
{
|
||||
|
||||
s->start();
|
||||
}
|
||||
#endif
|
||||
|
@ -150,11 +150,14 @@ Rectangle {
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
/*if(mouse.button != Qt.RightButton && !(mouse.modifiers & Qt.ControlModifier || mouse.modifiers & Qt.ShiftModifier))
|
||||
if(mouse.button == Qt.LeftButton && !(mouse.modifiers & Qt.ControlModifier || mouse.modifiers & Qt.ShiftModifier))
|
||||
{
|
||||
comicsSelectionHelper.setCurrentIndex(index)
|
||||
grid.currentIndex = index;
|
||||
}*/
|
||||
if(comicsSelectionHelper.isSelectedIndex(index))
|
||||
{
|
||||
comicsSelectionHelper.setCurrentIndex(index)
|
||||
grid.currentIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -166,30 +169,44 @@ Rectangle {
|
||||
//cover
|
||||
Image {
|
||||
id: coverElement
|
||||
width: 148
|
||||
height: 224
|
||||
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 4}
|
||||
width: 156
|
||||
height: 236
|
||||
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
|
||||
source: cover_path
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
smooth: true
|
||||
mipmap: true
|
||||
asynchronous : true
|
||||
cache: false //TODO clear cache only when it is neede
|
||||
cache: false //TODO clear cache only when it is needed
|
||||
|
||||
}
|
||||
|
||||
//border
|
||||
Rectangle {
|
||||
width: 156
|
||||
height: 236
|
||||
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
|
||||
color: "transparent"
|
||||
border {
|
||||
color: "#20FFFFFF"
|
||||
width: 1
|
||||
}
|
||||
}
|
||||
|
||||
//mark
|
||||
Image {
|
||||
id: mark
|
||||
width: 23
|
||||
height: 23
|
||||
source: read_column&&show_marks?"tick.png":has_been_opened&&show_marks?"reading.png":""
|
||||
anchors {right: coverElement.right; top: coverElement.top; topMargin: 11; rightMargin: 11}
|
||||
anchors {right: coverElement.right; top: coverElement.top; topMargin: 9; rightMargin: 9}
|
||||
asynchronous : true
|
||||
}
|
||||
|
||||
//title
|
||||
Text {
|
||||
id : titleText
|
||||
anchors { top: realCell.top; left: realCell.left; leftMargin: 4; rightMargin: 4; topMargin: 234; }
|
||||
anchors { top: realCell.top; left: realCell.left; leftMargin: 4; rightMargin: 4; topMargin: 238; }
|
||||
width: 148
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.WordWrap
|
||||
@ -339,6 +356,12 @@ Rectangle {
|
||||
currentIndex: 0
|
||||
cacheBuffer: 0
|
||||
|
||||
footer: Rectangle { //fix for the scroll issue, TODO find what causes the issue (some times the bottoms cells are hidden for the toolbar, no full scroll)
|
||||
height : 25
|
||||
width : parent.width
|
||||
color : backgroundColor
|
||||
}
|
||||
|
||||
move: Transition {
|
||||
NumberAnimation { properties: "x,y"; duration: 250 }
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 155 B After Width: | Height: | Size: 163 B |
Binary file not shown.
Before Width: | Height: | Size: 242 B After Width: | Height: | Size: 288 B |
@ -56,6 +56,9 @@ void ComicController::service(HttpRequest& request, HttpResponse& response)
|
||||
|
||||
comicFile->moveToThread(thread);
|
||||
|
||||
connect(comicFile, SIGNAL(errorOpening()), thread, SLOT(quit()));
|
||||
connect(comicFile, SIGNAL(errorOpening(QString)), thread, SLOT(quit()));
|
||||
connect(comicFile, SIGNAL(imagesLoaded()), thread, SLOT(quit()));
|
||||
connect(thread, SIGNAL(started()), comicFile, SLOT(process()));
|
||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||
|
||||
|
@ -10,6 +10,8 @@ ComicDownloadInfoController::ComicDownloadInfoController() {}
|
||||
|
||||
void ComicDownloadInfoController::service(HttpRequest& request, HttpResponse& response)
|
||||
{
|
||||
response.setHeader("Content-Type", "plain/text; charset=utf-8");
|
||||
|
||||
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
|
||||
QStringList pathElements = path.split('/');
|
||||
|
||||
|
@ -51,7 +51,7 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
|
||||
}
|
||||
|
||||
if(folderId!=1)
|
||||
t.setVariable("folder.name",folderName);
|
||||
t.setVariable("folder.name",folderName);
|
||||
else
|
||||
t.setVariable("folder.name",libraryName);
|
||||
QList<LibraryItem *> folderContent = DBHelper::getFolderSubfoldersFromLibrary(libraryId,folderId);
|
||||
@ -155,75 +155,81 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
|
||||
t.setVariable(QString("path%1.name").arg(i-1),DBHelper::getFolderName(libraryId,foldersPath[i].first));
|
||||
}
|
||||
|
||||
t.loop("element",numFoldersAtCurrentPage);
|
||||
int i = 0;
|
||||
while(i<numFoldersAtCurrentPage)
|
||||
{
|
||||
LibraryItem * item = folderContent.at(i + (page*elementsPerPage));
|
||||
t.setVariable(QString("element%1.name").arg(i),folderContent.at(i + (page*elementsPerPage))->name);
|
||||
if(item->isDir())
|
||||
{
|
||||
t.setVariable(QString("element%1.class").arg(i),"folder");
|
||||
|
||||
QList<LibraryItem *> children = DBHelper::getFolderComicsFromLibrary(libraryId, item->id);
|
||||
if(children.length()>0)
|
||||
if(folderContent.length() > 0)
|
||||
{
|
||||
t.loop("element",numFoldersAtCurrentPage);
|
||||
int i = 0;
|
||||
while(i<numFoldersAtCurrentPage)
|
||||
{
|
||||
LibraryItem * item = folderContent.at(i + (page*elementsPerPage));
|
||||
t.setVariable(QString("element%1.name").arg(i),folderContent.at(i + (page*elementsPerPage))->name);
|
||||
if(item->isDir())
|
||||
{
|
||||
const ComicDB * comic = static_cast<ComicDB*>(children.at(0));
|
||||
t.setVariable(QString("element%1.image.url").arg(i),QString("/library/%1/cover/%2.jpg?folderCover=true").arg(libraryId).arg(comic->info.hash));
|
||||
t.setVariable(QString("element%1.class").arg(i),"folder");
|
||||
|
||||
QList<LibraryItem *> children = DBHelper::getFolderComicsFromLibrary(libraryId, item->id);
|
||||
if(children.length()>0)
|
||||
{
|
||||
const ComicDB * comic = static_cast<ComicDB*>(children.at(0));
|
||||
t.setVariable(QString("element%1.image.url").arg(i),QString("/library/%1/cover/%2.jpg?folderCover=true").arg(libraryId).arg(comic->info.hash));
|
||||
}
|
||||
else
|
||||
t.setVariable(QString("element%1.image.url").arg(i),"/images/f.png");
|
||||
|
||||
t.setVariable(QString("element%1.browse").arg(i),QString("<a class =\"browseButton\" href=\"%1\">BROWSE</a>").arg(QString("/library/%1/folder/%2").arg(libraryId).arg(item->id)));
|
||||
t.setVariable(QString("element%1.cover.browse").arg(i),QString("<a href=\"%1\">").arg(QString("/library/%1/folder/%2").arg(libraryId).arg(item->id)));
|
||||
t.setVariable(QString("element%1.cover.browse.end").arg(i),"</a>");
|
||||
//t.setVariable(QString("element%1.url").arg(i),"/library/"+libraryName+"/folder/"+QString("%1").arg(folderContent.at(i + (page*10))->id));
|
||||
//t.setVariable(QString("element%1.downloadurl").arg(i),"/library/"+libraryName+"/folder/"+QString("%1/info").arg(folderContent.at(i + (page*elementsPerPage))->id));
|
||||
|
||||
t.setVariable(QString("element%1.download").arg(i),QString("<a onclick=\"this.innerHTML='IMPORTING';this.className='importedButton';\" class =\"importButton\" href=\"%1\">IMPORT</a>").arg("/library/"+QString::number(libraryId)+"/folder/"+QString("%1/info").arg(folderContent.at(i + (page*elementsPerPage))->id)));
|
||||
t.setVariable(QString("element%1.read").arg(i),"");
|
||||
|
||||
t.setVariable(QString("element%1.size").arg(i),"");
|
||||
t.setVariable(QString("element%1.pages").arg(i),"");
|
||||
t.setVariable(QString("element%1.status").arg(i),"");
|
||||
}
|
||||
else
|
||||
t.setVariable(QString("element%1.image.url").arg(i),"/images/f.png");
|
||||
|
||||
t.setVariable(QString("element%1.browse").arg(i),QString("<a class =\"browseButton\" href=\"%1\">BROWSE</a>").arg(QString("/library/%1/folder/%2").arg(libraryId).arg(item->id)));
|
||||
t.setVariable(QString("element%1.cover.browse").arg(i),QString("<a href=\"%1\">").arg(QString("/library/%1/folder/%2").arg(libraryId).arg(item->id)));
|
||||
t.setVariable(QString("element%1.cover.browse.end").arg(i),"</a>");
|
||||
//t.setVariable(QString("element%1.url").arg(i),"/library/"+libraryName+"/folder/"+QString("%1").arg(folderContent.at(i + (page*10))->id));
|
||||
//t.setVariable(QString("element%1.downloadurl").arg(i),"/library/"+libraryName+"/folder/"+QString("%1/info").arg(folderContent.at(i + (page*elementsPerPage))->id));
|
||||
|
||||
t.setVariable(QString("element%1.download").arg(i),QString("<a onclick=\"this.innerHTML='IMPORTING';this.className='importedButton';\" class =\"importButton\" href=\"%1\">IMPORT</a>").arg("/library/"+QString::number(libraryId)+"/folder/"+QString("%1/info").arg(folderContent.at(i + (page*elementsPerPage))->id)));
|
||||
t.setVariable(QString("element%1.read").arg(i),"");
|
||||
|
||||
t.setVariable(QString("element%1.size").arg(i),"");
|
||||
t.setVariable(QString("element%1.pages").arg(i),"");
|
||||
t.setVariable(QString("element%1.status").arg(i),"");
|
||||
}
|
||||
else
|
||||
{
|
||||
t.setVariable(QString("element%1.class").arg(i),"cover");
|
||||
const ComicDB * comic = (ComicDB *)item;
|
||||
t.setVariable(QString("element%1.browse").arg(i),"");
|
||||
//t.setVariable(QString("element%1.downloadurl").arg(i),"/library/"+libraryName+"/comic/"+QString("%1").arg(comic->id));
|
||||
if(!session.isComicOnDevice(comic->info.hash) && !session.isComicDownloaded(comic->info.hash))
|
||||
t.setVariable(QString("element%1.download").arg(i),QString("<a onclick=\"this.innerHTML='IMPORTING';this.className='importedButton';\" class =\"importButton\" href=\"%1\">IMPORT</a>").arg("/library/"+QString::number(libraryId)+"/comic/"+QString("%1").arg(comic->id)));
|
||||
else if (session.isComicOnDevice(comic->info.hash))
|
||||
{
|
||||
t.setVariable(QString("element%1.class").arg(i),"cover");
|
||||
const ComicDB * comic = (ComicDB *)item;
|
||||
t.setVariable(QString("element%1.browse").arg(i),"");
|
||||
//t.setVariable(QString("element%1.downloadurl").arg(i),"/library/"+libraryName+"/comic/"+QString("%1").arg(comic->id));
|
||||
if(!session.isComicOnDevice(comic->info.hash) && !session.isComicDownloaded(comic->info.hash))
|
||||
t.setVariable(QString("element%1.download").arg(i),QString("<a onclick=\"this.innerHTML='IMPORTING';this.className='importedButton';\" class =\"importButton\" href=\"%1\">IMPORT</a>").arg("/library/"+QString::number(libraryId)+"/comic/"+QString("%1").arg(comic->id)));
|
||||
else if (session.isComicOnDevice(comic->info.hash))
|
||||
t.setVariable(QString("element%1.download").arg(i),QString("<div class=\"importedButton\">IMPORTED</div>"));
|
||||
else
|
||||
t.setVariable(QString("element%1.download").arg(i),QString("<div class=\"importedButton\">IMPORTING</div>"));
|
||||
else
|
||||
t.setVariable(QString("element%1.download").arg(i),QString("<div class=\"importedButton\">IMPORTING</div>"));
|
||||
|
||||
//t.setVariable(QString("element%1.image.url").arg(i),"/images/f.png");
|
||||
//t.setVariable(QString("element%1.image.url").arg(i),"/images/f.png");
|
||||
|
||||
t.setVariable(QString("element%1.read").arg(i),QString("<a class =\"readButton\" href=\"%1\">READ</a>").arg("/library/"+QString::number(libraryId)+"/comic/"+QString("%1").arg(comic->id)+"/remote"));
|
||||
t.setVariable(QString("element%1.read").arg(i),QString("<a class =\"readButton\" href=\"%1\">READ</a>").arg("/library/"+QString::number(libraryId)+"/comic/"+QString("%1").arg(comic->id)+"/remote"));
|
||||
|
||||
t.setVariable(QString("element%1.image.url").arg(i),QString("/library/%1/cover/%2.jpg").arg(libraryId).arg(comic->info.hash));
|
||||
t.setVariable(QString("element%1.image.url").arg(i),QString("/library/%1/cover/%2.jpg").arg(libraryId).arg(comic->info.hash));
|
||||
|
||||
t.setVariable(QString("element%1.size").arg(i),"<span class=\"comicSize\">" + QString::number(comic->info.hash.right(comic->info.hash.length()-40).toInt()/1024.0/1024.0,'f',2)+"Mb</span>");
|
||||
if(comic->info.hasBeenOpened)
|
||||
t.setVariable(QString("element%1.pages").arg(i),QString("<span class=\"numPages\">%1/%2 pages</span>").arg(comic->info.currentPage).arg(comic->info.numPages.toInt()));
|
||||
else
|
||||
t.setVariable(QString("element%1.pages").arg(i),QString("<span class=\"numPages\">%1 pages</span>").arg(comic->info.numPages.toInt()));
|
||||
t.setVariable(QString("element%1.size").arg(i),"<span class=\"comicSize\">" + QString::number(comic->info.hash.right(comic->info.hash.length()-40).toInt()/1024.0/1024.0,'f',2)+"Mb</span>");
|
||||
if(comic->info.hasBeenOpened)
|
||||
t.setVariable(QString("element%1.pages").arg(i),QString("<span class=\"numPages\">%1/%2 pages</span>").arg(comic->info.currentPage).arg(comic->info.numPages.toInt()));
|
||||
else
|
||||
t.setVariable(QString("element%1.pages").arg(i),QString("<span class=\"numPages\">%1 pages</span>").arg(comic->info.numPages.toInt()));
|
||||
|
||||
if(comic->info.read)
|
||||
t.setVariable(QString("element%1.status").arg(i), QString("<div class=\"mark\"><img src=\"/images/readMark.png\" style = \"width: 15px\"/> </div>"));
|
||||
else if(comic->info.hasBeenOpened)
|
||||
t.setVariable(QString("element%1.status").arg(i), QString("<div class=\"mark\"><img src=\"/images/readingMark.png\" style = \"width: 15px\"/> </div>"));
|
||||
else
|
||||
t.setVariable(QString("element%1.status").arg(i),"");
|
||||
if(comic->info.read)
|
||||
t.setVariable(QString("element%1.status").arg(i), QString("<div class=\"mark\"><img src=\"/images/readMark.png\" style = \"width: 15px\"/> </div>"));
|
||||
else if(comic->info.hasBeenOpened)
|
||||
t.setVariable(QString("element%1.status").arg(i), QString("<div class=\"mark\"><img src=\"/images/readingMark.png\" style = \"width: 15px\"/> </div>"));
|
||||
else
|
||||
t.setVariable(QString("element%1.status").arg(i),"");
|
||||
|
||||
t.setVariable(QString("element%1.cover.browse").arg(i),"");
|
||||
t.setVariable(QString("element%1.cover.browse.end").arg(i),"");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
t.setVariable(QString("element%1.cover.browse").arg(i),"");
|
||||
t.setVariable(QString("element%1.cover.browse.end").arg(i),"");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
} else
|
||||
{
|
||||
t.loop("element",0);
|
||||
}
|
||||
|
||||
if(numPages > 1)
|
||||
{
|
||||
|
55
YACReaderLibrary/server/controllers/synccontroller.cpp
Normal file
55
YACReaderLibrary/server/controllers/synccontroller.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include "synccontroller.h"
|
||||
|
||||
#include "QsLog.h"
|
||||
#include <QUrl>
|
||||
|
||||
#include "comic_db.h"
|
||||
#include "db_helper.h"
|
||||
|
||||
SyncController::SyncController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SyncController::service(HttpRequest &request, HttpResponse &response)
|
||||
{
|
||||
QString postData = QString::fromUtf8(request.getBody());
|
||||
|
||||
QLOG_INFO() << "POST DATA: " << postData;
|
||||
|
||||
if(postData.length()>0) {
|
||||
QList<QString> data = postData.split("\n");
|
||||
|
||||
qulonglong libraryId;
|
||||
qulonglong comicId;
|
||||
int currentPage;
|
||||
QString hash;
|
||||
foreach(QString comicInfo, data)
|
||||
{
|
||||
QList<QString> comicInfoProgress = comicInfo.split("\t");
|
||||
|
||||
if(comicInfoProgress.length() == 4)
|
||||
{
|
||||
libraryId = comicInfoProgress.at(0).toULongLong();
|
||||
comicId = comicInfoProgress.at(1).toULongLong();
|
||||
hash = comicInfoProgress.at(2);
|
||||
currentPage = comicInfoProgress.at(3).toInt();
|
||||
|
||||
ComicInfo info;
|
||||
info.currentPage = currentPage;
|
||||
info.hash = hash; //TODO remove the hash check and add UUIDs for libraries
|
||||
info.id = comicId;
|
||||
DBHelper::updateFromRemoteClient(libraryId,info);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
response.setStatus(412,"No comic info received");
|
||||
response.writeText("",true);
|
||||
return;
|
||||
}
|
||||
|
||||
response.write("OK",true);
|
||||
}
|
||||
|
21
YACReaderLibrary/server/controllers/synccontroller.h
Normal file
21
YACReaderLibrary/server/controllers/synccontroller.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef SYNCCONTROLLER_H
|
||||
#define SYNCCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "httprequest.h"
|
||||
#include "httpresponse.h"
|
||||
#include "httprequesthandler.h"
|
||||
|
||||
class SyncController : public HttpRequestHandler {
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(SyncController);
|
||||
public:
|
||||
/** Constructor */
|
||||
SyncController();
|
||||
|
||||
/** Generates the response */
|
||||
void service(HttpRequest& request, HttpResponse& response);
|
||||
};
|
||||
|
||||
#endif // SYNCCONTROLLER_H
|
@ -99,66 +99,72 @@ void HttpConnectionHandler::disconnected() {
|
||||
}
|
||||
|
||||
void HttpConnectionHandler::read() {
|
||||
while (socket.bytesAvailable()) {
|
||||
#ifdef SUPERVERBOSE
|
||||
qDebug("HttpConnectionHandler (%p): read input",this);
|
||||
qDebug("HttpConnectionHandler (%p): read input",this);
|
||||
#endif
|
||||
|
||||
// Create new HttpRequest object if necessary
|
||||
if (!currentRequest) {
|
||||
currentRequest=new HttpRequest(settings);
|
||||
}
|
||||
|
||||
// Collect data for the request object
|
||||
while (socket.bytesAvailable() && currentRequest->getStatus()!=HttpRequest::complete && currentRequest->getStatus()!=HttpRequest::abort) {
|
||||
currentRequest->readFromSocket(socket);
|
||||
if (currentRequest->getStatus()==HttpRequest::waitForBody) {
|
||||
// Restart timer for read timeout, otherwise it would
|
||||
// expire during large file uploads.
|
||||
int readTimeout=settings->value("readTimeout",10000).toInt();
|
||||
readTimer.start(readTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
// If the request is aborted, return error message and close the connection
|
||||
if (currentRequest->getStatus()==HttpRequest::abort) {
|
||||
socket.write("HTTP/1.1 413 entity too large\r\nConnection: close\r\n\r\n413 Entity too large\r\n");
|
||||
socket.disconnectFromHost();
|
||||
delete currentRequest;
|
||||
currentRequest=0;
|
||||
return;
|
||||
}
|
||||
|
||||
// If the request is complete, let the request mapper dispatch it
|
||||
if (currentRequest->getStatus()==HttpRequest::complete) {
|
||||
readTimer.stop();
|
||||
qDebug("HttpConnectionHandler (%p): received request",this);
|
||||
HttpResponse response(&socket);
|
||||
//response.setHeader("Connection","close"); No funciona bien con NSURLConnection
|
||||
try {
|
||||
requestHandler->service(*currentRequest, response);
|
||||
}
|
||||
catch (...) {
|
||||
qCritical("HttpConnectionHandler (%p): An uncatched exception occured in the request handler",this);
|
||||
// Create new HttpRequest object if necessary
|
||||
if (!currentRequest) {
|
||||
currentRequest=new HttpRequest(settings);
|
||||
}
|
||||
|
||||
// Finalize sending the response if not already done
|
||||
if (!response.hasSentLastPart()) {
|
||||
response.write(QByteArray(),true);
|
||||
// Collect data for the request object
|
||||
while (socket.bytesAvailable() && currentRequest->getStatus()!=HttpRequest::complete && currentRequest->getStatus()!=HttpRequest::abort) {
|
||||
currentRequest->readFromSocket(socket);
|
||||
if (currentRequest->getStatus()==HttpRequest::waitForBody) {
|
||||
// Restart timer for read timeout, otherwise it would
|
||||
// expire during large file uploads.
|
||||
int readTimeout=settings->value("readTimeout",10000).toInt();
|
||||
readTimer.start(readTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
socket.disconnectFromHost(); //CAMBIADO s<>lo se van a soportar conexiones NO persistentes
|
||||
// If the request is aborted, return error message and close the connection
|
||||
if (currentRequest->getStatus()==HttpRequest::abort) {
|
||||
socket.write("HTTP/1.1 413 entity too large\r\nConnection: close\r\n\r\n413 Entity too large\r\n");
|
||||
socket.disconnectFromHost();
|
||||
delete currentRequest;
|
||||
currentRequest=0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Close the connection after delivering the response, if requested
|
||||
//if (QString::compare(currentRequest->getHeader("Connection"),"close",Qt::CaseInsensitive)==0) {
|
||||
// socket.disconnectFromHost();
|
||||
//}
|
||||
//else {
|
||||
// // Start timer for next request
|
||||
// int readTimeout=settings->value("readTimeout",10000).toInt();
|
||||
// readTimer.start(readTimeout);
|
||||
//}
|
||||
// Prepare for next request
|
||||
delete currentRequest;
|
||||
currentRequest=0;
|
||||
// If the request is complete, let the request mapper dispatch it
|
||||
if (currentRequest->getStatus()==HttpRequest::complete) {
|
||||
readTimer.stop();
|
||||
qDebug("HttpConnectionHandler (%p): received request",this);
|
||||
HttpResponse response(&socket);
|
||||
//response.setHeader("Connection","close"); No funciona bien con NSURLConnection
|
||||
try {
|
||||
requestHandler->service(*currentRequest, response);
|
||||
}
|
||||
catch (...) {
|
||||
qCritical("HttpConnectionHandler (%p): An uncatched exception occured in the request handler",this);
|
||||
}
|
||||
|
||||
// Finalize sending the response if not already done
|
||||
if (!response.hasSentLastPart()) {
|
||||
response.write(QByteArray(),true);
|
||||
}
|
||||
|
||||
//socket.disconnectFromHost(); //CAMBIADO s<>lo se van a soportar conexiones NO persistentes
|
||||
|
||||
// Close the connection after delivering the response, if requested
|
||||
if (QString::compare(currentRequest->getHeader("Connection"),"close",Qt::CaseInsensitive)==0) {
|
||||
socket.disconnectFromHost();
|
||||
}
|
||||
else {
|
||||
// Start timer for next request
|
||||
int readTimeout=settings->value("readTimeout",10000).toInt();
|
||||
readTimer.start(readTimeout);
|
||||
}
|
||||
// Prepare for next request
|
||||
delete currentRequest;
|
||||
currentRequest=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("HttpConnectionHandler (%p): received request",this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ HttpSessionStore::HttpSessionStore(QSettings* settings, QObject* parent)
|
||||
connect(&cleanupTimer,SIGNAL(timeout()),this,SLOT(timerEvent()));
|
||||
cleanupTimer.start(60000);
|
||||
cookieName=settings->value("cookieName","sessionid").toByteArray();
|
||||
expirationTime=settings->value("expirationTime",86400000).toInt();
|
||||
expirationTime=settings->value("expirationTime",864000000).toInt();
|
||||
qDebug("HttpSessionStore: Sessions expire after %i milliseconds",expirationTime);
|
||||
}
|
||||
|
||||
@ -90,7 +90,9 @@ void HttpSessionStore::timerEvent() {
|
||||
++i;
|
||||
HttpSession session=prev.value();
|
||||
qint64 lastAccess=session.getLastAccess();
|
||||
if (now-lastAccess>expirationTime) {
|
||||
if (now-lastAccess>expirationTime) { //TODO cleaning up will cause current opened comic to be deleted, so clients won't be able to download it
|
||||
//If the cleaning occurs in the midle of a download it going to cause issues
|
||||
//Temporal fix: use a big expirationTime = 10 days
|
||||
qDebug("HttpSessionStore: session %s expired",session.getId().data());
|
||||
sessions.erase(prev);
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QThreadStorage>
|
||||
#include <QHash>
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "controllers/updatecomiccontroller.h"
|
||||
#include "controllers/errorcontroller.h"
|
||||
#include "controllers/comicdownloadinfocontroller.h"
|
||||
#include "controllers/synccontroller.h"
|
||||
|
||||
#include "db_helper.h"
|
||||
#include "yacreader_libraries.h"
|
||||
@ -91,81 +92,86 @@ void RequestMapper::loadSession(HttpRequest & request, HttpResponse& response)
|
||||
}
|
||||
|
||||
void RequestMapper::service(HttpRequest& request, HttpResponse& response) {
|
||||
QByteArray path=request.getPath();
|
||||
qDebug("RequestMapper: path=%s",path.data());
|
||||
QByteArray path=request.getPath();
|
||||
qDebug("RequestMapper: path=%s",path.data());
|
||||
|
||||
QRegExp folder("/library/.+/folder/[0-9]+/?");//get comic content
|
||||
QRegExp folderInfo("/library/.+/folder/[0-9]+/info/?"); //get folder info
|
||||
QRegExp folder("/library/.+/folder/[0-9]+/?");//get comic content
|
||||
QRegExp folderInfo("/library/.+/folder/[0-9]+/info/?"); //get folder info
|
||||
QRegExp comicDownloadInfo("/library/.+/comic/[0-9]+/?"); //get comic info (basic/download info)
|
||||
QRegExp comicFullInfo("/library/.+/comic/[0-9]+/info/?"); //get comic info (full info)
|
||||
QRegExp comicOpen("/library/.+/comic/[0-9]+/remote/?"); //the server will open for reading the comic
|
||||
QRegExp comicUpdate("/library/.+/comic/[0-9]+/update/?"); //get comic info
|
||||
QRegExp comicClose("/library/.+/comic/[0-9]+/close/?"); //the server will close the comic and free memory
|
||||
QRegExp cover("/library/.+/cover/[0-9a-f]+.jpg"); //get comic cover (navigation)
|
||||
QRegExp comicPage("/library/.+/comic/[0-9]+/page/[0-9]+/?"); //get comic page
|
||||
QRegExp comicClose("/library/.+/comic/[0-9]+/close/?"); //the server will close the comic and free memory
|
||||
QRegExp cover("/library/.+/cover/[0-9a-f]+.jpg"); //get comic cover (navigation)
|
||||
QRegExp comicPage("/library/.+/comic/[0-9]+/page/[0-9]+/?"); //get comic page
|
||||
QRegExp comicPageRemote("/library/.+/comic/[0-9]+/page/[0-9]+/remote?"); //get comic page (remote reading)
|
||||
|
||||
QRegExp sync("/sync");
|
||||
|
||||
QRegExp library("/library/([0-9]+)/.+"); //permite verificar que la biblioteca solicitada existe
|
||||
|
||||
path = QUrl::fromPercentEncoding(path).toUtf8();
|
||||
|
||||
loadSession(request, response);
|
||||
if(!sync.exactMatch(path)) //no session is needed for syncback info, until security will be added
|
||||
loadSession(request, response);
|
||||
|
||||
//primera petición, se ha hecho un post, se sirven las bibliotecas si la seguridad mediante login no está habilitada
|
||||
//primera petición, se ha hecho un post, se sirven las bibliotecas si la seguridad mediante login no está habilitada
|
||||
if(path == "/") //Don't send data to the server using '/' !!!!
|
||||
{
|
||||
LibrariesController().service(request, response);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
|
||||
//se comprueba que la sesión sea la correcta con el fin de evitar accesos no autorizados
|
||||
HttpSession session=Static::sessionStore->getSession(request,response,false);
|
||||
if(!session.isNull() && session.contains("ySession"))
|
||||
LibrariesController().service(request, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sync.exactMatch(path))
|
||||
SyncController().service(request, response);
|
||||
else
|
||||
{
|
||||
if(library.indexIn(path)!=-1 && DBHelper::getLibraries().contains(library.cap(1).toInt()) )
|
||||
{
|
||||
//listar el contenido del folder
|
||||
if(folder.exactMatch(path))
|
||||
{
|
||||
FolderController().service(request, response);
|
||||
}
|
||||
else if (folderInfo.exactMatch(path))
|
||||
{
|
||||
FolderInfoController().service(request, response);
|
||||
}
|
||||
else if(cover.exactMatch(path))
|
||||
{
|
||||
CoverController().service(request, response);
|
||||
}
|
||||
else if(comicDownloadInfo.exactMatch(path))
|
||||
//se comprueba que la sesión sea la correcta con el fin de evitar accesos no autorizados
|
||||
HttpSession session=Static::sessionStore->getSession(request,response,false);
|
||||
if(!session.isNull() && session.contains("ySession"))
|
||||
{
|
||||
if(library.indexIn(path)!=-1 && DBHelper::getLibraries().contains(library.cap(1).toInt()) )
|
||||
{
|
||||
ComicDownloadInfoController().service(request, response);
|
||||
//listar el contenido del folder
|
||||
if(folder.exactMatch(path))
|
||||
{
|
||||
FolderController().service(request, response);
|
||||
}
|
||||
else if (folderInfo.exactMatch(path))
|
||||
{
|
||||
FolderInfoController().service(request, response);
|
||||
}
|
||||
else if(cover.exactMatch(path))
|
||||
{
|
||||
CoverController().service(request, response);
|
||||
}
|
||||
else if(comicDownloadInfo.exactMatch(path))
|
||||
{
|
||||
ComicDownloadInfoController().service(request, response);
|
||||
}
|
||||
else if(comicFullInfo.exactMatch(path) || comicOpen.exactMatch(path))//start download or start remote reading
|
||||
{
|
||||
ComicController().service(request, response);
|
||||
}
|
||||
else if(comicPage.exactMatch(path) || comicPageRemote.exactMatch(path))
|
||||
{
|
||||
PageController().service(request,response);
|
||||
}
|
||||
else if(comicUpdate.exactMatch(path))
|
||||
{
|
||||
UpdateComicController().service(request, response);
|
||||
}
|
||||
}
|
||||
else if(comicFullInfo.exactMatch(path) || comicOpen.exactMatch(path))//start download or start remote reading
|
||||
{
|
||||
ComicController().service(request, response);
|
||||
}
|
||||
else if(comicPage.exactMatch(path) || comicPageRemote.exactMatch(path))
|
||||
{
|
||||
PageController().service(request,response);
|
||||
}
|
||||
else if(comicUpdate.exactMatch(path))
|
||||
else
|
||||
{
|
||||
UpdateComicController().service(request, response);
|
||||
//response.writeText(library.cap(1));
|
||||
Static::staticFileController->service(request, response);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//response.writeText(library.cap(1));
|
||||
Static::staticFileController->service(request, response);
|
||||
}
|
||||
}
|
||||
else //acceso no autorizado, redirección
|
||||
{
|
||||
ErrorController(300).service(request,response);
|
||||
}
|
||||
}
|
||||
else //acceso no autorizado, redirección
|
||||
{
|
||||
ErrorController(300).service(request,response);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -5,31 +5,33 @@ HEADERS += \
|
||||
$$PWD/static.h \
|
||||
$$PWD/startup.h \
|
||||
$$PWD/requestmapper.h \
|
||||
$$PWD/controllers/comiccontroller.h \
|
||||
$$PWD/controllers/errorcontroller.h \
|
||||
$$PWD/controllers/foldercontroller.h \
|
||||
$$PWD/controllers/folderinfocontroller.h \
|
||||
$$PWD/controllers/librariescontroller.h \
|
||||
$$PWD/controllers/pagecontroller.h \
|
||||
$$PWD/controllers/sessionmanager.h \
|
||||
$$PWD/controllers/covercontroller.h \
|
||||
server/controllers/updatecomiccontroller.h \
|
||||
server/controllers/comicdownloadinfocontroller.h
|
||||
$$PWD/controllers/comiccontroller.h \
|
||||
$$PWD/controllers/errorcontroller.h \
|
||||
$$PWD/controllers/foldercontroller.h \
|
||||
$$PWD/controllers/folderinfocontroller.h \
|
||||
$$PWD/controllers/librariescontroller.h \
|
||||
$$PWD/controllers/pagecontroller.h \
|
||||
$$PWD/controllers/sessionmanager.h \
|
||||
$$PWD/controllers/covercontroller.h \
|
||||
$$PWD/controllers/updatecomiccontroller.h \
|
||||
$$PWD/controllers/comicdownloadinfocontroller.h \
|
||||
$$PWD/controllers/synccontroller.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/static.cpp \
|
||||
$$PWD/startup.cpp \
|
||||
$$PWD/requestmapper.cpp \
|
||||
$$PWD/controllers/comiccontroller.cpp \
|
||||
$$PWD/controllers/errorcontroller.cpp \
|
||||
$$PWD/controllers/foldercontroller.cpp \
|
||||
$$PWD/controllers/folderinfocontroller.cpp \
|
||||
$$PWD/controllers/librariescontroller.cpp \
|
||||
$$PWD/controllers/pagecontroller.cpp \
|
||||
$$PWD/controllers/sessionmanager.cpp \
|
||||
$$PWD/controllers/covercontroller.cpp \
|
||||
server/controllers/updatecomiccontroller.cpp \
|
||||
server/controllers/comicdownloadinfocontroller.cpp
|
||||
$$PWD/controllers/comiccontroller.cpp \
|
||||
$$PWD/controllers/errorcontroller.cpp \
|
||||
$$PWD/controllers/foldercontroller.cpp \
|
||||
$$PWD/controllers/folderinfocontroller.cpp \
|
||||
$$PWD/controllers/librariescontroller.cpp \
|
||||
$$PWD/controllers/pagecontroller.cpp \
|
||||
$$PWD/controllers/sessionmanager.cpp \
|
||||
$$PWD/controllers/covercontroller.cpp \
|
||||
$$PWD/controllers/updatecomiccontroller.cpp \
|
||||
$$PWD/controllers/comicdownloadinfocontroller.cpp \
|
||||
$$PWD/controllers/synccontroller.cpp
|
||||
|
||||
include(lib/bfLogging/bfLogging.pri)
|
||||
include(lib/bfHttpServer/bfHttpServer.pri)
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "comic.h"
|
||||
#include "comic.h"
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QRegExp>
|
||||
@ -18,9 +18,13 @@
|
||||
const QStringList Comic::imageExtensions = QStringList() << "*.jpg" << "*.jpeg" << "*.png" << "*.gif" << "*.tiff" << "*.tif" << "*.bmp" << "*.webp";
|
||||
const QStringList Comic::literalImageExtensions = QStringList() << "jpg" << "jpeg" << "png" << "gif" << "tiff" << "tif" << "bmp" << "webp";
|
||||
|
||||
#ifndef use_unarr
|
||||
const QStringList Comic::comicExtensions = QStringList() << "*.cbr" << "*.cbz" << "*.rar" << "*.zip" << "*.tar" << "*.pdf" << "*.7z" << "*.cb7" << "*.arj" << "*.cbt";
|
||||
const QStringList Comic::literalComicExtensions = QStringList() << "cbr" << "cbz" << "rar" << "zip" << "tar" << "pdf" << "7z" << "cb7" << "arj" << "cbt";
|
||||
|
||||
#else
|
||||
const QStringList Comic::comicExtensions = QStringList() << "*.cbr" << "*.cbz" << "*.rar" << "*.zip" << "*.tar" << "*.pdf" << "*.cbt";
|
||||
const QStringList Comic::literalComicExtensions = QStringList() << "cbr" << "cbz" << "rar" << "zip" << "tar" << "pdf" << "cbt";
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
Comic::Comic()
|
||||
:_pages(),_index(0),_path(),_loaded(false),bm(new Bookmarks()),_loadedPages(),_isPDF(false)
|
||||
@ -305,6 +309,7 @@ bool FileComic::load(const QString & path, const ComicDB & comic)
|
||||
else
|
||||
{
|
||||
//QMessageBox::critical(NULL,tr("Not found"),tr("Comic not found")+" : " + path);
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
emit errorOpening();
|
||||
return false;
|
||||
}
|
||||
@ -471,12 +476,14 @@ void FileComic::process()
|
||||
CompressedArchive archive(_path);
|
||||
if(!archive.toolsLoaded())
|
||||
{
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
emit errorOpening(tr("7z not found"));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!archive.isValid())
|
||||
{
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
emit errorOpening(tr("Format not supported"));
|
||||
return;
|
||||
}
|
||||
@ -488,6 +495,7 @@ void FileComic::process()
|
||||
if(_fileNames.size()==0)
|
||||
{
|
||||
//QMessageBox::critical(NULL,tr("File error"),tr("File not found or not images in file"));
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
emit errorOpening();
|
||||
return;
|
||||
}
|
||||
@ -507,6 +515,10 @@ void FileComic::process()
|
||||
|
||||
if(_firstPage == -1)
|
||||
_firstPage = bm->getLastPage();
|
||||
|
||||
if(_firstPage >= _pages.length())
|
||||
_firstPage = 0;
|
||||
|
||||
_index = _firstPage;
|
||||
emit(openAt(_index));
|
||||
|
||||
@ -527,9 +539,8 @@ void FileComic::process()
|
||||
emit imageLoaded(sortedIndex);
|
||||
emit imageLoaded(sortedIndex,_pages[sortedIndex]);
|
||||
}*/
|
||||
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
emit imagesLoaded();
|
||||
//moveToThread(QApplication::instance()->thread());
|
||||
}
|
||||
|
||||
|
||||
@ -587,6 +598,7 @@ void FolderComic::process()
|
||||
{
|
||||
//TODO emitir este mensaje en otro sitio
|
||||
//QMessageBox::critical(NULL,QObject::tr("No images found"),QObject::tr("There are not images on the selected folder"));
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
emit errorOpening();
|
||||
}
|
||||
else
|
||||
@ -594,6 +606,9 @@ void FolderComic::process()
|
||||
if(_firstPage == -1)
|
||||
_firstPage = bm->getLastPage();
|
||||
|
||||
if(_firstPage >= _pages.length())
|
||||
_firstPage = 0;
|
||||
|
||||
_index = _firstPage;
|
||||
|
||||
emit(openAt(_index));
|
||||
@ -617,8 +632,8 @@ void FolderComic::process()
|
||||
count++;
|
||||
}
|
||||
}
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
emit imagesLoaded();
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -660,6 +675,7 @@ bool PDFComic::load(const QString & path, int atPage)
|
||||
}
|
||||
else
|
||||
{
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
emit errorOpening();
|
||||
return false;
|
||||
}
|
||||
@ -682,6 +698,7 @@ bool PDFComic::load(const QString & path, const ComicDB & comic)
|
||||
else
|
||||
{
|
||||
//QMessageBox::critical(NULL,tr("Not found"),tr("Comic not found")+" : " + path);
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
emit errorOpening();
|
||||
return false;
|
||||
}
|
||||
@ -705,11 +722,13 @@ void PDFComic::process()
|
||||
{
|
||||
//delete pdfComic;
|
||||
//pdfComic = 0;
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
emit errorOpening();
|
||||
return;
|
||||
}
|
||||
if (pdfComic->isLocked())
|
||||
{
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
emit errorOpening();
|
||||
return;
|
||||
}
|
||||
@ -730,6 +749,10 @@ void PDFComic::process()
|
||||
|
||||
if(_firstPage == -1)
|
||||
_firstPage = bm->getLastPage();
|
||||
|
||||
if(_firstPage >= _pages.length())
|
||||
_firstPage = 0;
|
||||
|
||||
_index = _firstPage;
|
||||
emit(openAt(_index));
|
||||
|
||||
@ -741,8 +764,8 @@ void PDFComic::process()
|
||||
renderPage(i);
|
||||
|
||||
delete pdfComic;
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
emit imagesLoaded();
|
||||
moveToThread(QApplication::instance()->thread());
|
||||
}
|
||||
|
||||
void PDFComic::renderPage(int page)
|
||||
|
@ -355,7 +355,8 @@ void YACReaderFlowGL::paintGL()
|
||||
|
||||
void YACReaderFlowGL::resizeGL(int width, int height)
|
||||
{
|
||||
fontSize = (width + height) * 0.010;
|
||||
float pixelRatio = devicePixelRatio();
|
||||
fontSize = (width + height) * 0.010 * pixelRatio;
|
||||
if(fontSize < 10)
|
||||
fontSize = 10;
|
||||
|
||||
@ -368,12 +369,13 @@ void YACReaderFlowGL::resizeGL(int width, int height)
|
||||
|
||||
void YACReaderFlowGL::udpatePerspective(int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
float pixelRatio = devicePixelRatio();
|
||||
glViewport(0, 0, width*pixelRatio, height*pixelRatio);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
gluPerspective(20.0, GLdouble(width) / (float)height, 1.0, 200.0);
|
||||
gluPerspective(20.0, GLdouble(width) / (float)height, 1.0, 200.0);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
@ -384,7 +386,7 @@ void YACReaderFlowGL::calcPos(YACReader3DImage & image, int pos)
|
||||
{
|
||||
if(pos == 0){
|
||||
image.current = centerPos;
|
||||
}else{
|
||||
}else{
|
||||
if(pos > 0){
|
||||
image.current.x = (config.centerDistance)+(config.xDistance*pos);
|
||||
image.current.y = config.yDistance*pos*-1;
|
||||
@ -804,6 +806,8 @@ void YACReaderFlowGL::populate(int n)
|
||||
|
||||
void YACReaderFlowGL::reset()
|
||||
{
|
||||
makeCurrent();
|
||||
|
||||
startAnimationTimer();
|
||||
|
||||
currentSelected = 0;
|
||||
@ -819,6 +823,8 @@ void YACReaderFlowGL::reset()
|
||||
|
||||
if(!hasBeenInitialized)
|
||||
lazyPopulateObjects = -1;
|
||||
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
void YACReaderFlowGL::reload()
|
||||
@ -1101,8 +1107,9 @@ void YACReaderFlowGL::mousePressEvent(QMouseEvent *event)
|
||||
if(event->button() == Qt::LeftButton)
|
||||
{
|
||||
float x,y;
|
||||
x = event->x();
|
||||
y = event->y();
|
||||
float pixelRatio = devicePixelRatio();
|
||||
x = event->x()*pixelRatio;
|
||||
y = event->y()*pixelRatio;
|
||||
GLint viewport[4];
|
||||
GLdouble modelview[16];
|
||||
GLdouble projection[16];
|
||||
@ -1139,8 +1146,9 @@ void YACReaderFlowGL::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
{
|
||||
makeCurrent();
|
||||
float x,y;
|
||||
x = event->x();
|
||||
y = event->y();
|
||||
float pixelRatio = devicePixelRatio();
|
||||
x = event->x()*pixelRatio;
|
||||
y = event->y()*pixelRatio;
|
||||
GLint viewport[4];
|
||||
GLdouble modelview[16];
|
||||
GLdouble projection[16];
|
||||
@ -1269,6 +1277,8 @@ void YACReaderComicFlowGL::updateImageData()
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] indexes;
|
||||
}
|
||||
|
||||
void YACReaderComicFlowGL::remove(int item)
|
||||
@ -1405,6 +1415,8 @@ void YACReaderPageFlowGL::updateImageData()
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] indexes;
|
||||
}
|
||||
|
||||
void YACReaderPageFlowGL::populate(int n)
|
||||
|
@ -238,10 +238,10 @@ YACReaderFlowGL::YACReaderFlowGL(QWidget *parent,struct Preset p)
|
||||
|
||||
loaderThread->start();*/
|
||||
|
||||
QGLFormat f = format();
|
||||
/*QGLFormat f = format();
|
||||
f.setVersion(2, 1);
|
||||
f.setSwapInterval(0);
|
||||
setFormat(f);
|
||||
f.setSwapInterval(0);
|
||||
setFormat(f);*/
|
||||
|
||||
timerId = startTimer(updateInterval);
|
||||
|
||||
@ -325,8 +325,8 @@ void YACReaderFlowGL::paintGL()
|
||||
|
||||
void YACReaderFlowGL::resizeGL(int width, int height)
|
||||
{
|
||||
|
||||
fontSize = (width + height) * 0.010;
|
||||
float pixelRatio = devicePixelRatio();
|
||||
fontSize = (width + height) * 0.010 * pixelRatio;
|
||||
if(fontSize < 10)
|
||||
fontSize = 10;
|
||||
|
||||
@ -339,7 +339,8 @@ void YACReaderFlowGL::resizeGL(int width, int height)
|
||||
|
||||
void YACReaderFlowGL::udpatePerspective(int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
float pixelRatio = devicePixelRatio();
|
||||
glViewport(0, 0, width*pixelRatio, height*pixelRatio);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
@ -938,26 +939,25 @@ void YACReaderFlowGL::setPerformance(Performance performance)
|
||||
}
|
||||
|
||||
void YACReaderFlowGL::useVSync(bool b)
|
||||
{
|
||||
if(bUseVSync != b)
|
||||
{/*if(bUseVSync != b)
|
||||
{
|
||||
bUseVSync = b;
|
||||
if(b)
|
||||
{
|
||||
QGLFormat f = format();
|
||||
f.setVersion(2, 1);
|
||||
//f.setVersion(2, 1);
|
||||
f.setSwapInterval(1);
|
||||
setFormat(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
QGLFormat f = format();
|
||||
f.setVersion(2, 1);
|
||||
//f.setVersion(2, 1);
|
||||
f.setSwapInterval(0);
|
||||
setFormat(f);
|
||||
}
|
||||
reset();
|
||||
}
|
||||
reset();
|
||||
}*/
|
||||
}
|
||||
void YACReaderFlowGL::setShowMarks(bool value)
|
||||
{
|
||||
@ -1079,8 +1079,9 @@ void YACReaderFlowGL::mousePressEvent(QMouseEvent *event)
|
||||
if(event->button() == Qt::LeftButton)
|
||||
{
|
||||
float x,y;
|
||||
x = event->x();
|
||||
y = event->y();
|
||||
float pixelRatio = devicePixelRatio();
|
||||
x = event->x()*pixelRatio;
|
||||
y = event->y()*pixelRatio;
|
||||
GLint viewport[4];
|
||||
GLdouble modelview[16];
|
||||
GLdouble projection[16];
|
||||
@ -1114,8 +1115,9 @@ void YACReaderFlowGL::mousePressEvent(QMouseEvent *event)
|
||||
void YACReaderFlowGL::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
{
|
||||
float x,y;
|
||||
x = event->x();
|
||||
y = event->y();
|
||||
float pixelRatio = devicePixelRatio();
|
||||
x = event->x()*pixelRatio;
|
||||
y = event->y()*pixelRatio;
|
||||
GLint viewport[4];
|
||||
GLdouble modelview[16];
|
||||
GLdouble projection[16];
|
||||
@ -1243,6 +1245,7 @@ void YACReaderComicFlowGL::updateImageData()
|
||||
return;
|
||||
}
|
||||
}
|
||||
delete[] indexes;
|
||||
}
|
||||
|
||||
void YACReaderComicFlowGL::remove(int item)
|
||||
@ -1369,6 +1372,7 @@ void YACReaderPageFlowGL::updateImageData()
|
||||
return;
|
||||
}
|
||||
}
|
||||
delete[] indexes;
|
||||
}
|
||||
|
||||
void YACReaderPageFlowGL::populate(int n)
|
||||
|
69
common/opengl_checker.cpp
Normal file
69
common/opengl_checker.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include "opengl_checker.h"
|
||||
|
||||
#include "QsLog.h"
|
||||
|
||||
OpenGLChecker::OpenGLChecker()
|
||||
:compatibleOpenGLVersion(true)
|
||||
{
|
||||
QOpenGLContext * openGLContext = new QOpenGLContext();
|
||||
openGLContext->create();
|
||||
|
||||
if(!openGLContext->isValid())
|
||||
{
|
||||
compatibleOpenGLVersion = false;
|
||||
description = "unable to create QOpenGLContext";
|
||||
}
|
||||
|
||||
QSurfaceFormat format = openGLContext->format();
|
||||
|
||||
int majorVersion = format.majorVersion();
|
||||
int minorVersion = format.minorVersion();
|
||||
QString type;
|
||||
|
||||
switch (format.renderableType()) {
|
||||
case QSurfaceFormat::OpenGL:
|
||||
type = "desktop";
|
||||
break;
|
||||
|
||||
case QSurfaceFormat::OpenGLES:
|
||||
type = "OpenGL ES";
|
||||
break;
|
||||
|
||||
case QSurfaceFormat::OpenVG:
|
||||
type = "OpenVG";
|
||||
|
||||
default: case QSurfaceFormat::DefaultRenderableType:
|
||||
type = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
delete openGLContext;
|
||||
|
||||
description = QString("%1.%2 %3").arg(majorVersion).arg(minorVersion).arg(type);
|
||||
|
||||
if(format.renderableType() != QSurfaceFormat::OpenGL) //Desktop OpenGL
|
||||
compatibleOpenGLVersion = false;
|
||||
|
||||
#ifdef Q_OS_WIN //TODO check Qt version, and set this values depending on the use of QOpenGLWidget or QGLWidget
|
||||
static const int majorTargetVersion = 1;
|
||||
static const int minorTargetVersion = 4;
|
||||
#else
|
||||
static const int majorTargetVersion = 2;
|
||||
static const int minorTargetVersion = 0;
|
||||
#endif
|
||||
|
||||
if(majorVersion < majorTargetVersion)
|
||||
compatibleOpenGLVersion = false;
|
||||
if(majorVersion == majorTargetVersion && minorVersion < minorTargetVersion)
|
||||
compatibleOpenGLVersion = false;
|
||||
}
|
||||
|
||||
QString OpenGLChecker::textVersionDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
bool OpenGLChecker::hasCompatibleOpenGLVersion()
|
||||
{
|
||||
return compatibleOpenGLVersion;
|
||||
}
|
17
common/opengl_checker.h
Normal file
17
common/opengl_checker.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef OPENGL_CHECKER_H
|
||||
#define OPENGL_CHECKER_H
|
||||
|
||||
#include <QOpenGLContext>
|
||||
|
||||
class OpenGLChecker
|
||||
{
|
||||
public:
|
||||
OpenGLChecker();
|
||||
bool hasCompatibleOpenGLVersion();
|
||||
QString textVersionDescription();
|
||||
private:
|
||||
QString description;
|
||||
bool compatibleOpenGLVersion;
|
||||
};
|
||||
|
||||
#endif // OPENGL_CHECKER_H
|
@ -5,14 +5,14 @@ fi
|
||||
|
||||
echo "Compiling YACReader"
|
||||
cd ./YACReader
|
||||
/Users/luisangel/Qt/5.4/clang_64/bin/qmake -spec macx-clang "CONFIG+=release"
|
||||
/Users/luisangel/my_dev/Qt5.5.0/5.5/clang_64/bin/qmake -spec macx-clang "CONFIG+=release"
|
||||
#qmake -spec macx-g++ "CONFIG+=release"
|
||||
make
|
||||
cd ..
|
||||
|
||||
echo "Compiling YACReaderLibrary"
|
||||
cd ./YACReaderLibrary
|
||||
/Users/luisangel/Qt/5.4/clang_64/bin/qmake -spec macx-clang "CONFIG+=release"
|
||||
/Users/luisangel/my_dev/Qt5.5.0/5.5/clang_64/bin/qmake -spec macx-clang "CONFIG+=release"
|
||||
#qmake -spec macx-g++ "CONFIG+=release"
|
||||
make
|
||||
cd ..
|
||||
|
@ -1,7 +1,13 @@
|
||||
If you are trying to compile YACReader, you need to donwload de source code of 7zip (Windows) or p7zip (Linux/MacOSX).
|
||||
If you are trying to compile YACReader with a 7zip decompression backend, you need to download de source code of 7zip (Windows) or p7zip (Linux/MacOSX).
|
||||
|
||||
Please, extract it and rename the folder to lib7zip (Windows) or libp7zip (Linux/MacOSX), then copy it to $YACREADER_SRC/compressed_archive/ (this
|
||||
folder). If you are using a 64 bit Linux-System, please apply libp7zip.patch for successfull compilation or use compileX11.sh.
|
||||
Please extract it and rename the folder to lib7zip (Windows) or libp7zip (Linux/MacOSX), then copy it to $YACREADER_SRC/compressed_archive/ (this
|
||||
folder).
|
||||
|
||||
YACReader is compiled using 7zip/p7zip 9.20.1
|
||||
YACReader is compiled using 7zip/p7zip 9.20.1 and will not work with newer versions.
|
||||
|
||||
On Linux/Unix this means your YACReader installation will stop working if you update your installation of p7zip to a newer version. If you wish to keep using
|
||||
p7zip with YACReader, you can copy 7z.so and Codecs/Rar29.so from p7zip 9.20.1 to "/usr/lib/yacreader/". YACReader will then detect these files and use
|
||||
them instead of the system provided p7zip files which allows you to keep both YACReader and an up to date p7zip installation.
|
||||
|
||||
Please keep in mind this is only a workaround that is provided for backwards compatibility and not intended as a long time solution.
|
||||
It is recommended that you switch to unarr as a decompression backend instead (see README.txt in compressed_archive/unarr).
|
@ -18,7 +18,9 @@ DEFINE_GUID(CLSID_CFormatRar, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00,
|
||||
DEFINE_GUID(CLSID_CFormatZip, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0x01, 0x00, 0x00);
|
||||
DEFINE_GUID(CLSID_CFormatTar, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0xee, 0x00, 0x00);
|
||||
DEFINE_GUID(CLSID_CFormatArj, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0x04, 0x00, 0x00);
|
||||
DEFINE_GUID(CLSID_CFormatBZip2, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00);
|
||||
|
||||
//unused Formats
|
||||
/*DEFINE_GUID(CLSID_CFormatBZip2, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00);
|
||||
DEFINE_GUID(CLSID_CFormatCab, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0x00);
|
||||
DEFINE_GUID(CLSID_CFormatChm, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0xe9, 0x00, 0x00);
|
||||
DEFINE_GUID(CLSID_CFormatCompound,0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0xe5, 0x00, 0x00);
|
||||
@ -32,7 +34,7 @@ DEFINE_GUID(CLSID_CFormatNsis, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00,
|
||||
DEFINE_GUID(CLSID_CFormatRpm, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0xeb, 0x00, 0x00);
|
||||
DEFINE_GUID(CLSID_CFormatSplit, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0xea, 0x00, 0x00);
|
||||
DEFINE_GUID(CLSID_CFormatWim, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0xe6, 0x00, 0x00);
|
||||
DEFINE_GUID(CLSID_CFormatZ, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
|
||||
DEFINE_GUID(CLSID_CFormatZ, 0x23170f69, 0x40c1, 0x278a, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);*/
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
GUID _supportedFileFormats[] = {CLSID_CFormatRar,CLSID_CFormatZip,CLSID_CFormatTar,CLSID_CFormat7z,CLSID_CFormatArj};
|
||||
@ -71,6 +73,13 @@ struct SevenZipInterface {
|
||||
|
||||
//SevenZipInterface * szInterface;
|
||||
|
||||
const char rar[7]={static_cast<char>(0x52), static_cast<char>(0x61), static_cast<char>(0x72), static_cast<char>(0x21), static_cast<char>(0x1A), static_cast<char>(0x07), static_cast<char>(0x00)};
|
||||
const char rar5[8]={static_cast<char>(0x52), static_cast<char>(0x61), static_cast<char>(0x72), static_cast<char>(0x21), static_cast<char>(0x1A), static_cast<char>(0x07), static_cast<char>(0x01), static_cast<char>(0x00)};
|
||||
const char zip[2]={static_cast<char>(0x50), static_cast<char>(0x4B)};
|
||||
const char sevenz[6]={static_cast<char>(0x37), static_cast<char>(0x7A), static_cast<char>(0xBC), static_cast<char>(0xAF), static_cast<char>(0x27), static_cast<char>(0x1C)};
|
||||
const char tar[6]="ustar";
|
||||
const char arj[2]={static_cast<char>(0x60), static_cast<char>(0xEA)};
|
||||
|
||||
CompressedArchive::CompressedArchive(const QString & filePath, QObject *parent) :
|
||||
QObject(parent),sevenzLib(0),valid(false),tools(false)
|
||||
#ifdef Q_OS_UNIX
|
||||
@ -98,62 +107,144 @@ CompressedArchive::CompressedArchive(const QString & filePath, QObject *parent)
|
||||
// openCallbackSpec->PasswordIsDefined = true;
|
||||
// openCallbackSpec->Password = L"1";
|
||||
|
||||
for(unsigned int i=0;i<supportedFileFormats.size();i++)
|
||||
//get file type from suffix
|
||||
int i=-1;
|
||||
QFile filex(filePath);
|
||||
|
||||
if (!filex.open(QIODevice::ReadOnly))
|
||||
return;
|
||||
QByteArray magicNumber=filex.read(8); //read first 8 bytes
|
||||
|
||||
//if (memcmp(magicNumber,rar5,8)==0)
|
||||
//return; //rar5 is not supported
|
||||
//qDebug() << memcmp(magicNumber,rar,7);
|
||||
//TODO: this suffix matching is rather primitive - better approach?
|
||||
#ifdef Q_OS_UNIX
|
||||
if (memcmp(magicNumber,rar,6) != 0)
|
||||
{
|
||||
//match suffix to GUID list
|
||||
if (memcmp(magicNumber,zip,2)==0)
|
||||
i=0;
|
||||
else if (memcmp(magicNumber,sevenz,6)==0)
|
||||
i=2;
|
||||
else if (memcmp(magicNumber,arj,2)==0)
|
||||
i=3;
|
||||
else
|
||||
{
|
||||
filex.seek(257);
|
||||
magicNumber=filex.read(8);
|
||||
if (memcmp(magicNumber,tar,5)==0)
|
||||
i=1;
|
||||
}
|
||||
if (i==-1) //fallback code
|
||||
{
|
||||
QFileInfo fileinfo(filePath);
|
||||
if (fileinfo.suffix() == "zip" || fileinfo.suffix() == "cbz")
|
||||
{
|
||||
i=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (memcmp(magicNumber,rar,6) == 0)
|
||||
if (memcmp(magicNumber,rar5,7) == 0)
|
||||
return;
|
||||
else
|
||||
i=0;
|
||||
else if (memcmp(magicNumber,zip,2)==0)
|
||||
i=1;
|
||||
else if (memcmp(magicNumber,sevenz,6)==0)
|
||||
i=3;
|
||||
else if (memcmp(magicNumber,arj,2)==0)
|
||||
i=4;
|
||||
else {
|
||||
filex.seek(257);
|
||||
magicNumber=filex.read(8);
|
||||
if (memcmp(magicNumber,tar,5)==0)
|
||||
i=2;
|
||||
}
|
||||
if (i==-1) //fallback code
|
||||
{
|
||||
QFileInfo fileinfo(filePath);
|
||||
if (fileinfo.suffix() == "zip" || fileinfo.suffix() == "cbz")
|
||||
{
|
||||
i=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UNICODE
|
||||
if (!fileSpec->Open((LPCTSTR)filePath.toStdWString().c_str()))
|
||||
#else
|
||||
if (!fileSpec->Open((LPCTSTR)filePath.toStdString().c_str()))
|
||||
#endif
|
||||
{
|
||||
qDebug() << "unable to load" + filePath;
|
||||
return;
|
||||
}
|
||||
|
||||
//GUID uuid = supportedFileFormats[i];
|
||||
//qDebug() << "trying : " << uuid << endl;
|
||||
if (szInterface->createObjectFunc(&supportedFileFormats[i], &IID_InArchive, (void **)&szInterface->archive) != S_OK)
|
||||
{
|
||||
qDebug() << "wrong format";
|
||||
continue;
|
||||
}
|
||||
#ifdef UNICODE
|
||||
if (!fileSpec->Open((LPCTSTR)filePath.toStdWString().c_str()))
|
||||
#else
|
||||
if (!fileSpec->Open((LPCTSTR)filePath.toStdString().c_str()))
|
||||
#endif
|
||||
{
|
||||
qDebug() << "unable to load" + filePath;
|
||||
continue;
|
||||
}
|
||||
//qDebug() << "Can not open archive file : " + filePath << endl;
|
||||
if (szInterface->createObjectFunc(&supportedFileFormats[i], &IID_InArchive, (void **)&szInterface->archive) == S_OK)
|
||||
{
|
||||
//qDebug() << "Can not open archive file : " + filePath << endl;
|
||||
|
||||
if (szInterface->archive->Open(file, 0, openCallback) == S_OK)
|
||||
{
|
||||
valid = formatFound = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
qDebug() << "Can not open archive file : " + filePath << endl;
|
||||
{
|
||||
valid = formatFound = true;
|
||||
qDebug() << "Opened archive file : " + filePath << endl;
|
||||
setupFilesNames();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(!formatFound)
|
||||
{
|
||||
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if(!formatFound)
|
||||
{
|
||||
qDebug() << "Can not open archive" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (memcmp(magicNumber,rar5,7) == 0)
|
||||
return;//we don't support rar5
|
||||
|
||||
isRar=true; //tell the destructor we *tried* to open a rar file!
|
||||
if (szInterface->createObjectFunc(&CLSID_CFormatRar, &IID_InArchive, (void **)&szInterface->archive) != S_OK)
|
||||
{
|
||||
qDebug() << "Error creating rar archive :" + filePath;
|
||||
return;
|
||||
}
|
||||
|
||||
CMyComPtr<ISetCompressCodecsInfo> codecsInfo;
|
||||
CMyComPtr<ISetCompressCodecsInfo> codecsInfo;
|
||||
|
||||
if (szInterface->archive->QueryInterface(IID_ISetCompressCodecsInfo,(void **)&codecsInfo) != S_OK)
|
||||
{
|
||||
qDebug() << "Error getting rar codec :" + filePath;
|
||||
return;
|
||||
}
|
||||
|
||||
if (codecsInfo->SetCompressCodecsInfo(this) != S_OK)
|
||||
{
|
||||
qDebug() << "Error setting rar codec";
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef UNICODE
|
||||
if (!fileSpec->Open((LPCTSTR)filePath.toStdWString().data()))
|
||||
if (!fileSpec->Open((LPCTSTR)filePath.toStdWString().c_str()))
|
||||
#else
|
||||
if (!fileSpec->Open((LPCTSTR)filePath.toStdString().data()))
|
||||
if (!fileSpec->Open((LPCTSTR)filePath.toStdString().c_str()))
|
||||
#endif
|
||||
{
|
||||
qDebug() << "Error opening rar file :" + filePath;
|
||||
@ -164,25 +255,31 @@ CompressedArchive::CompressedArchive(const QString & filePath, QObject *parent)
|
||||
if (szInterface->archive->Open(file, 0, openCallback) == S_OK)
|
||||
{
|
||||
valid = formatFound = true;
|
||||
isRar = true;
|
||||
setupFilesNames();
|
||||
//isRar = true;
|
||||
}
|
||||
else
|
||||
qDebug() << "Error opening rar archive";
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
CompressedArchive::~CompressedArchive()
|
||||
{
|
||||
//always close the archive!
|
||||
if (szInterface->archive)
|
||||
{
|
||||
szInterface->archive->Close();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
if(isRar) //TODO: fix this!!! Possible memory leak. If AddRef is not used, a crash occurs in "delete szInterface"
|
||||
if(isRar) //TODO: Memory leak!!!! If AddRef is not used, a crash occurs in "delete szInterface"
|
||||
{
|
||||
szInterface->archive->AddRef();
|
||||
}
|
||||
#endif
|
||||
if(valid) //TODO: fix this!!! Memory leak.
|
||||
delete szInterface;
|
||||
delete szInterface;
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
delete rarLib;
|
||||
#endif
|
||||
@ -191,27 +288,27 @@ CompressedArchive::~CompressedArchive()
|
||||
|
||||
bool CompressedArchive::loadFunctions()
|
||||
{
|
||||
//LOAD library
|
||||
//TODO check if this works in OSX (7z.so instead of 7z.dylib)
|
||||
// fix1: try to load "7z.so"
|
||||
// fix2: rename 7z.so to 7z.dylib
|
||||
if(sevenzLib == 0)
|
||||
//LOAD library
|
||||
//TODO check if this works in OSX (7z.so instead of 7z.dylib)
|
||||
// fix1: try to load "7z.so"
|
||||
// fix2: rename 7z.so to 7z.dylib
|
||||
if(sevenzLib == 0)
|
||||
{
|
||||
#if defined Q_OS_UNIX
|
||||
#if defined Q_OS_MAC
|
||||
#if defined Q_OS_MAC
|
||||
rarLib = new QLibrary(QCoreApplication::applicationDirPath()+"/utils/Codecs/Rar29");
|
||||
#else
|
||||
//check if a yacreader specific version of p7zip exists on the system
|
||||
QFileInfo rarCodec(QString(LIBDIR)+"/yacreader/Codecs/Rar29.so");
|
||||
if (rarCodec.exists())
|
||||
{
|
||||
rarLib = new QLibrary(rarCodec.absoluteFilePath());
|
||||
}
|
||||
else
|
||||
{
|
||||
rarLib = new QLibrary(QString(LIBDIR)+"/p7zip/Codecs/Rar29.so");
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
//check if a yacreader specific version of p7zip exists on the system
|
||||
QFileInfo rarCodec(QString(LIBDIR)+"/yacreader/Codecs/Rar29.so");
|
||||
if (rarCodec.exists())
|
||||
{
|
||||
rarLib = new QLibrary(rarCodec.absoluteFilePath());
|
||||
}
|
||||
else
|
||||
{
|
||||
rarLib = new QLibrary(QString(LIBDIR)+"/p7zip/Codecs/Rar29.so");
|
||||
}
|
||||
#endif
|
||||
if(!rarLib->load())
|
||||
{
|
||||
qDebug() << "Error Loading Rar29.so : " + rarLib->errorString() << endl;
|
||||
@ -220,43 +317,43 @@ bool CompressedArchive::loadFunctions()
|
||||
}
|
||||
#endif
|
||||
#if defined Q_OS_UNIX && !defined Q_OS_MAC
|
||||
QFileInfo sevenzlibrary(QString(LIBDIR)+"/yacreader/7z.so");
|
||||
if (sevenzlibrary.exists())
|
||||
{
|
||||
sevenzLib = new QLibrary(sevenzlibrary.absoluteFilePath());
|
||||
}
|
||||
else
|
||||
{
|
||||
sevenzLib = new QLibrary(QString(LIBDIR)+"/p7zip/7z.so");
|
||||
}
|
||||
QFileInfo sevenzlibrary(QString(LIBDIR)+"/yacreader/7z.so");
|
||||
if (sevenzlibrary.exists())
|
||||
{
|
||||
sevenzLib = new QLibrary(sevenzlibrary.absoluteFilePath());
|
||||
}
|
||||
else
|
||||
{
|
||||
sevenzLib = new QLibrary(QString(LIBDIR)+"/p7zip/7z.so");
|
||||
}
|
||||
#else
|
||||
sevenzLib = new QLibrary(QCoreApplication::applicationDirPath()+"/utils/7z");
|
||||
#endif
|
||||
}
|
||||
if(!sevenzLib->load())
|
||||
{
|
||||
if(!sevenzLib->load())
|
||||
{
|
||||
qDebug() << "Error Loading 7z.dll : " + sevenzLib->errorString() << endl;
|
||||
QCoreApplication::exit(700); //TODO yacreader_global can't be used here, it is GUI dependant, YACReader::SevenZNotFound
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Loading functions" << endl;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Loading functions" << endl;
|
||||
|
||||
if((szInterface->createObjectFunc = (CreateObjectFunc)sevenzLib->resolve("CreateObject")) == 0)
|
||||
qDebug() << "fail loading function : CreateObject" << endl;
|
||||
if((szInterface->getMethodPropertyFunc = (GetMethodPropertyFunc)sevenzLib->resolve("GetMethodProperty")) == 0)
|
||||
qDebug() << "fail loading function : GetMethodProperty" << endl;
|
||||
if((szInterface->getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)sevenzLib->resolve("GetNumberOfMethods")) == 0)
|
||||
qDebug() << "fail loading function : GetNumberOfMethods" << endl;
|
||||
if((szInterface->getNumberOfFormatsFunc = (GetNumberOfFormatsFunc)sevenzLib->resolve("GetNumberOfFormats")) == 0)
|
||||
qDebug() << "fail loading function : GetNumberOfFormats" << endl;
|
||||
if((szInterface->getHandlerPropertyFunc = (GetHandlerPropertyFunc)sevenzLib->resolve("GetHandlerProperty")) == 0)
|
||||
qDebug() << "fail loading function : GetHandlerProperty" << endl;
|
||||
if((szInterface->getHandlerPropertyFunc2 = (GetHandlerPropertyFunc2)sevenzLib->resolve("GetHandlerProperty2")) == 0)
|
||||
qDebug() << "fail loading function : GetHandlerProperty2" << endl;
|
||||
if((szInterface->setLargePageModeFunc = (SetLargePageModeFunc)sevenzLib->resolve("SetLargePageMode")) == 0)
|
||||
qDebug() << "fail loading function : SetLargePageMode" << endl;
|
||||
if((szInterface->createObjectFunc = (CreateObjectFunc)sevenzLib->resolve("CreateObject")) == 0)
|
||||
qDebug() << "fail loading function : CreateObject" << endl;
|
||||
if((szInterface->getMethodPropertyFunc = (GetMethodPropertyFunc)sevenzLib->resolve("GetMethodProperty")) == 0)
|
||||
qDebug() << "fail loading function : GetMethodProperty" << endl;
|
||||
if((szInterface->getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)sevenzLib->resolve("GetNumberOfMethods")) == 0)
|
||||
qDebug() << "fail loading function : GetNumberOfMethods" << endl;
|
||||
if((szInterface->getNumberOfFormatsFunc = (GetNumberOfFormatsFunc)sevenzLib->resolve("GetNumberOfFormats")) == 0)
|
||||
qDebug() << "fail loading function : GetNumberOfFormats" << endl;
|
||||
if((szInterface->getHandlerPropertyFunc = (GetHandlerPropertyFunc)sevenzLib->resolve("GetHandlerProperty")) == 0)
|
||||
qDebug() << "fail loading function : GetHandlerProperty" << endl;
|
||||
if((szInterface->getHandlerPropertyFunc2 = (GetHandlerPropertyFunc2)sevenzLib->resolve("GetHandlerProperty2")) == 0)
|
||||
qDebug() << "fail loading function : GetHandlerProperty2" << endl;
|
||||
if((szInterface->setLargePageModeFunc = (SetLargePageModeFunc)sevenzLib->resolve("SetLargePageMode")) == 0)
|
||||
qDebug() << "fail loading function : SetLargePageMode" << endl;
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
if((szInterface->createObjectFuncRar = (CreateObjectFunc)rarLib->resolve("CreateObject")) == 0)
|
||||
@ -266,95 +363,127 @@ bool CompressedArchive::loadFunctions()
|
||||
if((szInterface->getNumberOfMethodsFuncRar = (GetNumberOfMethodsFunc)rarLib->resolve("GetNumberOfMethods")) == 0)
|
||||
qDebug() << "fail loading function (rar) : GetNumberOfMethods" << endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CompressedArchive::setupFilesNames()
|
||||
{
|
||||
quint32 numItems = getNumEntries();
|
||||
quint32 p = 0;
|
||||
for (quint32 i = 0; i < numItems; i++)
|
||||
{
|
||||
|
||||
// Get name of file
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
szInterface->archive->GetProperty(i, kpidIsDir, &prop);
|
||||
bool isDir;
|
||||
if (prop.vt == VT_BOOL)
|
||||
isDir = VARIANT_BOOLToBool(prop.boolVal);
|
||||
else if (prop.vt == VT_EMPTY)
|
||||
isDir = false;
|
||||
|
||||
if(!isDir)
|
||||
{
|
||||
szInterface->archive->GetProperty(i, kpidPath, &prop);
|
||||
UString s = ConvertPropVariantToString(prop);
|
||||
const wchar_t * chars = s.operator const wchar_t *();
|
||||
files.append(QString::fromWCharArray(chars));
|
||||
offsets.append(i);
|
||||
indexesToPages.insert(i,p);
|
||||
p++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
QVector<quint32> CompressedArchive::translateIndexes(const QVector<quint32> & indexes)
|
||||
{
|
||||
QVector<quint32> translatedIndexes;
|
||||
|
||||
foreach(quint32 i, indexes)
|
||||
{
|
||||
if(i < offsets.length())
|
||||
translatedIndexes.append(offsets.at(i));
|
||||
}
|
||||
|
||||
return translatedIndexes;
|
||||
}
|
||||
|
||||
QList<QString> CompressedArchive::getFileNames()
|
||||
{
|
||||
QList<QString> files;
|
||||
quint32 numItems = getNumFiles();
|
||||
for (quint32 i = 0; i < numItems; i++)
|
||||
{
|
||||
{
|
||||
// Get name of file
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
/*szInterface->archive->GetProperty(i, kpidIsDir, &prop);
|
||||
bool isDir;
|
||||
if (prop.vt == VT_BOOL)
|
||||
isDir = VARIANT_BOOLToBool(prop.boolVal);
|
||||
else if (prop.vt == VT_EMPTY)
|
||||
isDir = false;
|
||||
|
||||
if(!isDir)
|
||||
{*/
|
||||
szInterface->archive->GetProperty(i, kpidPath, &prop);
|
||||
UString s = ConvertPropVariantToString(prop);
|
||||
const wchar_t * chars = s.operator const wchar_t *();
|
||||
files.append(QString::fromWCharArray(chars));
|
||||
//}
|
||||
}
|
||||
}
|
||||
return files;
|
||||
return files;
|
||||
}
|
||||
|
||||
bool CompressedArchive::isValid()
|
||||
{
|
||||
return valid;
|
||||
return valid;
|
||||
}
|
||||
|
||||
bool CompressedArchive::toolsLoaded()
|
||||
{
|
||||
return tools;
|
||||
return tools;
|
||||
}
|
||||
|
||||
int CompressedArchive::getNumFiles()
|
||||
{
|
||||
quint32 numItems = 0;
|
||||
szInterface->archive->GetNumberOfItems(&numItems);
|
||||
return numItems;
|
||||
return files.length();
|
||||
}
|
||||
|
||||
int CompressedArchive::getNumEntries()
|
||||
{
|
||||
quint32 numItems = 0;
|
||||
szInterface->archive->GetNumberOfItems(&numItems);
|
||||
return numItems;
|
||||
}
|
||||
|
||||
QList<QByteArray> CompressedArchive::getAllData(const QVector<quint32> & indexes, ExtractDelegate * delegate)
|
||||
{
|
||||
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback(true,delegate);
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
|
||||
extractCallbackSpec->Init(szInterface->archive, L""); // second parameter is output folder path
|
||||
extractCallbackSpec->PasswordIsDefined = false;
|
||||
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback(indexesToPages, true, delegate);
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
|
||||
extractCallbackSpec->Init(szInterface->archive, L""); // second parameter is output folder path
|
||||
extractCallbackSpec->PasswordIsDefined = false;
|
||||
|
||||
HRESULT result;
|
||||
if(indexes.isEmpty())
|
||||
result = szInterface->archive->Extract(NULL, -1, false, extractCallback);
|
||||
else
|
||||
result = szInterface->archive->Extract(indexes.data(), indexes.count(), false, extractCallback);
|
||||
if (result != S_OK)
|
||||
{
|
||||
qDebug() << "Extract Error" << endl;
|
||||
}
|
||||
QVector<quint32> currentIndexes = translateIndexes(indexes);
|
||||
|
||||
return extractCallbackSpec->allFiles;
|
||||
HRESULT result;
|
||||
if(indexes.isEmpty())
|
||||
result = szInterface->archive->Extract(NULL, -1, false, extractCallback);
|
||||
else
|
||||
result = szInterface->archive->Extract(currentIndexes.data(), currentIndexes.count(), false, extractCallback);
|
||||
if (result != S_OK)
|
||||
{
|
||||
qDebug() << "Extract Error" << endl;
|
||||
}
|
||||
|
||||
return extractCallbackSpec->allFiles;
|
||||
}
|
||||
|
||||
QByteArray CompressedArchive::getRawDataAtIndex(int index)
|
||||
{
|
||||
if(index>=0 && index < getNumFiles())
|
||||
{
|
||||
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
|
||||
extractCallbackSpec->Init(szInterface->archive, L""); // second parameter is output folder path
|
||||
extractCallbackSpec->PasswordIsDefined = false;
|
||||
if(index>=0 && index < getNumFiles())
|
||||
{
|
||||
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback(indexesToPages);
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
|
||||
extractCallbackSpec->Init(szInterface->archive, L""); // second parameter is output folder path
|
||||
extractCallbackSpec->PasswordIsDefined = false;
|
||||
|
||||
UInt32 indices[1];
|
||||
indices[0] = index;
|
||||
HRESULT result = szInterface->archive->Extract(indices, 1, false, extractCallback);
|
||||
if (result != S_OK)
|
||||
{
|
||||
qDebug() << "Extract Error" << endl;
|
||||
}
|
||||
UInt32 indices[1];
|
||||
|
||||
return QByteArray((char *)extractCallbackSpec->data,extractCallbackSpec->newFileSize);
|
||||
}
|
||||
if(index < offsets.length())
|
||||
indices[0] = offsets.at(index);
|
||||
else
|
||||
indices[0] = index;
|
||||
|
||||
HRESULT result = szInterface->archive->Extract(indices, 1, false, extractCallback);
|
||||
if (result != S_OK)
|
||||
{
|
||||
qDebug() << "Extract Error" << endl;
|
||||
}
|
||||
|
||||
return QByteArray((char *)extractCallbackSpec->data,extractCallbackSpec->newFileSize);
|
||||
}
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
@ -384,5 +513,3 @@ STDMETHODIMP CompressedArchive::CreateEncoder(UInt32 index, const GUID *interfac
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -28,6 +28,7 @@ typedef quint32 (_MY_WINAPI *SetLargePageModeFunc)();
|
||||
class QLibrary;
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
|
||||
struct SevenZipInterface;
|
||||
|
||||
@ -59,6 +60,7 @@ signals:
|
||||
|
||||
public slots:
|
||||
int getNumFiles();
|
||||
int getNumEntries();
|
||||
QList<QByteArray> getAllData(const QVector<quint32> & indexes, ExtractDelegate * delegate = 0);
|
||||
QByteArray getRawDataAtIndex(int index);
|
||||
QList<QString> getFileNames();
|
||||
@ -66,6 +68,7 @@ public slots:
|
||||
bool toolsLoaded();
|
||||
private:
|
||||
SevenZipInterface * szInterface;
|
||||
|
||||
QLibrary * sevenzLib;
|
||||
#ifdef Q_OS_UNIX
|
||||
QLibrary * rarLib;
|
||||
@ -73,6 +76,12 @@ private:
|
||||
bool loadFunctions();
|
||||
bool tools;
|
||||
bool valid;
|
||||
QList<QString> files;
|
||||
QList<qint32> offsets;
|
||||
QMap<qint32, qint32> indexesToPages;
|
||||
|
||||
void setupFilesNames();
|
||||
QVector<quint32> translateIndexes(const QVector<quint32> &indexes);
|
||||
|
||||
friend class MyCodecs;
|
||||
};
|
||||
|
@ -90,8 +90,9 @@ public:
|
||||
UString Password;
|
||||
Byte * data;
|
||||
UInt64 newFileSize;
|
||||
QMap<qint32, qint32> indexesToPages;
|
||||
|
||||
CArchiveExtractCallback(bool c = false,ExtractDelegate * d = 0) : PasswordIsDefined(false),all(c),delegate(d) {}
|
||||
CArchiveExtractCallback(const QMap<qint32, qint32> & indexesToPages ,bool c = false,ExtractDelegate * d = 0) : PasswordIsDefined(false),all(c),delegate(d),indexesToPages(indexesToPages) {}
|
||||
~CArchiveExtractCallback() {MidFree(data);}
|
||||
};
|
||||
|
||||
@ -117,7 +118,11 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
|
||||
{
|
||||
*outStream = 0;
|
||||
_outFileStream.Release();
|
||||
_index = index;
|
||||
|
||||
if(indexesToPages.isEmpty())
|
||||
_index = index;
|
||||
else
|
||||
_index = indexesToPages.value(index);
|
||||
|
||||
{
|
||||
// Get Name
|
||||
|
6
compressed_archive/unarr/README.txt
Normal file
6
compressed_archive/unarr/README.txt
Normal file
@ -0,0 +1,6 @@
|
||||
To use unarr as a decompression engine when building YACReader, download https://github.com/zeniko/unarr/archive/master.zip and extract it in this folder.
|
||||
This will build unarr as a part of YACReader (static build).
|
||||
|
||||
If you're on a Linux/Unix system and prefer to use unarr as a shared library, have a look at https://github.com/selmf/unarr/
|
||||
This fork of unarr includes a CMake based build system that allows you to build and install unarr as a shared library. YACReader will detect and use
|
||||
the installed library at build time if it is installed.
|
127
compressed_archive/unarr/compressed_archive.cpp
Normal file
127
compressed_archive/unarr/compressed_archive.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
#include "compressed_archive.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QDebug>
|
||||
|
||||
#include "extract_delegate.h"
|
||||
|
||||
extern"C" {
|
||||
#include "unarr.h"
|
||||
}
|
||||
|
||||
CompressedArchive::CompressedArchive(const QString & filePath, QObject *parent) :
|
||||
QObject(parent),valid(false),tools(true),numFiles(0),ar(NULL),stream(NULL)
|
||||
{
|
||||
//open file
|
||||
stream = ar_open_file(filePath.toStdString().c_str());
|
||||
if (!stream)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//open archive
|
||||
ar = ar_open_rar_archive(stream);
|
||||
//TODO: build unarr with 7z support and test this!
|
||||
//if (!ar) ar = ar_open_7z_archive(stream);
|
||||
if (!ar) ar = ar_open_tar_archive(stream);
|
||||
//zip detection is costly, so it comes last...
|
||||
if (!ar) ar = ar_open_zip_archive(stream, false);
|
||||
if (!ar)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//initial parse
|
||||
while (ar_parse_entry(ar))
|
||||
{
|
||||
//make sure we really got a file header
|
||||
if (ar_entry_get_size(ar) > 0)
|
||||
{
|
||||
fileNames.append(ar_entry_get_name(ar));
|
||||
offsets.append(ar_entry_get_offset(ar));
|
||||
numFiles++;
|
||||
}
|
||||
}
|
||||
if (!ar_at_eof(ar))
|
||||
{
|
||||
//fail if the initial parse didn't reach EOF
|
||||
//this might be a bit too drastic
|
||||
qDebug() << "Error while parsing archive";
|
||||
return;
|
||||
}
|
||||
if (numFiles > 0)
|
||||
{
|
||||
valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
CompressedArchive::~CompressedArchive()
|
||||
{
|
||||
ar_close_archive(ar);
|
||||
ar_close(stream);
|
||||
}
|
||||
|
||||
QList<QString> CompressedArchive::getFileNames()
|
||||
{
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
bool CompressedArchive::isValid()
|
||||
{
|
||||
return valid;
|
||||
}
|
||||
|
||||
bool CompressedArchive::toolsLoaded()
|
||||
{
|
||||
//for backwards compatibilty
|
||||
return tools;
|
||||
}
|
||||
|
||||
int CompressedArchive::getNumFiles()
|
||||
{
|
||||
return numFiles;
|
||||
}
|
||||
|
||||
void CompressedArchive::getAllData(const QVector<quint32> & indexes, ExtractDelegate * delegate)
|
||||
{
|
||||
if (indexes.isEmpty())
|
||||
return;
|
||||
|
||||
QByteArray buffer;
|
||||
|
||||
int i=0;
|
||||
while (i < indexes.count())
|
||||
{
|
||||
//use the offset list so we generated so we're not getting any non-page files
|
||||
ar_parse_entry_at(ar, offsets.at(indexes.at(i))); //set ar_entry to start of indexes
|
||||
buffer.resize(ar_entry_get_size(ar));
|
||||
if (ar_entry_uncompress(ar, buffer.data(), buffer.size())) //did we extract it?
|
||||
{
|
||||
delegate->fileExtracted(indexes.at(i), buffer); //return extracted file
|
||||
}
|
||||
else
|
||||
{
|
||||
delegate->crcError(indexes.at(i)); //we could not extract it...
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray CompressedArchive::getRawDataAtIndex(int index)
|
||||
{
|
||||
QByteArray buffer;
|
||||
if(index >= 0 && index < getNumFiles())
|
||||
{
|
||||
ar_parse_entry_at(ar, offsets.at(index));
|
||||
buffer.resize(ar_entry_get_size(ar));
|
||||
if(ar_entry_uncompress(ar, buffer.data(), buffer.size()))
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
return QByteArray();
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
37
compressed_archive/unarr/compressed_archive.h
Normal file
37
compressed_archive/unarr/compressed_archive.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef COMPRESSED_ARCHIVE_H
|
||||
#define COMPRESSED_ARCHIVE_H
|
||||
|
||||
#include <QObject>
|
||||
#include "extract_delegate.h"
|
||||
extern"C" {
|
||||
#include "unarr.h"
|
||||
}
|
||||
|
||||
class CompressedArchive : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CompressedArchive(const QString & filePath, QObject *parent = 0);
|
||||
~CompressedArchive();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
int getNumFiles();
|
||||
void getAllData(const QVector<quint32> & indexes, ExtractDelegate * delegate=0);
|
||||
QByteArray getRawDataAtIndex(int index);
|
||||
QList<QString> getFileNames();
|
||||
bool isValid();
|
||||
bool toolsLoaded();
|
||||
private:
|
||||
|
||||
bool tools;
|
||||
bool valid;
|
||||
QList<QString> fileNames;
|
||||
int numFiles;
|
||||
ar_archive *ar;
|
||||
ar_stream *stream;
|
||||
QList<qint64> offsets;
|
||||
};
|
||||
|
||||
#endif // COMPRESSED_ARCHIVE_H
|
14
compressed_archive/unarr/extract_delegate.h
Normal file
14
compressed_archive/unarr/extract_delegate.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef EXTRACT_DELEGATE_H
|
||||
#define EXTRACT_DELEGATE_H
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
class ExtractDelegate
|
||||
{
|
||||
public:
|
||||
virtual void fileExtracted(int index, const QByteArray & rawData) = 0;
|
||||
virtual void crcError(int index) = 0;
|
||||
virtual void unknownError(int index) = 0;
|
||||
};
|
||||
|
||||
#endif //EXTRACT_DELEGATE_H
|
36
compressed_archive/unarr/unarr-wrapper.pri
Normal file
36
compressed_archive/unarr/unarr-wrapper.pri
Normal file
@ -0,0 +1,36 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
DEPENDPATH += $$PWD
|
||||
|
||||
HEADERS += $$PWD/extract_delegate.h \
|
||||
$$PWD/compressed_archive.h \
|
||||
|
||||
SOURCES += $$PWD/compressed_archive.cpp \
|
||||
|
||||
unix:!macx:exists (/usr/include/unarr.h) {
|
||||
message(Using system provided unarr installation)
|
||||
LIBS+=-lunarr
|
||||
DEFINES+=use_unarr
|
||||
}
|
||||
else:macx:exists (../../dependencies/unarr/libunarr.dynlib) {
|
||||
LIBS += -L../../dependencies/unarr/ -lunarr
|
||||
DEFINES+=use_unarr
|
||||
}
|
||||
|
||||
else:win32:exists (../../dependencies/unarr/unarr.dll) {
|
||||
LIBS += -L../../dependencies/unarr/ -lunarr
|
||||
DEFINES+=use_unarr
|
||||
}
|
||||
|
||||
else:exists ($$PWD/unarr-master) {
|
||||
message(Found unarr source-code)
|
||||
message(Unarr will be build as a part of YACReader)
|
||||
|
||||
#qmake based unarr build system
|
||||
#this should only be used for testing or as a last resort
|
||||
include(unarr.pro)
|
||||
DEFINES+=use_unarr
|
||||
}
|
||||
else {
|
||||
error(Missing dependency: unarr decrompression backend. Please install libunarr on your system\
|
||||
or provide a copy of the unarr source code in compressed_archive/unarr/unarr-master)
|
||||
}
|
51
compressed_archive/unarr/unarr.pro
Normal file
51
compressed_archive/unarr/unarr.pro
Normal file
@ -0,0 +1,51 @@
|
||||
INCLUDEPATH += $$PWD/unarr-master/
|
||||
DEPENDPATH += $$PWD/unarr-master/
|
||||
|
||||
HEADERS+=$$PWD/unarr-master/common/allocator.h\
|
||||
$$PWD/unarr-master/common/unarr-imp.h\
|
||||
$$PWD/unarr-master/lzmasdk/CpuArch.h\
|
||||
$$PWD/unarr-master/lzmasdk/Ppmd7.h\
|
||||
$$PWD/unarr-master/lzmasdk/Ppmd.h\
|
||||
$$PWD/unarr-master/lzmasdk/LzmaDec.h\
|
||||
$$PWD/unarr-master/lzmasdk/Ppmd8.h\
|
||||
$$PWD/unarr-master/lzmasdk/Types.h\
|
||||
$$PWD/unarr-master/lzmasdk/CpuArch.h\
|
||||
$$PWD/unarr-master/lzmasdk/Ppmd7.h\
|
||||
$$PWD/unarr-master/lzmasdk/Ppmd.h\
|
||||
$$PWD/unarr-master/lzmasdk/LzmaDec.h\
|
||||
$$PWD/unarr-master/lzmasdk/Ppmd8.h\
|
||||
$$PWD/unarr-master/lzmasdk/Types.h\
|
||||
$$PWD/unarr-master/lzmasdk/CpuArch.h\
|
||||
$$PWD/unarr-master/lzmasdk/Ppmd7.h\
|
||||
$$PWD/unarr-master/lzmasdk/Ppmd.h\
|
||||
$$PWD/unarr-master/lzmasdk/LzmaDec.h\
|
||||
$$PWD/unarr-master/lzmasdk/Ppmd8.h\
|
||||
$$PWD/unarr-master/lzmasdk/Types.h\
|
||||
$$PWD/unarr-master/tar/tar.h\
|
||||
$$PWD/unarr-master/_7z/_7z.h\
|
||||
$$PWD/unarr-master/unarr.h
|
||||
|
||||
SOURCES+=$$PWD/unarr-master/common/conv.c\
|
||||
$$PWD/unarr-master/common/custalloc.c\
|
||||
$$PWD/unarr-master/common/unarr.c\
|
||||
$$PWD/unarr-master/common/crc32.c\
|
||||
$$PWD/unarr-master/common/stream.c\
|
||||
$$PWD/unarr-master/lzmasdk/CpuArch.c\
|
||||
$$PWD/unarr-master/lzmasdk/Ppmd7.c\
|
||||
$$PWD/unarr-master/lzmasdk/Ppmd8.c\
|
||||
$$PWD/unarr-master/lzmasdk/LzmaDec.c\
|
||||
$$PWD/unarr-master/lzmasdk/Ppmd7Dec.c\
|
||||
$$PWD/unarr-master/lzmasdk/Ppmd8Dec.c\
|
||||
$$PWD/unarr-master/zip/inflate.c\
|
||||
$$PWD/unarr-master/zip/parse-zip.c\
|
||||
$$PWD/unarr-master/zip/uncompress-zip.c\
|
||||
$$PWD/unarr-master/zip/zip.c\
|
||||
$$PWD/unarr-master/rar/filter-rar.c\
|
||||
$$PWD/unarr-master/rar/parse-rar.c\
|
||||
$$PWD/unarr-master/rar/rarvm.c\
|
||||
$$PWD/unarr-master/rar/huffman-rar.c\
|
||||
$$PWD/unarr-master/rar/rar.c\
|
||||
$$PWD/unarr-master/rar/uncompress-rar.c\
|
||||
$$PWD/unarr-master/tar/parse-tar.c\
|
||||
$$PWD/unarr-master/tar/tar.c\
|
||||
$$PWD/unarr-master/_7z/_7z.c
|
@ -1,6 +1,23 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
DEPENDPATH += $$PWD
|
||||
|
||||
win32 {
|
||||
!exists (../compressed_archive/lib7zip) {
|
||||
error(You\'ll need 7zip source code to compile YACReader. \
|
||||
Please check the compressed_archive folder for further instructions.)
|
||||
}
|
||||
}
|
||||
|
||||
unix {
|
||||
exists (../compressed_archive/libp7zip) {
|
||||
message(Found p7zip source code...)
|
||||
system(patch -N -p0 -i libp7zip.patch)
|
||||
} else {
|
||||
error(You\'ll need 7zip source code to compile YACReader. \
|
||||
Please check the compressed_archive folder for further instructions.)
|
||||
}
|
||||
}
|
||||
|
||||
CONFIG += precompile_header
|
||||
|
||||
win32 {PRECOMPILED_HEADER = $$PWD/StdAfx.h}
|
||||
|
40
config.pri
Normal file
40
config.pri
Normal file
@ -0,0 +1,40 @@
|
||||
#functions to automatically initialize some of YACReader's build options to
|
||||
#default values if they're not set on build time
|
||||
#for a more detailed description, see INSTALL.TXT
|
||||
|
||||
#check Qt version
|
||||
QT_VERSION = $$[QT_VERSION]
|
||||
QT_VERSION = $$split(QT_VERSION, ".")
|
||||
QT_VER_MAJ = $$member(QT_VERSION, 0)
|
||||
QT_VER_MIN = $$member(QT_VERSION, 1)
|
||||
|
||||
lessThan(QT_VER_MAJ, 5) {
|
||||
error(YACReader requires Qt 5 or newer but Qt $$[QT_VERSION] was detected.)
|
||||
}
|
||||
lessThan(QT_VER_MIN, 4):!CONFIG(no_opengl) {
|
||||
CONFIG += legacy_gl_widget
|
||||
message ("Qt < 5.4 detected. Using QGLWidget for coverflow.")
|
||||
}
|
||||
lessThan(QT_VER_MIN, 3){
|
||||
error ("You need at least Qt 5.3 to build YACReader or YACReaderLibrary")
|
||||
}
|
||||
|
||||
#build without opengl widget support
|
||||
CONFIG(no_opengl) {
|
||||
DEFINES += NO_OPENGL
|
||||
}
|
||||
|
||||
!CONFIG(unarr):!CONFIG(7zip) {
|
||||
unix {
|
||||
!macx {
|
||||
CONFIG+=unarr
|
||||
}
|
||||
else {
|
||||
CONFIG+=7zip
|
||||
}
|
||||
|
||||
}
|
||||
win32 {
|
||||
CONFIG+=7zip
|
||||
}
|
||||
}
|
@ -175,7 +175,7 @@ YACReaderMacOSXToolbar::YACReaderMacOSXToolbar(QObject *parent)
|
||||
{
|
||||
yosemite = true;
|
||||
//TODO yosemite new constants are not found in compilation time
|
||||
[nswindow setTitleVisibility:1]; //NSWindowTitleHidden
|
||||
[nswindow setTitleVisibility:NSWindowTitleHidden];
|
||||
//TODO NSFullSizeContentViewWindowMask produces an offset in the windows' content
|
||||
//nswindow.styleMask |= 1 << 15; // NSFullSizeContentViewWindowMask;
|
||||
[nativeToolBar setSizeMode:NSToolbarSizeModeSmall]; //TODO figure out how to load specific images in Yosemite
|
||||
@ -215,7 +215,7 @@ void YACReaderMacOSXToolbar::addSpace(int size)
|
||||
QMacToolBarItem *toolBarItem = addItem(QIcon(),"");
|
||||
NSToolbarItem * nativeItem = toolBarItem->nativeToolBarItem();
|
||||
|
||||
static const NSRect frameRect = { { 0.0, 0.0 }, { size, 16.0 } };
|
||||
static const NSRect frameRect = { { 0.0, 0.0 }, { CGFloat(size), 16.0 } };
|
||||
NSView *view = [[NSView alloc] initWithFrame:frameRect];
|
||||
|
||||
[nativeItem setView:view];
|
||||
|
@ -46,6 +46,9 @@ YACReaderOptionsDialog::YACReaderOptionsDialog(QWidget * parent)
|
||||
#ifndef NO_OPENGL
|
||||
useGL = new QCheckBox(tr("Use hardware acceleration (restart needed)"));
|
||||
connect(useGL,SIGNAL(stateChanged(int)),this,SLOT(saveUseGL(int)));
|
||||
#endif
|
||||
#ifdef FORCE_ANGLE
|
||||
useGL->setHidden(true);
|
||||
#endif
|
||||
//sw CONNECTIONS
|
||||
connect(sw->radio1,SIGNAL(toggled(bool)),this,SLOT(setClassicConfigSW()));
|
||||
|
@ -85,9 +85,9 @@ YACReaderTitledToolBar::YACReaderTitledToolBar(const QString & title, QWidget *p
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum);
|
||||
setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum);
|
||||
|
||||
setMinimumHeight(25);
|
||||
setMinimumHeight(25);
|
||||
}
|
||||
|
||||
|
||||
@ -97,9 +97,9 @@ void YACReaderTitledToolBar::addAction(QAction * action)
|
||||
|
||||
QToolButton * tb = new QToolButton(this);
|
||||
tb->setCursor(QCursor(Qt::ArrowCursor));
|
||||
tb->setDefaultAction(action);
|
||||
tb->setIconSize(QSize(16,16));
|
||||
tb->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
|
||||
tb->setDefaultAction(action);
|
||||
tb->setIconSize(QSize(16,16));
|
||||
tb->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
|
||||
//tb->setStyleSheet("QToolButton:hover {background-color:#C5C5C5;}");
|
||||
|
||||
mainLayout->addWidget(tb);
|
||||
|
@ -4,10 +4,10 @@
|
||||
#include <QWidget>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
class QToolBarStretch : public QWidget
|
||||
class YACReaderToolBarStretch : public QWidget
|
||||
{
|
||||
public:
|
||||
QToolBarStretch(QWidget * parent=0):QWidget(parent)
|
||||
YACReaderToolBarStretch(QWidget * parent=0):QWidget(parent)
|
||||
{
|
||||
QHBoxLayout * l= new QHBoxLayout();
|
||||
l->addStretch();
|
||||
|
@ -2,7 +2,7 @@
|
||||
#Script to create a source tarball for YACReader distribution and packaging
|
||||
#This should be run from YACReaders top source directory
|
||||
|
||||
YACVERSION=7.2.0
|
||||
YACVERSION=8.0
|
||||
if [ -f Makefile ]
|
||||
then
|
||||
make distclean
|
||||
@ -17,6 +17,6 @@ fi
|
||||
#Use tar's --exclude feature to make sure we get a pristine tar for distribution.
|
||||
#Exclude all version control system related files and rename the top directory in the tarball using --transform.
|
||||
tar cfJ yacreader-${YACVERSION}-src.tar.xz --exclude '*.rej' --exclude '*.orig' --exclude '*.gch' --exclude 'dependencies' --exclude '*.o' \
|
||||
--exclude 'yacreader*tar*' --exclude '.hg*' --exclude 'lib7zip' --exclude 'libp7zip' --exclude-vcs ./* --transform s/./yacreader-${YACVERSION}/
|
||||
--exclude 'yacreader*tar*' --exclude '.hg*' --exclude 'lib7zip' --exclude 'libp7zip' --exclude 'unarr-master' --exclude-vcs ./* --transform s/./yacreader-${YACVERSION}/
|
||||
#Calculate checksum to enable packagers to verify whether they are using the original tarball.
|
||||
md5sum yacreader-${YACVERSION}-src.tar.xz > yacreader-${YACVERSION}-src.tar.xz.md5sum
|
@ -5,7 +5,7 @@ body{
|
||||
|
||||
/* libraries */
|
||||
#contentLibraries{
|
||||
width: 300px;
|
||||
width: 400px;
|
||||
border: 1px solid #C6C6C6;
|
||||
background-color: white;
|
||||
margin-left: auto;
|
||||
@ -36,7 +36,7 @@ body{
|
||||
|
||||
#contentLibraries .library-link
|
||||
{
|
||||
width: 211px;
|
||||
width: 311px;
|
||||
height: 28px;
|
||||
border: none;
|
||||
padding: 11px 0 0 0px;
|
||||
@ -47,6 +47,7 @@ body{
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
color: #525252 ;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#contentLibraries a
|
||||
|
@ -5,11 +5,10 @@ body{
|
||||
|
||||
/* libraries */
|
||||
#contentLibraries{
|
||||
width: 300px;
|
||||
border: 1px solid #C6C6C6;
|
||||
background-color: white;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
margin-top: 9px;
|
||||
}
|
||||
|
||||
@ -36,7 +35,7 @@ body{
|
||||
|
||||
#contentLibraries .library-link
|
||||
{
|
||||
width: 211px;
|
||||
width: 65%;
|
||||
height: 28px;
|
||||
border: none;
|
||||
padding: 11px 0 0 0px;
|
||||
@ -47,6 +46,7 @@ body{
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
color: #525252 ;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#contentLibraries a
|
||||
@ -62,7 +62,7 @@ body{
|
||||
|
||||
#contentLibraries .library-indicator
|
||||
{
|
||||
float: left;
|
||||
float: right;
|
||||
background-color: white;
|
||||
height: 8px;
|
||||
padding: 16px 16px 15px 16px;
|
||||
@ -181,10 +181,10 @@ body{
|
||||
|
||||
#itemContainer li
|
||||
{
|
||||
width: 300px;
|
||||
|
||||
height: 120px;
|
||||
border: 1px solid #E2E2E2;
|
||||
margin: 9px auto 0px auto;
|
||||
margin: 9px 10px 0px 10px;
|
||||
background-color: white;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
@ -218,22 +218,22 @@ overflow: hidden;
|
||||
.info
|
||||
{
|
||||
padding: 8px 0px 0px 0px;
|
||||
float: left;
|
||||
|
||||
position: relative;
|
||||
height: 115px;
|
||||
width: 212px;
|
||||
|
||||
padding-left: 82px;
|
||||
}
|
||||
|
||||
.buttons
|
||||
{
|
||||
position:absolute;
|
||||
bottom:0px;
|
||||
left:0px;
|
||||
left:80px;
|
||||
right: 0px;
|
||||
border-top: 1px solid #e2e2e2;
|
||||
padding-top: 3px;
|
||||
height: 25px;
|
||||
width: 220px;
|
||||
font-family: Arial;
|
||||
color: #6e6e6e;
|
||||
font-size: 10px;
|
||||
@ -245,7 +245,7 @@ width: 212px;
|
||||
bottom:24px;
|
||||
padding-top: 3px;
|
||||
height: 25px;
|
||||
width: 220px;
|
||||
width: 100%;
|
||||
font-family: Arial;
|
||||
color: #adadad;
|
||||
font-size: 10px;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
/Users/luisangel/Qt/5.4/clang_64/bin/macdeployqt YACReader.app
|
||||
/Users/luisangel/Qt/5.4/clang_64/bin/macdeployqt YACReaderLibrary.app -qmldir=./YACReaderLibrary/qml
|
||||
/Users/luisangel/my_dev/Qt5.5.0/5.5/clang_64/bin/macdeployqt YACReader.app
|
||||
/Users/luisangel/my_dev/Qt5.5.0/5.5/clang_64/bin/macdeployqt YACReaderLibrary.app -qmldir=./YACReaderLibrary/qml
|
||||
|
||||
#macdeployqt YACReader.app
|
||||
#macdeployqt YACReaderLibrary.app
|
||||
|
23
tests/compressed_archive_test/compressed_archive_test.pro
Normal file
23
tests/compressed_archive_test/compressed_archive_test.pro
Normal file
@ -0,0 +1,23 @@
|
||||
TEMPLATE = app
|
||||
CONFIG += console
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
|
||||
QT += core
|
||||
|
||||
win32 {
|
||||
LIBS += -loleaut32 -lole32
|
||||
QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT
|
||||
QMAKE_LFLAGS_RELEASE += /LTCG
|
||||
CONFIG -= embed_manifest_exe
|
||||
}
|
||||
|
||||
!CONFIG(unarr){
|
||||
include(../../compressed_archive/wrapper.pri)
|
||||
} else {
|
||||
include(../../compressed_archive/unarr/unarr-wrapper.pri)
|
||||
}
|
||||
|
||||
|
||||
|
86
tests/compressed_archive_test/main.cpp
Normal file
86
tests/compressed_archive_test/main.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include "compressed_archive.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
//This program uses PROTOS Genome Test Suite c10-archive [0] for testing the CompressedArchive wrapper files support
|
||||
//It tests the following formats: RAR, ZIP, TAR
|
||||
//Arter downloading c10-archive-r1.iso, open it and full extract RAR_TAR.BZ2, ZIP_TAR.BZ2, TAR_TAR.BZ2 files into a folder
|
||||
//This program takes the path to that folder as an argument
|
||||
//
|
||||
// [0] https://www.ee.oulu.fi/research/ouspg/PROTOS_Test-Suite_c10-archive#Download
|
||||
//
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
{
|
||||
cout << "Usage: compressed_archive_test PATH" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//QCoreApplication app(argc, argv);
|
||||
|
||||
QString s(argv[1]);
|
||||
|
||||
QStringList supportedFormats;
|
||||
supportedFormats << "rar"<< "zip" << "tar";
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
quint32 totalFiles = 0;
|
||||
foreach (QString format, supportedFormats) {
|
||||
QDir rootDir(s);
|
||||
if(!rootDir.cd(format))
|
||||
{
|
||||
cout << "Folder for format '" << format.toStdString() << "' not found" << endl;
|
||||
continue;
|
||||
}
|
||||
rootDir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
|
||||
|
||||
QFileInfoList files = rootDir.entryInfoList();
|
||||
quint32 totalFormat = 0;
|
||||
quint32 errors = 0;
|
||||
quint64 init = timer.elapsed();
|
||||
|
||||
foreach(QFileInfo fileInfo, files)
|
||||
{
|
||||
totalFiles++;
|
||||
totalFormat++;
|
||||
CompressedArchive archive(fileInfo.filePath());
|
||||
if(!archive.isValid())
|
||||
errors++;
|
||||
else
|
||||
{
|
||||
int i = archive.getNumFiles();
|
||||
cerr << i;
|
||||
QList<QString> filenames = archive.getFileNames();
|
||||
if (!filenames.isEmpty())
|
||||
{
|
||||
cerr << archive.getFileNames().at(0).toStdString();
|
||||
}
|
||||
}
|
||||
}
|
||||
quint64 end = timer.elapsed();
|
||||
|
||||
|
||||
cout << "Format '" << format.toStdString() <<"'" << endl;
|
||||
cout << "Total files : " << totalFormat << endl;
|
||||
cout << "Errors : " << errors << endl;
|
||||
cout << "Elapsed time : " << (end - init) / 1000 <<"s" << endl;
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
cout << "Total time : " << timer.elapsed() / 1000 <<"s" <<endl;
|
||||
cout << endl;
|
||||
|
||||
//return app.exec();
|
||||
}
|
Reference in New Issue
Block a user