From 22b283cc3ddab128b9af9c800ea3dea0337e678c Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 19 Feb 2026 17:50:22 +0100 Subject: [PATCH 001/187] YACReader 10! --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb2249f47..1db2abc4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ Version counting is based on semantic versioning (Major.Feature.Patch) +## 10 (WIP) + ## 9.16.4 ### YACReaderLibrary From 2ec2defc8cf1252c99ce79a8bd7126b06cfce8fd Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Tue, 20 Jan 2026 09:03:56 +0100 Subject: [PATCH 002/187] Remove ANGLE support --- YACReader/YACReader.pro | 32 ++++----------------- YACReader/main.cpp | 4 --- YACReaderLibrary/YACReaderLibrary.pro | 32 ++++----------------- YACReaderLibrary/classic_comics_view.cpp | 1 - YACReaderLibrary/main.cpp | 4 --- custom_widgets/yacreader_options_dialog.cpp | 3 -- 6 files changed, 12 insertions(+), 64 deletions(-) diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro index d50940f8f..3eb06c233 100644 --- a/YACReader/YACReader.pro +++ b/YACReader/YACReader.pro @@ -12,22 +12,12 @@ DEFINES += YACREADER include (../config.pri) include (../dependencies/pdf_backend.pri) -CONFIG(force_angle) { - contains(QMAKE_TARGET.arch, x86_64) { - Release:DESTDIR = ../release64_angle - Debug:DESTDIR = ../debug64_angle - } else { - Release:DESTDIR = ../release_angle - Debug:DESTDIR = ../debug_angle - } +contains(QMAKE_TARGET.arch, x86_64) { + Release:DESTDIR = ../release64 + Debug:DESTDIR = ../debug64 } else { - contains(QMAKE_TARGET.arch, x86_64) { - Release:DESTDIR = ../release64 - Debug:DESTDIR = ../debug64 - } else { - Release:DESTDIR = ../release - Debug:DESTDIR = ../debug - } + Release:DESTDIR = ../release + Debug:DESTDIR = ../debug } SOURCES += main.cpp @@ -39,18 +29,8 @@ INCLUDEPATH += ../common \ 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 += -loleaut32 -lole32 -lshell32 -lopengl32 -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 += -loleaut32 -lole32 -lshell32 -lopengl32 -luser32 - } + LIBS += -loleaut32 -lole32 -lshell32 -lopengl32 -luser32 msvc { QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL diff --git a/YACReader/main.cpp b/YACReader/main.cpp index 39bbf3eb2..cc757ce7f 100644 --- a/YACReader/main.cpp +++ b/YACReader/main.cpp @@ -112,10 +112,6 @@ 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"); diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 2330a7825..4e552b409 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -20,18 +20,8 @@ include (../dependencies/pdf_backend.pri) INCLUDEPATH += ../common/gl -# there are two builds for Windows, Desktop OpenGL based and ANGLE OpenGL ES based win32 { - CONFIG(force_angle) { - message("using ANGLE") - LIBS += -loleaut32 -lole32 -lshell32 -lopengl32 -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 += -loleaut32 -lole32 -lshell32 -lopengl32 -luser32 - } + LIBS += -loleaut32 -lole32 -lshell32 -lopengl32 -luser32 msvc { QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL @@ -40,22 +30,12 @@ win32 { CONFIG -= embed_manifest_exe } -CONFIG(force_angle) { - contains(QMAKE_TARGET.arch, x86_64) { - Release:DESTDIR = ../release64_angle - Debug:DESTDIR = ../debug64_angle - } else { - Release:DESTDIR = ../release_angle - Debug:DESTDIR = ../debug_angle - } +contains(QMAKE_TARGET.arch, x86_64) { + Release:DESTDIR = ../release64 + Debug:DESTDIR = ../debug64 } else { - contains(QMAKE_TARGET.arch, x86_64) { - Release:DESTDIR = ../release64 - Debug:DESTDIR = ../debug64 - } else { - Release:DESTDIR = ../release - Debug:DESTDIR = ../debug - } + Release:DESTDIR = ../release + Debug:DESTDIR = ../debug } macx { diff --git a/YACReaderLibrary/classic_comics_view.cpp b/YACReaderLibrary/classic_comics_view.cpp index 66b602b9a..9368779d1 100644 --- a/YACReaderLibrary/classic_comics_view.cpp +++ b/YACReaderLibrary/classic_comics_view.cpp @@ -19,7 +19,6 @@ 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); diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index 0af94d5f1..5e703c2d2 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -146,10 +146,6 @@ 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"); app.setApplicationVersion(VERSION); diff --git a/custom_widgets/yacreader_options_dialog.cpp b/custom_widgets/yacreader_options_dialog.cpp index 8f6de9a80..6f5178cc1 100644 --- a/custom_widgets/yacreader_options_dialog.cpp +++ b/custom_widgets/yacreader_options_dialog.cpp @@ -45,9 +45,6 @@ YACReaderOptionsDialog::YACReaderOptionsDialog(QWidget *parent) #ifndef NO_OPENGL useGL = new QCheckBox(tr("Use hardware acceleration (restart needed)")); connect(useGL, &QCheckBox::stateChanged, this, &YACReaderOptionsDialog::saveUseGL); -#endif -#ifdef FORCE_ANGLE - useGL->setHidden(true); #endif // sw CONNECTIONS connect(sw->radio1, &QAbstractButton::toggled, this, &YACReaderOptionsDialog::setClassicConfigSW); From 91b8a31727b07465ec0bf52d36f628f2b7b71ded Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 15 Jan 2026 18:52:27 +0100 Subject: [PATCH 003/187] AI generated migration for a more modern OpenGL (3.3 + ES 3.0) approach that supports tinting --- common/gl/yacreader_flow_gl.cpp | 1008 +++++++++++++++++++++---------- common/gl/yacreader_flow_gl.h | 87 +-- common/opengl_checker.cpp | 30 +- 3 files changed, 749 insertions(+), 376 deletions(-) diff --git a/common/gl/yacreader_flow_gl.cpp b/common/gl/yacreader_flow_gl.cpp index 8c4998a1a..aba6dffbe 100644 --- a/common/gl/yacreader_flow_gl.cpp +++ b/common/gl/yacreader_flow_gl.cpp @@ -4,9 +4,18 @@ #include #include -/*** Animation Settings ***/ +// Structure for per-instance data +struct InstanceData { + QMatrix4x4 modelMatrix; + float leftUpShading; + float leftDownShading; + float rightUpShading; + float rightDownShading; + float opacity; + float padding[3]; // Align to 16 bytes +}; -/*** Position Configuration ***/ +/*** Preset Configurations ***/ int YACReaderFlowGL::updateInterval = 16; @@ -190,11 +199,10 @@ struct Preset pressetYACReaderFlowDownConfig = { }; /*Constructor*/ YACReaderFlowGL::YACReaderFlowGL(QWidget *parent, struct Preset p) - : QOpenGLWidget(/*QOpenGLWidget migration QGLFormat(QGL::SampleBuffers),*/ parent), numObjects(0), lazyPopulateObjects(-1), hasBeenInitialized(false), bUseVSync(false), flowRightToLeft(false) + : QOpenGLWidget(parent), numObjects(0), lazyPopulateObjects(-1), hasBeenInitialized(false), bUseVSync(false), flowRightToLeft(false) { updateCount = 0; config = p; - currentSelected = 0; centerPos.x = 0.f; @@ -202,37 +210,39 @@ YACReaderFlowGL::YACReaderFlowGL(QWidget *parent, struct Preset p) centerPos.z = 1.f; centerPos.rot = 0.f; - /*** Style ***/ shadingTop = 0.8f; shadingBottom = 0.02f; reflectionUp = 0.f; reflectionBottom = 0.6f; - /*** System variables ***/ + setBackgroundColor(Qt::black); + numObjects = 0; - // CFImage Dummy; viewRotate = 0.f; viewRotateActive = 0; stepBackup = config.animationStep / config.animationSpeedUp; - /*QTimer * timer = new QTimer(); - connect(timer, SIGNAL(timeout()), this, SLOT(updateImageData())); - timer->start(70); - */ - - /*loader = new WidgetLoader(0,this); - loader->flow = this; - QThread * loaderThread = new QThread(parent); - - loader->moveToThread(loaderThread); - - loaderThread->start();*/ - QSurfaceFormat f = format(); - f.setSamples(4); - f.setVersion(2, 1); f.setSwapInterval(0); + + // Detect if we should use OpenGL ES + // Check if app-level ES is forced (via Qt::AA_UseOpenGLES) + bool forceES = QCoreApplication::testAttribute(Qt::AA_UseOpenGLES); + + if (forceES) { + // Use OpenGL ES 3.0 + f.setRenderableType(QSurfaceFormat::OpenGLES); + f.setVersion(3, 0); + qDebug() << "YACReaderFlowGL: Requesting OpenGL ES 3.0 context"; + } else { + // Use Desktop OpenGL 3.3 Core + f.setRenderableType(QSurfaceFormat::OpenGL); + f.setVersion(3, 3); + f.setProfile(QSurfaceFormat::CoreProfile); + qDebug() << "YACReaderFlowGL: Requesting Desktop OpenGL 3.3 Core context"; + } + setFormat(f); timerId = startTimer(updateInterval); @@ -242,9 +252,6 @@ void YACReaderFlowGL::timerEvent(QTimerEvent *event) { if (timerId == event->timerId()) update(); - - // if(!worker->isRunning()) - // worker->start(); } void YACReaderFlowGL::startAnimationTimer() @@ -263,6 +270,34 @@ void YACReaderFlowGL::stopAnimationTimer() YACReaderFlowGL::~YACReaderFlowGL() { + makeCurrent(); + + delete vao; + delete vbo; + delete instanceVBO; + delete shaderProgram; + + if (defaultTexture) { + if (defaultTexture->isCreated()) + defaultTexture->destroy(); + delete defaultTexture; + } + +#ifdef YACREADER_LIBRARY + if (markTexture) { + if (markTexture->isCreated()) + markTexture->destroy(); + delete markTexture; + } + + if (readingTexture) { + if (readingTexture->isCreated()) + readingTexture->destroy(); + delete readingTexture; + } +#endif + + doneCurrent(); } QSize YACReaderFlowGL::minimumSizeHint() const @@ -270,20 +305,246 @@ QSize YACReaderFlowGL::minimumSizeHint() const return QSize(320, 200); } -/*QSize YACReaderFlowGL::sizeHint() const +void YACReaderFlowGL::setupShaders() { - return QSize(320, 200); -}*/ + bool isES = QOpenGLContext::currentContext()->isOpenGLES(); + + // Vertex Shader - Desktop GL 3.3 + const char *vertexShaderSourceGL = R"( + #version 330 core + layout(location = 0) in vec3 position; + layout(location = 1) in vec2 texCoord; + layout(location = 2) in mat4 instanceModel; + layout(location = 6) in vec4 instanceShading1; + layout(location = 7) in float instanceOpacity; + + out vec2 vTexCoord; + out vec4 vColor; + + uniform mat4 viewProjectionMatrix; + + void main() + { + gl_Position = viewProjectionMatrix * instanceModel * vec4(position, 1.0); + vTexCoord = texCoord; + + float leftUpShading = instanceShading1.x; + float leftDownShading = instanceShading1.y; + float rightUpShading = instanceShading1.z; + float rightDownShading = instanceShading1.w; + + float leftShading = mix(leftDownShading, leftUpShading, (position.y + 0.5)); + float rightShading = mix(rightDownShading, rightUpShading, (position.y + 0.5)); + float shading = mix(leftShading, rightShading, (position.x + 0.5)); + + vColor = vec4(shading * instanceOpacity); + } + )"; + + // Vertex Shader - OpenGL ES 3.0 + const char *vertexShaderSourceES = R"( + #version 300 es + precision highp float; + + layout(location = 0) in vec3 position; + layout(location = 1) in vec2 texCoord; + layout(location = 2) in mat4 instanceModel; + layout(location = 6) in vec4 instanceShading1; + layout(location = 7) in float instanceOpacity; + + out vec2 vTexCoord; + out vec4 vColor; + + uniform mat4 viewProjectionMatrix; + + void main() + { + gl_Position = viewProjectionMatrix * instanceModel * vec4(position, 1.0); + vTexCoord = texCoord; + + float leftUpShading = instanceShading1.x; + float leftDownShading = instanceShading1.y; + float rightUpShading = instanceShading1.z; + float rightDownShading = instanceShading1.w; + + float leftShading = mix(leftDownShading, leftUpShading, (position.y + 0.5)); + float rightShading = mix(rightDownShading, rightUpShading, (position.y + 0.5)); + float shading = mix(leftShading, rightShading, (position.x + 0.5)); + + vColor = vec4(shading * instanceOpacity); + } + )"; + + // Fragment Shader - Desktop GL 3.3 + const char *fragmentShaderSourceGL = R"( + #version 330 core + in vec2 vTexCoord; + in vec4 vColor; + + out vec4 fragColor; + + uniform sampler2D texture; + uniform bool isReflection; + uniform float reflectionUp; + uniform float reflectionDown; + uniform vec3 backgroundColor; + uniform vec3 shadingColor; + + void main() + { + vec2 texCoord = vTexCoord; + + if (isReflection) { + texCoord.y = 1.0 - vTexCoord.y; + vec4 texColor = texture2D(texture, texCoord); + float gradientFade = mix(1.0/3.0, reflectionUp / 2.0, vTexCoord.y); + float shadingAmount = vColor.r * gradientFade; + vec3 shadedColor = mix(backgroundColor, texColor.rgb, shadingAmount); + fragColor = vec4(shadedColor, texColor.a); + } else { + vec4 texColor = texture2D(texture, texCoord); + float shadingAmount = vColor.r; + vec3 shadedColor = mix(backgroundColor, texColor.rgb, shadingAmount); + fragColor = vec4(shadedColor, texColor.a); + } + } + )"; + + // Fragment Shader - OpenGL ES 3.0 + const char *fragmentShaderSourceES = R"( + #version 300 es + precision highp float; + + in vec2 vTexCoord; + in vec4 vColor; + + out vec4 fragColor; + + uniform sampler2D texture; + uniform bool isReflection; + uniform float reflectionUp; + uniform float reflectionDown; + uniform vec3 backgroundColor; + uniform vec3 shadingColor; + + void main() + { + vec2 texCoord = vTexCoord; + + if (isReflection) { + texCoord.y = 1.0 - vTexCoord.y; + vec4 texColor = texture(texture, texCoord); + float gradientFade = mix(1.0/3.0, reflectionUp / 2.0, vTexCoord.y); + float shadingAmount = vColor.r * gradientFade; + vec3 shadedColor = mix(backgroundColor, texColor.rgb, shadingAmount); + fragColor = vec4(shadedColor, texColor.a); + } else { + vec4 texColor = texture(texture, texCoord); + float shadingAmount = vColor.r; + vec3 shadedColor = mix(backgroundColor, texColor.rgb, shadingAmount); + fragColor = vec4(shadedColor, texColor.a); + } + } + )"; + + // Select shaders based on context type + const char *vertexShader = isES ? vertexShaderSourceES : vertexShaderSourceGL; + const char *fragmentShader = isES ? fragmentShaderSourceES : fragmentShaderSourceGL; + + qDebug() << "YACReaderFlowGL: Using" << (isES ? "OpenGL ES 3.0" : "Desktop OpenGL 3.3") << "shaders"; + + shaderProgram = new QOpenGLShaderProgram(this); + shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader); + shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader); + + if (!shaderProgram->link()) { + qWarning() << "YACReaderFlowGL: Shader linking failed:" << shaderProgram->log(); + } +} + +void YACReaderFlowGL::setupGeometry() +{ + // VAO for regular covers + vao = new QOpenGLVertexArrayObject(this); + vao->create(); + vao->bind(); + + vbo = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + vbo->create(); + vbo->bind(); + + // Quad vertices with texture coordinates + GLfloat vertices[] = { + // Position (x, y, z), TexCoord (u, v) + -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-left + 0.5f, -0.5f, 0.0f, 1.0f, 1.0f, // Bottom-right + 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right + -0.5f, 0.5f, 0.0f, 0.0f, 0.0f // Top-left + }; + + vbo->allocate(vertices, sizeof(vertices)); + + // Position attribute + shaderProgram->enableAttributeArray(0); + shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, 5 * sizeof(GLfloat)); + + // TexCoord attribute + shaderProgram->enableAttributeArray(1); + shaderProgram->setAttributeBuffer(1, GL_FLOAT, 3 * sizeof(GLfloat), 2, 5 * sizeof(GLfloat)); + + // Create instance buffer (will be filled per-frame) + instanceVBO = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + instanceVBO->create(); + instanceVBO->bind(); + + // Per-instance attributes (model matrix = 4 vec4s, shading = 1 vec4, opacity = 1 float) + // Location 2-5: model matrix (mat4) + for (int i = 0; i < 4; i++) { + shaderProgram->enableAttributeArray(2 + i); + shaderProgram->setAttributeBuffer(2 + i, GL_FLOAT, i * 4 * sizeof(GLfloat), 4, 21 * sizeof(GLfloat)); + glVertexAttribDivisor(2 + i, 1); // Advance once per instance + } + + // Location 6: shading vec4 (leftUp, leftDown, rightUp, rightDown) + shaderProgram->enableAttributeArray(6); + shaderProgram->setAttributeBuffer(6, GL_FLOAT, 16 * sizeof(GLfloat), 4, 21 * sizeof(GLfloat)); + glVertexAttribDivisor(6, 1); + + // Location 7: opacity float + shaderProgram->enableAttributeArray(7); + shaderProgram->setAttributeBuffer(7, GL_FLOAT, 20 * sizeof(GLfloat), 1, 21 * sizeof(GLfloat)); + glVertexAttribDivisor(7, 1); + + vao->release(); + instanceVBO->release(); + vbo->release(); +} void YACReaderFlowGL::initializeGL() { - glShadeModel(GL_SMOOTH); + if (!context() || !context()->isValid()) { + qWarning() << "YACReaderFlowGL: Invalid OpenGL context"; + return; + } + + initializeOpenGLFunctions(); + + // Verify instancing support (available in OpenGL 3.3+ and ES 3.0+) + bool hasInstancing = context()->hasExtension(QByteArrayLiteral("GL_ARB_instanced_arrays")) || + context()->format().majorVersion() >= 3; + + if (!hasInstancing) { + qWarning() << "YACReaderFlowGL: Instanced rendering not supported!"; + qWarning() << "YACReaderFlowGL: OpenGL version:" << context()->format().majorVersion() << "." << context()->format().minorVersion(); + return; + } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + setupShaders(); + setupGeometry(); defaultTexture = new QOpenGLTexture(QImage(":/images/defaultCover.png")); defaultTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear); + #ifdef YACREADER_LIBRARY markTexture = new QOpenGLTexture(QImage(":/images/readRibbon.png")); markTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear); @@ -291,6 +552,7 @@ void YACReaderFlowGL::initializeGL() readingTexture = new QOpenGLTexture(QImage(":/images/readingRibbon.png")); readingTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear); #endif + if (lazyPopulateObjects != -1) populate(lazyPopulateObjects); @@ -299,31 +561,30 @@ void YACReaderFlowGL::initializeGL() void YACReaderFlowGL::paintGL() { + if (!context() || !context()->isValid() || !shaderProgram) + return; + QPainter painter; painter.begin(this); - painter.beginNativePainting(); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); - glEnable(GL_COLOR_MATERIAL); glEnable(GL_BLEND); glEnable(GL_MULTISAMPLE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glClearColor(0, 0, 0, 1); + glClearColor(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF(), 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (numObjects > 0) { updatePositions(); - udpatePerspective(width(), height()); + updatePerspective(width(), height()); draw(); } glDisable(GL_MULTISAMPLE); glDisable(GL_BLEND); - glDisable(GL_COLOR_MATERIAL); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); @@ -333,8 +594,7 @@ void YACReaderFlowGL::paintGL() font.setFamily("Arial"); font.setPointSize(fontSize); painter.setFont(font); - - painter.setPen(QColor(76, 76, 76)); + painter.setPen(textColor); painter.drawText(10, fontSize + 10, QString("%1/%2").arg(currentSelected + 1).arg(numObjects)); painter.end(); @@ -342,32 +602,28 @@ void YACReaderFlowGL::paintGL() void YACReaderFlowGL::resizeGL(int width, int height) { + if (!context() || !context()->isValid()) + return; + fontSize = (width + height) * 0.010; if (fontSize < 10) fontSize = 10; - // int side = qMin(width, height); - udpatePerspective(width, height); + updatePerspective(width, height); if (numObjects > 0) updatePositions(); } -void YACReaderFlowGL::udpatePerspective(int width, int height) +void YACReaderFlowGL::updatePerspective(int width, int height) { + if (!context() || !context()->isValid()) + return; + float pixelRatio = devicePixelRatioF(); glViewport(0, 0, width * pixelRatio, height * pixelRatio); - - glMatrixMode(GL_PROJECTION); - QMatrix4x4 perspectiveMatrix; - perspectiveMatrix.setToIdentity(); - perspectiveMatrix.perspective(20.0, GLdouble(width) / (float)height, 1.0, 200.0); - glLoadMatrixf(perspectiveMatrix.constData()); - glMatrixMode(GL_MODELVIEW); } -//----------------------------------------------------------------------------- -/*Private*/ void YACReaderFlowGL::calcPos(YACReader3DImage &image, int pos) { if (flowRightToLeft) { @@ -390,10 +646,10 @@ void YACReaderFlowGL::calcPos(YACReader3DImage &image, int pos) } } } + void YACReaderFlowGL::calcVector(YACReader3DVector &vector, int pos) { calcPos(dummy, pos); - vector.x = dummy.current.x; vector.y = dummy.current.y; vector.z = dummy.current.z; @@ -410,7 +666,6 @@ bool YACReaderFlowGL::animate(YACReader3DVector ¤tVector, YACReader3DVecto if (fabs(rotDiff) < 0.01 && fabs(xDiff) < 0.001 && fabs(yDiff) < 0.001 && fabs(zDiff) < 0.001) return true; - // calculate and apply positions currentVector.x = currentVector.x + (xDiff)*config.animationStep; currentVector.y = currentVector.y + (yDiff)*config.animationStep; currentVector.z = currentVector.z + (zDiff)*config.animationStep; @@ -423,124 +678,160 @@ bool YACReaderFlowGL::animate(YACReader3DVector ¤tVector, YACReader3DVecto return false; } + void YACReaderFlowGL::drawCover(const YACReader3DImage &image) { + if (!shaderProgram || !vao || !image.texture) + return; + float w = image.width; float h = image.height; - // fadeout + // Calculate opacity - original formula exactly float opacity = 1 - 1 / (config.animationFadeOutDist + config.viewRotateLightStrenght * fabs(viewRotate)) * fabs(0 - image.current.x); - glLoadIdentity(); - glTranslatef(config.cfX, config.cfY, config.cfZ); - glRotatef(config.cfRX, 1, 0, 0); - glRotatef(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); - glRotatef(config.cfRZ, 0, 0, 1); + // Setup matrices + QMatrix4x4 projectionMatrix; + projectionMatrix.perspective(config.zoom, GLdouble(width()) / (float)height(), 1.0, 200.0); - glTranslatef(image.current.x, image.current.y, image.current.z); + QMatrix4x4 viewMatrix; + viewMatrix.translate(config.cfX, config.cfY, config.cfZ); + viewMatrix.rotate(config.cfRX, 1, 0, 0); + viewMatrix.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); + viewMatrix.rotate(config.cfRZ, 0, 0, 1); - glPushMatrix(); - glRotatef(image.current.rot, 0, 1, 0); + QMatrix4x4 modelMatrix; + modelMatrix.translate(image.current.x, image.current.y, image.current.z); + modelMatrix.rotate(image.current.rot, 0, 1, 0); + modelMatrix.translate(0.0f, -0.5f + h / 2.0f, 0.0f); + modelMatrix.scale(w, h, 1.0f); - glEnable(GL_TEXTURE_2D); - image.texture->bind(); + QMatrix4x4 mvpMatrix = projectionMatrix * viewMatrix * modelMatrix; - // calculate shading + // Calculate per-corner shading exactly as original float LShading = ((config.rotation != 0) ? ((image.current.rot < 0) ? 1 - 1 / config.rotation * image.current.rot : 1) : 1); float RShading = ((config.rotation != 0) ? ((image.current.rot > 0) ? 1 - 1 / (config.rotation * -1) * image.current.rot : 1) : 1); float LUP = shadingTop + (1 - shadingTop) * LShading; float LDOWN = shadingBottom + (1 - shadingBottom) * LShading; float RUP = shadingTop + (1 - shadingTop) * RShading; float RDOWN = shadingBottom + (1 - shadingBottom) * RShading; - ; - // DrawCover - glBegin(GL_QUADS); + // Bind shader and set uniforms + shaderProgram->bind(); + shaderProgram->setUniformValue("mvpMatrix", mvpMatrix); + shaderProgram->setUniformValue("leftUpShading", LUP); + shaderProgram->setUniformValue("leftDownShading", LDOWN); + shaderProgram->setUniformValue("rightUpShading", RUP); + shaderProgram->setUniformValue("rightDownShading", RDOWN); + shaderProgram->setUniformValue("opacity", opacity); + shaderProgram->setUniformValue("isReflection", false); + + // Bind texture and VAO + image.texture->bind(); + vao->bind(); - // esquina inferior izquierda - glColor4f(LDOWN * opacity, LDOWN * opacity, LDOWN * opacity, 1); - glTexCoord2f(0.0f, 1.0f); - glVertex3f(w / 2.f * -1.f, -0.5f, 0.f); + // Draw cover + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - // esquina inferior derecha - glColor4f(RDOWN * opacity, RDOWN * opacity, RDOWN * opacity, 1); - glTexCoord2f(1.0f, 1.0f); - glVertex3f(w / 2.f, -0.5f, 0.f); + // Draw marks if needed + if (showMarks && loaded[image.index] && marks[image.index] != Unread) { + QOpenGLTexture *markTex = (marks[image.index] == Read) ? markTexture : readingTexture; - // esquina superior derecha - glColor4f(RUP * opacity, RUP * opacity, RUP * opacity, 1); - glTexCoord2f(1.0f, 0.0f); - glVertex3f(w / 2.f, -0.5f + h, 0.f); + QMatrix4x4 markModel; + markModel.translate(image.current.x, image.current.y, image.current.z); + markModel.rotate(image.current.rot, 0, 1, 0); - // esquina superior izquierda - glColor4f(LUP * opacity, LUP * opacity, LUP * opacity, 1); - glTexCoord2f(0.0f, 0.0f); - glVertex3f(w / 2.f * -1.f, -0.5f + h, 0.f); + float markWidth = 0.15f; + float markHeight = 0.2f; + float markCenterX = w / 2.0f - 0.125f; + float markCenterY = -0.588f + h; - glEnd(); + markModel.translate(markCenterX, markCenterY, 0.001f); + markModel.scale(markWidth, markHeight, 1.0f); - // Draw reflection - glBegin(GL_QUADS); + QMatrix4x4 mvpMark = projectionMatrix * viewMatrix * markModel; - // esquina inferior izquierda - glColor4f(LUP * opacity * reflectionUp / 2, LUP * opacity * reflectionUp / 2, LUP * opacity * reflectionUp / 2, 1); - glTexCoord2f(0.0f, 0.0f); - glVertex3f(w / 2.f * -1.f, -0.5f - h, 0.f); + shaderProgram->setUniformValue("mvpMatrix", mvpMark); + shaderProgram->setUniformValue("leftUpShading", RUP * opacity); + shaderProgram->setUniformValue("leftDownShading", RUP * opacity); + shaderProgram->setUniformValue("rightUpShading", RUP * opacity); + shaderProgram->setUniformValue("rightDownShading", RUP * opacity); + shaderProgram->setUniformValue("opacity", 1.0f); + shaderProgram->setUniformValue("isReflection", false); + + markTex->bind(); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + + vao->release(); + shaderProgram->release(); +} + +void YACReaderFlowGL::drawReflection(const YACReader3DImage &image) +{ + if (!shaderProgram || !vao || !image.texture) + return; - // esquina inferior derecha - glColor4f(RUP * opacity * reflectionUp / 2, RUP * opacity * reflectionUp / 2, RUP * opacity * reflectionUp / 2, 1); - glTexCoord2f(1.0f, 0.0f); - glVertex3f(w / 2.f, -0.5f - h, 0.f); + float w = image.width; + float h = image.height; - // esquina superior derecha - glColor4f(RDOWN * opacity / 3, RDOWN * opacity / 3, RDOWN * opacity / 3, 1); - glTexCoord2f(1.0f, 1.0f); - glVertex3f(w / 2.f, -0.5f, 0.f); + // Calculate opacity - original formula exactly + float opacity = 1 - 1 / (config.animationFadeOutDist + config.viewRotateLightStrenght * fabs(viewRotate)) * fabs(0 - image.current.x); - // esquina superior izquierda - glColor4f(LDOWN * opacity / 3, LDOWN * opacity / 3, LDOWN * opacity / 3, 1); - glTexCoord2f(0.0f, 1.0f); - glVertex3f(w / 2.f * -1.f, -0.5f, 0.f); + // Setup matrices + QMatrix4x4 projectionMatrix; + projectionMatrix.perspective(config.zoom, GLdouble(width()) / (float)height(), 1.0, 200.0); - glEnd(); - glDisable(GL_TEXTURE_2D); + QMatrix4x4 viewMatrix; + viewMatrix.translate(config.cfX, config.cfY, config.cfZ); + viewMatrix.rotate(config.cfRX, 1, 0, 0); + viewMatrix.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); + viewMatrix.rotate(config.cfRZ, 0, 0, 1); - if (showMarks && loaded[image.index] && marks[image.index] != Unread) { - glEnable(GL_TEXTURE_2D); - if (marks[image.index] == Read) - markTexture->bind(); - else - readingTexture->bind(); - glBegin(GL_QUADS); - - // esquina inferior izquierda - glColor4f(RUP * opacity, RUP * opacity, RUP * opacity, 1); - glTexCoord2f(0.0f, 1.0f); - glVertex3f(w / 2.f - 0.2, -0.688f + h, 0.001f); - - // esquina inferior derecha - glColor4f(RUP * opacity, RUP * opacity, RUP * opacity, 1); - glTexCoord2f(1.0f, 1.0f); - glVertex3f(w / 2.f - 0.05, -0.688f + h, 0.001f); - - // esquina superior derecha - glColor4f(RUP * opacity, RUP * opacity, RUP * opacity, 1); - glTexCoord2f(1.0f, 0.0f); - glVertex3f(w / 2.f - 0.05, -0.488f + h, 0.001f); - - // esquina superior izquierda - glColor4f(RUP * opacity, RUP * opacity, RUP * opacity, 1); - glTexCoord2f(0.0f, 0.0f); - glVertex3f(w / 2.f - 0.2, -0.488f + h, 0.001f); - - glEnd(); - glDisable(GL_TEXTURE_2D); - } + // Calculate per-corner shading exactly as original + float LShading = ((config.rotation != 0) ? ((image.current.rot < 0) ? 1 - 1 / config.rotation * image.current.rot : 1) : 1); + float RShading = ((config.rotation != 0) ? ((image.current.rot > 0) ? 1 - 1 / (config.rotation * -1) * image.current.rot : 1) : 1); + float LUP = shadingTop + (1 - shadingTop) * LShading; + float LDOWN = shadingBottom + (1 - shadingBottom) * LShading; + float RUP = shadingTop + (1 - shadingTop) * RShading; + float RDOWN = shadingBottom + (1 - shadingBottom) * RShading; + + // Draw reflection + // In the old code, the reflection quad had vertices from y=-0.5-h (bottom) to y=-0.5 (top) + // The OLD reflection shading was: + // - Bottom corners (y = -0.5-h): LUP*opacity*reflectionUp/2, RUP*opacity*reflectionUp/2 + // - Top corners (y = -0.5): LDOWN*opacity/3, RDOWN*opacity/3 + // This means the reflection uses INVERTED vertical shading (LUP/RUP at bottom, LDOWN/RDOWN at top) + // We need to pass swapped values to match this + QMatrix4x4 reflectionMatrix; + reflectionMatrix.translate(image.current.x, image.current.y, image.current.z); + reflectionMatrix.rotate(image.current.rot, 0, 1, 0); + reflectionMatrix.translate(0.0f, -0.5f - h / 2.0f, 0.0f); + reflectionMatrix.scale(w, h, 1.0f); + + QMatrix4x4 mvpReflection = projectionMatrix * viewMatrix * reflectionMatrix; + + shaderProgram->bind(); + shaderProgram->setUniformValue("mvpMatrix", mvpReflection); + // Swap UP and DOWN for reflection to match old behavior + shaderProgram->setUniformValue("leftUpShading", LDOWN); + shaderProgram->setUniformValue("leftDownShading", LUP); + shaderProgram->setUniformValue("rightUpShading", RDOWN); + shaderProgram->setUniformValue("rightDownShading", RUP); + shaderProgram->setUniformValue("opacity", opacity); + shaderProgram->setUniformValue("isReflection", true); + shaderProgram->setUniformValue("reflectionUp", reflectionUp); + shaderProgram->setUniformValue("reflectionDown", reflectionBottom); + + image.texture->bind(); + vao->bind(); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glPopMatrix(); + vao->release(); + shaderProgram->release(); } -/*Public*/ void YACReaderFlowGL::cleanupAnimation() { config.animationStep = stepBackup; @@ -549,25 +840,189 @@ void YACReaderFlowGL::cleanupAnimation() void YACReaderFlowGL::draw() { + if (!shaderProgram || !vao || numObjects == 0) + return; + + // Calculate view-projection matrix once + // Note: Old implementation used fixed 20.0 degrees FOV, not config.zoom + QMatrix4x4 projectionMatrix; + projectionMatrix.perspective(20.0, GLdouble(width()) / (float)height(), 1.0, 200.0); + + QMatrix4x4 viewMatrix; + viewMatrix.translate(config.cfX, config.cfY, config.cfZ); + viewMatrix.rotate(config.cfRX, 1, 0, 0); + viewMatrix.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); + viewMatrix.rotate(config.cfRZ, 0, 0, 1); + + QMatrix4x4 viewProjectionMatrix = projectionMatrix * viewMatrix; + + // Bind shader once + shaderProgram->bind(); + shaderProgram->setUniformValue("viewProjectionMatrix", viewProjectionMatrix); + shaderProgram->setUniformValue("backgroundColor", + QVector3D(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF())); + shaderProgram->setUniformValue("shadingColor", + QVector3D(shadingColor.redF(), shadingColor.greenF(), shadingColor.blueF())); + int CS = currentSelected; - int count; - // Draw right Covers - for (count = numObjects - 1; count > -1; count--) { + // Prepare instance data for all covers + QVector instanceData; + QVector drawOrder; + + // Build draw order (back to front) + for (int count = numObjects - 1; count > -1; count--) { if (count > CS) { - drawCover(images[count]); + drawOrder.append(count); } } - - // Draw left Covers - for (count = 0; count < numObjects - 1; count++) { + for (int count = 0; count < numObjects - 1; count++) { if (count < CS) { - drawCover(images[count]); + drawOrder.append(count); + } + } + drawOrder.append(CS); + + // Draw reflections first + shaderProgram->setUniformValue("isReflection", true); + shaderProgram->setUniformValue("reflectionUp", reflectionUp); + shaderProgram->setUniformValue("reflectionDown", reflectionBottom); + + for (int idx : drawOrder) { + if (images[idx].texture) { + prepareInstanceData(images[idx], true, instanceData); + + instanceVBO->bind(); + instanceVBO->allocate(instanceData.data(), instanceData.size() * sizeof(GLfloat)); + + images[idx].texture->bind(); + vao->bind(); + glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, 1); + + instanceData.clear(); } } - // Draw Center Cover - drawCover(images[CS]); + // Draw covers + shaderProgram->setUniformValue("isReflection", false); + + for (int idx : drawOrder) { + if (images[idx].texture) { + prepareInstanceData(images[idx], false, instanceData); + + instanceVBO->bind(); + instanceVBO->allocate(instanceData.data(), instanceData.size() * sizeof(GLfloat)); + + images[idx].texture->bind(); + vao->bind(); + glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, 1); + + // Draw marks if needed + if (showMarks && loaded[images[idx].index] && marks[images[idx].index] != Unread) { + drawMark(images[idx], viewProjectionMatrix); + } + + instanceData.clear(); + } + } + + vao->release(); + shaderProgram->release(); +} + +void YACReaderFlowGL::prepareInstanceData(const YACReader3DImage &image, bool isReflection, QVector &data) +{ + float w = image.width; + float h = image.height; + + // Calculate opacity + float opacity = 1 - 1 / (config.animationFadeOutDist + config.viewRotateLightStrenght * fabs(viewRotate)) * fabs(0 - image.current.x); + + // Calculate model matrix + QMatrix4x4 modelMatrix; + modelMatrix.translate(image.current.x, image.current.y, image.current.z); + modelMatrix.rotate(image.current.rot, 0, 1, 0); + + if (isReflection) { + modelMatrix.translate(0.0f, -0.5f - h / 2.0f, 0.0f); + } else { + modelMatrix.translate(0.0f, -0.5f + h / 2.0f, 0.0f); + } + modelMatrix.scale(w, h, 1.0f); + + // Calculate shading + float LShading = ((config.rotation != 0) ? ((image.current.rot < 0) ? 1 - 1 / config.rotation * image.current.rot : 1) : 1); + float RShading = ((config.rotation != 0) ? ((image.current.rot > 0) ? 1 - 1 / (config.rotation * -1) * image.current.rot : 1) : 1); + float LUP = shadingTop + (1 - shadingTop) * LShading; + float LDOWN = shadingBottom + (1 - shadingBottom) * LShading; + float RUP = shadingTop + (1 - shadingTop) * RShading; + float RDOWN = shadingBottom + (1 - shadingBottom) * RShading; + + // For reflection, swap vertical shading + if (isReflection) { + float temp = LUP; + LUP = LDOWN; + LDOWN = temp; + temp = RUP; + RUP = RDOWN; + RDOWN = temp; + } + + // Pack instance data: mat4 (16 floats) + vec4 shading (4 floats) + float opacity (1 float) = 21 floats + const float *matData = modelMatrix.constData(); + for (int i = 0; i < 16; i++) { + data.append(matData[i]); + } + data.append(LUP); + data.append(LDOWN); + data.append(RUP); + data.append(RDOWN); + data.append(opacity); +} + +void YACReaderFlowGL::drawMark(const YACReader3DImage &image, const QMatrix4x4 &viewProjectionMatrix) +{ + QOpenGLTexture *markTex = (marks[image.index] == Read) ? markTexture : readingTexture; + + float w = image.width; + float h = image.height; + float opacity = 1 - 1 / (config.animationFadeOutDist + config.viewRotateLightStrenght * fabs(viewRotate)) * fabs(0 - image.current.x); + + float LShading = ((config.rotation != 0) ? ((image.current.rot < 0) ? 1 - 1 / config.rotation * image.current.rot : 1) : 1); + float RShading = ((config.rotation != 0) ? ((image.current.rot > 0) ? 1 - 1 / (config.rotation * -1) * image.current.rot : 1) : 1); + float RUP = shadingTop + (1 - shadingTop) * RShading; + + QMatrix4x4 markModel; + markModel.translate(image.current.x, image.current.y, image.current.z); + markModel.rotate(image.current.rot, 0, 1, 0); + + float markWidth = 0.15f; + float markHeight = 0.2f; + float markCenterX = w / 2.0f - 0.125f; + float markCenterY = -0.588f + h; + + markModel.translate(markCenterX, markCenterY, 0.001f); + markModel.scale(markWidth, markHeight, 1.0f); + + // Prepare instance data for mark + QVector markData; + const float *matData = markModel.constData(); + for (int i = 0; i < 16; i++) { + markData.append(matData[i]); + } + float shadingValue = RUP * opacity; + markData.append(shadingValue); + markData.append(shadingValue); + markData.append(shadingValue); + markData.append(shadingValue); + markData.append(1.0f); + + instanceVBO->bind(); + instanceVBO->allocate(markData.data(), markData.size() * sizeof(GLfloat)); + + markTex->bind(); + vao->bind(); + glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, 1); } void YACReaderFlowGL::showPrevious() @@ -575,7 +1030,6 @@ void YACReaderFlowGL::showPrevious() startAnimationTimer(); if (currentSelected > 0) { - currentSelected--; emit centerIndexChanged(currentSelected); config.animationStep *= config.animationSpeedUp; @@ -597,7 +1051,6 @@ void YACReaderFlowGL::showNext() startAnimationTimer(); if (currentSelected < numObjects - 1) { - currentSelected++; emit centerIndexChanged(currentSelected); config.animationStep *= config.animationSpeedUp; @@ -624,7 +1077,6 @@ void YACReaderFlowGL::setCurrentIndex(int pos) startAnimationTimer(); currentSelected = pos; - config.animationStep *= config.animationSpeedUp; if (config.animationStep > config.animationStepMax) { @@ -641,25 +1093,21 @@ void YACReaderFlowGL::setCurrentIndex(int pos) void YACReaderFlowGL::updatePositions() { int count; - bool stopAnimation = true; + for (count = numObjects - 1; count > -1; count--) { calcVector(images[count].animEnd, count - currentSelected); if (!animate(images[count].current, images[count].animEnd)) stopAnimation = false; } - // slowly reset view angle if (!viewRotateActive) { viewRotate += (0 - viewRotate) * config.viewRotateSub; } - if (fabs(images[currentSelected].current.x - images[currentSelected].animEnd.x) < 1) // viewRotate < 0.2) - { + if (fabs(images[currentSelected].current.x - images[currentSelected].animEnd.x) < 1) { cleanupAnimation(); - if (updateCount >= 0) // TODO parametrizar - { - + if (updateCount >= 0) { updateCount = 0; updateImageData(); } else @@ -676,13 +1124,10 @@ void YACReaderFlowGL::insert(char *name, QOpenGLTexture *texture, float x, float startAnimationTimer(); Q_UNUSED(name) - // set a new entry if (item == -1) { images.push_back(YACReader3DImage()); - item = numObjects; numObjects++; - calcVector(images[item].current, item); images[item].current.z = images[item].current.z - 1; } @@ -691,7 +1136,6 @@ void YACReaderFlowGL::insert(char *name, QOpenGLTexture *texture, float x, float images[item].width = x; images[item].height = y; images[item].index = item; - // strcpy(cfImages[item].name,name); } void YACReaderFlowGL::remove(int item) @@ -704,7 +1148,6 @@ void YACReaderFlowGL::remove(int item) loaded.remove(item); marks.remove(item); - // reposition current selection if (item <= currentSelected && currentSelected != 0) { currentSelected--; } @@ -742,7 +1185,6 @@ void YACReaderFlowGL::add(int item) insert(s.toLocal8Bit().data(), defaultTexture, x, y, item); } -/*Info*/ YACReader3DImage YACReaderFlowGL::getCurrentSelected() { return images[currentSelected]; @@ -781,7 +1223,6 @@ void YACReaderFlowGL::populate(int n) void YACReaderFlowGL::reset() { makeCurrent(); - startAnimationTimer(); currentSelected = 0; @@ -804,130 +1245,93 @@ void YACReaderFlowGL::reset() void YACReaderFlowGL::reload() { startAnimationTimer(); - int n = numObjects; reset(); populate(n); } -// slots +// Slot implementations void YACReaderFlowGL::setCF_RX(int value) { startAnimationTimer(); - config.cfRX = value; } void YACReaderFlowGL::setCF_RY(int value) { startAnimationTimer(); - config.cfRY = value; } void YACReaderFlowGL::setCF_RZ(int value) { startAnimationTimer(); - config.cfRZ = value; } - -void YACReaderFlowGL::setZoom(int zoom) -{ - startAnimationTimer(); - - int width = this->width(); - int height = this->height(); - glViewport(0, 0, width, height); - - glMatrixMode(GL_PROJECTION); - QMatrix4x4 zoomMatrix; - zoomMatrix.setToIdentity(); - zoomMatrix.perspective(zoom, (float)width / (float)height, 1.0, 200.0); - glLoadMatrixf(zoomMatrix.constData()); - glMatrixMode(GL_MODELVIEW); -} - void YACReaderFlowGL::setRotation(int angle) { startAnimationTimer(); - config.rotation = -angle; } -// sets the distance between the covers void YACReaderFlowGL::setX_Distance(int distance) { startAnimationTimer(); - config.xDistance = distance / 100.0; } -// sets the distance between the centered and the non centered covers void YACReaderFlowGL::setCenter_Distance(int distance) { startAnimationTimer(); - config.centerDistance = distance / 100.0; } -// sets the pushback amount void YACReaderFlowGL::setZ_Distance(int distance) { startAnimationTimer(); - config.zDistance = distance / 100.0; } - void YACReaderFlowGL::setCF_Y(int value) { startAnimationTimer(); - config.cfY = value / 100.0; } - void YACReaderFlowGL::setCF_Z(int value) { startAnimationTimer(); - config.cfZ = value; } - void YACReaderFlowGL::setY_Distance(int value) { startAnimationTimer(); - config.yDistance = value / 100.0; } - void YACReaderFlowGL::setFadeOutDist(int value) { startAnimationTimer(); - config.animationFadeOutDist = value; } - void YACReaderFlowGL::setLightStrenght(int value) { startAnimationTimer(); - config.viewRotateLightStrenght = value; } - void YACReaderFlowGL::setMaxAngle(int value) { startAnimationTimer(); - config.viewAngle = value; } - void YACReaderFlowGL::setPreset(const Preset &p) { startAnimationTimer(); - config = p; } +void YACReaderFlowGL::setZoom(int zoom) +{ + startAnimationTimer(); + config.zoom = zoom; +} + void YACReaderFlowGL::setPerformance(Performance performance) { if (this->performance != performance) { startAnimationTimer(); - this->performance = performance; reload(); } @@ -937,61 +1341,47 @@ void YACReaderFlowGL::useVSync(bool b) { if (bUseVSync != b) { bUseVSync = b; - if (b) { - QSurfaceFormat f = format(); - f.setVersion(2, 1); - f.setSwapInterval(1); - setFormat(f); - } else { - QSurfaceFormat f = format(); - f.setVersion(2, 1); - f.setSwapInterval(0); - setFormat(f); - } + QSurfaceFormat f = format(); + f.setVersion(3, 3); + f.setProfile(QSurfaceFormat::CoreProfile); + f.setSwapInterval(b ? 1 : 0); + setFormat(f); reset(); } } + void YACReaderFlowGL::setShowMarks(bool value) { startAnimationTimer(); - showMarks = value; } void YACReaderFlowGL::setMarks(QVector marks) { startAnimationTimer(); - this->marks = marks; } void YACReaderFlowGL::setMarkImage(QImage &image) { Q_UNUSED(image); - // qué pasa la primera vez?? - // deleteTexture(markTexture); - // markTexture = bindTexture(image,GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption | QGLContext::MipmapBindOption); } void YACReaderFlowGL::markSlide(int index, YACReader::YACReaderComicReadStatus status) { startAnimationTimer(); - marks[index] = status; } void YACReaderFlowGL::unmarkSlide(int index) { startAnimationTimer(); - marks[index] = YACReader::Unread; } void YACReaderFlowGL::setSlideSize(QSize size) { Q_UNUSED(size); - // TODO calcular el tamaño del widget } void YACReaderFlowGL::clear() { reset(); } - void YACReaderFlowGL::setCenterIndex(unsigned int index) { setCurrentIndex(index); @@ -1004,26 +1394,52 @@ int YACReaderFlowGL::centerIndex() { return currentSelected; } -void YACReaderFlowGL::updateMarks() +void YACReaderFlowGL::updateMarks() { } +void YACReaderFlowGL::render() { } +void YACReaderFlowGL::setFlowRightToLeft(bool b) { - // do nothing + flowRightToLeft = b; } -/*void YACReaderFlowGL::setFlowType(FlowType flowType) -{ - //TODO esperar a que se reimplemente flowtype -}*/ -void YACReaderFlowGL::render() + +void YACReaderFlowGL::setBackgroundColor(const QColor &color) { - // do nothing + backgroundColor = color; + + // Auto-calculate shadingColor based on background brightness + qreal luminance = (backgroundColor.redF() * 0.299 + + backgroundColor.greenF() * 0.587 + + backgroundColor.blueF() * 0.114); + + if (luminance < 0.5) { + // Dark background - shade towards white + shadingColor = QColor(255, 255, 255); + // Use original shading values for dark backgrounds + shadingTop = 0.8f; + shadingBottom = 0.02f; + } else { + // Light background - shade towards black + shadingColor = QColor(0, 0, 0); + // Adjust shading range for better contrast on light backgrounds + shadingTop = 0.95f; + shadingBottom = 0.3f; + } + + update(); } -void YACReaderFlowGL::setFlowRightToLeft(bool b) +void YACReaderFlowGL::setTextColor(const QColor &color) { - flowRightToLeft = b; + textColor = color; + update(); } -// EVENTOS +void YACReaderFlowGL::setShadingColor(const QColor &color) +{ + shadingColor = color; + update(); +} +// Event handlers void YACReaderFlowGL::wheelEvent(QWheelEvent *event) { Movement m = getMovement(event); @@ -1062,7 +1478,6 @@ void YACReaderFlowGL::keyPressEvent(QKeyEvent *event) } if (event->key() == Qt::Key_Up) { - // emit selected(centerIndex()); return; } @@ -1096,44 +1511,60 @@ void YACReaderFlowGL::mouseDoubleClickEvent(QMouseEvent *event) QVector3D YACReaderFlowGL::getPlaneIntersection(int x, int y, YACReader3DImage plane) { - // get viewport and matrices - // TODO: these should be cached!!! + if (!context() || !context()->isValid()) + return QVector3D(0, 0, 0); + GLint viewport[4]; QMatrix4x4 m_modelview; QMatrix4x4 m_projection; + makeCurrent(); glGetIntegerv(GL_VIEWPORT, viewport); - glGetFloatv(GL_MODELVIEW_MATRIX, m_modelview.data()); - glGetFloatv(GL_PROJECTION_MATRIX, m_projection.data()); + + m_projection.perspective(config.zoom, GLdouble(width()) / (float)height(), 1.0, 200.0); + + m_modelview.translate(config.cfX, config.cfY, config.cfZ); + m_modelview.rotate(config.cfRX, 1, 0, 0); + m_modelview.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); + m_modelview.rotate(config.cfRZ, 0, 0, 1); + m_modelview.translate(plane.current.x, plane.current.y, plane.current.z); + m_modelview.rotate(plane.current.rot, 0, 1, 0); + m_modelview.scale(plane.width, plane.height, 1.0f); + doneCurrent(); - // create the picking ray QVector3D ray_origin(x * devicePixelRatioF(), y * devicePixelRatioF(), 0); QVector3D ray_end(x * devicePixelRatioF(), y * devicePixelRatioF(), 1.0); - // TODO: These should be cached in the class - ray_origin = ray_origin.unproject(m_modelview, m_projection, QRect(viewport[0], viewport[1], viewport[2], viewport[3])); ray_end = ray_end.unproject(m_modelview, m_projection, QRect(viewport[0], viewport[1], viewport[2], viewport[3])); QVector3D ray_vector = ray_end - ray_origin; - // calculate the plane vectors - QVector3D plane_origin((plane.width / 2) * -1, -0.5, 0); - QVector3D plane_vektor_1 = QVector3D(plane.width / 2, -0.5, 0) - plane_origin; - QVector3D plane_vektor_2 = QVector3D((plane.width / 2) * -1, -0.5 * plane.height, 0) - plane_origin; + QVector3D plane_origin(-0.5f, -0.5f, 0); + QVector3D plane_vektor_1 = QVector3D(0.5f, -0.5f, 0) - plane_origin; + QVector3D plane_vektor_2 = QVector3D(-0.5f, 0.5f, 0) - plane_origin; - // get the intersection using Cramer's rule. We only x for the line, not the plane - double intersection_LES_determinant = ((plane_vektor_1.x() * plane_vektor_2.y() * (-1) * ray_vector.z()) + (plane_vektor_2.x() * (-1) * ray_vector.y() * plane_vektor_1.z()) + ((-1) * ray_vector.x() * plane_vektor_1.y() * plane_vektor_2.z()) - ((-1) * ray_vector.x() * plane_vektor_2.y() * plane_vektor_1.z()) - (plane_vektor_1.x() * (-1) * ray_vector.y() * plane_vektor_2.z()) - (plane_vektor_2.x() * plane_vektor_1.y() * (-1) * ray_vector.z())); + double intersection_LES_determinant = ((plane_vektor_1.x() * plane_vektor_2.y() * (-1) * ray_vector.z()) + + (plane_vektor_2.x() * (-1) * ray_vector.y() * plane_vektor_1.z()) + + ((-1) * ray_vector.x() * plane_vektor_1.y() * plane_vektor_2.z()) - + ((-1) * ray_vector.x() * plane_vektor_2.y() * plane_vektor_1.z()) - + (plane_vektor_1.x() * (-1) * ray_vector.y() * plane_vektor_2.z()) - + (plane_vektor_2.x() * plane_vektor_1.y() * (-1) * ray_vector.z())); QVector3D det = ray_origin - plane_origin; - double intersection_ray_determinant = ((plane_vektor_1.x() * plane_vektor_2.y() * det.z()) + (plane_vektor_2.x() * det.y() * plane_vektor_1.z()) + (det.x() * plane_vektor_1.y() * plane_vektor_2.z()) - (det.x() * plane_vektor_2.y() * plane_vektor_1.z()) - (plane_vektor_1.x() * det.y() * plane_vektor_2.z()) - (plane_vektor_2.x() * plane_vektor_1.y() * det.z())); + double intersection_ray_determinant = ((plane_vektor_1.x() * plane_vektor_2.y() * det.z()) + + (plane_vektor_2.x() * det.y() * plane_vektor_1.z()) + + (det.x() * plane_vektor_1.y() * plane_vektor_2.z()) - + (det.x() * plane_vektor_2.y() * plane_vektor_1.z()) - + (plane_vektor_1.x() * det.y() * plane_vektor_2.z()) - + (plane_vektor_2.x() * plane_vektor_1.y() * det.z())); - // return the intersection point return ray_origin + ray_vector * (intersection_ray_determinant / intersection_LES_determinant); } +// YACReaderComicFlowGL implementation YACReaderComicFlowGL::YACReaderComicFlowGL(QWidget *parent, struct Preset p) : YACReaderFlowGL(parent, p) { @@ -1150,22 +1581,13 @@ void YACReaderComicFlowGL::setImagePaths(QStringList paths) YACReaderFlowGL::populate(paths.size()); lazyPopulateObjects = paths.size(); this->paths = paths; - // numObjects = paths.size(); } -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - void YACReaderComicFlowGL::updateImageData() { - // can't do anything, wait for the next possibility if (worker->busy()) return; - // set image of last one int idx = worker->index(); if (idx >= 0 && !worker->result().isNull()) { if (!loaded[idx]) { @@ -1186,8 +1608,6 @@ void YACReaderComicFlowGL::updateImageData() } } - // try to load only few images on the left and right side - // i.e. all visible ones plus some extra int count = 8; switch (performance) { case low: @@ -1203,6 +1623,7 @@ void YACReaderComicFlowGL::updateImageData() count = 16; break; } + int *indexes = new int[2 * count + 1]; int center = currentSelected; indexes[0] = center; @@ -1210,18 +1631,13 @@ void YACReaderComicFlowGL::updateImageData() indexes[j * 2 + 1] = center + j + 1; indexes[j * 2 + 2] = center - j - 1; } + for (int c = 0; c < 2 * count + 1; c++) { int i = indexes[c]; if ((i >= 0) && (i < numObjects)) - if (!loaded[i]) // slide(i).isNull()) - { - // loader->loadTexture(i); - // loaded[i]=true; - // schedule thumbnail generation + if (!loaded[i]) { if (paths.size() > 0) { QString fname = paths.at(i); - // loaded[i]=true; - worker->generate(i, fname); } delete[] indexes; @@ -1247,19 +1663,17 @@ void YACReaderComicFlowGL::add(const QString &path, int index) { worker->lock(); worker->reset(); - paths.insert(index, path); - YACReaderFlowGL::add(index); - worker->unlock(); } void YACReaderComicFlowGL::resortCovers(QList newOrder) { worker->lock(); - worker->reset(); // is this necesary? + worker->reset(); startAnimationTimer(); + QList pathsNew; QVector loadedNew; QVector marksNew; @@ -1286,6 +1700,7 @@ void YACReaderComicFlowGL::resortCovers(QList newOrder) worker->unlock(); } +// YACReaderPageFlowGL implementation YACReaderPageFlowGL::YACReaderPageFlowGL(QWidget *parent, struct Preset p) : YACReaderFlowGL(parent, p) { @@ -1319,19 +1734,11 @@ YACReaderPageFlowGL::~YACReaderPageFlowGL() doneCurrent(); } -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - void YACReaderPageFlowGL::updateImageData() { - // can't do anything, wait for the next possibility if (worker->busy()) return; - // set image of last one int idx = worker->index(); if (idx >= 0 && !worker->result().isNull()) { if (!loaded[idx]) { @@ -1353,8 +1760,6 @@ void YACReaderPageFlowGL::updateImageData() } } - // try to load only few images on the left and right side - // i.e. all visible ones plus some extra int count = 8; switch (performance) { case low: @@ -1370,6 +1775,7 @@ void YACReaderPageFlowGL::updateImageData() count = 14; break; } + int *indexes = new int[2 * count + 1]; int center = currentSelected; indexes[0] = center; @@ -1377,15 +1783,13 @@ void YACReaderPageFlowGL::updateImageData() indexes[j * 2 + 1] = center + j + 1; indexes[j * 2 + 2] = center - j - 1; } + for (int c = 0; c < 2 * count + 1; c++) { int i = indexes[c]; if ((i >= 0) && (i < numObjects)) if (rawImages.size() > 0) - - if (!loaded[i] && imagesReady[i]) // slide(i).isNull()) - { + if (!loaded[i] && imagesReady[i]) { worker->generate(i, rawImages.at(i)); - delete[] indexes; return; } @@ -1402,12 +1806,10 @@ void YACReaderPageFlowGL::populate(int n) lazyPopulateObjects = n; imagesReady = QVector(n, false); rawImages = QVector(n); - imagesSetted = QVector(n, false); // puede sobrar + imagesSetted = QVector(n, false); } -//----------------------------------------------------------------------------- -// ImageLoader -//----------------------------------------------------------------------------- +// ImageLoaderGL implementation QImage ImageLoaderGL::loadImage(const QString &fileName) { QImage image; @@ -1427,7 +1829,7 @@ QImage ImageLoaderGL::loadImage(const QString &fileName) image = image.scaledToWidth(320, Qt::SmoothTransformation); break; case ultraHigh: - break; // no scaling in ultraHigh + break; } return image; @@ -1463,7 +1865,6 @@ void ImageLoaderGL::generate(int index, const QString &fileName) if (!isRunning()) start(); else { - // already running, wake up whenever ready restart = true; condition.wakeOne(); } @@ -1482,7 +1883,6 @@ void ImageLoaderGL::unlock() void ImageLoaderGL::run() { for (;;) { - // copy necessary data mutex.lock(); this->working = true; QString fileName = this->fileName; @@ -1490,13 +1890,11 @@ void ImageLoaderGL::run() QImage image = loadImage(fileName); - // let everyone knows it is ready mutex.lock(); this->working = false; this->img = image; mutex.unlock(); - // put to sleep mutex.lock(); if (!this->restart) condition.wait(&mutex); @@ -1510,9 +1908,7 @@ QImage ImageLoaderGL::result() return img; } -//----------------------------------------------------------------------------- -// ImageLoader -//----------------------------------------------------------------------------- +// ImageLoaderByteArrayGL implementation QImage ImageLoaderByteArrayGL::loadImage(const QByteArray &raw) { QImage image; @@ -1569,7 +1965,6 @@ void ImageLoaderByteArrayGL::generate(int index, const QByteArray &raw) if (!isRunning()) start(); else { - // already running, wake up whenever ready restart = true; condition.wakeOne(); } @@ -1578,7 +1973,6 @@ void ImageLoaderByteArrayGL::generate(int index, const QByteArray &raw) void ImageLoaderByteArrayGL::run() { for (;;) { - // copy necessary data mutex.lock(); this->working = true; QByteArray raw = this->rawData; @@ -1586,13 +1980,11 @@ void ImageLoaderByteArrayGL::run() QImage image = loadImage(raw); - // let everyone knows it is ready mutex.lock(); this->working = false; this->img = image; mutex.unlock(); - // put to sleep mutex.lock(); if (!this->restart) condition.wait(&mutex); diff --git a/common/gl/yacreader_flow_gl.h b/common/gl/yacreader_flow_gl.h index b40ea4128..5571c24bd 100644 --- a/common/gl/yacreader_flow_gl.h +++ b/common/gl/yacreader_flow_gl.h @@ -1,4 +1,4 @@ -// OpenGL Coverflow API by J.Roth +// OpenGL Coverflow API by J.Roth - Modernized with Shaders #ifndef __YACREADER_FLOW_GL_H #define __YACREADER_FLOW_GL_H @@ -13,9 +13,13 @@ #endif #include +#include +#include +#include +#include #include -#include "pictureflow.h" //TODO mover los tipos de flow de sitio +#include "pictureflow.h" #include "scroll_management.h" class ImageLoaderGL; @@ -39,7 +43,6 @@ struct YACReader3DVector { // the image/texture info struct struct YACReader3DImage { QOpenGLTexture *texture; - // char name[256]; float width; float height; @@ -105,7 +108,7 @@ extern struct Preset presetYACReaderFlowOverlappedStripeConfig; extern struct Preset pressetYACReaderFlowUpConfig; extern struct Preset pressetYACReaderFlowDownConfig; -class YACReaderFlowGL : public QOpenGLWidget, public ScrollManagement +class YACReaderFlowGL : public QOpenGLWidget, protected QOpenGLExtraFunctions, public ScrollManagement { Q_OBJECT protected: @@ -118,11 +121,13 @@ class YACReaderFlowGL : public QOpenGLWidget, public ScrollManagement /*functions*/ void calcPos(YACReader3DImage &image, int pos); void calcVector(YACReader3DVector &vector, int pos); - // returns true if the animation is finished for Current bool animate(YACReader3DVector ¤tVector, YACReader3DVector &toVector); void drawCover(const YACReader3DImage &image); + void drawReflection(const YACReader3DImage &image); + void prepareInstanceData(const YACReader3DImage &image, bool isReflection, QVector &data); + void drawMark(const YACReader3DImage &image, const QMatrix4x4 &viewProjectionMatrix); - void udpatePerspective(int width, int height); + void updatePerspective(int width, int height); int updateCount; int fontSize; @@ -130,11 +135,19 @@ class YACReaderFlowGL : public QOpenGLWidget, public ScrollManagement QOpenGLTexture *defaultTexture = nullptr; QOpenGLTexture *markTexture = nullptr; QOpenGLTexture *readingTexture = nullptr; + + // Shader program and buffers + QOpenGLShaderProgram *shaderProgram = nullptr; + QOpenGLBuffer *vbo = nullptr; + QOpenGLBuffer *instanceVBO = nullptr; + QOpenGLVertexArrayObject *vao = nullptr; + void initializeGL(); void paintGL(); void timerEvent(QTimerEvent *); + void setupShaders(); + void setupGeometry(); - // number of Covers int numObjects; int lazyPopulateObjects; bool showMarks; @@ -151,116 +164,81 @@ class YACReaderFlowGL : public QOpenGLWidget, public ScrollManagement /*** Animation Settings ***/ Preset config; - // sets/returns the curent selected cover int currentSelected; - // defines the position of the centered cover YACReader3DVector centerPos; /*** Style ***/ - // sets the amount of shading of the covers in the back (0-1) float shadingTop; float shadingBottom; - // sets the reflection strenght (0-1) float reflectionUp; float reflectionBottom; + /*** Theme Colors ***/ + QColor backgroundColor; + QColor textColor; + QColor shadingColor; + /*** System info ***/ float viewRotate; - // sets the updateInterval in ms static int updateInterval; - // sets flow direction right-to-left (manga mode) bool flowRightToLeft; void startAnimationTimer(); void stopAnimationTimer(); public: - /*Constructor*/ YACReaderFlowGL(QWidget *parent = 0, struct Preset p = pressetYACReaderFlowDownConfig); virtual ~YACReaderFlowGL(); - // size; QSize minimumSizeHint() const; - // QSize sizeHint() const; - /*functions*/ - - // if called it moves the coverflow to the left void showPrevious(); - // if called it moves the coverflow to the right void showNext(); - // go to void setCurrentIndex(int pos); - // must be called whenever the coverflow animation is stopped void cleanupAnimation(); - // Draws the coverflow void draw(); - // updates the coverflow void updatePositions(); - // inserts a new item to the coverflow - // if item is set to a value > -1 it updates a already set value - // otherwise a new entry is set void insert(char *name, QOpenGLTexture *texture, float x, float y, int item = -1); - // removes a item virtual void remove(int item); - // inserts a default texture into `item` and set is as pending to load void add(int item); - // replaces the texture of the item 'item' with Tex void replace(char *name, QOpenGLTexture *texture, float x, float y, int item); - // create n covers with the default nu void populate(int n); - /*Info*/ - // retuns the YACReader3DImage Struct of the current selected item - // to read title or textures YACReader3DImage getCurrentSelected(); public slots: void setCF_RX(int value); - // the Y Rotation of the Coverflow void setCF_RY(int value); - // the Z Rotation of the Coverflow void setCF_RZ(int value); - - // perspective void setZoom(int zoom); - void setRotation(int angle); - // sets the distance between the covers void setX_Distance(int distance); - // sets the distance between the centered and the non centered covers void setCenter_Distance(int distance); - // sets the pushback amount void setZ_Distance(int distance); - void setCF_Y(int value); void setCF_Z(int value); - void setY_Distance(int value); - void setFadeOutDist(int value); - void setLightStrenght(int value); - void setMaxAngle(int value); - void setPreset(const Preset &p); - void setPerformance(Performance performance); - void useVSync(bool b); - void setFlowRightToLeft(bool b); + // Theme color setters + void setBackgroundColor(const QColor &color); + void setTextColor(const QColor &color); + void setShadingColor(const QColor &color); + virtual void updateImageData() = 0; void reset(); void reload(); - // interface with yacreaderlibrary, compatibility void setShowMarks(bool value); void setMarks(QVector marks); void setMarkImage(QImage &image); @@ -272,16 +250,15 @@ public slots: void showSlide(int index); int centerIndex(); void updateMarks(); - // void setFlowType(PictureFlow::FlowType flowType); void render(); - // void paintEvent(QPaintEvent *event); QVector3D getPlaneIntersection(int x, int y, YACReader3DImage plane); void mouseDoubleClickEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event); void wheelEvent(QWheelEvent *event); void keyPressEvent(QKeyEvent *event); void resizeGL(int width, int height); + friend class ImageLoaderGL; friend class ImageLoaderByteArrayGL; @@ -329,7 +306,6 @@ class ImageLoaderGL : public QThread public: ImageLoaderGL(YACReaderFlowGL *flow); ~ImageLoaderGL(); - // returns FALSE if worker is still busy and can't take the task bool busy() const; void generate(int index, const QString &fileName); void reset() @@ -365,7 +341,6 @@ class ImageLoaderByteArrayGL : public QThread public: ImageLoaderByteArrayGL(YACReaderFlowGL *flow); ~ImageLoaderByteArrayGL(); - // returns FALSE if worker is still busy and can't take the task bool busy() const; void generate(int index, const QByteArray &raw); void reset() diff --git a/common/opengl_checker.cpp b/common/opengl_checker.cpp index 5779657d1..2a73af96e 100644 --- a/common/opengl_checker.cpp +++ b/common/opengl_checker.cpp @@ -42,21 +42,27 @@ OpenGLChecker::OpenGLChecker() 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; + // Check for Desktop OpenGL OR OpenGL ES 3.0+ + bool isDesktopGL = (format.renderableType() == QSurfaceFormat::OpenGL); + bool isOpenGLES = (format.renderableType() == QSurfaceFormat::OpenGLES); + + if (isDesktopGL) { + // Desktop OpenGL requirements +#ifdef Q_OS_WIN + if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 4)) + compatibleOpenGLVersion = false; #else - static const int majorTargetVersion = 2; - static const int minorTargetVersion = 0; + if (majorVersion < 2) + compatibleOpenGLVersion = false; #endif - - if (majorVersion < majorTargetVersion) - compatibleOpenGLVersion = false; - if (majorVersion == majorTargetVersion && minorVersion < minorTargetVersion) + } else if (isOpenGLES) { + // OpenGL ES requirements: 3.0 or higher + if (majorVersion < 3) + compatibleOpenGLVersion = false; + } else { + // Unknown or unsupported renderable type compatibleOpenGLVersion = false; + } } QString OpenGLChecker::textVersionDescription() From 3381754c12414d99057653bf00ae48716f7bba92 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 17 Jan 2026 22:46:27 +0100 Subject: [PATCH 004/187] Add an initial rhi implementation that mimics the opengl implementation --- .claude/settings.local.json | 8 + YACReader/YACReader.pro | 25 +- YACReader/goto_flow_gl.cpp | 8 +- YACReader/goto_flow_gl.h | 10 +- YACReader/viewer.cpp | 8 + YACReaderLibrary/YACReaderLibrary.pro | 25 +- YACReaderLibrary/comic_flow_widget.cpp | 11 +- YACReaderLibrary/comic_flow_widget.h | 9 +- YACReaderLibrary/comics_view.cpp | 8 +- YACReaderLibrary/folder_content_view.cpp | 8 +- YACReaderLibrary/library_window.cpp | 7 + YACReaderLibrary/main.cpp | 7 + common/opengl_checker.cpp | 2 - common/rhi/README.md | 287 ++++ common/rhi/shaders/README.md | 49 + common/rhi/shaders/compile_shaders.bat | 19 + common/rhi/shaders/compile_shaders.sh | 19 + common/rhi/shaders/flow.frag | 44 + common/rhi/shaders/flow.frag.qsb | Bin 0 -> 1990 bytes common/rhi/shaders/flow.vert | 59 + common/rhi/shaders/flow.vert.qsb | Bin 0 -> 2957 bytes common/rhi/shaders/shaders.qrc | 6 + common/rhi/yacreader_flow_rhi.cpp | 1744 ++++++++++++++++++++++ common/rhi/yacreader_flow_rhi.h | 394 +++++ third_party/QsLog/QsLogDestConsole.cpp | 3 + 25 files changed, 2739 insertions(+), 21 deletions(-) create mode 100644 .claude/settings.local.json create mode 100644 common/rhi/README.md create mode 100644 common/rhi/shaders/README.md create mode 100644 common/rhi/shaders/compile_shaders.bat create mode 100644 common/rhi/shaders/compile_shaders.sh create mode 100644 common/rhi/shaders/flow.frag create mode 100644 common/rhi/shaders/flow.frag.qsb create mode 100644 common/rhi/shaders/flow.vert create mode 100644 common/rhi/shaders/flow.vert.qsb create mode 100644 common/rhi/shaders/shaders.qrc create mode 100644 common/rhi/yacreader_flow_rhi.cpp create mode 100644 common/rhi/yacreader_flow_rhi.h diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 000000000..ad2f5cfa0 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,8 @@ +{ + "permissions": { + "allow": [ + "Bash(qsb:*)", + "Bash(ls:*)" + ] + } +} diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro index 3eb06c233..3cc1aa769 100644 --- a/YACReader/YACReader.pro +++ b/YACReader/YACReader.pro @@ -27,10 +27,20 @@ INCLUDEPATH += ../common \ !CONFIG(no_opengl) { INCLUDEPATH += ../common/gl + greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { + INCLUDEPATH += ../common/rhi + DEFINES += YACREADER_USE_RHI + } } win32 { - LIBS += -loleaut32 -lole32 -lshell32 -lopengl32 -luser32 + LIBS += -loleaut32 -lole32 -lshell32 -luser32 + # When using RHI (Qt 6.7+), don't link OpenGL directly - QRhiWidget handles graphics APIs + greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { + message("RHI mode: not linking opengl32 (using QRhiWidget)") + } else { + LIBS += -lopengl32 + } msvc { QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL @@ -51,6 +61,10 @@ QT += network widgets core multimedia svg greaterThan(QT_MAJOR_VERSION, 5): QT += openglwidgets core5compat +greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { + QT += gui-private +} + #CONFIG += release CONFIG -= flat @@ -93,6 +107,10 @@ HEADERS += ../common/comic.h \ !CONFIG(no_opengl) { HEADERS += ../common/gl/yacreader_flow_gl.h \ goto_flow_gl.h + + greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { + HEADERS += ../common/rhi/yacreader_flow_rhi.h + } } SOURCES += ../common/comic.cpp \ @@ -132,6 +150,11 @@ SOURCES += ../common/comic.cpp \ !CONFIG(no_opengl) { SOURCES += ../common/gl/yacreader_flow_gl.cpp \ goto_flow_gl.cpp + + greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { + SOURCES += ../common/rhi/yacreader_flow_rhi.cpp + RESOURCES += ../common/rhi/shaders/shaders.qrc + } } include(../custom_widgets/custom_widgets_yacreader.pri) diff --git a/YACReader/goto_flow_gl.cpp b/YACReader/goto_flow_gl.cpp index 323e368d6..27772e216 100644 --- a/YACReader/goto_flow_gl.cpp +++ b/YACReader/goto_flow_gl.cpp @@ -15,17 +15,17 @@ GoToFlowGL::GoToFlowGL(QWidget *parent, FlowType flowType) : GoToFlowWidget(parent) { Q_UNUSED(flowType) - flow = new YACReaderPageFlowGL(this); + flow = new YACReaderPageFlowImpl(this); flow->setShowMarks(false); imageSize = Configuration::getConfiguration().getGotoSlideSize(); flow->setSlideSize(imageSize); - connect(flow, &YACReaderFlowGL::centerIndexChanged, this, &GoToFlowWidget::setPageNumber); - connect(flow, &YACReaderFlowGL::selected, this, &GoToFlowGL::goToPage); + connect(flow, &YACReaderPageFlowImpl::centerIndexChanged, this, &GoToFlowWidget::setPageNumber); + connect(flow, &YACReaderPageFlowImpl::selected, this, &GoToFlowGL::goToPage); connect(toolBar, &GoToFlowToolBar::goToPage, this, &GoToFlowGL::goToPage); - connect(toolBar, &GoToFlowToolBar::setCenter, flow, &YACReaderFlowGL::setCenterIndex); + connect(toolBar, &GoToFlowToolBar::setCenter, flow, &YACReaderPageFlowImpl::setCenterIndex); mainLayout->addWidget(flow); toolBar->raise(); diff --git a/YACReader/goto_flow_gl.h b/YACReader/goto_flow_gl.h index 34ede703d..d2278641c 100644 --- a/YACReader/goto_flow_gl.h +++ b/YACReader/goto_flow_gl.h @@ -3,7 +3,15 @@ #include "yacreader_global.h" #include "goto_flow_widget.h" + +// Conditional include based on Qt version and RHI availability +#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) +#include "yacreader_flow_rhi.h" +using YACReaderPageFlowImpl = YACReaderPageFlow3D; +#else #include "yacreader_flow_gl.h" +using YACReaderPageFlowImpl = YACReaderPageFlowGL; +#endif class QLineEdit; class QIntValidator; @@ -28,7 +36,7 @@ class GoToFlowGL : public GoToFlowWidget void setFlowRightToLeft(bool b) override; private: - YACReaderPageFlowGL *flow; + YACReaderPageFlowImpl *flow; void keyPressEvent(QKeyEvent *event) override; void resizeEvent(QResizeEvent *event) override; // Comic * comic; diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index b8ac3ccdc..c4e4bfb53 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -86,6 +86,13 @@ Viewer::Viewer(QWidget *parent) // CONFIG GOTO_FLOW-------------------------------------------------------- #ifndef NO_OPENGL +#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) + // When using RHI, don't check OpenGL - assume hardware acceleration is available + bool openGLAvailable = true; + + if (!settings->contains(USE_OPEN_GL)) + settings->setValue(USE_OPEN_GL, 2); +#else OpenGLChecker openGLChecker; bool openGLAvailable = openGLChecker.hasCompatibleOpenGLVersion(); @@ -93,6 +100,7 @@ Viewer::Viewer(QWidget *parent) settings->setValue(USE_OPEN_GL, 2); else if (!openGLAvailable) settings->setValue(USE_OPEN_GL, 0); +#endif if ((settings->value(USE_OPEN_GL).toBool() == true)) goToFlow = new GoToFlowGL(this, Configuration::getConfiguration().getFlowType()); diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 4e552b409..79d1ed173 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -20,8 +20,18 @@ include (../dependencies/pdf_backend.pri) INCLUDEPATH += ../common/gl +greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { + INCLUDEPATH += ../common/rhi + DEFINES += YACREADER_USE_RHI +} win32 { - LIBS += -loleaut32 -lole32 -lshell32 -lopengl32 -luser32 + LIBS += -loleaut32 -lole32 -lshell32 -luser32 + # When using RHI (Qt 6.7+), don't link OpenGL directly - QRhiWidget handles graphics APIs + message("RHI mode: not linking opengl32 (using QRhiWidget)") + greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { + } else { + LIBS += -lopengl32 + } msvc { QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL @@ -51,6 +61,10 @@ QT += sql network widgets svg quickcontrols2 greaterThan(QT_MAJOR_VERSION, 5): QT += openglwidgets core5compat +greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { + QT += gui-private +} + # Input HEADERS += comic_flow.h \ ../common/concurrent_queue.h \ @@ -140,6 +154,10 @@ HEADERS += comic_flow.h \ !CONFIG(no_opengl) { HEADERS += ../common/gl/yacreader_flow_gl.h + + greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { + HEADERS += ../common/rhi/yacreader_flow_rhi.h + } } SOURCES += comic_flow.cpp \ @@ -228,6 +246,11 @@ SOURCES += comic_flow.cpp \ !CONFIG(no_opengl) { SOURCES += ../common/gl/yacreader_flow_gl.cpp + + greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { + SOURCES += ../common/rhi/yacreader_flow_rhi.cpp + RESOURCES += ../common/rhi/shaders/shaders.qrc + } } macx { diff --git a/YACReaderLibrary/comic_flow_widget.cpp b/YACReaderLibrary/comic_flow_widget.cpp index 95515d913..f0bc487cb 100644 --- a/YACReaderLibrary/comic_flow_widget.cpp +++ b/YACReaderLibrary/comic_flow_widget.cpp @@ -158,10 +158,15 @@ void ComicFlowWidgetSW::resortCovers(QList newOrder) ComicFlowWidgetGL::ComicFlowWidgetGL(QWidget *parent) : ComicFlowWidget(parent) { - flow = new YACReaderComicFlowGL(parent); +#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) + qDebug() << "ComicFlowWidgetGL: Creating YACReaderComicFlow3D (RHI implementation)"; +#else + qDebug() << "ComicFlowWidgetGL: Creating YACReaderComicFlowGL (OpenGL implementation)"; +#endif + flow = new YACReaderComicFlowImpl(this); - connect(flow, &YACReaderFlowGL::centerIndexChanged, this, &ComicFlowWidget::centerIndexChanged); - connect(flow, &YACReaderFlowGL::selected, this, &ComicFlowWidget::selected); + connect(flow, &YACReaderComicFlowImpl::centerIndexChanged, this, &ComicFlowWidget::centerIndexChanged); + connect(flow, &YACReaderComicFlowImpl::selected, this, &ComicFlowWidget::selected); auto l = new QVBoxLayout; l->addWidget(flow); diff --git a/YACReaderLibrary/comic_flow_widget.h b/YACReaderLibrary/comic_flow_widget.h index ace364884..981585925 100644 --- a/YACReaderLibrary/comic_flow_widget.h +++ b/YACReaderLibrary/comic_flow_widget.h @@ -6,7 +6,14 @@ #include "pictureflow.h" #include "comic_flow.h" #ifndef NO_OPENGL +// Conditional include based on Qt version and RHI availability +#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) +#include "yacreader_flow_rhi.h" +using YACReaderComicFlowImpl = YACReaderComicFlow3D; +#else #include "yacreader_flow_gl.h" +using YACReaderComicFlowImpl = YACReaderComicFlowGL; +#endif #endif class ComicFlowWidget : public QWidget { @@ -83,7 +90,7 @@ class ComicFlowWidgetGL : public ComicFlowWidget { Q_OBJECT private: - YACReaderComicFlowGL *flow; + YACReaderComicFlowImpl *flow; public: ComicFlowWidgetGL(QWidget *parent = nullptr); diff --git a/YACReaderLibrary/comics_view.cpp b/YACReaderLibrary/comics_view.cpp index b2cca088c..88ac2e6ed 100644 --- a/YACReaderLibrary/comics_view.cpp +++ b/YACReaderLibrary/comics_view.cpp @@ -17,10 +17,10 @@ ComicsView::ComicsView(QWidget *parent) view = new QQuickWidget(); - // QQuickWidget requires rendering into OpenGL framebuffer objects -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - view->quickWindow()->setGraphicsApi(QSGRendererInterface::OpenGL); -#endif + // In Qt 6, QQuickWidget supports Qt RHI and can use any graphics backend + // (Vulkan, Metal, Direct3D, OpenGL, or software rendering). + // The backend can be configured via QQuickWindow::setGraphicsApi() or QSG_RHI_BACKEND env var. + // Note: All widgets in the same top-level window must use the same graphics API. view->setResizeMode(QQuickWidget::SizeRootObjectToView); connect( diff --git a/YACReaderLibrary/folder_content_view.cpp b/YACReaderLibrary/folder_content_view.cpp index 679e8f2d2..8d31844e9 100644 --- a/YACReaderLibrary/folder_content_view.cpp +++ b/YACReaderLibrary/folder_content_view.cpp @@ -26,10 +26,10 @@ FolderContentView::FolderContentView(QAction *toogleRecentVisibilityAction, QWid view = new QQuickWidget(); - // QQuickWidget requires rendering into OpenGL framebuffer objects -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - view->quickWindow()->setGraphicsApi(QSGRendererInterface::OpenGL); -#endif + // In Qt 6, QQuickWidget supports Qt RHI and can use any graphics backend + // (Vulkan, Metal, Direct3D, OpenGL, or software rendering). + // The backend can be configured via QQuickWindow::setGraphicsApi() or QSG_RHI_BACKEND env var. + // Note: All widgets in the same top-level window must use the same graphics API. view->setResizeMode(QQuickWidget::SizeRootObjectToView); connect( diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 78ac4f3ad..158a20106 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -204,6 +204,12 @@ void LibraryWindow::setupOpenglSetting() // FLOW----------------------------------------------------------------------- //--------------------------------------------------------------------------- +#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) + // When using RHI, assume hardware acceleration is available + bool openGLAvailable = true; + if (!settings->contains(USE_OPEN_GL)) + settings->setValue(USE_OPEN_GL, 2); +#else OpenGLChecker openGLChecker; bool openGLAvailable = openGLChecker.hasCompatibleOpenGLVersion(); @@ -212,6 +218,7 @@ void LibraryWindow::setupOpenglSetting() else if (!openGLAvailable) settings->setValue(USE_OPEN_GL, 0); #endif +#endif } void LibraryWindow::setupUI() diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index 5e703c2d2..e60e9ae69 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -83,8 +83,12 @@ void logSystemAndConfig() else QLOG_INFO() << "OpenGL : disabled"; +#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) + QLOG_INFO() << "Using RHI (Qt Rendering Hardware Interface) - graphics backend will be auto-selected"; +#else OpenGLChecker checker; QLOG_INFO() << "OpenGL version : " << checker.textVersionDescription(); +#endif auto libraries = DBHelper::getLibraries().getLibraries(); QLOG_INFO() << "Libraries: "; @@ -200,6 +204,8 @@ int main(int argc, char **argv) #endif parser.process(app); +// When using RHI (Qt 6.7+), don't allow OpenGL attribute overrides +#if !defined(YACREADER_USE_RHI) || QT_VERSION < QT_VERSION_CHECK(6, 7, 0) #ifdef Q_OS_WIN if (parser.isSet("opengl")) { QTextStream qout(stdout); @@ -216,6 +222,7 @@ int main(int argc, char **argv) parser.showHelp(); } } +#endif #endif if (parser.isSet("loglevel")) { diff --git a/common/opengl_checker.cpp b/common/opengl_checker.cpp index 2a73af96e..a6d1840f8 100644 --- a/common/opengl_checker.cpp +++ b/common/opengl_checker.cpp @@ -1,7 +1,5 @@ #include "opengl_checker.h" -#include "QsLog.h" - OpenGLChecker::OpenGLChecker() : compatibleOpenGLVersion(true) { diff --git a/common/rhi/README.md b/common/rhi/README.md new file mode 100644 index 000000000..fd1247976 --- /dev/null +++ b/common/rhi/README.md @@ -0,0 +1,287 @@ +# YACReader Flow RHI Implementation + +This directory contains the QRhiWidget-based implementation of the YACReader 3D cover flow, providing cross-platform 3D rendering support for Qt 6.7+. + +## Overview + +The RHI (Rendering Hardware Interface) implementation is a modern replacement for the OpenGL-based flow (`yacreader_flow_gl`) that: + +- ✅ Supports **multiple graphics APIs**: Vulkan, Metal, Direct3D 11/12, OpenGL +- ✅ Provides **native performance** on modern platforms (Metal on macOS, D3D on Windows) +- ✅ Maintains **100% API compatibility** with the OpenGL version +- ✅ Works seamlessly with **Qt 6.7+** while Qt5 continues using OpenGL +- ✅ Enables **future-proof** rendering infrastructure + +## Architecture + +### Class Hierarchy + +``` +QRhiWidget (Qt base class) + └── YACReaderFlow3D (Base implementation) + ├── YACReaderComicFlow3D (File path-based loading for library) + └── YACReaderPageFlow3D (Byte array-based loading for viewer) +``` + +### Files + +- **yacreader_flow_rhi.h** - Header with class definitions +- **yacreader_flow_rhi.cpp** - Implementation +- **shaders/** - GLSL 450 shaders and compiled .qsb files +- **README.md** - This file + +## Key Features + +### Graphics Pipeline + +The implementation uses: +- **Instanced rendering** for efficient batch drawing +- **Dual-pass rendering** (reflections + covers) +- **MSAA** (4x by default) for anti-aliasing +- **Depth testing** and back-face culling +- **Alpha blending** for transparency + +### Resource Management + +QRhi resources managed: +- `QRhiBuffer` for vertices, instance data, and uniforms +- `QRhiTexture` for cover images, marks, and default texture +- `QRhiSampler` for texture filtering +- `QRhiGraphicsPipeline` for render state +- `QRhiShaderResourceBindings` for uniform/texture bindings + +### Shader System + +Shaders are written in **GLSL 4.50** and compiled to `.qsb` format supporting: +- OpenGL ES 2.0, 3.0 +- OpenGL 2.1, 3.0+ +- HLSL (Direct3D 11/12) +- Metal Shading Language (macOS/iOS) + +## Integration + +### Qt5 vs Qt6 Selection + +The build system automatically selects the appropriate implementation: + +**Qt 5.x**: Uses `YACReaderFlowGL` (OpenGL-based) +**Qt 6.0-6.6**: Uses `YACReaderFlowGL` (OpenGL-based) +**Qt 6.7+**: Uses `YACReaderFlow3D` (RHI-based) if `YACREADER_USE_RHI` is defined + +### Type Aliases + +Applications use type aliases for seamless switching: + +```cpp +#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) +using YACReaderPageFlowImpl = YACReaderPageFlow3D; +using YACReaderComicFlowImpl = YACReaderComicFlow3D; +#else +using YACReaderPageFlowImpl = YACReaderPageFlowGL; +using YACReaderComicFlowImpl = YACReaderComicFlowGL; +#endif +``` + +### Example Usage (YACReader Viewer) + +```cpp +// goto_flow_gl.cpp +flow = new YACReaderPageFlowImpl(this); +flow->setShowMarks(false); +flow->populate(numPages); +connect(flow, &YACReaderPageFlowImpl::selected, this, &GoToFlowGL::goToPage); +``` + +### Example Usage (YACReaderLibrary) + +```cpp +// comic_flow_widget.cpp +flow = new YACReaderComicFlowImpl(parent); +flow->setImagePaths(pathsList); +connect(flow, &YACReaderComicFlowImpl::centerIndexChanged, + this, &ComicFlowWidget::centerIndexChanged); +``` + +## API Compatibility + +All public methods from `YACReaderFlowGL` are preserved: + +### Navigation +- `showPrevious()`, `showNext()` +- `setCurrentIndex(int)`, `setCenterIndex(unsigned int)` +- `showSlide(int)`, `centerIndex()` + +### Configuration +- `setPreset(const Preset &)` +- `setPerformance(Performance)` +- `setFlowRightToLeft(bool)` +- `setZoom(int)`, `setRotation(int)` +- `setCF_RX/RY/RZ(int)`, `setCF_Y/Z(int)` +- `setX_Distance(int)`, `setCenter_Distance(int)`, etc. + +### Appearance +- `setBackgroundColor(const QColor &)` +- `setTextColor(const QColor &)` +- `setShadingColor(const QColor &)` +- `setShowMarks(bool)`, `setMarks(QVector<...>)` + +### Content Management +- `populate(int)`, `clear()`, `reset()`, `reload()` +- `insert()`, `remove(int)`, `add(int)`, `replace()` +- Subclass-specific: `setImagePaths()`, `resortCovers()`, etc. + +## Building + +### Prerequisites + +1. **Qt 6.7 or later** +2. **qsb tool** (Qt Shader Baker) in PATH +3. **C++17 compiler** + +### Compile Shaders + +Before building YACReader, compile the shaders: + +```bash +cd common/rhi/shaders +# Windows +compile_shaders.bat + +# Unix/macOS +chmod +x compile_shaders.sh +./compile_shaders.sh +``` + +This generates `flow.vert.qsb` and `flow.frag.qsb` which are embedded via `shaders.qrc`. + +### Build YACReader + +The `.pro` files automatically include RHI sources for Qt 6.7+: + +```bash +qmake YACReader.pro +make +``` + +For Qt 5 builds, the OpenGL version is used automatically. + +## Graphics API Selection + +QRhiWidget auto-selects the best API per platform: + +- **macOS/iOS**: Metal (native) +- **Windows**: Direct3D 11 (default) or Direct3D 12 +- **Linux**: Vulkan or OpenGL +- **Android**: OpenGL ES 3.0 or Vulkan + +You can force a specific API via environment variables (for testing): + +```bash +# Force OpenGL +export QSG_RHI_BACKEND=opengl + +# Force Vulkan +export QSG_RHI_BACKEND=vulkan + +# Force Direct3D 11 (Windows) +set QSG_RHI_BACKEND=d3d11 +``` + +## Performance + +Performance tiers match the OpenGL version: + +- **Low**: 8 covers loaded, 128px textures (page flow) / 200px (comic flow) +- **Medium**: 10 covers, 196px / 256px textures +- **High**: 12 covers, 256px / 320px textures +- **Ultra High**: 14-16 covers, full resolution textures + +Texture loading happens asynchronously via worker threads (`ImageLoader3D`, `ImageLoaderByteArray3D`). + +## Debugging + +### Enable Validation Layers + +For debugging graphics issues, enable validation: + +```cpp +flow->setDebugLayerEnabled(true); // Call before widget is shown +``` + +This activates: +- **Vulkan**: VK_LAYER_KHRONOS_validation +- **Direct3D**: D3D11 debug layer +- **Metal**: Metal API validation + +### Check Active Graphics API + +```cpp +QRhi *rhi = flow->rhi(); +qDebug() << "Backend:" << rhi->backend(); +qDebug() << "Driver:" << rhi->driverInfo(); +``` + +### Common Issues + +**Problem**: Shaders fail to load +**Solution**: Ensure `.qsb` files are compiled and included in resources + +**Problem**: Black screen on Qt 6.7 +**Solution**: Check if `YACREADER_USE_RHI` is defined in build + +**Problem**: Crashes on resize/reparent +**Solution**: `releaseResources()` properly cleans up all QRhi objects + +## Migration from OpenGL + +The RHI version is a **drop-in replacement** requiring no application code changes beyond the build system. + +### What's Different (Internal) + +| OpenGL API | QRhi Equivalent | +|------------|-----------------| +| `glDrawArraysInstanced()` | `cb->drawIndexed(instanceCount)` | +| `glUniform*()` | Update `QRhiBuffer` with uniform data | +| `glBindTexture()` | `QRhiShaderResourceBindings` | +| `glBlendFunc()` | `QRhiGraphicsPipeline::setTargetBlends()` | +| `glEnable(GL_DEPTH_TEST)` | `pipeline->setDepthTest(true)` | + +### What's the Same + +- All public API methods and signatures +- Animation system and timing +- Preset configurations +- Event handling (mouse, keyboard, wheel) +- Worker thread texture loading +- Performance tiers + +## Known Limitations + +1. **Qt Version**: Requires Qt 6.7+ (released April 2024) +2. **QRhi Stability**: QRhi APIs may change in minor Qt releases +3. **Mixed Renderers**: Only one graphics API per window +4. **Shader Compilation**: Must recompile shaders when modifying source + +## Future Improvements + +Potential enhancements: +- [ ] GPU-side frustum culling +- [ ] Compute shader for texture generation +- [ ] HDR/wide color gamut support +- [ ] Ray-traced reflections (via RHI compute) +- [ ] Dynamic LOD based on distance + +## References + +- [QRhiWidget Class Documentation](https://doc.qt.io/qt-6/qrhiwidget.html) +- [QRhi Overview](https://doc.qt.io/qt-6/qrhi.html) +- [Qt RHI Examples](https://doc.qt.io/qt-6/qtwidgets-rhi-cuberhiwidget-example.html) +- [Qt Shader Tools (qsb)](https://doc.qt.io/qt-6/qtshadertools-index.html) + +## License + +Same as YACReader project license. + +## Author + +Generated as part of the YACReader OpenGL modernization initiative. diff --git a/common/rhi/shaders/README.md b/common/rhi/shaders/README.md new file mode 100644 index 000000000..7b8828201 --- /dev/null +++ b/common/rhi/shaders/README.md @@ -0,0 +1,49 @@ +# YACReader Flow RHI Shaders + +This directory contains the GLSL 4.50 shaders for the QRhiWidget-based flow implementation. + +## Files + +- `flow.vert` - Vertex shader (GLSL 450) +- `flow.frag` - Fragment shader (GLSL 450) +- `flow.vert.qsb` - Compiled vertex shader (multi-platform) +- `flow.frag.qsb` - Compiled fragment shader (multi-platform) +- `compile_shaders.bat` - Windows compilation script +- `compile_shaders.sh` - Unix/macOS compilation script +- `shaders.qrc` - Qt resource file + +## Compiling Shaders + +The shaders must be compiled to `.qsb` format using Qt's `qsb` tool before building YACReader. + +### Prerequisites + +Ensure `qsb` is in your PATH. It's typically located in: +- Windows: `C:\Qt\6.x.x\msvc2019_64\bin\qsb.exe` +- macOS: `/opt/Qt/6.x.x/macos/bin/qsb` +- Linux: `/opt/Qt/6.x.x/gcc_64/bin/qsb` + +### Compilation + +**Windows:** +```cmd +cd common/rhi/shaders +compile_shaders.bat +``` + +**Unix/macOS:** +```bash +cd common/rhi/shaders +chmod +x compile_shaders.sh +./compile_shaders.sh +``` + +The compiled `.qsb` files contain shader variants for: +- OpenGL ES 2.0, 3.0 +- OpenGL 2.1, 3.0+ +- HLSL (Direct3D 11/12) +- Metal Shading Language (macOS/iOS) + +## Note + +The `.qsb` files are included in the repository for convenience. Recompile only if you modify the shader source. diff --git a/common/rhi/shaders/compile_shaders.bat b/common/rhi/shaders/compile_shaders.bat new file mode 100644 index 000000000..56ce73818 --- /dev/null +++ b/common/rhi/shaders/compile_shaders.bat @@ -0,0 +1,19 @@ +@echo off +REM Compile shaders to .qsb format for Qt RHI +REM Requires qsb tool from Qt installation + +echo Compiling flow vertex shader... +qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o flow.vert.qsb flow.vert +if %ERRORLEVEL% NEQ 0 ( + echo Error compiling vertex shader + exit /b 1 +) + +echo Compiling flow fragment shader... +qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o flow.frag.qsb flow.frag +if %ERRORLEVEL% NEQ 0 ( + echo Error compiling fragment shader + exit /b 1 +) + +echo Shader compilation complete! diff --git a/common/rhi/shaders/compile_shaders.sh b/common/rhi/shaders/compile_shaders.sh new file mode 100644 index 000000000..f084121f2 --- /dev/null +++ b/common/rhi/shaders/compile_shaders.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Compile shaders to .qsb format for Qt RHI +# Requires qsb tool from Qt installation + +echo "Compiling flow vertex shader..." +qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o flow.vert.qsb flow.vert +if [ $? -ne 0 ]; then + echo "Error compiling vertex shader" + exit 1 +fi + +echo "Compiling flow fragment shader..." +qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o flow.frag.qsb flow.frag +if [ $? -ne 0 ]; then + echo "Error compiling fragment shader" + exit 1 +fi + +echo "Shader compilation complete!" diff --git a/common/rhi/shaders/flow.frag b/common/rhi/shaders/flow.frag new file mode 100644 index 000000000..01b474d9a --- /dev/null +++ b/common/rhi/shaders/flow.frag @@ -0,0 +1,44 @@ +#version 450 + +// Inputs from vertex shader +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec4 vColor; +layout(location = 2) in float vIsReflection; + +// Output +layout(location = 0) out vec4 fragColor; + +// Uniform buffer +layout(std140, binding = 0) uniform UniformBuffer +{ + mat4 viewProjectionMatrix; + vec3 backgroundColor; + float _pad0; + vec3 shadingColor; + float _pad1; + float reflectionUp; + float reflectionDown; + int isReflection; + float _pad2; +}; + +// Texture and sampler +layout(binding = 1) uniform sampler2D coverTexture; + +void main() +{ + vec4 texColor = texture(coverTexture, vTexCoord); + + // Apply shading: multiply texture by vColor.r to darken + float shadingAmount = vColor.r; + + // For reflections, apply gradient fade (darker at bottom, fading to black) + if (vIsReflection > 0.5) { + // vTexCoord.y goes from 1 (top of reflection, near cover) to 0 (bottom, far from cover) + // We want it brightest near the cover and fading away + float gradientFade = mix(0.0, 0.33, vTexCoord.y); + shadingAmount *= gradientFade; + } + + fragColor = vec4(texColor.rgb * shadingAmount, texColor.a); +} diff --git a/common/rhi/shaders/flow.frag.qsb b/common/rhi/shaders/flow.frag.qsb new file mode 100644 index 0000000000000000000000000000000000000000..f50613bb41bc80d1f8194c9a3d4b5aabc6de262b GIT binary patch literal 1990 zcmV;%2RZlv03F$Qob6d#Zxcrp9$%7xxkI=^x)2Huq|W*l0>LJblr~aO(p+ez5Sfj= zb{1@}wYzo#C{kbg+Q}mWm6>dZ%`zK)999A}3>W*I7VEJNgBS`_xrk5~+DqU92+T8=ErYEx zh?%U&JZ6D-9YxXRUg9C{Y8h-9tkPw9Pgg_S`Wo1=KmiKX*hAKY`!aZeDh64BO|lH! zH556_QXIUtfNPsA0jJHL`}}?k&Uk=ZkUho@k=%@;>pWvmQ zf^+b>-R^@@f2&sC209AYRzJZ`WGS*y?Z+xth}$cI_7-mvaYQ_*8wLQ4LERSGOUZuM zAbpn<=<`T;bO`kyVh7j*LQlZKM2m+&1iwF8SXoH8UMZ2uVqZWOB5m)FK?6rA%$i}< zg*;@ckjw1$Rf_`wGcR`YPE*8s$e6`Yh3s|1!~Gq9=U(5tgUDk6|xQ z_yDH|+Vl_;$413Q>04qU!e$gKOxS{gMF?9`uqa_q6>Na8X9_k*SV_T#2-{My1B6v6 z<{8Q%Q)rpPQ{ZKo??)s|NnZqgIErE< zFV8w+(?lO34DB5wePQB1&Sd`xexy$jhWo?h%OKHbXm5!4&oI$rh@A%d9L0v~7SZR4 zM)?cGJ4o_KUnUIs5r0px-ya4qH3ffP(TntTxW4`I>%6pcL-9MoL_bJBk)9w7^PrOt z5yj6e(dU4^N3v0hD@Spm{t?J7_5$)qJ@Q*#IVETJDc^bW1?d^WCZVswtTUd_{?C96 z5HI$_K_!l1?vJ0oMsyBntou=_d5-FRl4|-XXhptL#B-AS6yf?2djR`bkBd~(^P~gg zxI{SepC(%FjZh800eQ^P6~eHNKLNiy&%Xjc?&0|ur8uuDcH`vd4Mq1D;fEm;NZ+Iy zB&Z**6A$`zjrOJNEy|6g$0>JTfIXx?AncYB7h=DFU(&x(lE=IysTPai3)VYDSd!uk zQB9@2G}-$S>>+=KWYQG#Ft5MRnN{R&6aESLIYqKe!R`+uT_Zw)K64N9~&kgxhrV$efjkZk3wd}f<)b&`yF^d+bwyerlLn~Kp!<+7ctvY}) z*K?XhPg|>7W!tGeY?jNW6MG%gVATvSqqQt^d&#k%n?(;q9~+)y?M(CSmRU?|n?~_P z#j%_9(yU#z9kIg=YK4YT(iK*B%P3j(N>9F|3OHuDD$K1ldgF8Uc3td15SryKw|9by zQ`50sh_Wfd^M|PwCNs*O$ck&!8dcLt&1pp&lDcZ{cumIywwB?%1ottPl-2@#*0!C} zw2DKvC^`uWM_Thf4`VIcDrs2C_!y;{3wx*&#I+pWqS@43T=inSV|PpqlrsCE26ga2 zT6mG5I$32c?(;y)YkDF(#y5rej;e|Ss?56g$S9ehsb=lO^@KhS0_n7lE16Cv(|Rg7 zmDRIT**odmS;ecwOY#es->aKBpKign%RejC!XwA1%o(1su5Y0Kkd3&^Mq=mXEA6IV z+ju)yiEXgB8;b=F#|~?+@b{g=k<#Bad}r@ntN#~T{VS!_zw5Mm_Fb#*r`4@`SC}|X03C1#1lz8{w@BfExZztw&H+q=f%V-V!P}~${_80vw^ijofJ=2MA>aqZi zyS0Az#93bP4A0aGDrqY-(gobI!9hbgU8-4p`Lvjw<}BY z%TEfkj_taI`Ff-2Q6C14gO{rxem1+fxICvT`I25J+rA0vKk*$Vnua}`SZsO$FBHE) z!^)Gws^L^jPZuiq3`2&3Z;+9sGRoB4Cq!A|Jqz+y=UaJS0}iYeZA?z46fS6x{&Rjatce*&k|@#g)!Ck1AVN)sqDlc?&8uj zNCimBcHY<+Z~wkg5>K1J!)AS5zMrAPbFBSdE&aeNr@h{t-p}w9 zs^VQ%#=-x@{$?jKc8yO2|Is%@)xEzqK<(f#c;g|e%nVzM3Y--KycG2A7^o1J4${hKk_Ka6XXr@BX5$UDwTBae1q+s-34Sjl~gKZ)e7kDufOT( zndxb4*-EJ&DgDQvFDg%UR8Iw}PM;0sszv3iCVjS5O?Bz}wki^ClAiH@;!mag-49U- zL=!)hs0^aXA4*gK(Scz^N7N>Pdqfw|;}aQ8fepi*0vc&Yog)XIMr(2c=@}d5bTkq2 z1q#-q@yU^%gTtJig!5IkPT!lMer=HbsbM6~B}kTN^g4ax+3zBb>0uO{nupbvx|TZs zp-DSTZtTzwU39oZ6ZRB2T%vHV&{!>Ub1BehkvP<$n|3UuxK3b?+-U?gqz_q7cryD$Xw#@C}m3S2z!j>(PNY_#%I}MbW_&i`d|xxk>&VI zs^j_an3~0GW{>J+?t%yCS&@+?JVf`{TsulA)Uf!GlCrc)5Q4kX@(wB2i32k zeTWVWJ0Bt!{(SH9)ysum&@5Evc&TY(6N3RBq$6hr*{FM+kX7l)^G;(cJ1x+2k)HSI zS)}JvdhXD3m!5k(1~IVTb4njqmLGsT0r?2zNyraFJ`l-HNrAtBBjkEpVE>(9!VI^O*M?*iBq_RkXJ_o_nyLp!3SS zrjWDlucSEuEbr@_iuN(b{)r`jZpn2^b}iYn9b?xhm<}$ zMt(%;v-1JXf^+jYIF!&m0o|C;9ffXO=$?dbLg=1C43h6@=p^4W&`G{$p_6>iVGfe- zdFUjc1D)hM2A$-40XdL-$DxyaFG45zUV=`yPSasNUq%j}K#raiwpWmkr!n7Wg)NV{ zJ&)Lr3EK?fJdQYCf{oAis~GbYa4`05iYN!$I}|I|f|E+uhcecleSZSIkxwbTe}79p zEYAaT3YbdBt?P!#!D;AZ{?0%r^Y;#P<6>TC;eQ5puGzmKJloD;{Ii$?pVN1huCHax z@m=5+P_KTfbj@MgMaT;{^FLF%-u!{MmXyBFS;zOnUkHB%bND;qm&3SKsN?hf0b=0V za1~?B3hryre~YU|rplAP2ARBxQ zcp29h&@=vX$Ohj4epTR`&@;Xc+2GfJZwdT5^o(~Q8{18#Yn_pADP0QK#=8Oi zUF6Y+j_dVd+L5d?KO+hl;}&ong9p3e9b(Zuq`d`kpZIH_G(; zn*Up1SZ~heFQJzYbKil@aQ#Z@bH%oMkpDrEozy>jCh=Ru{CLA}p#y(BzU6j%p5Jjw z#bPek3%dPA;9T!`Ex)^Qw%=;G-P~6>hyFI|LDkvv-0kJAf75LQ=FzwLLmrPcQ9fm7S8H;V$=Tdz00&RQz2Bo$q^)z-sZ-%Qt^_qRLR z;&lSY>s=XGY~u2KZf`!9>+9*or|Hz@s${DNG^f>m;BuH%V(bO=PQzXFn{K<-^|xsb zqadZxkn(6q#e!6vO~2>qS#8z3yOcaumz}L^?#?;i?=~%mvJ<2jbTZ6n7uw!tW++$n z5|v`((H_8>WpOTT)*D{18+mE-)}`3OF}=1&&VAX%Y(BJD)T&UKDiV#vrf9D zlxZnvS}HR$db_N(Ys<(qji0A&QApeN&a3fQXGjq;n`N4HN`)dg2Wv!((W-=7w&mpI zYB3RcIGWKpQ0i7-Pqal z*4Bs9-%h|s@Ne7kMA!{)CvQbK8=v6p;A~KOUZecY%_PQ;^VuQIT5}q~*h>T#=Si~c z#8~thBKL5|7`9jKGi1>6=!oR$)4P|;Sp|Ma4gO?-FYg!l{Q|#V;P(sseu4iVFYvz; z1^#wa;OF)WJlVWXc4g1Bm4?{LLu?gelhxbr2Z_q9QL{LQ8tAJY$)mSiW`Ddy|v}jqlhl3xZT`Rsf2@@DrU7WD>O4#moHuUuy(HN_j%Vx^liK);F4*0LTUhZi3C|h)Z~MJu@hX4yy!N z2Ui~2^uhJANbul}NOy>CZs}w$jC7yD#T{;tsM=~p%7)M+ekf>=)D+@%FxFZnu(GU) zP9}*PwE5!YL>yu5Y^(7IyK*<^cRN=2d$Q-BRI&d`cl!6oy-uUuZ@SJ~8*Wf<*Lp#- z?XA9@i}XEjqxlB^Q&@jHm+SZV2zKflZjZ9+I-%G6(04e4+bsJ%4)?HbvxesA{$A+B zeg2zob})BNago!W)o84&^n3Ixs_i#A#hDv7(wYqcDa9dHWfQ=%%_aBe%8EI-3`#`n zbu#+Wm6gG(^t=_UXig=nWQUPbEG0e>c1n$u_{vCpIfk!}#8+bYxh(vkB1!ZKYjx~O zB(ZO1V8gm7fhT9oB5{>+ccLw&zva!M5d}G#T6g2dtkdvAQtJf1%xxDT^$+`SA){Al zhMJ!R=c~Q>_-P&8d#2oWvW-l+(}tVN!_9*})KApl@AT>|8Y1oen{O3uf~B>iu^TMo zObDH!R-Jd3Xe&EYFu_*t(_j992@B0;kFN4^aJ4m#%nz5Ro>u#8&UY5m#k|)VK+J(7ykVV6%*1N D8729a literal 0 HcmV?d00001 diff --git a/common/rhi/shaders/shaders.qrc b/common/rhi/shaders/shaders.qrc new file mode 100644 index 000000000..37a0d50b8 --- /dev/null +++ b/common/rhi/shaders/shaders.qrc @@ -0,0 +1,6 @@ + + + flow.vert.qsb + flow.frag.qsb + + diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp new file mode 100644 index 000000000..dc3f7c490 --- /dev/null +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -0,0 +1,1744 @@ +#include "yacreader_flow_rhi.h" +#include +#include + +// Structure for per-instance data +struct InstanceData { + QMatrix4x4 modelMatrix; + float leftUpShading; + float leftDownShading; + float rightUpShading; + float rightDownShading; + float opacity; + float padding[3]; // Align to 16 bytes +}; + +/*** Preset Configurations ***/ +// Note: The preset configurations are already defined in yacreader_flow_gl.cpp +// We just reference them here as extern to avoid duplicate symbols + +int YACReaderFlow3D::updateInterval = 16; + +static QShader getShader(const QString &name) +{ + QFile f(name); + return f.open(QIODevice::ReadOnly) ? QShader::fromSerialized(f.readAll()) : QShader(); +} + +/*Constructor*/ +YACReaderFlow3D::YACReaderFlow3D(QWidget *parent, struct Preset p) + : QRhiWidget(parent), numObjects(0), lazyPopulateObjects(-1), hasBeenInitialized(false), backgroundColor(Qt::black), textColor(Qt::white), shadingColor(Qt::black), flowRightToLeft(false), showMarks(true) +{ + updateCount = 0; + config = p; + currentSelected = 0; + + centerPos.x = 0.f; + centerPos.y = 0.f; + centerPos.z = 1.f; + centerPos.rot = 0.f; + + shadingTop = 0.8f; + shadingBottom = 0.02f; + reflectionUp = 0.f; + reflectionBottom = 0.6f; + + setBackgroundColor(Qt::black); + + numObjects = 0; + viewRotate = 0.f; + viewRotateActive = 0; + stepBackup = config.animationStep / config.animationSpeedUp; + + // Request 4x MSAA for the QRhiWidget's render target + setSampleCount(4); + + timerId = -1; +} + +YACReaderFlow3D::~YACReaderFlow3D() +{ + if (timerId != -1) { + killTimer(timerId); + timerId = -1; + } +} + +void YACReaderFlow3D::timerEvent(QTimerEvent *event) +{ + if (timerId == event->timerId()) + update(); +} + +void YACReaderFlow3D::startAnimationTimer() +{ + if (timerId == -1) + timerId = startTimer(updateInterval); +} + +void YACReaderFlow3D::stopAnimationTimer() +{ + if (timerId != -1) { + killTimer(timerId); + timerId = -1; + } +} + +void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) +{ + if (m_rhi != rhi()) { + releaseResources(); + m_rhi = rhi(); + } + + if (!m_rhi) + return; + + // Initialize default texture from image + if (!defaultTexture) { + QImage defaultImage(":/images/defaultCover.png"); + + defaultTexture = m_rhi->newTexture(QRhiTexture::BGRA8, defaultImage.size(), 1, QRhiTexture::MipMapped); + defaultTexture->create(); + QRhiResourceUpdateBatch *batch = m_rhi->nextResourceUpdateBatch(); + batch->uploadTexture(defaultTexture, defaultImage); + cb->resourceUpdate(batch); + qDebug() << "YACReaderFlow3D: Created defaultTexture" << defaultImage.size(); + } + +#ifdef YACREADER_LIBRARY + // Initialize mark textures + if (!markTexture) { + QImage markImage(":/images/readRibbon.png"); + if (!markImage.isNull()) { + markTexture = m_rhi->newTexture(QRhiTexture::BGRA8, markImage.size(), 1, QRhiTexture::MipMapped); + markTexture->create(); + + QRhiResourceUpdateBatch *batch = m_rhi->nextResourceUpdateBatch(); + batch->uploadTexture(markTexture, markImage); + cb->resourceUpdate(batch); + } + } + + if (!readingTexture) { + QImage readingImage(":/images/readingRibbon.png"); + if (!readingImage.isNull()) { + readingTexture = m_rhi->newTexture(QRhiTexture::BGRA8, readingImage.size(), 1, QRhiTexture::MipMapped); + readingTexture->create(); + + QRhiResourceUpdateBatch *batch = m_rhi->nextResourceUpdateBatch(); + batch->uploadTexture(readingTexture, readingImage); + cb->resourceUpdate(batch); + } + } +#endif + + // Create vertex buffer (quad geometry) + if (!vertexBuffer) { + // Use a triangle list (two triangles = 6 vertices) because some RHI backends + // don't support TriangleFan. Each vertex: x,y,z,u,v (5 floats). + vertexBuffer = m_rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, 6 * 5 * sizeof(float)); + vertexBuffer->create(); + + // Two triangles forming a quad (triangle list): + // Tri 1: bottom-left, bottom-right, top-right + // Tri 2: bottom-left, top-right, top-left + // Texture coords flipped vertically to match OpenGL convention + float vertices[] = { + // Position (x, y, z), TexCoord (u, v) + -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-left + 0.5f, -0.5f, 0.0f, 1.0f, 1.0f, // Bottom-right + 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right + + -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-left + 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right + -0.5f, 0.5f, 0.0f, 0.0f, 0.0f // Top-left + }; + + QRhiResourceUpdateBatch *batch = m_rhi->nextResourceUpdateBatch(); + batch->uploadStaticBuffer(vertexBuffer, vertices); + cb->resourceUpdate(batch); + } + + // Initialize alignment for uniform buffers + if (alignedUniformSize == 0) { + alignedUniformSize = m_rhi->ubufAligned(sizeof(UniformData)); + } + + // Create sampler + if (!sampler) { + // Use no mipmap sampling to avoid LOD changes with camera Z + sampler = m_rhi->newSampler( + QRhiSampler::Linear, + QRhiSampler::Linear, + QRhiSampler::None, + QRhiSampler::ClampToEdge, + QRhiSampler::ClampToEdge); + sampler->create(); + } + + // Create instance buffer for per-draw instance data + if (!instanceBuffer) { + // Allocate buffer for per-instance data (model matrix + shading + opacity + flipFlag) + // mat4 (16 floats) + vec4 (4 floats) + float (1 float) + float (1 float) = 22 floats + instanceBuffer = m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, 22 * sizeof(float)); + instanceBuffer->create(); + } + + // Setup graphics pipeline + if (!pipeline) { + // Load shaders + QShader vertShader = getShader(QLatin1String(":/shaders/flow.vert.qsb")); + QShader fragShader = getShader(QLatin1String(":/shaders/flow.frag.qsb")); + + if (!vertShader.isValid() || !fragShader.isValid()) { + qWarning() << "YACReaderFlow3D: Failed to load shaders!"; + return; + } + + // Create default shader resource bindings for pipeline creation + // We'll create texture-specific ones on-demand in drawCover + shaderBindings = m_rhi->newShaderResourceBindings(); + shaderBindings->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, uniformBuffer), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, defaultTexture, sampler) }); + shaderBindings->create(); + + // Create pipeline + pipeline = m_rhi->newGraphicsPipeline(); + + // Disable alpha blending temporarily to test if blending causes darkening + QRhiGraphicsPipeline::TargetBlend blend; + blend.enable = true; + blend.srcColor = QRhiGraphicsPipeline::SrcAlpha; + blend.dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha; + blend.srcAlpha = QRhiGraphicsPipeline::One; + blend.dstAlpha = QRhiGraphicsPipeline::OneMinusSrcAlpha; + pipeline->setTargetBlends({ blend }); + + // Enable depth test (restore depth writes for normal rendering) + pipeline->setDepthTest(true); + pipeline->setDepthWrite(true); + pipeline->setDepthOp(QRhiGraphicsPipeline::Less); + + // Diagnostic: disable culling to avoid missing-triangle artifacts + pipeline->setCullMode(QRhiGraphicsPipeline::Back); + + // Determine the MSAA sample count to use. Query the RHI for supported counts + // and clamp to at most 4 samples for safety. + int requestedSamples = sampleCount(); + int samplesToUse = 1; + if (requestedSamples > 1 && m_rhi) { + QVector supported = m_rhi->supportedSampleCounts(); + int maxSupported = 1; + for (int s : supported) { + if (s > maxSupported) + maxSupported = s; + } + samplesToUse = qMin(requestedSamples, qMin(4, maxSupported)); + } + if (samplesToUse > 1) + pipeline->setSampleCount(samplesToUse); + + // Use triangle fan topology to match OpenGL draw mode (this makes the app to crash) + // pipeline->setTopology(QRhiGraphicsPipeline::TriangleFan); + + // Set shaders + pipeline->setShaderStages({ { QRhiShaderStage::Vertex, vertShader }, + { QRhiShaderStage::Fragment, fragShader } }); + + // Setup vertex input layout + QRhiVertexInputLayout inputLayout; + inputLayout.setBindings({ + { 5 * sizeof(float) }, // Per-vertex data (position + texCoord) + { 22 * sizeof(float), QRhiVertexInputBinding::PerInstance } // Per-instance data (+ flip flag) + }); + inputLayout.setAttributes({ + // Per-vertex attributes + { 0, 0, QRhiVertexInputAttribute::Float3, 0 }, // position + { 0, 1, QRhiVertexInputAttribute::Float2, 3 * sizeof(float) }, // texCoord + + // Per-instance attributes (model matrix as 4 vec4s) + { 1, 2, QRhiVertexInputAttribute::Float4, 0 * sizeof(float) }, // row 0 + { 1, 3, QRhiVertexInputAttribute::Float4, 4 * sizeof(float) }, // row 1 + { 1, 4, QRhiVertexInputAttribute::Float4, 8 * sizeof(float) }, // row 2 + { 1, 5, QRhiVertexInputAttribute::Float4, 12 * sizeof(float) }, // row 3 + { 1, 6, QRhiVertexInputAttribute::Float4, 16 * sizeof(float) }, // shading vec4 + { 1, 7, QRhiVertexInputAttribute::Float, 20 * sizeof(float) }, // opacity + { 1, 8, QRhiVertexInputAttribute::Float, 21 * sizeof(float) } // flipFlag (1.0 = reflection) + }); + pipeline->setVertexInputLayout(inputLayout); + + // Set shader resource bindings and render pass descriptor + pipeline->setShaderResourceBindings(shaderBindings); + pipeline->setRenderPassDescriptor(renderTarget()->renderPassDescriptor()); + + if (!pipeline->create()) { + qWarning() << "YACReaderFlow3D: Failed to create graphics pipeline!"; + delete pipeline; + pipeline = nullptr; + } + } + + // Call populate only once per data loaded. + if (!hasBeenInitialized && lazyPopulateObjects != -1) { + populate(lazyPopulateObjects); + lazyPopulateObjects = -1; + } + + hasBeenInitialized = true; +} + +void YACReaderFlow3D::ensureUniformBufferCapacity(int requiredSlots) +{ + if (!m_rhi || alignedUniformSize == 0) + return; + + // Check if we need to resize + if (uniformBufferCapacity >= requiredSlots && uniformBuffer) + return; + + // Delete old buffer if it exists + if (uniformBuffer) { + delete uniformBuffer; + uniformBuffer = nullptr; + } + + // Create new larger buffer + // Each draw needs its own uniform slot (cover + reflection + optional mark = 3 per object) + const int totalSize = requiredSlots * alignedUniformSize; + uniformBuffer = m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, totalSize); + if (uniformBuffer->create()) { + uniformBufferCapacity = requiredSlots; + + // Invalidate shader bindings cache since the uniform buffer changed + for (auto *srb : shaderBindingsCache) { + delete srb; + } + shaderBindingsCache.clear(); + + // Recreate default shader bindings for pipeline + if (shaderBindings) { + delete shaderBindings; + } + shaderBindings = m_rhi->newShaderResourceBindings(); + shaderBindings->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, uniformBuffer), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, defaultTexture, sampler) }); + shaderBindings->create(); + } else { + qWarning() << "YACReaderFlow3D: Failed to create uniform buffer of size" << totalSize; + uniformBufferCapacity = 0; + } +} + +void YACReaderFlow3D::render(QRhiCommandBuffer *cb) +{ + if (!m_rhi || numObjects == 0) + return; + + const QSize outputSize = renderTarget()->pixelSize(); + const QColor clearColor = backgroundColor; + + // Update positions and animations + updatePositions(); + + // Prepare view-projection matrix + // Use fixed 20.0 degrees FOV - zoom is controlled via cfZ (camera distance) + QMatrix4x4 projectionMatrix; + projectionMatrix.perspective(20.0, float(outputSize.width()) / float(outputSize.height()), 1.0, 200.0); + + QMatrix4x4 viewMatrix; + viewMatrix.translate(config.cfX, config.cfY, config.cfZ); + viewMatrix.rotate(config.cfRX, 1, 0, 0); + viewMatrix.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); + viewMatrix.rotate(config.cfRZ, 0, 0, 1); + + QMatrix4x4 viewProjectionMatrix = projectionMatrix * viewMatrix; + + // Build draw order (back to front for proper alpha blending) + QVector drawOrder; + for (int count = numObjects - 1; count > -1; count--) { + if (count > currentSelected) { + drawOrder.append(count); + } + } + for (int count = 0; count < numObjects - 1; count++) { + if (count < currentSelected) { + drawOrder.append(count); + } + } + drawOrder.append(currentSelected); + + // Structure to hold draw info + struct DrawInfo { + int imageIndex; + bool isReflection; + bool isMark; + QRhiTexture *texture; + float instanceData[22]; + UniformData uniformData; + }; + + // Collect all draws we need to make + // Important: OpenGL draws reflections FIRST, then covers+marks (for correct depth sorting) + QVector draws; + + // Phase 1: Add all reflections + for (int idx : drawOrder) { + if (idx < 0 || idx >= images.size() || !images[idx].texture) + continue; + + DrawInfo reflDraw; + reflDraw.imageIndex = idx; + reflDraw.isReflection = true; + reflDraw.isMark = false; + reflDraw.texture = images[idx].texture; + prepareDrawData(images[idx], true, false, viewProjectionMatrix, reflDraw.instanceData, reflDraw.uniformData); + draws.append(reflDraw); + } + + // Phase 2: Add all covers (and marks) + for (int idx : drawOrder) { + if (idx < 0 || idx >= images.size() || !images[idx].texture) + continue; + + // Add cover draw + DrawInfo coverDraw; + coverDraw.imageIndex = idx; + coverDraw.isReflection = false; + coverDraw.isMark = false; + coverDraw.texture = images[idx].texture; + prepareDrawData(images[idx], false, false, viewProjectionMatrix, coverDraw.instanceData, coverDraw.uniformData); + draws.append(coverDraw); + + if (idx < 0 || idx >= marks.size()) + continue; + + if (idx >= loaded.size()) + continue; + + // Add mark draw immediately after its cover + if (showMarks && loaded[idx] && marks[idx] != Unread) { + QRhiTexture *markTex = (marks[idx] == Read) ? markTexture : readingTexture; + if (markTex) { + DrawInfo markDraw; + markDraw.imageIndex = idx; + markDraw.isReflection = false; + markDraw.isMark = true; + markDraw.texture = markTex; + prepareDrawData(images[idx], false, true, viewProjectionMatrix, markDraw.instanceData, markDraw.uniformData); + draws.append(markDraw); + } + } + } + + // Ensure uniform buffer is large enough + ensureUniformBufferCapacity(draws.size()); + + if (!uniformBuffer) { + qWarning() << "YACReaderFlow3D: No uniform buffer available for rendering"; + return; + } + + // Ensure instance buffer is large enough for all draws + const int requiredInstanceSize = draws.size() * 22 * sizeof(float); + if (!instanceBuffer || instanceBuffer->size() < requiredInstanceSize) { + if (instanceBuffer) { + delete instanceBuffer; + } + instanceBuffer = m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, requiredInstanceSize); + if (!instanceBuffer->create()) { + qWarning() << "YACReaderFlow3D: Failed to create instance buffer of size" << requiredInstanceSize; + return; + } + } + + // === PHASE 1: PREPARE (BEFORE PASS) === + // Update ALL uniform and instance data for ALL draws in one batch + QRhiResourceUpdateBatch *batch = m_rhi->nextResourceUpdateBatch(); + + // Process pending texture uploads + if (!pendingTextureUploads.isEmpty()) { + for (const auto &upload : pendingTextureUploads) { + if (upload.index >= 0 && upload.index < images.size() && images[upload.index].texture) { + batch->uploadTexture(images[upload.index].texture, upload.image); + } + } + pendingTextureUploads.clear(); + } + + // Update uniform buffer with all draw data + for (int i = 0; i < draws.size(); ++i) { + int offset = i * alignedUniformSize; + batch->updateDynamicBuffer(uniformBuffer, offset, sizeof(UniformData), &draws[i].uniformData); + } + + // Update instance buffer with all instance data + for (int i = 0; i < draws.size(); ++i) { + int offset = i * 22 * sizeof(float); + batch->updateDynamicBuffer(instanceBuffer, offset, 22 * sizeof(float), draws[i].instanceData); + } + + // === PHASE 2: RENDER (DURING PASS) === + cb->beginPass(renderTarget(), clearColor, { 1.0f, 0 }, batch); + + if (pipeline) { + cb->setGraphicsPipeline(pipeline); + cb->setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height())); + + // Execute all draws + for (int i = 0; i < draws.size(); ++i) { + const DrawInfo &draw = draws[i]; + executeDrawWithOffset(cb, draw.texture, draw.instanceData, i); + } + } + + cb->endPass(); +} + +void YACReaderFlow3D::prepareDrawData(const YACReader3DImageRHI &image, bool isReflection, bool isMark, + const QMatrix4x4 &viewProjectionMatrix, + float *outInstanceData, UniformData &outUniformData) +{ + float w = image.width; + float h = image.height; + + // Calculate opacity + float opacity = 1 - 1 / (config.animationFadeOutDist + config.viewRotateLightStrenght * fabs(viewRotate)) * fabs(0 - image.current.x); + + // Calculate shading + float LShading = ((config.rotation != 0) ? ((image.current.rot < 0) ? 1 - 1 / config.rotation * image.current.rot : 1) : 1); + float RShading = ((config.rotation != 0) ? ((image.current.rot > 0) ? 1 - 1 / (config.rotation * -1) * image.current.rot : 1) : 1); + float LUP = shadingTop + (1 - shadingTop) * LShading; + float LDOWN = shadingBottom + (1 - shadingBottom) * LShading; + float RUP = shadingTop + (1 - shadingTop) * RShading; + float RDOWN = shadingBottom + (1 - shadingBottom) * RShading; + + QMatrix4x4 modelMatrix; + modelMatrix.translate(image.current.x, image.current.y, image.current.z); + modelMatrix.rotate(image.current.rot, 0, 1, 0); + + if (isMark) { + // Mark-specific transform + float markWidth = 0.15f; + float markHeight = 0.2f; + float markCenterX = w / 2.0f - 0.125f; + float markCenterY = -0.588f + h; + modelMatrix.translate(markCenterX, markCenterY, 0.001f); + modelMatrix.scale(markWidth, markHeight, 1.0f); + + float shadingValue = RUP * opacity; + outInstanceData[16] = shadingValue; + outInstanceData[17] = shadingValue; + outInstanceData[18] = shadingValue; + outInstanceData[19] = shadingValue; + outInstanceData[20] = 1.0f; + outInstanceData[21] = isReflection ? 1.0f : 0.0f; + } else { + // Cover/reflection transform + if (isReflection) { + modelMatrix.translate(0.0f, -0.5f - h / 2.0f, 0.0f); + // Swap vertical shading for reflection + float temp = LUP; + LUP = LDOWN; + LDOWN = temp; + temp = RUP; + RUP = RDOWN; + RDOWN = temp; + } else { + modelMatrix.translate(0.0f, -0.5f + h / 2.0f, 0.0f); + } + modelMatrix.scale(w, h, 1.0f); + + outInstanceData[16] = LUP; + outInstanceData[17] = LDOWN; + outInstanceData[18] = RUP; + outInstanceData[19] = RDOWN; + outInstanceData[20] = opacity; + outInstanceData[21] = isReflection ? 1.0f : 0.0f; + } + + // Pack model matrix into instance data + const float *matData = modelMatrix.constData(); + for (int i = 0; i < 16; i++) { + outInstanceData[i] = matData[i]; + } + + // Prepare uniform data + outUniformData.viewProjectionMatrix = viewProjectionMatrix; + outUniformData.backgroundColor = QVector3D(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF()); + outUniformData.shadingColor = QVector3D(shadingColor.redF(), shadingColor.greenF(), shadingColor.blueF()); + outUniformData.reflectionUp = reflectionUp; + outUniformData.reflectionDown = reflectionBottom; + outUniformData.isReflection = isReflection ? 1 : 0; +} + +void YACReaderFlow3D::executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture *texture, + const float *instanceData, int uniformSlot) +{ + if (!texture || !instanceBuffer || !vertexBuffer) + return; + + // NOTE: We cannot update the instance buffer here during the render pass! + // Instead, we'll need to either: + // 1. Use the instance data from uniforms (move it to uniform buffer) + // 2. Or pre-upload all instance data before the pass + // + // For now, let's use approach #1: embed instance data in uniforms via a large instance buffer + // that we populate before the pass, similar to uniforms + // + // Actually, the simplest solution: update the instance buffer ONCE per draw using dynamic updates + // But we need to do this cleverly - we can't call resourceUpdate during pass. + // + // The solution: Create an instance buffer large enough for ALL draws, update it before pass, + // and use offsets during drawing. + + // Get or create shader resource bindings for this texture with dynamic offset support + QRhiShaderResourceBindings *srb = shaderBindingsCache.value(texture, nullptr); + if (!srb) { + srb = m_rhi->newShaderResourceBindings(); + srb->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, uniformBuffer), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture, sampler) }); + srb->create(); + shaderBindingsCache.insert(texture, srb); + } + + // Set shader resources with dynamic offset for uniform buffer + QRhiCommandBuffer::DynamicOffset dynOfs[] = { + { 0, quint32(uniformSlot * alignedUniformSize) } + }; + cb->setShaderResources(srb, 1, dynOfs); + + // Bind vertex buffers with offset into instance buffer + const QRhiCommandBuffer::VertexInput vbufBindings[] = { + { vertexBuffer, 0 }, + { instanceBuffer, quint32(uniformSlot * 22 * sizeof(float)) } // Use slot index for instance data offset + }; + cb->setVertexInput(0, 2, vbufBindings); + + // Draw two triangles (6 vertices) forming a quad + cb->draw(6); +} + +// Note: The old drawCover() and drawMark() methods have been removed. +// Rendering now uses prepareDrawData() and executeDrawWithOffset() which properly +// batch all resource updates before the render pass begins, following Qt RHI best practices. + +void YACReaderFlow3D::releaseResources() +{ + delete vertexBuffer; + vertexBuffer = nullptr; + + delete instanceBuffer; + instanceBuffer = nullptr; + + delete uniformBuffer; + uniformBuffer = nullptr; + + delete sampler; + sampler = nullptr; + + delete pipeline; + pipeline = nullptr; + + delete shaderBindings; + shaderBindings = nullptr; + + // Clean up shader bindings cache + for (auto *srb : shaderBindingsCache) { + delete srb; + } + shaderBindingsCache.clear(); + + delete defaultTexture; + defaultTexture = nullptr; + + delete markTexture; + markTexture = nullptr; + + delete readingTexture; + readingTexture = nullptr; + + m_rhi = nullptr; +} + +void YACReaderFlow3D::showEvent(QShowEvent *event) +{ + QRhiWidget::showEvent(event); + startAnimationTimer(); +} + +void YACReaderFlow3D::cleanupAnimation() +{ + config.animationStep = stepBackup; + viewRotateActive = 0; +} + +void YACReaderFlow3D::draw() +{ + update(); +} + +void YACReaderFlow3D::calcPos(YACReader3DImageRHI &image, int pos) +{ + if (flowRightToLeft) { + pos = pos * -1; + } + + if (pos == 0) { + image.current = centerPos; + } else { + if (pos > 0) { + image.current.x = (config.centerDistance) + (config.xDistance * pos); + image.current.y = config.yDistance * pos * -1; + image.current.z = config.zDistance * pos * -1; + image.current.rot = config.rotation; + } else { + image.current.x = (config.centerDistance) * -1 + (config.xDistance * pos); + image.current.y = config.yDistance * pos; + image.current.z = config.zDistance * pos; + image.current.rot = config.rotation * -1; + } + } +} + +void YACReaderFlow3D::calcVector(YACReader3DVector &vector, int pos) +{ + calcPos(dummy, pos); + vector.x = dummy.current.x; + vector.y = dummy.current.y; + vector.z = dummy.current.z; + vector.rot = dummy.current.rot; +} + +bool YACReaderFlow3D::animate(YACReader3DVector ¤tVector, YACReader3DVector &toVector) +{ + float rotDiff = toVector.rot - currentVector.rot; + float xDiff = toVector.x - currentVector.x; + float yDiff = toVector.y - currentVector.y; + float zDiff = toVector.z - currentVector.z; + + if (fabs(rotDiff) < 0.01 && fabs(xDiff) < 0.001 && fabs(yDiff) < 0.001 && fabs(zDiff) < 0.001) + return true; + + currentVector.x = currentVector.x + (xDiff)*config.animationStep; + currentVector.y = currentVector.y + (yDiff)*config.animationStep; + currentVector.z = currentVector.z + (zDiff)*config.animationStep; + + if (fabs(rotDiff) > 0.01) { + currentVector.rot = currentVector.rot + (rotDiff) * (config.animationStep * config.preRotation); + } else { + viewRotateActive = 0; + } + + return false; +} + +void YACReaderFlow3D::showPrevious() +{ + startAnimationTimer(); + + if (currentSelected > 0) { + currentSelected--; + emit centerIndexChanged(currentSelected); + config.animationStep *= config.animationSpeedUp; + + if (config.animationStep > config.animationStepMax) { + config.animationStep = config.animationStepMax; + } + + if (viewRotateActive && viewRotate > -1) { + viewRotate -= config.viewRotateAdd; + } + + viewRotateActive = 1; + } +} + +void YACReaderFlow3D::showNext() +{ + startAnimationTimer(); + + if (currentSelected < numObjects - 1) { + currentSelected++; + emit centerIndexChanged(currentSelected); + config.animationStep *= config.animationSpeedUp; + + if (config.animationStep > config.animationStepMax) { + config.animationStep = config.animationStepMax; + } + + if (viewRotateActive && viewRotate < 1) { + viewRotate += config.viewRotateAdd; + } + + viewRotateActive = 1; + } +} + +void YACReaderFlow3D::setCurrentIndex(int pos) +{ + if (!(pos >= 0 && pos < images.length() && images.length() > 0)) + return; + if (pos >= images.length() && images.length() > 0) + pos = images.length() - 1; + + startAnimationTimer(); + + currentSelected = pos; + config.animationStep *= config.animationSpeedUp; + + if (config.animationStep > config.animationStepMax) { + config.animationStep = config.animationStepMax; + } + + if (viewRotateActive && viewRotate < 1) { + viewRotate += config.viewRotateAdd; + } + + viewRotateActive = 1; +} + +void YACReaderFlow3D::updatePositions() +{ + int count; + bool stopAnimation = true; + + for (count = numObjects - 1; count > -1; count--) { + calcVector(images[count].animEnd, count - currentSelected); + if (!animate(images[count].current, images[count].animEnd)) + stopAnimation = false; + } + + if (!viewRotateActive) { + viewRotate += (0 - viewRotate) * config.viewRotateSub; + } + + if (fabs(images[currentSelected].current.x - images[currentSelected].animEnd.x) < 1) { + cleanupAnimation(); + if (updateCount >= 0) { + updateCount = 0; + updateImageData(); + } else + updateCount++; + } else + updateCount++; + + if (stopAnimation) + stopAnimationTimer(); +} + +void YACReaderFlow3D::insert(char *name, QRhiTexture *texture, float x, float y, int item) +{ + startAnimationTimer(); + + Q_UNUSED(name) + if (item == -1) { + images.push_back(YACReader3DImageRHI()); + item = numObjects; + numObjects++; + calcVector(images[item].current, item); + images[item].current.z = images[item].current.z - 1; + } + + images[item].texture = texture; + images[item].width = x; + images[item].height = y; + images[item].index = item; +} + +void YACReaderFlow3D::remove(int item) +{ + if (item < 0 || item >= images.size()) + return; + + startAnimationTimer(); + + loaded.remove(item); + marks.remove(item); + + if (item <= currentSelected && currentSelected != 0) { + currentSelected--; + } + + QRhiTexture *texture = images[item].texture; + + int count = item; + while (count <= numObjects - 1) { + images[count].index--; + count++; + } + images.removeAt(item); + + if (texture != defaultTexture) + delete texture; + + numObjects--; +} + +void YACReaderFlow3D::add(int item) +{ + float x = 1; + float y = 1 * (700.f / 480.0f); + QString s = "cover"; + + images.insert(item, YACReader3DImageRHI()); + loaded.insert(item, false); + marks.insert(item, Unread); + numObjects++; + + for (int i = item + 1; i < numObjects; i++) { + images[i].index++; + } + + insert(s.toLocal8Bit().data(), defaultTexture, x, y, item); +} + +YACReader3DImageRHI YACReaderFlow3D::getCurrentSelected() +{ + return images[currentSelected]; +} + +void YACReaderFlow3D::replace(char *name, QRhiTexture *texture, float x, float y, int item) +{ + startAnimationTimer(); + + Q_UNUSED(name) + if (images[item].index == item) { + images[item].texture = texture; + images[item].width = x; + images[item].height = y; + loaded[item] = true; + } else + loaded[item] = false; +} + +void YACReaderFlow3D::populate(int n) +{ + if (hasBeenInitialized) { + clear(); + } + emit centerIndexChanged(0); + + float x = 1; + float y = 1 * (700.f / 480.0f); + int i; + + for (i = 0; i < n; i++) { + QString s = "cover"; + insert(s.toLocal8Bit().data(), defaultTexture, x, y); + } + + loaded = QVector(n, false); +} + +void YACReaderFlow3D::reset() +{ + startAnimationTimer(); + + currentSelected = 0; + loaded.clear(); + + for (int i = 0; i < numObjects; i++) { + if (images[i].texture != defaultTexture) + delete images[i].texture; + } + + numObjects = 0; + images.clear(); + + if (!hasBeenInitialized) + lazyPopulateObjects = -1; +} + +void YACReaderFlow3D::reload() +{ + startAnimationTimer(); + int n = numObjects; + reset(); + populate(n); +} + +// Slot implementations +void YACReaderFlow3D::setCF_RX(int value) +{ + startAnimationTimer(); + config.cfRX = value; +} + +void YACReaderFlow3D::setCF_RY(int value) +{ + startAnimationTimer(); + config.cfRY = value; +} + +void YACReaderFlow3D::setCF_RZ(int value) +{ + startAnimationTimer(); + config.cfRZ = value; +} + +void YACReaderFlow3D::setRotation(int angle) +{ + startAnimationTimer(); + config.rotation = -angle; +} + +void YACReaderFlow3D::setX_Distance(int distance) +{ + startAnimationTimer(); + config.xDistance = distance / 100.0; +} + +void YACReaderFlow3D::setCenter_Distance(int distance) +{ + startAnimationTimer(); + config.centerDistance = distance / 100.0; +} + +void YACReaderFlow3D::setZ_Distance(int distance) +{ + startAnimationTimer(); + config.zDistance = distance / 100.0; +} + +void YACReaderFlow3D::setCF_Y(int value) +{ + startAnimationTimer(); + config.cfY = value / 100.0; +} + +void YACReaderFlow3D::setCF_Z(int value) +{ + startAnimationTimer(); + config.cfZ = value; +} + +void YACReaderFlow3D::setY_Distance(int value) +{ + startAnimationTimer(); + config.yDistance = value / 100.0; +} + +void YACReaderFlow3D::setFadeOutDist(int value) +{ + startAnimationTimer(); + config.animationFadeOutDist = value; +} + +void YACReaderFlow3D::setLightStrenght(int value) +{ + startAnimationTimer(); + config.viewRotateLightStrenght = value; +} + +void YACReaderFlow3D::setMaxAngle(int value) +{ + startAnimationTimer(); + config.viewAngle = value; +} + +void YACReaderFlow3D::setPreset(const Preset &p) +{ + startAnimationTimer(); + config = p; +} + +void YACReaderFlow3D::setZoom(int zoom) +{ + startAnimationTimer(); + config.zoom = zoom; +} + +void YACReaderFlow3D::setPerformance(Performance performance) +{ + if (this->performance != performance) { + startAnimationTimer(); + this->performance = performance; + reload(); + } +} + +void YACReaderFlow3D::useVSync(bool b) +{ + // No-op for RHI - VSync is handled by the platform + Q_UNUSED(b); +} + +void YACReaderFlow3D::setShowMarks(bool value) +{ + startAnimationTimer(); + showMarks = value; +} + +void YACReaderFlow3D::setMarks(QVector marks) +{ + startAnimationTimer(); + this->marks = marks; +} + +void YACReaderFlow3D::setMarkImage(QImage &image) +{ + Q_UNUSED(image); +} + +void YACReaderFlow3D::markSlide(int index, YACReader::YACReaderComicReadStatus status) +{ + startAnimationTimer(); + marks[index] = status; +} + +void YACReaderFlow3D::unmarkSlide(int index) +{ + startAnimationTimer(); + marks[index] = YACReader::Unread; +} + +void YACReaderFlow3D::setSlideSize(QSize size) +{ + Q_UNUSED(size); +} + +void YACReaderFlow3D::clear() +{ + reset(); +} + +void YACReaderFlow3D::setCenterIndex(unsigned int index) +{ + setCurrentIndex(index); +} + +void YACReaderFlow3D::showSlide(int index) +{ + setCurrentIndex(index); +} + +int YACReaderFlow3D::centerIndex() +{ + return currentSelected; +} + +void YACReaderFlow3D::updateMarks() { } + +void YACReaderFlow3D::render() +{ + update(); +} + +void YACReaderFlow3D::resizeGL(int width, int height) +{ + Q_UNUSED(width); + Q_UNUSED(height); + // No-op for RHI - handled automatically +} + +void YACReaderFlow3D::setFlowRightToLeft(bool b) +{ + flowRightToLeft = b; +} + +void YACReaderFlow3D::setBackgroundColor(const QColor &color) +{ + backgroundColor = color; + + // Auto-calculate shadingColor based on background brightness + qreal luminance = (backgroundColor.redF() * 0.299 + + backgroundColor.greenF() * 0.587 + + backgroundColor.blueF() * 0.114); + + if (luminance < 0.5) { + // Dark background - shade towards white + shadingColor = QColor(255, 255, 255); + shadingTop = 0.8f; + shadingBottom = 0.02f; + } else { + // Light background - shade towards black + shadingColor = QColor(0, 0, 0); + shadingTop = 0.95f; + shadingBottom = 0.3f; + } + + update(); +} + +void YACReaderFlow3D::setTextColor(const QColor &color) +{ + textColor = color; + update(); +} + +void YACReaderFlow3D::setShadingColor(const QColor &color) +{ + shadingColor = color; + update(); +} + +// Event handlers +void YACReaderFlow3D::wheelEvent(QWheelEvent *event) +{ + Movement m = getMovement(event); + switch (m) { + case None: + return; + case Forward: + showNext(); + break; + case Backward: + showPrevious(); + break; + default: + break; + } +} + +void YACReaderFlow3D::keyPressEvent(QKeyEvent *event) +{ + if ((event->key() == Qt::Key_Left && !flowRightToLeft) || (event->key() == Qt::Key_Right && flowRightToLeft)) { + if (event->modifiers() == Qt::ControlModifier) + setCurrentIndex((currentSelected - 10 < 0) ? 0 : currentSelected - 10); + else + showPrevious(); + event->accept(); + return; + } + + if ((event->key() == Qt::Key_Right && !flowRightToLeft) || (event->key() == Qt::Key_Left && flowRightToLeft)) { + if (event->modifiers() == Qt::ControlModifier) + setCurrentIndex((currentSelected + 10 >= numObjects) ? numObjects - 1 : currentSelected + 10); + else + showNext(); + event->accept(); + return; + } + + if (event->key() == Qt::Key_Up) { + return; + } + + event->ignore(); +} + +void YACReaderFlow3D::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton && currentSelected >= 0 && currentSelected < images.size()) { + auto position = event->position(); + QVector3D intersection = getPlaneIntersection(position.x(), position.y(), images[currentSelected]); + if ((intersection.x() > 0.5 && !flowRightToLeft) || (intersection.x() < -0.5 && flowRightToLeft)) { + showNext(); + } else if ((intersection.x() < -0.5 && !flowRightToLeft) || (intersection.x() > 0.5 && flowRightToLeft)) { + showPrevious(); + } + } else { + QRhiWidget::mousePressEvent(event); + } +} + +void YACReaderFlow3D::mouseDoubleClickEvent(QMouseEvent *event) +{ + if (currentSelected >= 0 && currentSelected < images.size()) { + auto position = event->position(); + QVector3D intersection = getPlaneIntersection(position.x(), position.y(), images[currentSelected]); + + if (intersection.x() < 0.5 && intersection.x() > -0.5) { + emit selected(centerIndex()); + event->accept(); + } + } +} + +QVector3D YACReaderFlow3D::getPlaneIntersection(int x, int y, YACReader3DImageRHI plane) +{ + // Simplified for now - proper ray-plane intersection calculation needed + // This requires access to the viewport and matrices + const QSize outputSize = renderTarget()->pixelSize(); + + QMatrix4x4 m_projection; + m_projection.perspective(config.zoom, float(outputSize.width()) / float(outputSize.height()), 1.0, 200.0); + + QMatrix4x4 m_modelview; + m_modelview.translate(config.cfX, config.cfY, config.cfZ); + m_modelview.rotate(config.cfRX, 1, 0, 0); + m_modelview.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); + m_modelview.rotate(config.cfRZ, 0, 0, 1); + m_modelview.translate(plane.current.x, plane.current.y, plane.current.z); + m_modelview.rotate(plane.current.rot, 0, 1, 0); + m_modelview.scale(plane.width, plane.height, 1.0f); + + QVector3D ray_origin(x * devicePixelRatioF(), y * devicePixelRatioF(), 0); + QVector3D ray_end(x * devicePixelRatioF(), y * devicePixelRatioF(), 1.0); + + ray_origin = ray_origin.unproject(m_modelview, m_projection, QRect(0, 0, outputSize.width(), outputSize.height())); + ray_end = ray_end.unproject(m_modelview, m_projection, QRect(0, 0, outputSize.width(), outputSize.height())); + + QVector3D ray_vector = ray_end - ray_origin; + + QVector3D plane_origin(-0.5f, -0.5f, 0); + QVector3D plane_vektor_1 = QVector3D(0.5f, -0.5f, 0) - plane_origin; + QVector3D plane_vektor_2 = QVector3D(-0.5f, 0.5f, 0) - plane_origin; + + double intersection_LES_determinant = ((plane_vektor_1.x() * plane_vektor_2.y() * (-1) * ray_vector.z()) + + (plane_vektor_2.x() * (-1) * ray_vector.y() * plane_vektor_1.z()) + + ((-1) * ray_vector.x() * plane_vektor_1.y() * plane_vektor_2.z()) - + ((-1) * ray_vector.x() * plane_vektor_2.y() * plane_vektor_1.z()) - + (plane_vektor_1.x() * (-1) * ray_vector.y() * plane_vektor_2.z()) - + (plane_vektor_2.x() * plane_vektor_1.y() * (-1) * ray_vector.z())); + + QVector3D det = ray_origin - plane_origin; + + double intersection_ray_determinant = ((plane_vektor_1.x() * plane_vektor_2.y() * det.z()) + + (plane_vektor_2.x() * det.y() * plane_vektor_1.z()) + + (det.x() * plane_vektor_1.y() * plane_vektor_2.z()) - + (det.x() * plane_vektor_2.y() * plane_vektor_1.z()) - + (plane_vektor_1.x() * det.y() * plane_vektor_2.z()) - + (plane_vektor_2.x() * plane_vektor_1.y() * det.z())); + + return ray_origin + ray_vector * (intersection_ray_determinant / intersection_LES_determinant); +} + +QSize YACReaderFlow3D::minimumSizeHint() const +{ + return QSize(320, 200); +} + +// YACReaderComicFlow3D implementation +YACReaderComicFlow3D::YACReaderComicFlow3D(QWidget *parent, struct Preset p) + : YACReaderFlow3D(parent, p) +{ + worker = new ImageLoader3D(this); + worker->flow = this; +} + +void YACReaderComicFlow3D::setImagePaths(QStringList paths) +{ + worker->reset(); + reset(); + numObjects = 0; + + if (hasBeenInitialized) { + YACReaderFlow3D::populate(paths.size()); + } else { + lazyPopulateObjects = paths.size(); + } + + this->paths = paths; +} + +void YACReaderComicFlow3D::updateImageData() +{ + if (worker->busy()) + return; + + int idx = worker->index(); + if (idx >= 0 && !worker->result().isNull()) { + if (!loaded[idx]) { + float x = 1; + QImage img = worker->result(); + + // // Ensure the loaded image is in RGBA8888 layout so QRhi interprets channels correctly + // if (img.format() != QImage::Format_RGBA8888) + // img = img.convertToFormat(QImage::Format_RGBA8888); + + // Create QRhiTexture from the loaded image + if (m_rhi) { + QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, + (performance == high || performance == ultraHigh) ? QRhiTexture::MipMapped : QRhiTexture::UsedAsTransferSource); + + if (texture->create()) { + // Queue texture upload (image already converted to RGBA8888) + PendingTextureUpload upload; + upload.index = idx; + upload.image = img; + upload.x = x; + upload.y = 1 * (float(img.height()) / img.width()); + pendingTextureUploads.append(upload); + + QString s = "cover"; + replace(s.toLocal8Bit().data(), texture, upload.x, upload.y, idx); + } + } + } + } + + int count = 8; + switch (performance) { + case low: + count = 8; + break; + case medium: + count = 10; + break; + case high: + count = 12; + break; + case ultraHigh: + count = 16; + break; + } + + int *indexes = new int[2 * count + 1]; + int center = currentSelected; + indexes[0] = center; + for (int j = 0; j < count; j++) { + indexes[j * 2 + 1] = center + j + 1; + indexes[j * 2 + 2] = center - j - 1; + } + + for (int c = 0; c < 2 * count + 1; c++) { + int i = indexes[c]; + if ((i >= 0) && (i < numObjects)) + if (!loaded[i]) { + if (paths.size() > 0) { + QString fname = paths.at(i); + worker->generate(i, fname); + } + delete[] indexes; + return; + } + } + + delete[] indexes; +} + +void YACReaderComicFlow3D::remove(int item) +{ + worker->lock(); + worker->reset(); + YACReaderFlow3D::remove(item); + if (item >= 0 && item < paths.size()) { + paths.removeAt(item); + } + worker->unlock(); +} + +void YACReaderComicFlow3D::add(const QString &path, int index) +{ + worker->lock(); + worker->reset(); + paths.insert(index, path); + YACReaderFlow3D::add(index); + worker->unlock(); +} + +void YACReaderComicFlow3D::resortCovers(QList newOrder) +{ + worker->lock(); + worker->reset(); + startAnimationTimer(); + + QList pathsNew; + QVector loadedNew; + QVector marksNew; + QVector imagesNew; + + int index = 0; + foreach (int i, newOrder) { + if (i < 0 || i >= images.size()) { + continue; + } + + pathsNew << paths.at(i); + loadedNew << loaded.at(i); + marksNew << marks.at(i); + imagesNew << images.at(i); + imagesNew.last().index = index++; + } + + paths = pathsNew; + loaded = loadedNew; + marks = marksNew; + images = imagesNew; + + worker->unlock(); +} + +// YACReaderPageFlow3D implementation +YACReaderPageFlow3D::YACReaderPageFlow3D(QWidget *parent, struct Preset p) + : YACReaderFlow3D(parent, p) +{ + worker = new ImageLoaderByteArray3D(this); + worker->flow = this; +} + +YACReaderPageFlow3D::~YACReaderPageFlow3D() +{ + if (timerId != -1) { + this->killTimer(timerId); + timerId = -1; + } + rawImages.clear(); + + // Clean up textures + for (auto &image : images) { + if (image.texture != defaultTexture) { + delete image.texture; + } + } +} + +void YACReaderPageFlow3D::updateImageData() +{ + if (worker->busy()) + return; + + int idx = worker->index(); + if (idx >= 0 && !worker->result().isNull()) { + if (!loaded[idx]) { + float x = 1; + QImage img = worker->result(); + + // Create QRhiTexture from the loaded image + if (m_rhi) { + QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, + (performance == high || performance == ultraHigh) ? QRhiTexture::MipMapped : QRhiTexture::UsedAsTransferSource); + + if (texture->create()) { + float y = 1 * (float(img.height()) / img.width()); + QString s = "cover"; + replace(s.toLocal8Bit().data(), texture, x, y, idx); + loaded[idx] = true; + } + } + } + } + + int count = 8; + switch (performance) { + case low: + count = 8; + break; + case medium: + count = 10; + break; + case high: + count = 12; + break; + case ultraHigh: + count = 14; + break; + } + + int *indexes = new int[2 * count + 1]; + int center = currentSelected; + indexes[0] = center; + for (int j = 0; j < count; j++) { + indexes[j * 2 + 1] = center + j + 1; + indexes[j * 2 + 2] = center - j - 1; + } + + for (int c = 0; c < 2 * count + 1; c++) { + int i = indexes[c]; + if ((i >= 0) && (i < numObjects)) + if (rawImages.size() > 0) + if (!loaded[i] && imagesReady[i]) { + worker->generate(i, rawImages.at(i)); + delete[] indexes; + return; + } + } + + delete[] indexes; +} + +void YACReaderPageFlow3D::populate(int n) +{ + worker->reset(); + + if (hasBeenInitialized) { + YACReaderFlow3D::populate(n); + } else { + lazyPopulateObjects = n; + } + + imagesReady = QVector(n, false); + rawImages = QVector(n); + imagesSetted = QVector(n, false); +} + +// ImageLoader3D implementation +QImage ImageLoader3D::loadImage(const QString &fileName) +{ + QImage image; + + if (!image.load(fileName)) { + return QImage(); + } + + switch (flow->performance) { + case low: + image = image.scaledToWidth(200, Qt::SmoothTransformation); + break; + case medium: + image = image.scaledToWidth(256, Qt::SmoothTransformation); + break; + case high: + image = image.scaledToWidth(320, Qt::SmoothTransformation); + break; + case ultraHigh: + break; + } + + return image; +} + +ImageLoader3D::ImageLoader3D(YACReaderFlow3D *flow) + : QThread(), flow(flow), restart(false), working(false), idx(-1) +{ +} + +ImageLoader3D::~ImageLoader3D() +{ + mutex.lock(); + condition.wakeOne(); + mutex.unlock(); + wait(); +} + +bool ImageLoader3D::busy() const +{ + return isRunning() ? working : false; +} + +void ImageLoader3D::generate(int index, const QString &fileName) +{ + mutex.lock(); + this->idx = index; + this->fileName = fileName; + this->size = size; + this->img = QImage(); + mutex.unlock(); + + if (!isRunning()) + start(); + else { + restart = true; + condition.wakeOne(); + } +} + +void ImageLoader3D::lock() +{ + mutex.lock(); +} + +void ImageLoader3D::unlock() +{ + mutex.unlock(); +} + +void ImageLoader3D::run() +{ + for (;;) { + mutex.lock(); + this->working = true; + QString fileName = this->fileName; + mutex.unlock(); + + QImage image = loadImage(fileName); + + mutex.lock(); + this->working = false; + this->img = image; + mutex.unlock(); + + mutex.lock(); + if (!this->restart) + condition.wait(&mutex); + restart = false; + mutex.unlock(); + } +} + +QImage ImageLoader3D::result() +{ + return img; +} + +// ImageLoaderByteArray3D implementation +QImage ImageLoaderByteArray3D::loadImage(const QByteArray &raw) +{ + QImage image; + + if (!image.loadFromData(raw)) { + return QImage(); + } + + switch (flow->performance) { + case low: + image = image.scaledToWidth(128, Qt::SmoothTransformation); + break; + case medium: + image = image.scaledToWidth(196, Qt::SmoothTransformation); + break; + case high: + image = image.scaledToWidth(256, Qt::SmoothTransformation); + break; + case ultraHigh: + image = image.scaledToWidth(320, Qt::SmoothTransformation); + break; + } + + return image; +} + +ImageLoaderByteArray3D::ImageLoaderByteArray3D(YACReaderFlow3D *flow) + : QThread(), flow(flow), restart(false), working(false), idx(-1) +{ +} + +ImageLoaderByteArray3D::~ImageLoaderByteArray3D() +{ + mutex.lock(); + condition.wakeOne(); + mutex.unlock(); + wait(); +} + +bool ImageLoaderByteArray3D::busy() const +{ + return isRunning() ? working : false; +} + +void ImageLoaderByteArray3D::generate(int index, const QByteArray &raw) +{ + mutex.lock(); + this->idx = index; + this->rawData = raw; + this->size = size; + this->img = QImage(); + mutex.unlock(); + + if (!isRunning()) + start(); + else { + restart = true; + condition.wakeOne(); + } +} + +void ImageLoaderByteArray3D::run() +{ + for (;;) { + mutex.lock(); + this->working = true; + QByteArray raw = this->rawData; + mutex.unlock(); + + QImage image = loadImage(raw); + + mutex.lock(); + this->working = false; + this->img = image; + mutex.unlock(); + + mutex.lock(); + if (!this->restart) + condition.wait(&mutex); + restart = false; + mutex.unlock(); + } +} + +QImage ImageLoaderByteArray3D::result() +{ + return img; +} diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h new file mode 100644 index 000000000..7e87769d0 --- /dev/null +++ b/common/rhi/yacreader_flow_rhi.h @@ -0,0 +1,394 @@ +// Qt RHI-based Coverflow for YACReader +// Compatible with Qt 6.7+ using QRhiWidget +#ifndef __YACREADER_FLOW_RHI_H +#define __YACREADER_FLOW_RHI_H + +#include + +#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) + +#include +#include +#include +#include + +#include "pictureflow.h" +#include "scroll_management.h" + +// Reuse enums and structs from OpenGL version +enum Performance { + low = 0, + medium, + high, + ultraHigh +}; + +// Cover Vector +struct YACReader3DVector { + float x; + float y; + float z; + float rot; +}; + +// the image/texture info struct +struct YACReader3DImageRHI { + QRhiTexture *texture; + + float width; + float height; + + int index; + + YACReader3DVector current; + YACReader3DVector animEnd; +}; + +struct Preset { + /*** Animation Settings ***/ + float animationStep; + float animationSpeedUp; + float animationStepMax; + float animationFadeOutDist; + float preRotation; + float viewRotateLightStrenght; + float viewRotateAdd; + float viewRotateSub; + float viewAngle; + + /*** Position Configuration ***/ + float cfX; + float cfY; + float cfZ; + float cfRX; + float cfRY; + float cfRZ; + float rotation; + float xDistance; + float centerDistance; + float zDistance; + float yDistance; + + float zoom; +}; + +extern struct Preset defaultYACReaderFlowConfig; +extern struct Preset presetYACReaderFlowClassicConfig; +extern struct Preset presetYACReaderFlowStripeConfig; +extern struct Preset presetYACReaderFlowOverlappedStripeConfig; +extern struct Preset pressetYACReaderFlowUpConfig; +extern struct Preset pressetYACReaderFlowDownConfig; + +class ImageLoader3D; +class ImageLoaderByteArray3D; + +class YACReaderFlow3D : public QRhiWidget, public ScrollManagement +{ + Q_OBJECT + +protected: + int timerId; + + /*** System variables ***/ + YACReader3DImageRHI dummy; + int viewRotateActive; + float stepBackup; + + /*functions*/ + void calcPos(YACReader3DImageRHI &image, int pos); + void calcVector(YACReader3DVector &vector, int pos); + bool animate(YACReader3DVector ¤tVector, YACReader3DVector &toVector); + void prepareInstanceData(const YACReader3DImageRHI &image, bool isReflection, QVector &data); + + int updateCount; + int fontSize; + + // RHI resources + QRhiTexture *defaultTexture = nullptr; + QRhiTexture *markTexture = nullptr; + QRhiTexture *readingTexture = nullptr; + + QRhiBuffer *vertexBuffer = nullptr; + QRhiBuffer *instanceBuffer = nullptr; + QRhiBuffer *uniformBuffer = nullptr; + int alignedUniformSize = 0; // Cached aligned uniform buffer size + int uniformBufferCapacity = 0; // Number of uniform slots allocated + + QRhiSampler *sampler = nullptr; + QRhiGraphicsPipeline *pipeline = nullptr; + QRhiShaderResourceBindings *shaderBindings = nullptr; + + // Cache of shader resource bindings per texture (to avoid recreating every frame) + QMap shaderBindingsCache; + + // Pending texture uploads (for async image loading) + struct PendingTextureUpload { + int index; + QImage image; + float x; + float y; + }; + QVector pendingTextureUploads; + + // Uniform buffer data structure + struct UniformData { + QMatrix4x4 viewProjectionMatrix; + QVector3D backgroundColor; + float _pad0; + QVector3D shadingColor; + float _pad1; + float reflectionUp; + float reflectionDown; + int isReflection; + float _pad2; + }; + + void timerEvent(QTimerEvent *); + + int numObjects; + int lazyPopulateObjects; + bool showMarks; + QVector loaded; + QVector marks; + + QVector images; + + bool hasBeenInitialized; + + Performance performance; + + /*** Animation Settings ***/ + Preset config; + + int currentSelected; + + YACReader3DVector centerPos; + + /*** Style ***/ + float shadingTop; + float shadingBottom; + + float reflectionUp; + float reflectionBottom; + + /*** Theme Colors ***/ + QColor backgroundColor; + QColor textColor; + QColor shadingColor; + + /*** System info ***/ + float viewRotate; + + static int updateInterval; + + bool flowRightToLeft; + + void startAnimationTimer(); + void stopAnimationTimer(); + + // QRhiWidget overrides + void initialize(QRhiCommandBuffer *cb) override; + void render(QRhiCommandBuffer *cb) override; + void releaseResources() override; + void showEvent(QShowEvent *event) override; + + // Helper methods + QRhiTexture *createTextureFromImage(QRhiCommandBuffer *cb, const QImage &image); + void updateUniformBuffer(QRhiCommandBuffer *cb, const UniformData &data); + void prepareMarkInstanceData(const YACReader3DImageRHI &image, QVector &data); + void ensureUniformBufferCapacity(int requiredSlots); + void prepareDrawData(const YACReader3DImageRHI &image, bool isReflection, bool isMark, + const QMatrix4x4 &viewProjectionMatrix, float *outInstanceData, + UniformData &outUniformData); + void executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture *texture, + const float *instanceData, int uniformSlot); + +protected: + QRhi *m_rhi = nullptr; + std::unique_ptr m_vbuf; + std::unique_ptr m_ubuf; + std::unique_ptr m_srb; + std::unique_ptr m_pipeline; + QMatrix4x4 m_viewProjection; + float m_rotation = 0.0f; + +public: + YACReaderFlow3D(QWidget *parent = nullptr, struct Preset p = pressetYACReaderFlowDownConfig); + virtual ~YACReaderFlow3D(); + + QSize minimumSizeHint() const override; + + void showPrevious(); + void showNext(); + void setCurrentIndex(int pos); + void cleanupAnimation(); + void draw(); + void updatePositions(); + void insert(char *name, QRhiTexture *texture, float x, float y, int item = -1); + virtual void remove(int item); + void add(int item); + void replace(char *name, QRhiTexture *texture, float x, float y, int item); + void populate(int n); + YACReader3DImageRHI getCurrentSelected(); + +public slots: + void setCF_RX(int value); + void setCF_RY(int value); + void setCF_RZ(int value); + void setZoom(int zoom); + void setRotation(int angle); + void setX_Distance(int distance); + void setCenter_Distance(int distance); + void setZ_Distance(int distance); + void setCF_Y(int value); + void setCF_Z(int value); + void setY_Distance(int value); + void setFadeOutDist(int value); + void setLightStrenght(int value); + void setMaxAngle(int value); + void setPreset(const Preset &p); + void setPerformance(Performance performance); + void useVSync(bool b); // Compatibility method (no-op for RHI) + void setFlowRightToLeft(bool b); + + // Theme color setters + void setBackgroundColor(const QColor &color); + void setTextColor(const QColor &color); + void setShadingColor(const QColor &color); + + virtual void updateImageData() = 0; + + void reset(); + void reload(); + + void setShowMarks(bool value); + void setMarks(QVector marks); + void setMarkImage(QImage &image); + void markSlide(int index, YACReader::YACReaderComicReadStatus status); + void unmarkSlide(int index); + void setSlideSize(QSize size); + void clear(); + void setCenterIndex(unsigned int index); + void showSlide(int index); + int centerIndex(); + void updateMarks(); + void render(); // Compatibility method (triggers update()) + void resizeGL(int width, int height); // Compatibility method (no-op for RHI) + + QVector3D getPlaneIntersection(int x, int y, YACReader3DImageRHI plane); + void mouseDoubleClickEvent(QMouseEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void wheelEvent(QWheelEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + + friend class ImageLoader3D; + friend class ImageLoaderByteArray3D; + +signals: + void centerIndexChanged(int); + void selected(unsigned int); +}; + +class YACReaderComicFlow3D : public YACReaderFlow3D +{ +public: + YACReaderComicFlow3D(QWidget *parent = nullptr, struct Preset p = defaultYACReaderFlowConfig); + void setImagePaths(QStringList paths); + void updateImageData() override; + void remove(int item) override; + void add(const QString &path, int index); + void resortCovers(QList newOrder); + friend class ImageLoader3D; + +private: + ImageLoader3D *worker; + +protected: + QList paths; +}; + +class YACReaderPageFlow3D : public YACReaderFlow3D +{ +public: + YACReaderPageFlow3D(QWidget *parent = nullptr, struct Preset p = defaultYACReaderFlowConfig); + ~YACReaderPageFlow3D(); + void updateImageData() override; + void populate(int n); + QVector imagesReady; + QVector rawImages; + QVector imagesSetted; + friend class ImageLoaderByteArray3D; + +private: + ImageLoaderByteArray3D *worker; +}; + +class ImageLoader3D : public QThread +{ +public: + ImageLoader3D(YACReaderFlow3D *flow); + ~ImageLoader3D(); + bool busy() const; + void generate(int index, const QString &fileName); + void reset() + { + idx = -1; + fileName = ""; + } + int index() const { return idx; } + void lock(); + void unlock(); + QImage result(); + YACReaderFlow3D *flow; + QImage loadImage(const QString &fileName); + +protected: + void run() override; + +private: + QMutex mutex; + QWaitCondition condition; + + bool restart; + bool working; + int idx; + QString fileName; + QSize size; + QImage img; +}; + +class ImageLoaderByteArray3D : public QThread +{ +public: + ImageLoaderByteArray3D(YACReaderFlow3D *flow); + ~ImageLoaderByteArray3D(); + bool busy() const; + void generate(int index, const QByteArray &raw); + void reset() + { + idx = -1; + rawData.clear(); + } + int index() const { return idx; } + QImage result(); + YACReaderFlow3D *flow; + QImage loadImage(const QByteArray &rawData); + +protected: + void run() override; + +private: + QMutex mutex; + QWaitCondition condition; + + bool restart; + bool working; + int idx; + QByteArray rawData; + QSize size; + QImage img; +}; + +#endif // QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) + +#endif // __YACREADER_FLOW_RHI_H diff --git a/third_party/QsLog/QsLogDestConsole.cpp b/third_party/QsLog/QsLogDestConsole.cpp index 472d538da..d7d21646b 100644 --- a/third_party/QsLog/QsLogDestConsole.cpp +++ b/third_party/QsLog/QsLogDestConsole.cpp @@ -41,6 +41,9 @@ void QsDebugOutput::output( const QString& message ) { WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), message.utf16(), message.size(), NULL, NULL); WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), L"\n", 1, NULL, NULL); + + fprintf(stdout, "%s\n", qPrintable(message)); + fflush(stdout); } #endif From e6b7174c629c3c60aecd82a87fc21732aec17dcb Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 17 Jan 2026 22:56:46 +0100 Subject: [PATCH 005/187] Put rhi resources into a scene struct --- common/rhi/yacreader_flow_rhi.cpp | 273 +++++++++++------------------- common/rhi/yacreader_flow_rhi.h | 97 +++++++---- 2 files changed, 162 insertions(+), 208 deletions(-) diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index dc3f7c490..e897ce1b4 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -2,17 +2,6 @@ #include #include -// Structure for per-instance data -struct InstanceData { - QMatrix4x4 modelMatrix; - float leftUpShading; - float leftDownShading; - float rightUpShading; - float rightDownShading; - float opacity; - float padding[3]; // Align to 16 bytes -}; - /*** Preset Configurations ***/ // Note: The preset configurations are already defined in yacreader_flow_gl.cpp // We just reference them here as extern to avoid duplicate symbols @@ -87,58 +76,57 @@ void YACReaderFlow3D::stopAnimationTimer() void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) { if (m_rhi != rhi()) { - releaseResources(); + scene.reset(); m_rhi = rhi(); } if (!m_rhi) return; + // Helper to get or create resource update batch + auto getResourceBatch = [this]() { + if (!scene.resourceUpdates) + scene.resourceUpdates = m_rhi->nextResourceUpdateBatch(); + return scene.resourceUpdates; + }; + // Initialize default texture from image - if (!defaultTexture) { + if (!scene.defaultTexture) { QImage defaultImage(":/images/defaultCover.png"); - defaultTexture = m_rhi->newTexture(QRhiTexture::BGRA8, defaultImage.size(), 1, QRhiTexture::MipMapped); - defaultTexture->create(); - QRhiResourceUpdateBatch *batch = m_rhi->nextResourceUpdateBatch(); - batch->uploadTexture(defaultTexture, defaultImage); - cb->resourceUpdate(batch); + scene.defaultTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, defaultImage.size(), 1, QRhiTexture::MipMapped)); + scene.defaultTexture->create(); + getResourceBatch()->uploadTexture(scene.defaultTexture.get(), defaultImage); qDebug() << "YACReaderFlow3D: Created defaultTexture" << defaultImage.size(); } #ifdef YACREADER_LIBRARY // Initialize mark textures - if (!markTexture) { + if (!scene.markTexture) { QImage markImage(":/images/readRibbon.png"); if (!markImage.isNull()) { - markTexture = m_rhi->newTexture(QRhiTexture::BGRA8, markImage.size(), 1, QRhiTexture::MipMapped); - markTexture->create(); - - QRhiResourceUpdateBatch *batch = m_rhi->nextResourceUpdateBatch(); - batch->uploadTexture(markTexture, markImage); - cb->resourceUpdate(batch); + scene.markTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, markImage.size(), 1, QRhiTexture::MipMapped)); + scene.markTexture->create(); + getResourceBatch()->uploadTexture(scene.markTexture.get(), markImage); } } - if (!readingTexture) { + if (!scene.readingTexture) { QImage readingImage(":/images/readingRibbon.png"); if (!readingImage.isNull()) { - readingTexture = m_rhi->newTexture(QRhiTexture::BGRA8, readingImage.size(), 1, QRhiTexture::MipMapped); - readingTexture->create(); - - QRhiResourceUpdateBatch *batch = m_rhi->nextResourceUpdateBatch(); - batch->uploadTexture(readingTexture, readingImage); - cb->resourceUpdate(batch); + scene.readingTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, readingImage.size(), 1, QRhiTexture::MipMapped)); + scene.readingTexture->create(); + getResourceBatch()->uploadTexture(scene.readingTexture.get(), readingImage); } } #endif // Create vertex buffer (quad geometry) - if (!vertexBuffer) { + if (!scene.vertexBuffer) { // Use a triangle list (two triangles = 6 vertices) because some RHI backends // don't support TriangleFan. Each vertex: x,y,z,u,v (5 floats). - vertexBuffer = m_rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, 6 * 5 * sizeof(float)); - vertexBuffer->create(); + scene.vertexBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, 6 * 5 * sizeof(float))); + scene.vertexBuffer->create(); // Two triangles forming a quad (triangle list): // Tri 1: bottom-left, bottom-right, top-right @@ -155,38 +143,36 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) -0.5f, 0.5f, 0.0f, 0.0f, 0.0f // Top-left }; - QRhiResourceUpdateBatch *batch = m_rhi->nextResourceUpdateBatch(); - batch->uploadStaticBuffer(vertexBuffer, vertices); - cb->resourceUpdate(batch); + getResourceBatch()->uploadStaticBuffer(scene.vertexBuffer.get(), vertices); } // Initialize alignment for uniform buffers - if (alignedUniformSize == 0) { - alignedUniformSize = m_rhi->ubufAligned(sizeof(UniformData)); + if (scene.alignedUniformSize == 0) { + scene.alignedUniformSize = m_rhi->ubufAligned(sizeof(UniformData)); } // Create sampler - if (!sampler) { + if (!scene.sampler) { // Use no mipmap sampling to avoid LOD changes with camera Z - sampler = m_rhi->newSampler( + scene.sampler.reset(m_rhi->newSampler( QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None, QRhiSampler::ClampToEdge, - QRhiSampler::ClampToEdge); - sampler->create(); + QRhiSampler::ClampToEdge)); + scene.sampler->create(); } // Create instance buffer for per-draw instance data - if (!instanceBuffer) { + if (!scene.instanceBuffer) { // Allocate buffer for per-instance data (model matrix + shading + opacity + flipFlag) // mat4 (16 floats) + vec4 (4 floats) + float (1 float) + float (1 float) = 22 floats - instanceBuffer = m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, 22 * sizeof(float)); - instanceBuffer->create(); + scene.instanceBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, 22 * sizeof(float))); + scene.instanceBuffer->create(); } // Setup graphics pipeline - if (!pipeline) { + if (!scene.pipeline) { // Load shaders QShader vertShader = getShader(QLatin1String(":/shaders/flow.vert.qsb")); QShader fragShader = getShader(QLatin1String(":/shaders/flow.frag.qsb")); @@ -198,33 +184,31 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) // Create default shader resource bindings for pipeline creation // We'll create texture-specific ones on-demand in drawCover - shaderBindings = m_rhi->newShaderResourceBindings(); - shaderBindings->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, uniformBuffer), - QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, defaultTexture, sampler) }); - shaderBindings->create(); + scene.shaderBindings.reset(m_rhi->newShaderResourceBindings()); + scene.shaderBindings->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, scene.uniformBuffer.get()), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, scene.defaultTexture.get(), scene.sampler.get()) }); + scene.shaderBindings->create(); // Create pipeline - pipeline = m_rhi->newGraphicsPipeline(); + scene.pipeline.reset(m_rhi->newGraphicsPipeline()); - // Disable alpha blending temporarily to test if blending causes darkening + // Setup alpha blending QRhiGraphicsPipeline::TargetBlend blend; blend.enable = true; blend.srcColor = QRhiGraphicsPipeline::SrcAlpha; blend.dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha; blend.srcAlpha = QRhiGraphicsPipeline::One; blend.dstAlpha = QRhiGraphicsPipeline::OneMinusSrcAlpha; - pipeline->setTargetBlends({ blend }); + scene.pipeline->setTargetBlends({ blend }); - // Enable depth test (restore depth writes for normal rendering) - pipeline->setDepthTest(true); - pipeline->setDepthWrite(true); - pipeline->setDepthOp(QRhiGraphicsPipeline::Less); + // Enable depth test + scene.pipeline->setDepthTest(true); + scene.pipeline->setDepthWrite(true); + scene.pipeline->setDepthOp(QRhiGraphicsPipeline::Less); - // Diagnostic: disable culling to avoid missing-triangle artifacts - pipeline->setCullMode(QRhiGraphicsPipeline::Back); + scene.pipeline->setCullMode(QRhiGraphicsPipeline::Back); - // Determine the MSAA sample count to use. Query the RHI for supported counts - // and clamp to at most 4 samples for safety. + // Determine the MSAA sample count to use int requestedSamples = sampleCount(); int samplesToUse = 1; if (requestedSamples > 1 && m_rhi) { @@ -237,20 +221,17 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) samplesToUse = qMin(requestedSamples, qMin(4, maxSupported)); } if (samplesToUse > 1) - pipeline->setSampleCount(samplesToUse); - - // Use triangle fan topology to match OpenGL draw mode (this makes the app to crash) - // pipeline->setTopology(QRhiGraphicsPipeline::TriangleFan); + scene.pipeline->setSampleCount(samplesToUse); // Set shaders - pipeline->setShaderStages({ { QRhiShaderStage::Vertex, vertShader }, - { QRhiShaderStage::Fragment, fragShader } }); + scene.pipeline->setShaderStages({ { QRhiShaderStage::Vertex, vertShader }, + { QRhiShaderStage::Fragment, fragShader } }); // Setup vertex input layout QRhiVertexInputLayout inputLayout; inputLayout.setBindings({ { 5 * sizeof(float) }, // Per-vertex data (position + texCoord) - { 22 * sizeof(float), QRhiVertexInputBinding::PerInstance } // Per-instance data (+ flip flag) + { 22 * sizeof(float), QRhiVertexInputBinding::PerInstance } // Per-instance data }); inputLayout.setAttributes({ // Per-vertex attributes @@ -266,19 +247,24 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) { 1, 7, QRhiVertexInputAttribute::Float, 20 * sizeof(float) }, // opacity { 1, 8, QRhiVertexInputAttribute::Float, 21 * sizeof(float) } // flipFlag (1.0 = reflection) }); - pipeline->setVertexInputLayout(inputLayout); + scene.pipeline->setVertexInputLayout(inputLayout); // Set shader resource bindings and render pass descriptor - pipeline->setShaderResourceBindings(shaderBindings); - pipeline->setRenderPassDescriptor(renderTarget()->renderPassDescriptor()); + scene.pipeline->setShaderResourceBindings(scene.shaderBindings.get()); + scene.pipeline->setRenderPassDescriptor(renderTarget()->renderPassDescriptor()); - if (!pipeline->create()) { + if (!scene.pipeline->create()) { qWarning() << "YACReaderFlow3D: Failed to create graphics pipeline!"; - delete pipeline; - pipeline = nullptr; + scene.pipeline.reset(); } } + // Submit any pending resource updates + if (scene.resourceUpdates) { + cb->resourceUpdate(scene.resourceUpdates); + scene.resourceUpdates = nullptr; + } + // Call populate only once per data loaded. if (!hasBeenInitialized && lazyPopulateObjects != -1) { populate(lazyPopulateObjects); @@ -290,43 +276,35 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) void YACReaderFlow3D::ensureUniformBufferCapacity(int requiredSlots) { - if (!m_rhi || alignedUniformSize == 0) + if (!m_rhi || scene.alignedUniformSize == 0) return; // Check if we need to resize - if (uniformBufferCapacity >= requiredSlots && uniformBuffer) + if (scene.uniformBufferCapacity >= requiredSlots && scene.uniformBuffer) return; - // Delete old buffer if it exists - if (uniformBuffer) { - delete uniformBuffer; - uniformBuffer = nullptr; - } + // Reset uniform buffer + scene.uniformBuffer.reset(); // Create new larger buffer // Each draw needs its own uniform slot (cover + reflection + optional mark = 3 per object) - const int totalSize = requiredSlots * alignedUniformSize; - uniformBuffer = m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, totalSize); - if (uniformBuffer->create()) { - uniformBufferCapacity = requiredSlots; + const int totalSize = requiredSlots * scene.alignedUniformSize; + scene.uniformBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, totalSize)); + if (scene.uniformBuffer->create()) { + scene.uniformBufferCapacity = requiredSlots; // Invalidate shader bindings cache since the uniform buffer changed - for (auto *srb : shaderBindingsCache) { - delete srb; - } - shaderBindingsCache.clear(); + qDeleteAll(scene.shaderBindingsCache); + scene.shaderBindingsCache.clear(); // Recreate default shader bindings for pipeline - if (shaderBindings) { - delete shaderBindings; - } - shaderBindings = m_rhi->newShaderResourceBindings(); - shaderBindings->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, uniformBuffer), - QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, defaultTexture, sampler) }); - shaderBindings->create(); + scene.shaderBindings.reset(m_rhi->newShaderResourceBindings()); + scene.shaderBindings->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, scene.uniformBuffer.get()), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, scene.defaultTexture.get(), scene.sampler.get()) }); + scene.shaderBindings->create(); } else { qWarning() << "YACReaderFlow3D: Failed to create uniform buffer of size" << totalSize; - uniformBufferCapacity = 0; + scene.uniformBufferCapacity = 0; } } @@ -418,7 +396,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) // Add mark draw immediately after its cover if (showMarks && loaded[idx] && marks[idx] != Unread) { - QRhiTexture *markTex = (marks[idx] == Read) ? markTexture : readingTexture; + QRhiTexture *markTex = (marks[idx] == Read) ? scene.markTexture.get() : scene.readingTexture.get(); if (markTex) { DrawInfo markDraw; markDraw.imageIndex = idx; @@ -434,19 +412,16 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) // Ensure uniform buffer is large enough ensureUniformBufferCapacity(draws.size()); - if (!uniformBuffer) { + if (!scene.uniformBuffer) { qWarning() << "YACReaderFlow3D: No uniform buffer available for rendering"; return; } // Ensure instance buffer is large enough for all draws const int requiredInstanceSize = draws.size() * 22 * sizeof(float); - if (!instanceBuffer || instanceBuffer->size() < requiredInstanceSize) { - if (instanceBuffer) { - delete instanceBuffer; - } - instanceBuffer = m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, requiredInstanceSize); - if (!instanceBuffer->create()) { + if (!scene.instanceBuffer || scene.instanceBuffer->size() < requiredInstanceSize) { + scene.instanceBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, requiredInstanceSize)); + if (!scene.instanceBuffer->create()) { qWarning() << "YACReaderFlow3D: Failed to create instance buffer of size" << requiredInstanceSize; return; } @@ -468,21 +443,21 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) // Update uniform buffer with all draw data for (int i = 0; i < draws.size(); ++i) { - int offset = i * alignedUniformSize; - batch->updateDynamicBuffer(uniformBuffer, offset, sizeof(UniformData), &draws[i].uniformData); + int offset = i * scene.alignedUniformSize; + batch->updateDynamicBuffer(scene.uniformBuffer.get(), offset, sizeof(UniformData), &draws[i].uniformData); } // Update instance buffer with all instance data for (int i = 0; i < draws.size(); ++i) { int offset = i * 22 * sizeof(float); - batch->updateDynamicBuffer(instanceBuffer, offset, 22 * sizeof(float), draws[i].instanceData); + batch->updateDynamicBuffer(scene.instanceBuffer.get(), offset, 22 * sizeof(float), draws[i].instanceData); } // === PHASE 2: RENDER (DURING PASS) === cb->beginPass(renderTarget(), clearColor, { 1.0f, 0 }, batch); - if (pipeline) { - cb->setGraphicsPipeline(pipeline); + if (scene.pipeline) { + cb->setGraphicsPipeline(scene.pipeline.get()); cb->setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height())); // Execute all draws @@ -575,43 +550,31 @@ void YACReaderFlow3D::prepareDrawData(const YACReader3DImageRHI &image, bool isR void YACReaderFlow3D::executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture *texture, const float *instanceData, int uniformSlot) { - if (!texture || !instanceBuffer || !vertexBuffer) + if (!texture || !scene.instanceBuffer || !scene.vertexBuffer) return; - // NOTE: We cannot update the instance buffer here during the render pass! - // Instead, we'll need to either: - // 1. Use the instance data from uniforms (move it to uniform buffer) - // 2. Or pre-upload all instance data before the pass - // - // For now, let's use approach #1: embed instance data in uniforms via a large instance buffer - // that we populate before the pass, similar to uniforms - // - // Actually, the simplest solution: update the instance buffer ONCE per draw using dynamic updates - // But we need to do this cleverly - we can't call resourceUpdate during pass. - // - // The solution: Create an instance buffer large enough for ALL draws, update it before pass, - // and use offsets during drawing. + Q_UNUSED(instanceData) // Get or create shader resource bindings for this texture with dynamic offset support - QRhiShaderResourceBindings *srb = shaderBindingsCache.value(texture, nullptr); + QRhiShaderResourceBindings *srb = scene.shaderBindingsCache.value(texture, nullptr); if (!srb) { srb = m_rhi->newShaderResourceBindings(); - srb->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, uniformBuffer), - QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture, sampler) }); + srb->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, scene.uniformBuffer.get()), + QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture, scene.sampler.get()) }); srb->create(); - shaderBindingsCache.insert(texture, srb); + scene.shaderBindingsCache.insert(texture, srb); } // Set shader resources with dynamic offset for uniform buffer QRhiCommandBuffer::DynamicOffset dynOfs[] = { - { 0, quint32(uniformSlot * alignedUniformSize) } + { 0, quint32(uniformSlot * scene.alignedUniformSize) } }; cb->setShaderResources(srb, 1, dynOfs); // Bind vertex buffers with offset into instance buffer const QRhiCommandBuffer::VertexInput vbufBindings[] = { - { vertexBuffer, 0 }, - { instanceBuffer, quint32(uniformSlot * 22 * sizeof(float)) } // Use slot index for instance data offset + { scene.vertexBuffer.get(), 0 }, + { scene.instanceBuffer.get(), quint32(uniformSlot * 22 * sizeof(float)) } }; cb->setVertexInput(0, 2, vbufBindings); @@ -625,39 +588,7 @@ void YACReaderFlow3D::executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture * void YACReaderFlow3D::releaseResources() { - delete vertexBuffer; - vertexBuffer = nullptr; - - delete instanceBuffer; - instanceBuffer = nullptr; - - delete uniformBuffer; - uniformBuffer = nullptr; - - delete sampler; - sampler = nullptr; - - delete pipeline; - pipeline = nullptr; - - delete shaderBindings; - shaderBindings = nullptr; - - // Clean up shader bindings cache - for (auto *srb : shaderBindingsCache) { - delete srb; - } - shaderBindingsCache.clear(); - - delete defaultTexture; - defaultTexture = nullptr; - - delete markTexture; - markTexture = nullptr; - - delete readingTexture; - readingTexture = nullptr; - + scene.reset(); m_rhi = nullptr; } @@ -869,7 +800,7 @@ void YACReaderFlow3D::remove(int item) } images.removeAt(item); - if (texture != defaultTexture) + if (texture != scene.defaultTexture.get()) delete texture; numObjects--; @@ -890,7 +821,7 @@ void YACReaderFlow3D::add(int item) images[i].index++; } - insert(s.toLocal8Bit().data(), defaultTexture, x, y, item); + insert(s.toLocal8Bit().data(), scene.defaultTexture.get(), x, y, item); } YACReader3DImageRHI YACReaderFlow3D::getCurrentSelected() @@ -925,7 +856,7 @@ void YACReaderFlow3D::populate(int n) for (i = 0; i < n; i++) { QString s = "cover"; - insert(s.toLocal8Bit().data(), defaultTexture, x, y); + insert(s.toLocal8Bit().data(), scene.defaultTexture.get(), x, y); } loaded = QVector(n, false); @@ -939,7 +870,7 @@ void YACReaderFlow3D::reset() loaded.clear(); for (int i = 0; i < numObjects; i++) { - if (images[i].texture != defaultTexture) + if (images[i].texture != scene.defaultTexture.get()) delete images[i].texture; } @@ -1469,7 +1400,7 @@ YACReaderPageFlow3D::~YACReaderPageFlow3D() // Clean up textures for (auto &image : images) { - if (image.texture != defaultTexture) { + if (image.texture != scene.defaultTexture.get()) { delete image.texture; } } diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index 7e87769d0..6d778f5de 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -89,12 +89,10 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement protected: int timerId; - /*** System variables ***/ YACReader3DImageRHI dummy; int viewRotateActive; float stepBackup; - /*functions*/ void calcPos(YACReader3DImageRHI &image, int pos); void calcVector(YACReader3DVector &vector, int pos); bool animate(YACReader3DVector ¤tVector, YACReader3DVector &toVector); @@ -103,34 +101,7 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement int updateCount; int fontSize; - // RHI resources - QRhiTexture *defaultTexture = nullptr; - QRhiTexture *markTexture = nullptr; - QRhiTexture *readingTexture = nullptr; - - QRhiBuffer *vertexBuffer = nullptr; - QRhiBuffer *instanceBuffer = nullptr; - QRhiBuffer *uniformBuffer = nullptr; - int alignedUniformSize = 0; // Cached aligned uniform buffer size - int uniformBufferCapacity = 0; // Number of uniform slots allocated - - QRhiSampler *sampler = nullptr; - QRhiGraphicsPipeline *pipeline = nullptr; - QRhiShaderResourceBindings *shaderBindings = nullptr; - - // Cache of shader resource bindings per texture (to avoid recreating every frame) - QMap shaderBindingsCache; - - // Pending texture uploads (for async image loading) - struct PendingTextureUpload { - int index; - QImage image; - float x; - float y; - }; - QVector pendingTextureUploads; - - // Uniform buffer data structure + // Uniform buffer data structure (must match shader layout) struct UniformData { QMatrix4x4 viewProjectionMatrix; QVector3D backgroundColor; @@ -143,7 +114,65 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement float _pad2; }; - void timerEvent(QTimerEvent *); + // Pending texture uploads (for async image loading) + struct PendingTextureUpload { + int index; + QImage image; + float x; + float y; + }; + + // Scene struct encapsulating all RHI resources + struct Scene { + // Textures + std::unique_ptr defaultTexture; + std::unique_ptr markTexture; + std::unique_ptr readingTexture; + + // Buffers + std::unique_ptr vertexBuffer; + std::unique_ptr instanceBuffer; + std::unique_ptr uniformBuffer; + + // Pipeline and bindings + std::unique_ptr sampler; + std::unique_ptr pipeline; + std::unique_ptr shaderBindings; + + // Cache of shader resource bindings per texture (raw pointers, owned by this struct) + QMap shaderBindingsCache; + + // Uniform buffer sizing + int alignedUniformSize = 0; + int uniformBufferCapacity = 0; + + // Pending resource updates (accumulated between frames) + QRhiResourceUpdateBatch *resourceUpdates = nullptr; + + // Reset all resources (cleans up cache manually) + void reset() + { + qDeleteAll(shaderBindingsCache); + shaderBindingsCache.clear(); + defaultTexture.reset(); + markTexture.reset(); + readingTexture.reset(); + vertexBuffer.reset(); + instanceBuffer.reset(); + uniformBuffer.reset(); + sampler.reset(); + pipeline.reset(); + shaderBindings.reset(); + alignedUniformSize = 0; + uniformBufferCapacity = 0; + resourceUpdates = nullptr; + } + }; + + Scene scene; + QVector pendingTextureUploads; + + void timerEvent(QTimerEvent *) override; int numObjects; int lazyPopulateObjects; @@ -205,12 +234,6 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement protected: QRhi *m_rhi = nullptr; - std::unique_ptr m_vbuf; - std::unique_ptr m_ubuf; - std::unique_ptr m_srb; - std::unique_ptr m_pipeline; - QMatrix4x4 m_viewProjection; - float m_rotation = 0.0f; public: YACReaderFlow3D(QWidget *parent = nullptr, struct Preset p = pressetYACReaderFlowDownConfig); From 65fd07bb99ce132fb09ae8634029ae324c035dab Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 17 Jan 2026 23:03:56 +0100 Subject: [PATCH 006/187] Add proper resources cleaning --- common/rhi/yacreader_flow_rhi.cpp | 35 ++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index e897ce1b4..933959271 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -51,6 +51,18 @@ YACReaderFlow3D::~YACReaderFlow3D() killTimer(timerId); timerId = -1; } + + // Clean up image textures (not owned by Scene) + for (int i = 0; i < numObjects; i++) { + if (images[i].texture && images[i].texture != scene.defaultTexture.get()) { + delete images[i].texture; + } + } + images.clear(); + numObjects = 0; + + // Release all RHI resources + scene.reset(); } void YACReaderFlow3D::timerEvent(QTimerEvent *event) @@ -800,8 +812,15 @@ void YACReaderFlow3D::remove(int item) } images.removeAt(item); - if (texture != scene.defaultTexture.get()) + if (texture != scene.defaultTexture.get()) { + // Remove shader bindings for this texture before deleting it + auto it = scene.shaderBindingsCache.find(texture); + if (it != scene.shaderBindingsCache.end()) { + delete it.value(); + scene.shaderBindingsCache.erase(it); + } delete texture; + } numObjects--; } @@ -869,9 +888,17 @@ void YACReaderFlow3D::reset() currentSelected = 0; loaded.clear(); + // Clean up image textures and remove their entries from shader bindings cache for (int i = 0; i < numObjects; i++) { - if (images[i].texture != scene.defaultTexture.get()) + if (images[i].texture != scene.defaultTexture.get()) { + // Remove shader bindings for this texture before deleting it + auto it = scene.shaderBindingsCache.find(images[i].texture); + if (it != scene.shaderBindingsCache.end()) { + delete it.value(); + scene.shaderBindingsCache.erase(it); + } delete images[i].texture; + } } numObjects = 0; @@ -1398,12 +1425,14 @@ YACReaderPageFlow3D::~YACReaderPageFlow3D() } rawImages.clear(); - // Clean up textures + // Clean up textures and clear images to prevent double-delete in base destructor for (auto &image : images) { if (image.texture != scene.defaultTexture.get()) { delete image.texture; } } + images.clear(); + numObjects = 0; } void YACReaderPageFlow3D::updateImageData() From 816d5bfe9a635da7a3fda2d217d1ed8064a9e1fb Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 18 Jan 2026 10:06:44 +0100 Subject: [PATCH 007/187] Extract the comic and page flow classes to their own files --- YACReader/YACReader.pro | 4 + YACReader/goto_flow_gl.h | 2 +- YACReaderLibrary/YACReaderLibrary.pro | 4 + YACReaderLibrary/comic_flow_widget.h | 2 +- common/rhi/yacreader_comic_flow_rhi.cpp | 246 +++++++++++++ common/rhi/yacreader_comic_flow_rhi.h | 59 ++++ common/rhi/yacreader_flow_rhi.cpp | 444 +----------------------- common/rhi/yacreader_flow_rhi.h | 105 +----- common/rhi/yacreader_page_flow_rhi.cpp | 204 +++++++++++ common/rhi/yacreader_page_flow_rhi.h | 55 +++ 10 files changed, 582 insertions(+), 543 deletions(-) create mode 100644 common/rhi/yacreader_comic_flow_rhi.cpp create mode 100644 common/rhi/yacreader_comic_flow_rhi.h create mode 100644 common/rhi/yacreader_page_flow_rhi.cpp create mode 100644 common/rhi/yacreader_page_flow_rhi.h diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro index 3cc1aa769..940ea7231 100644 --- a/YACReader/YACReader.pro +++ b/YACReader/YACReader.pro @@ -110,6 +110,8 @@ HEADERS += ../common/comic.h \ greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { HEADERS += ../common/rhi/yacreader_flow_rhi.h + HEADERS += ../common/rhi/yacreader_comic_flow_rhi.h \ + ../common/rhi/yacreader_page_flow_rhi.h } } @@ -153,6 +155,8 @@ SOURCES += ../common/comic.cpp \ greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { SOURCES += ../common/rhi/yacreader_flow_rhi.cpp + SOURCES += ../common/rhi/yacreader_comic_flow_rhi.cpp \ + ../common/rhi/yacreader_page_flow_rhi.cpp RESOURCES += ../common/rhi/shaders/shaders.qrc } } diff --git a/YACReader/goto_flow_gl.h b/YACReader/goto_flow_gl.h index d2278641c..8afc0ce3b 100644 --- a/YACReader/goto_flow_gl.h +++ b/YACReader/goto_flow_gl.h @@ -6,7 +6,7 @@ // Conditional include based on Qt version and RHI availability #if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) -#include "yacreader_flow_rhi.h" +#include "yacreader_page_flow_rhi.h" using YACReaderPageFlowImpl = YACReaderPageFlow3D; #else #include "yacreader_flow_gl.h" diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 79d1ed173..11952c353 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -157,6 +157,8 @@ HEADERS += comic_flow.h \ greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { HEADERS += ../common/rhi/yacreader_flow_rhi.h + HEADERS += ../common/rhi/yacreader_comic_flow_rhi.h \ + ../common/rhi/yacreader_page_flow_rhi.h } } @@ -249,6 +251,8 @@ SOURCES += comic_flow.cpp \ greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { SOURCES += ../common/rhi/yacreader_flow_rhi.cpp + SOURCES += ../common/rhi/yacreader_comic_flow_rhi.cpp \ + ../common/rhi/yacreader_page_flow_rhi.cpp RESOURCES += ../common/rhi/shaders/shaders.qrc } } diff --git a/YACReaderLibrary/comic_flow_widget.h b/YACReaderLibrary/comic_flow_widget.h index 981585925..51217cc46 100644 --- a/YACReaderLibrary/comic_flow_widget.h +++ b/YACReaderLibrary/comic_flow_widget.h @@ -8,7 +8,7 @@ #ifndef NO_OPENGL // Conditional include based on Qt version and RHI availability #if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) -#include "yacreader_flow_rhi.h" +#include "yacreader_comic_flow_rhi.h" using YACReaderComicFlowImpl = YACReaderComicFlow3D; #else #include "yacreader_flow_gl.h" diff --git a/common/rhi/yacreader_comic_flow_rhi.cpp b/common/rhi/yacreader_comic_flow_rhi.cpp new file mode 100644 index 000000000..bf7bafaa5 --- /dev/null +++ b/common/rhi/yacreader_comic_flow_rhi.cpp @@ -0,0 +1,246 @@ +#include "yacreader_comic_flow_rhi.h" +#include + +// YACReaderComicFlow3D implementation +YACReaderComicFlow3D::YACReaderComicFlow3D(QWidget *parent, struct Preset p) + : YACReaderFlow3D(parent, p) +{ + worker = new ImageLoader3D(this); + worker->flow = this; +} + +void YACReaderComicFlow3D::setImagePaths(QStringList paths) +{ + worker->reset(); + reset(); + numObjects = 0; + + if (hasBeenInitialized) { + YACReaderFlow3D::populate(paths.size()); + } else { + lazyPopulateObjects = paths.size(); + } + + this->paths = paths; +} + +void YACReaderComicFlow3D::updateImageData() +{ + if (worker->busy()) + return; + + int idx = worker->index(); + if (idx >= 0 && !worker->result().isNull()) { + if (!loaded[idx]) { + float x = 1; + QImage img = worker->result(); + + // Create QRhiTexture from the loaded image + if (m_rhi) { + QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, + (performance == high || performance == ultraHigh) ? QRhiTexture::MipMapped : QRhiTexture::UsedAsTransferSource); + + if (texture->create()) { + PendingTextureUpload upload; + upload.index = idx; + upload.image = img; + upload.x = x; + upload.y = 1 * (float(img.height()) / img.width()); + pendingTextureUploads.append(upload); + + QString s = "cover"; + replace(s.toLocal8Bit().data(), texture, upload.x, upload.y, idx); + } + } + } + } + + int count = 8; + switch (performance) { + case low: + count = 8; + break; + case medium: + count = 10; + break; + case high: + count = 12; + break; + case ultraHigh: + count = 16; + break; + } + + int *indexes = new int[2 * count + 1]; + int center = currentSelected; + indexes[0] = center; + for (int j = 0; j < count; j++) { + indexes[j * 2 + 1] = center + j + 1; + indexes[j * 2 + 2] = center - j - 1; + } + + for (int c = 0; c < 2 * count + 1; c++) { + int i = indexes[c]; + if ((i >= 0) && (i < numObjects)) + if (!loaded[i]) { + if (paths.size() > 0) { + QString fname = paths.at(i); + worker->generate(i, fname); + } + delete[] indexes; + return; + } + } + + delete[] indexes; +} + +void YACReaderComicFlow3D::remove(int item) +{ + worker->lock(); + worker->reset(); + YACReaderFlow3D::remove(item); + if (item >= 0 && item < paths.size()) { + paths.removeAt(item); + } + worker->unlock(); +} + +void YACReaderComicFlow3D::add(const QString &path, int index) +{ + worker->lock(); + worker->reset(); + paths.insert(index, path); + YACReaderFlow3D::add(index); + worker->unlock(); +} + +void YACReaderComicFlow3D::resortCovers(QList newOrder) +{ + worker->lock(); + worker->reset(); + startAnimationTimer(); + + QList pathsNew; + QVector loadedNew; + QVector marksNew; + QVector imagesNew; + + int index = 0; + foreach (int i, newOrder) { + if (i < 0 || i >= images.size()) { + continue; + } + + pathsNew << paths.at(i); + loadedNew << loaded.at(i); + marksNew << marks.at(i); + imagesNew << images.at(i); + imagesNew.last().index = index++; + } + + paths = pathsNew; + loaded = loadedNew; + marks = marksNew; + images = imagesNew; + + worker->unlock(); +} + +// ImageLoader3D implementation +QImage ImageLoader3D::loadImage(const QString &fileName) +{ + QImage image; + + if (!image.load(fileName)) { + return QImage(); + } + + switch (flow->performance) { + case low: + image = image.scaledToWidth(200, Qt::SmoothTransformation); + break; + case medium: + image = image.scaledToWidth(256, Qt::SmoothTransformation); + break; + case high: + image = image.scaledToWidth(320, Qt::SmoothTransformation); + break; + case ultraHigh: + break; + } + + return image; +} + +ImageLoader3D::ImageLoader3D(YACReaderFlow3D *flow) + : QThread(), flow(flow), restart(false), working(false), idx(-1) +{ +} + +ImageLoader3D::~ImageLoader3D() +{ + mutex.lock(); + condition.wakeOne(); + mutex.unlock(); + wait(); +} + +bool ImageLoader3D::busy() const +{ + return isRunning() ? working : false; +} + +void ImageLoader3D::generate(int index, const QString &fileName) +{ + mutex.lock(); + this->idx = index; + this->fileName = fileName; + this->img = QImage(); + mutex.unlock(); + + if (!isRunning()) + start(); + else { + restart = true; + condition.wakeOne(); + } +} + +void ImageLoader3D::lock() +{ + mutex.lock(); +} + +void ImageLoader3D::unlock() +{ + mutex.unlock(); +} + +void ImageLoader3D::run() +{ + for (;;) { + mutex.lock(); + this->working = true; + QString fileName = this->fileName; + mutex.unlock(); + + QImage image = loadImage(fileName); + + mutex.lock(); + this->working = false; + this->img = image; + mutex.unlock(); + + mutex.lock(); + if (!this->restart) + condition.wait(&mutex); + restart = false; + mutex.unlock(); + } +} + +QImage ImageLoader3D::result() +{ + return img; +} diff --git a/common/rhi/yacreader_comic_flow_rhi.h b/common/rhi/yacreader_comic_flow_rhi.h new file mode 100644 index 000000000..c64db0e89 --- /dev/null +++ b/common/rhi/yacreader_comic_flow_rhi.h @@ -0,0 +1,59 @@ +#ifndef __YACREADER_COMIC_FLOW_RHI_H +#define __YACREADER_COMIC_FLOW_RHI_H + +#include "yacreader_flow_rhi.h" + +class ImageLoader3D; + +class YACReaderComicFlow3D : public YACReaderFlow3D +{ +public: + YACReaderComicFlow3D(QWidget *parent = nullptr, struct Preset p = defaultYACReaderFlowConfig); + void setImagePaths(QStringList paths); + void updateImageData() override; + void remove(int item) override; + void add(const QString &path, int index); + void resortCovers(QList newOrder); + friend class ImageLoader3D; + +private: + ImageLoader3D *worker; + +protected: + QList paths; +}; + +class ImageLoader3D : public QThread +{ +public: + ImageLoader3D(YACReaderFlow3D *flow); + ~ImageLoader3D(); + bool busy() const; + void generate(int index, const QString &fileName); + void reset() + { + idx = -1; + fileName = ""; + } + int index() const { return idx; } + void lock(); + void unlock(); + QImage result(); + YACReaderFlow3D *flow; + QImage loadImage(const QString &fileName); + +protected: + void run() override; + +private: + QMutex mutex; + QWaitCondition condition; + + bool restart; + bool working; + int idx; + QString fileName; + QImage img; +}; + +#endif // __YACREADER_COMIC_FLOW_RHI_H diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index 933959271..b84874774 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -1259,446 +1259,6 @@ QSize YACReaderFlow3D::minimumSizeHint() const } // YACReaderComicFlow3D implementation -YACReaderComicFlow3D::YACReaderComicFlow3D(QWidget *parent, struct Preset p) - : YACReaderFlow3D(parent, p) -{ - worker = new ImageLoader3D(this); - worker->flow = this; -} - -void YACReaderComicFlow3D::setImagePaths(QStringList paths) -{ - worker->reset(); - reset(); - numObjects = 0; - - if (hasBeenInitialized) { - YACReaderFlow3D::populate(paths.size()); - } else { - lazyPopulateObjects = paths.size(); - } - - this->paths = paths; -} - -void YACReaderComicFlow3D::updateImageData() -{ - if (worker->busy()) - return; - - int idx = worker->index(); - if (idx >= 0 && !worker->result().isNull()) { - if (!loaded[idx]) { - float x = 1; - QImage img = worker->result(); - - // // Ensure the loaded image is in RGBA8888 layout so QRhi interprets channels correctly - // if (img.format() != QImage::Format_RGBA8888) - // img = img.convertToFormat(QImage::Format_RGBA8888); - - // Create QRhiTexture from the loaded image - if (m_rhi) { - QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, - (performance == high || performance == ultraHigh) ? QRhiTexture::MipMapped : QRhiTexture::UsedAsTransferSource); - - if (texture->create()) { - // Queue texture upload (image already converted to RGBA8888) - PendingTextureUpload upload; - upload.index = idx; - upload.image = img; - upload.x = x; - upload.y = 1 * (float(img.height()) / img.width()); - pendingTextureUploads.append(upload); - - QString s = "cover"; - replace(s.toLocal8Bit().data(), texture, upload.x, upload.y, idx); - } - } - } - } - - int count = 8; - switch (performance) { - case low: - count = 8; - break; - case medium: - count = 10; - break; - case high: - count = 12; - break; - case ultraHigh: - count = 16; - break; - } - - int *indexes = new int[2 * count + 1]; - int center = currentSelected; - indexes[0] = center; - for (int j = 0; j < count; j++) { - indexes[j * 2 + 1] = center + j + 1; - indexes[j * 2 + 2] = center - j - 1; - } - - for (int c = 0; c < 2 * count + 1; c++) { - int i = indexes[c]; - if ((i >= 0) && (i < numObjects)) - if (!loaded[i]) { - if (paths.size() > 0) { - QString fname = paths.at(i); - worker->generate(i, fname); - } - delete[] indexes; - return; - } - } - - delete[] indexes; -} - -void YACReaderComicFlow3D::remove(int item) -{ - worker->lock(); - worker->reset(); - YACReaderFlow3D::remove(item); - if (item >= 0 && item < paths.size()) { - paths.removeAt(item); - } - worker->unlock(); -} - -void YACReaderComicFlow3D::add(const QString &path, int index) -{ - worker->lock(); - worker->reset(); - paths.insert(index, path); - YACReaderFlow3D::add(index); - worker->unlock(); -} - -void YACReaderComicFlow3D::resortCovers(QList newOrder) -{ - worker->lock(); - worker->reset(); - startAnimationTimer(); - - QList pathsNew; - QVector loadedNew; - QVector marksNew; - QVector imagesNew; +// YACReaderComicFlow3D implementation moved to common/rhi/yacreader_comic_flow_rhi.* - int index = 0; - foreach (int i, newOrder) { - if (i < 0 || i >= images.size()) { - continue; - } - - pathsNew << paths.at(i); - loadedNew << loaded.at(i); - marksNew << marks.at(i); - imagesNew << images.at(i); - imagesNew.last().index = index++; - } - - paths = pathsNew; - loaded = loadedNew; - marks = marksNew; - images = imagesNew; - - worker->unlock(); -} - -// YACReaderPageFlow3D implementation -YACReaderPageFlow3D::YACReaderPageFlow3D(QWidget *parent, struct Preset p) - : YACReaderFlow3D(parent, p) -{ - worker = new ImageLoaderByteArray3D(this); - worker->flow = this; -} - -YACReaderPageFlow3D::~YACReaderPageFlow3D() -{ - if (timerId != -1) { - this->killTimer(timerId); - timerId = -1; - } - rawImages.clear(); - - // Clean up textures and clear images to prevent double-delete in base destructor - for (auto &image : images) { - if (image.texture != scene.defaultTexture.get()) { - delete image.texture; - } - } - images.clear(); - numObjects = 0; -} - -void YACReaderPageFlow3D::updateImageData() -{ - if (worker->busy()) - return; - - int idx = worker->index(); - if (idx >= 0 && !worker->result().isNull()) { - if (!loaded[idx]) { - float x = 1; - QImage img = worker->result(); - - // Create QRhiTexture from the loaded image - if (m_rhi) { - QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, - (performance == high || performance == ultraHigh) ? QRhiTexture::MipMapped : QRhiTexture::UsedAsTransferSource); - - if (texture->create()) { - float y = 1 * (float(img.height()) / img.width()); - QString s = "cover"; - replace(s.toLocal8Bit().data(), texture, x, y, idx); - loaded[idx] = true; - } - } - } - } - - int count = 8; - switch (performance) { - case low: - count = 8; - break; - case medium: - count = 10; - break; - case high: - count = 12; - break; - case ultraHigh: - count = 14; - break; - } - - int *indexes = new int[2 * count + 1]; - int center = currentSelected; - indexes[0] = center; - for (int j = 0; j < count; j++) { - indexes[j * 2 + 1] = center + j + 1; - indexes[j * 2 + 2] = center - j - 1; - } - - for (int c = 0; c < 2 * count + 1; c++) { - int i = indexes[c]; - if ((i >= 0) && (i < numObjects)) - if (rawImages.size() > 0) - if (!loaded[i] && imagesReady[i]) { - worker->generate(i, rawImages.at(i)); - delete[] indexes; - return; - } - } - - delete[] indexes; -} - -void YACReaderPageFlow3D::populate(int n) -{ - worker->reset(); - - if (hasBeenInitialized) { - YACReaderFlow3D::populate(n); - } else { - lazyPopulateObjects = n; - } - - imagesReady = QVector(n, false); - rawImages = QVector(n); - imagesSetted = QVector(n, false); -} - -// ImageLoader3D implementation -QImage ImageLoader3D::loadImage(const QString &fileName) -{ - QImage image; - - if (!image.load(fileName)) { - return QImage(); - } - - switch (flow->performance) { - case low: - image = image.scaledToWidth(200, Qt::SmoothTransformation); - break; - case medium: - image = image.scaledToWidth(256, Qt::SmoothTransformation); - break; - case high: - image = image.scaledToWidth(320, Qt::SmoothTransformation); - break; - case ultraHigh: - break; - } - - return image; -} - -ImageLoader3D::ImageLoader3D(YACReaderFlow3D *flow) - : QThread(), flow(flow), restart(false), working(false), idx(-1) -{ -} - -ImageLoader3D::~ImageLoader3D() -{ - mutex.lock(); - condition.wakeOne(); - mutex.unlock(); - wait(); -} - -bool ImageLoader3D::busy() const -{ - return isRunning() ? working : false; -} - -void ImageLoader3D::generate(int index, const QString &fileName) -{ - mutex.lock(); - this->idx = index; - this->fileName = fileName; - this->size = size; - this->img = QImage(); - mutex.unlock(); - - if (!isRunning()) - start(); - else { - restart = true; - condition.wakeOne(); - } -} - -void ImageLoader3D::lock() -{ - mutex.lock(); -} - -void ImageLoader3D::unlock() -{ - mutex.unlock(); -} - -void ImageLoader3D::run() -{ - for (;;) { - mutex.lock(); - this->working = true; - QString fileName = this->fileName; - mutex.unlock(); - - QImage image = loadImage(fileName); - - mutex.lock(); - this->working = false; - this->img = image; - mutex.unlock(); - - mutex.lock(); - if (!this->restart) - condition.wait(&mutex); - restart = false; - mutex.unlock(); - } -} - -QImage ImageLoader3D::result() -{ - return img; -} - -// ImageLoaderByteArray3D implementation -QImage ImageLoaderByteArray3D::loadImage(const QByteArray &raw) -{ - QImage image; - - if (!image.loadFromData(raw)) { - return QImage(); - } - - switch (flow->performance) { - case low: - image = image.scaledToWidth(128, Qt::SmoothTransformation); - break; - case medium: - image = image.scaledToWidth(196, Qt::SmoothTransformation); - break; - case high: - image = image.scaledToWidth(256, Qt::SmoothTransformation); - break; - case ultraHigh: - image = image.scaledToWidth(320, Qt::SmoothTransformation); - break; - } - - return image; -} - -ImageLoaderByteArray3D::ImageLoaderByteArray3D(YACReaderFlow3D *flow) - : QThread(), flow(flow), restart(false), working(false), idx(-1) -{ -} - -ImageLoaderByteArray3D::~ImageLoaderByteArray3D() -{ - mutex.lock(); - condition.wakeOne(); - mutex.unlock(); - wait(); -} - -bool ImageLoaderByteArray3D::busy() const -{ - return isRunning() ? working : false; -} - -void ImageLoaderByteArray3D::generate(int index, const QByteArray &raw) -{ - mutex.lock(); - this->idx = index; - this->rawData = raw; - this->size = size; - this->img = QImage(); - mutex.unlock(); - - if (!isRunning()) - start(); - else { - restart = true; - condition.wakeOne(); - } -} - -void ImageLoaderByteArray3D::run() -{ - for (;;) { - mutex.lock(); - this->working = true; - QByteArray raw = this->rawData; - mutex.unlock(); - - QImage image = loadImage(raw); - - mutex.lock(); - this->working = false; - this->img = image; - mutex.unlock(); - - mutex.lock(); - if (!this->restart) - condition.wait(&mutex); - restart = false; - mutex.unlock(); - } -} - -QImage ImageLoaderByteArray3D::result() -{ - return img; -} +// Implementations for derived flows and loaders live in their own files. diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index 6d778f5de..f22f173fc 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -81,6 +81,8 @@ extern struct Preset pressetYACReaderFlowDownConfig; class ImageLoader3D; class ImageLoaderByteArray3D; +class YACReaderComicFlow3D; +class YACReaderPageFlow3D; class YACReaderFlow3D : public QRhiWidget, public ScrollManagement { @@ -312,105 +314,10 @@ public slots: void selected(unsigned int); }; -class YACReaderComicFlow3D : public YACReaderFlow3D -{ -public: - YACReaderComicFlow3D(QWidget *parent = nullptr, struct Preset p = defaultYACReaderFlowConfig); - void setImagePaths(QStringList paths); - void updateImageData() override; - void remove(int item) override; - void add(const QString &path, int index); - void resortCovers(QList newOrder); - friend class ImageLoader3D; - -private: - ImageLoader3D *worker; - -protected: - QList paths; -}; - -class YACReaderPageFlow3D : public YACReaderFlow3D -{ -public: - YACReaderPageFlow3D(QWidget *parent = nullptr, struct Preset p = defaultYACReaderFlowConfig); - ~YACReaderPageFlow3D(); - void updateImageData() override; - void populate(int n); - QVector imagesReady; - QVector rawImages; - QVector imagesSetted; - friend class ImageLoaderByteArray3D; - -private: - ImageLoaderByteArray3D *worker; -}; - -class ImageLoader3D : public QThread -{ -public: - ImageLoader3D(YACReaderFlow3D *flow); - ~ImageLoader3D(); - bool busy() const; - void generate(int index, const QString &fileName); - void reset() - { - idx = -1; - fileName = ""; - } - int index() const { return idx; } - void lock(); - void unlock(); - QImage result(); - YACReaderFlow3D *flow; - QImage loadImage(const QString &fileName); - -protected: - void run() override; - -private: - QMutex mutex; - QWaitCondition condition; - - bool restart; - bool working; - int idx; - QString fileName; - QSize size; - QImage img; -}; - -class ImageLoaderByteArray3D : public QThread -{ -public: - ImageLoaderByteArray3D(YACReaderFlow3D *flow); - ~ImageLoaderByteArray3D(); - bool busy() const; - void generate(int index, const QByteArray &raw); - void reset() - { - idx = -1; - rawData.clear(); - } - int index() const { return idx; } - QImage result(); - YACReaderFlow3D *flow; - QImage loadImage(const QByteArray &rawData); - -protected: - void run() override; - -private: - QMutex mutex; - QWaitCondition condition; - - bool restart; - bool working; - int idx; - QByteArray rawData; - QSize size; - QImage img; -}; +/* Derived flow & loader classes moved to dedicated files: + - common/rhi/yacreader_comic_flow_rhi.h/.cpp + - common/rhi/yacreader_page_flow_rhi.h/.cpp +*/ #endif // QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) diff --git a/common/rhi/yacreader_page_flow_rhi.cpp b/common/rhi/yacreader_page_flow_rhi.cpp new file mode 100644 index 000000000..87da6e6ab --- /dev/null +++ b/common/rhi/yacreader_page_flow_rhi.cpp @@ -0,0 +1,204 @@ +#include "yacreader_page_flow_rhi.h" +#include + +// YACReaderPageFlow3D implementation +YACReaderPageFlow3D::YACReaderPageFlow3D(QWidget *parent, struct Preset p) + : YACReaderFlow3D(parent, p) +{ + worker = new ImageLoaderByteArray3D(this); + worker->flow = this; +} + +YACReaderPageFlow3D::~YACReaderPageFlow3D() +{ + if (timerId != -1) { + this->killTimer(timerId); + timerId = -1; + } + rawImages.clear(); + + // Clean up textures and clear images to prevent double-delete in base destructor + for (auto &image : images) { + if (image.texture != scene.defaultTexture.get()) { + delete image.texture; + } + } + images.clear(); + numObjects = 0; +} + +void YACReaderPageFlow3D::updateImageData() +{ + if (worker->busy()) + return; + + int idx = worker->index(); + if (idx >= 0 && !worker->result().isNull()) { + if (!loaded[idx]) { + float x = 1; + QImage img = worker->result(); + + // Create QRhiTexture from the loaded image and queue the pixel upload + if (m_rhi) { + QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, + (performance == high || performance == ultraHigh) ? QRhiTexture::MipMapped : QRhiTexture::UsedAsTransferSource); + + if (texture->create()) { + // Queue the image upload so it happens together with other resource updates + PendingTextureUpload upload; + upload.index = idx; + upload.image = img; + upload.x = x; + upload.y = 1 * (float(img.height()) / img.width()); + pendingTextureUploads.append(upload); + + QString s = "cover"; + replace(s.toLocal8Bit().data(), texture, upload.x, upload.y, idx); + } + } + } + } + + int count = 8; + switch (performance) { + case low: + count = 8; + break; + case medium: + count = 10; + break; + case high: + count = 12; + break; + case ultraHigh: + count = 14; + break; + } + + int *indexes = new int[2 * count + 1]; + int center = currentSelected; + indexes[0] = center; + for (int j = 0; j < count; j++) { + indexes[j * 2 + 1] = center + j + 1; + indexes[j * 2 + 2] = center - j - 1; + } + + for (int c = 0; c < 2 * count + 1; c++) { + int i = indexes[c]; + if ((i >= 0) && (i < numObjects)) + if (rawImages.size() > 0) + if (!loaded[i] && imagesReady[i]) { + worker->generate(i, rawImages.at(i)); + delete[] indexes; + return; + } + } + + delete[] indexes; +} + +void YACReaderPageFlow3D::populate(int n) +{ + worker->reset(); + reset(); + numObjects = 0; + + if (hasBeenInitialized) { + YACReaderFlow3D::populate(n); + } else { + lazyPopulateObjects = n; + } + + imagesReady = QVector(n, false); + rawImages = QVector(n); + imagesSetted = QVector(n, false); +} + +// ImageLoaderByteArray3D implementation +QImage ImageLoaderByteArray3D::loadImage(const QByteArray &raw) +{ + QImage image; + + if (!image.loadFromData(raw)) { + return QImage(); + } + + switch (flow->performance) { + case low: + image = image.scaledToWidth(128, Qt::SmoothTransformation); + break; + case medium: + image = image.scaledToWidth(196, Qt::SmoothTransformation); + break; + case high: + image = image.scaledToWidth(256, Qt::SmoothTransformation); + break; + case ultraHigh: + image = image.scaledToWidth(320, Qt::SmoothTransformation); + break; + } + + return image; +} + +ImageLoaderByteArray3D::ImageLoaderByteArray3D(YACReaderFlow3D *flow) + : QThread(), flow(flow), restart(false), working(false), idx(-1) +{ +} + +ImageLoaderByteArray3D::~ImageLoaderByteArray3D() +{ + mutex.lock(); + condition.wakeOne(); + mutex.unlock(); + wait(); +} + +bool ImageLoaderByteArray3D::busy() const +{ + return isRunning() ? working : false; +} + +void ImageLoaderByteArray3D::generate(int index, const QByteArray &raw) +{ + mutex.lock(); + this->idx = index; + this->rawData = raw; + this->img = QImage(); + mutex.unlock(); + + if (!isRunning()) + start(); + else { + restart = true; + condition.wakeOne(); + } +} + +void ImageLoaderByteArray3D::run() +{ + for (;;) { + mutex.lock(); + this->working = true; + QByteArray raw = this->rawData; + mutex.unlock(); + + QImage image = loadImage(raw); + + mutex.lock(); + this->working = false; + this->img = image; + mutex.unlock(); + + mutex.lock(); + if (!this->restart) + condition.wait(&mutex); + restart = false; + mutex.unlock(); + } +} + +QImage ImageLoaderByteArray3D::result() +{ + return img; +} diff --git a/common/rhi/yacreader_page_flow_rhi.h b/common/rhi/yacreader_page_flow_rhi.h new file mode 100644 index 000000000..b188b6ff0 --- /dev/null +++ b/common/rhi/yacreader_page_flow_rhi.h @@ -0,0 +1,55 @@ +#ifndef __YACREADER_PAGE_FLOW_RHI_H +#define __YACREADER_PAGE_FLOW_RHI_H + +#include "yacreader_flow_rhi.h" + +class ImageLoaderByteArray3D; + +class YACReaderPageFlow3D : public YACReaderFlow3D +{ +public: + YACReaderPageFlow3D(QWidget *parent = nullptr, struct Preset p = defaultYACReaderFlowConfig); + ~YACReaderPageFlow3D(); + void updateImageData() override; + void populate(int n); + QVector imagesReady; + QVector rawImages; + QVector imagesSetted; + friend class ImageLoaderByteArray3D; + +private: + ImageLoaderByteArray3D *worker; +}; + +class ImageLoaderByteArray3D : public QThread +{ +public: + ImageLoaderByteArray3D(YACReaderFlow3D *flow); + ~ImageLoaderByteArray3D(); + bool busy() const; + void generate(int index, const QByteArray &raw); + void reset() + { + idx = -1; + rawData.clear(); + } + int index() const { return idx; } + QImage result(); + YACReaderFlow3D *flow; + QImage loadImage(const QByteArray &rawData); + +protected: + void run() override; + +private: + QMutex mutex; + QWaitCondition condition; + + bool restart; + bool working; + int idx; + QByteArray rawData; + QImage img; +}; + +#endif // __YACREADER_PAGE_FLOW_RHI_H From b142ffd6c962cf907b21b136fbac9013a57a4182 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 18 Jan 2026 10:24:06 +0100 Subject: [PATCH 008/187] Remove comments --- common/rhi/yacreader_flow_rhi.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index b84874774..442b890e7 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -1257,8 +1257,3 @@ QSize YACReaderFlow3D::minimumSizeHint() const { return QSize(320, 200); } - -// YACReaderComicFlow3D implementation -// YACReaderComicFlow3D implementation moved to common/rhi/yacreader_comic_flow_rhi.* - -// Implementations for derived flows and loaders live in their own files. From 48aaf36fab4a035b3dc2aa6e2745f4f7ce25538c Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 18 Jan 2026 10:24:13 +0100 Subject: [PATCH 009/187] Format --- common/rhi/yacreader_flow_rhi.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index 442b890e7..84fde6a13 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -16,7 +16,15 @@ static QShader getShader(const QString &name) /*Constructor*/ YACReaderFlow3D::YACReaderFlow3D(QWidget *parent, struct Preset p) - : QRhiWidget(parent), numObjects(0), lazyPopulateObjects(-1), hasBeenInitialized(false), backgroundColor(Qt::black), textColor(Qt::white), shadingColor(Qt::black), flowRightToLeft(false), showMarks(true) + : QRhiWidget(parent), + numObjects(0), + lazyPopulateObjects(-1), + showMarks(true), + hasBeenInitialized(false), + backgroundColor(Qt::black), + textColor(Qt::white), + shadingColor(Qt::black), + flowRightToLeft(false) { updateCount = 0; config = p; From c4c59ab96a380e9964e772348e3abd9eae3becf0 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 18 Jan 2026 12:36:34 +0100 Subject: [PATCH 010/187] Ensure resources dynamically Content and settings can vary at any moment and we need to be prepared for always have a consistent context --- common/rhi/yacreader_flow_rhi.cpp | 234 +++++++++++++++++------------- common/rhi/yacreader_flow_rhi.h | 1 + 2 files changed, 137 insertions(+), 98 deletions(-) diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index 84fde6a13..66c521a72 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -95,17 +95,18 @@ void YACReaderFlow3D::stopAnimationTimer() void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) { - if (m_rhi != rhi()) { + auto newRhi = rhi(); + if (m_rhi != newRhi) { scene.reset(); - m_rhi = rhi(); + m_rhi = newRhi; } - if (!m_rhi) + if (m_rhi == nullptr) return; // Helper to get or create resource update batch auto getResourceBatch = [this]() { - if (!scene.resourceUpdates) + if (scene.resourceUpdates == nullptr) scene.resourceUpdates = m_rhi->nextResourceUpdateBatch(); return scene.resourceUpdates; }; @@ -191,94 +192,36 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) scene.instanceBuffer->create(); } - // Setup graphics pipeline - if (!scene.pipeline) { - // Load shaders - QShader vertShader = getShader(QLatin1String(":/shaders/flow.vert.qsb")); - QShader fragShader = getShader(QLatin1String(":/shaders/flow.frag.qsb")); - - if (!vertShader.isValid() || !fragShader.isValid()) { - qWarning() << "YACReaderFlow3D: Failed to load shaders!"; - return; + // Determine how many items we'll have (either already populated or pending lazy population) + const int itemCount = (lazyPopulateObjects != -1) ? lazyPopulateObjects : numObjects; + + // Create uniform buffer sized for the actual content + // Each item needs up to 3 draw slots: cover + reflection + mark + // If no items yet, we'll create the buffer later in ensureUniformBufferCapacity() + if (!scene.uniformBuffer && itemCount > 0) { + const int requiredSlots = itemCount * 3; + const int totalSize = requiredSlots * scene.alignedUniformSize; + scene.uniformBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, totalSize)); + if (scene.uniformBuffer->create()) { + scene.uniformBufferCapacity = requiredSlots; + } else { + qWarning() << "YACReaderFlow3D: Failed to create uniform buffer for" << itemCount << "items"; + scene.uniformBuffer.reset(); + scene.uniformBufferCapacity = 0; } + } - // Create default shader resource bindings for pipeline creation - // We'll create texture-specific ones on-demand in drawCover + // Create shader bindings for pipeline (requires uniform buffer) + if (!scene.shaderBindings && scene.uniformBuffer) { scene.shaderBindings.reset(m_rhi->newShaderResourceBindings()); - scene.shaderBindings->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, scene.uniformBuffer.get()), + scene.shaderBindings->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, scene.uniformBuffer.get(), sizeof(UniformData)), QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, scene.defaultTexture.get(), scene.sampler.get()) }); scene.shaderBindings->create(); - - // Create pipeline - scene.pipeline.reset(m_rhi->newGraphicsPipeline()); - - // Setup alpha blending - QRhiGraphicsPipeline::TargetBlend blend; - blend.enable = true; - blend.srcColor = QRhiGraphicsPipeline::SrcAlpha; - blend.dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha; - blend.srcAlpha = QRhiGraphicsPipeline::One; - blend.dstAlpha = QRhiGraphicsPipeline::OneMinusSrcAlpha; - scene.pipeline->setTargetBlends({ blend }); - - // Enable depth test - scene.pipeline->setDepthTest(true); - scene.pipeline->setDepthWrite(true); - scene.pipeline->setDepthOp(QRhiGraphicsPipeline::Less); - - scene.pipeline->setCullMode(QRhiGraphicsPipeline::Back); - - // Determine the MSAA sample count to use - int requestedSamples = sampleCount(); - int samplesToUse = 1; - if (requestedSamples > 1 && m_rhi) { - QVector supported = m_rhi->supportedSampleCounts(); - int maxSupported = 1; - for (int s : supported) { - if (s > maxSupported) - maxSupported = s; - } - samplesToUse = qMin(requestedSamples, qMin(4, maxSupported)); - } - if (samplesToUse > 1) - scene.pipeline->setSampleCount(samplesToUse); - - // Set shaders - scene.pipeline->setShaderStages({ { QRhiShaderStage::Vertex, vertShader }, - { QRhiShaderStage::Fragment, fragShader } }); - - // Setup vertex input layout - QRhiVertexInputLayout inputLayout; - inputLayout.setBindings({ - { 5 * sizeof(float) }, // Per-vertex data (position + texCoord) - { 22 * sizeof(float), QRhiVertexInputBinding::PerInstance } // Per-instance data - }); - inputLayout.setAttributes({ - // Per-vertex attributes - { 0, 0, QRhiVertexInputAttribute::Float3, 0 }, // position - { 0, 1, QRhiVertexInputAttribute::Float2, 3 * sizeof(float) }, // texCoord - - // Per-instance attributes (model matrix as 4 vec4s) - { 1, 2, QRhiVertexInputAttribute::Float4, 0 * sizeof(float) }, // row 0 - { 1, 3, QRhiVertexInputAttribute::Float4, 4 * sizeof(float) }, // row 1 - { 1, 4, QRhiVertexInputAttribute::Float4, 8 * sizeof(float) }, // row 2 - { 1, 5, QRhiVertexInputAttribute::Float4, 12 * sizeof(float) }, // row 3 - { 1, 6, QRhiVertexInputAttribute::Float4, 16 * sizeof(float) }, // shading vec4 - { 1, 7, QRhiVertexInputAttribute::Float, 20 * sizeof(float) }, // opacity - { 1, 8, QRhiVertexInputAttribute::Float, 21 * sizeof(float) } // flipFlag (1.0 = reflection) - }); - scene.pipeline->setVertexInputLayout(inputLayout); - - // Set shader resource bindings and render pass descriptor - scene.pipeline->setShaderResourceBindings(scene.shaderBindings.get()); - scene.pipeline->setRenderPassDescriptor(renderTarget()->renderPassDescriptor()); - - if (!scene.pipeline->create()) { - qWarning() << "YACReaderFlow3D: Failed to create graphics pipeline!"; - scene.pipeline.reset(); - } } + // Create pipeline if we have all prerequisites + ensurePipeline(); + // Submit any pending resource updates if (scene.resourceUpdates) { cb->resourceUpdate(scene.resourceUpdates); @@ -317,17 +260,104 @@ void YACReaderFlow3D::ensureUniformBufferCapacity(int requiredSlots) qDeleteAll(scene.shaderBindingsCache); scene.shaderBindingsCache.clear(); - // Recreate default shader bindings for pipeline + // Recreate default shader bindings for pipeline (using dynamic offset) scene.shaderBindings.reset(m_rhi->newShaderResourceBindings()); - scene.shaderBindings->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, scene.uniformBuffer.get()), + scene.shaderBindings->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, scene.uniformBuffer.get(), sizeof(UniformData)), QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, scene.defaultTexture.get(), scene.sampler.get()) }); scene.shaderBindings->create(); + + // If pipeline doesn't exist yet (content added after initial empty initialization), + // we need to create it now. This is handled by ensurePipeline(). } else { qWarning() << "YACReaderFlow3D: Failed to create uniform buffer of size" << totalSize; scene.uniformBufferCapacity = 0; } } +void YACReaderFlow3D::ensurePipeline() +{ + if (scene.pipeline || !m_rhi || !scene.uniformBuffer || !scene.shaderBindings) + return; + + // Load shaders + QShader vertShader = getShader(QLatin1String(":/shaders/flow.vert.qsb")); + QShader fragShader = getShader(QLatin1String(":/shaders/flow.frag.qsb")); + + if (!vertShader.isValid() || !fragShader.isValid()) { + qWarning() << "YACReaderFlow3D: Failed to load shaders!"; + return; + } + + // Create pipeline + scene.pipeline.reset(m_rhi->newGraphicsPipeline()); + + // Setup alpha blending + QRhiGraphicsPipeline::TargetBlend blend; + blend.enable = true; + blend.srcColor = QRhiGraphicsPipeline::SrcAlpha; + blend.dstColor = QRhiGraphicsPipeline::OneMinusSrcAlpha; + blend.srcAlpha = QRhiGraphicsPipeline::One; + blend.dstAlpha = QRhiGraphicsPipeline::OneMinusSrcAlpha; + scene.pipeline->setTargetBlends({ blend }); + + // Enable depth test + scene.pipeline->setDepthTest(true); + scene.pipeline->setDepthWrite(true); + scene.pipeline->setDepthOp(QRhiGraphicsPipeline::Less); + + scene.pipeline->setCullMode(QRhiGraphicsPipeline::Back); + + // Determine the MSAA sample count to use + int requestedSamples = sampleCount(); + int samplesToUse = 1; + if (requestedSamples > 1 && m_rhi) { + QVector supported = m_rhi->supportedSampleCounts(); + int maxSupported = 1; + for (int s : std::as_const(supported)) { + if (s > maxSupported) + maxSupported = s; + } + samplesToUse = qMin(requestedSamples, qMin(4, maxSupported)); + } + if (samplesToUse > 1) + scene.pipeline->setSampleCount(samplesToUse); + + // Set shaders + scene.pipeline->setShaderStages({ { QRhiShaderStage::Vertex, vertShader }, + { QRhiShaderStage::Fragment, fragShader } }); + + // Setup vertex input layout + QRhiVertexInputLayout inputLayout; + inputLayout.setBindings({ + { 5 * sizeof(float) }, // Per-vertex data (position + texCoord) + { 22 * sizeof(float), QRhiVertexInputBinding::PerInstance } // Per-instance data + }); + inputLayout.setAttributes({ + // Per-vertex attributes + { 0, 0, QRhiVertexInputAttribute::Float3, 0 }, // position + { 0, 1, QRhiVertexInputAttribute::Float2, 3 * sizeof(float) }, // texCoord + + // Per-instance attributes (model matrix as 4 vec4s) + { 1, 2, QRhiVertexInputAttribute::Float4, 0 * sizeof(float) }, // row 0 + { 1, 3, QRhiVertexInputAttribute::Float4, 4 * sizeof(float) }, // row 1 + { 1, 4, QRhiVertexInputAttribute::Float4, 8 * sizeof(float) }, // row 2 + { 1, 5, QRhiVertexInputAttribute::Float4, 12 * sizeof(float) }, // row 3 + { 1, 6, QRhiVertexInputAttribute::Float4, 16 * sizeof(float) }, // shading vec4 + { 1, 7, QRhiVertexInputAttribute::Float, 20 * sizeof(float) }, // opacity + { 1, 8, QRhiVertexInputAttribute::Float, 21 * sizeof(float) } // flipFlag (1.0 = reflection) + }); + scene.pipeline->setVertexInputLayout(inputLayout); + + // Set shader resource bindings and render pass descriptor + scene.pipeline->setShaderResourceBindings(scene.shaderBindings.get()); + scene.pipeline->setRenderPassDescriptor(renderTarget()->renderPassDescriptor()); + + if (!scene.pipeline->create()) { + qWarning() << "YACReaderFlow3D: Failed to create graphics pipeline!"; + scene.pipeline.reset(); + } +} + void YACReaderFlow3D::render(QRhiCommandBuffer *cb) { if (!m_rhi || numObjects == 0) @@ -437,8 +467,16 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) return; } + // Ensure pipeline exists (may not exist if content was added after empty initialization) + ensurePipeline(); + + if (!scene.pipeline) { + qWarning() << "YACReaderFlow3D: No pipeline available for rendering"; + return; + } + // Ensure instance buffer is large enough for all draws - const int requiredInstanceSize = draws.size() * 22 * sizeof(float); + auto requiredInstanceSize = static_cast(draws.size() * 22 * sizeof(float)); if (!scene.instanceBuffer || scene.instanceBuffer->size() < requiredInstanceSize) { scene.instanceBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, requiredInstanceSize)); if (!scene.instanceBuffer->create()) { @@ -453,7 +491,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) // Process pending texture uploads if (!pendingTextureUploads.isEmpty()) { - for (const auto &upload : pendingTextureUploads) { + for (const auto &upload : std::as_const(pendingTextureUploads)) { if (upload.index >= 0 && upload.index < images.size() && images[upload.index].texture) { batch->uploadTexture(images[upload.index].texture, upload.image); } @@ -476,15 +514,13 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) // === PHASE 2: RENDER (DURING PASS) === cb->beginPass(renderTarget(), clearColor, { 1.0f, 0 }, batch); - if (scene.pipeline) { - cb->setGraphicsPipeline(scene.pipeline.get()); - cb->setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height())); + cb->setGraphicsPipeline(scene.pipeline.get()); + cb->setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height())); - // Execute all draws - for (int i = 0; i < draws.size(); ++i) { - const DrawInfo &draw = draws[i]; - executeDrawWithOffset(cb, draw.texture, draw.instanceData, i); - } + // Execute all draws + for (int i = 0; i < draws.size(); ++i) { + const DrawInfo &draw = draws[i]; + executeDrawWithOffset(cb, draw.texture, draw.instanceData, i); } cb->endPass(); @@ -579,7 +615,7 @@ void YACReaderFlow3D::executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture * QRhiShaderResourceBindings *srb = scene.shaderBindingsCache.value(texture, nullptr); if (!srb) { srb = m_rhi->newShaderResourceBindings(); - srb->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, scene.uniformBuffer.get()), + srb->setBindings({ QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, scene.uniformBuffer.get(), sizeof(UniformData)), QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture, scene.sampler.get()) }); srb->create(); scene.shaderBindingsCache.insert(texture, srb); @@ -887,6 +923,7 @@ void YACReaderFlow3D::populate(int n) } loaded = QVector(n, false); + marks = QVector(n, Unread); } void YACReaderFlow3D::reset() @@ -895,6 +932,7 @@ void YACReaderFlow3D::reset() currentSelected = 0; loaded.clear(); + marks.clear(); // Clean up image textures and remove their entries from shader bindings cache for (int i = 0; i < numObjects; i++) { diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index f22f173fc..1cb38291f 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -228,6 +228,7 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement void updateUniformBuffer(QRhiCommandBuffer *cb, const UniformData &data); void prepareMarkInstanceData(const YACReader3DImageRHI &image, QVector &data); void ensureUniformBufferCapacity(int requiredSlots); + void ensurePipeline(); void prepareDrawData(const YACReader3DImageRHI &image, bool isReflection, bool isMark, const QMatrix4x4 &viewProjectionMatrix, float *outInstanceData, UniformData &outUniformData); From 6053fca00504f0a9f8c0a3108364da7a85bde052 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 18 Jan 2026 12:58:15 +0100 Subject: [PATCH 011/187] Use a QLabel to show the current/total text --- common/rhi/yacreader_flow_rhi.cpp | 53 +++++++++++++++++++++++++++++++ common/rhi/yacreader_flow_rhi.h | 16 ++++++++++ 2 files changed, 69 insertions(+) diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index 66c521a72..e2736a938 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -51,6 +51,12 @@ YACReaderFlow3D::YACReaderFlow3D(QWidget *parent, struct Preset p) setSampleCount(4); timerId = -1; + + // Create and configure the index label + indexLabel = new QLabel(this); + indexLabel->setAttribute(Qt::WA_TransparentForMouseEvents); + indexLabel->setAutoFillBackground(false); + updateIndexLabelStyle(); } YACReaderFlow3D::~YACReaderFlow3D() @@ -369,6 +375,9 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) // Update positions and animations updatePositions(); + // Update index label if values changed + updateIndexLabel(); + // Prepare view-projection matrix // Use fixed 20.0 degrees FOV - zoom is controlled via cfZ (camera distance) QMatrix4x4 projectionMatrix; @@ -654,6 +663,12 @@ void YACReaderFlow3D::showEvent(QShowEvent *event) startAnimationTimer(); } +void YACReaderFlow3D::resizeEvent(QResizeEvent *event) +{ + QRhiWidget::resizeEvent(event); + updateIndexLabelStyle(); +} + void YACReaderFlow3D::cleanupAnimation() { config.animationStep = stepBackup; @@ -1168,6 +1183,11 @@ void YACReaderFlow3D::setBackgroundColor(const QColor &color) void YACReaderFlow3D::setTextColor(const QColor &color) { textColor = color; + + QPalette palette = indexLabel->palette(); + palette.setColor(QPalette::WindowText, textColor); + indexLabel->setPalette(palette); + update(); } @@ -1299,6 +1319,39 @@ QVector3D YACReaderFlow3D::getPlaneIntersection(int x, int y, YACReader3DImageRH return ray_origin + ray_vector * (intersection_ray_determinant / intersection_LES_determinant); } +void YACReaderFlow3D::updateIndexLabel() +{ + int currentDisplay = currentSelected + 1; + int totalDisplay = numObjects; + + if (indexLabelState.current != currentDisplay || indexLabelState.total != totalDisplay) { + indexLabelState.current = currentDisplay; + indexLabelState.total = totalDisplay; + indexLabel->setText(QString("%1/%2").arg(currentDisplay).arg(totalDisplay)); + indexLabel->adjustSize(); + } +} + +void YACReaderFlow3D::updateIndexLabelStyle() +{ + int w = width(); + int h = height(); + + int newFontSize = static_cast((w + h) * 0.010); + if (newFontSize < 10) + newFontSize = 10; + + QFont font("Arial", newFontSize); + indexLabel->setFont(font); + + QPalette palette = indexLabel->palette(); + palette.setColor(QPalette::WindowText, textColor); + indexLabel->setPalette(palette); + + indexLabel->move(10, 10); + indexLabel->adjustSize(); +} + QSize YACReaderFlow3D::minimumSizeHint() const { return QSize(320, 200); diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index 1cb38291f..1b481c781 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -79,6 +79,7 @@ extern struct Preset presetYACReaderFlowOverlappedStripeConfig; extern struct Preset pressetYACReaderFlowUpConfig; extern struct Preset pressetYACReaderFlowDownConfig; +class QLabel; class ImageLoader3D; class ImageLoaderByteArray3D; class YACReaderComicFlow3D; @@ -103,6 +104,12 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement int updateCount; int fontSize; + // Cached state for the index label to avoid unnecessary updates + struct IndexLabelState { + int current = -1; + int total = -1; + }; + // Uniform buffer data structure (must match shader layout) struct UniformData { QMatrix4x4 viewProjectionMatrix; @@ -174,6 +181,10 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement Scene scene; QVector pendingTextureUploads; + // Index label (shows "current/total" in top-left corner) + QLabel *indexLabel = nullptr; + IndexLabelState indexLabelState; + void timerEvent(QTimerEvent *) override; int numObjects; @@ -222,6 +233,11 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement void render(QRhiCommandBuffer *cb) override; void releaseResources() override; void showEvent(QShowEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + + // Index label helpers + void updateIndexLabel(); + void updateIndexLabelStyle(); // Helper methods QRhiTexture *createTextureFromImage(QRhiCommandBuffer *cb, const QImage &image); From 5e21657791b96accb50cbc69b569ac72e35e8731 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 18 Jan 2026 13:56:29 +0100 Subject: [PATCH 012/187] Simplify code --- common/rhi/yacreader_flow_rhi.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index e2736a938..40451bc7c 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -315,18 +315,13 @@ void YACReaderFlow3D::ensurePipeline() // Determine the MSAA sample count to use int requestedSamples = sampleCount(); - int samplesToUse = 1; if (requestedSamples > 1 && m_rhi) { QVector supported = m_rhi->supportedSampleCounts(); - int maxSupported = 1; - for (int s : std::as_const(supported)) { - if (s > maxSupported) - maxSupported = s; - } - samplesToUse = qMin(requestedSamples, qMin(4, maxSupported)); + auto it = std::upper_bound(supported.begin(), supported.end(), requestedSamples); + int samplesToUse = (it != supported.begin()) ? *std::prev(it) : 1; + if (samplesToUse > 1) + scene.pipeline->setSampleCount(samplesToUse); } - if (samplesToUse > 1) - scene.pipeline->setSampleCount(samplesToUse); // Set shaders scene.pipeline->setShaderStages({ { QRhiShaderStage::Vertex, vertShader }, From 4e18fb69d7456ee2d3344c1d570f378479c539a1 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 18 Jan 2026 14:16:17 +0100 Subject: [PATCH 013/187] Lazy population can clear already set marks We need to initialize marks separated from populate --- common/rhi/yacreader_flow_rhi.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index 40451bc7c..14e058180 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -933,7 +933,6 @@ void YACReaderFlow3D::populate(int n) } loaded = QVector(n, false); - marks = QVector(n, Unread); } void YACReaderFlow3D::reset() From 7384d507217c484e931d1f8412ae265b168676a8 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 18 Jan 2026 15:19:09 +0100 Subject: [PATCH 014/187] Fix mipmapping --- common/rhi/yacreader_comic_flow_rhi.cpp | 6 ++--- common/rhi/yacreader_flow_rhi.cpp | 31 ++++++++++++------------- common/rhi/yacreader_flow_rhi.h | 4 ++-- common/rhi/yacreader_page_flow_rhi.cpp | 6 ++--- 4 files changed, 21 insertions(+), 26 deletions(-) diff --git a/common/rhi/yacreader_comic_flow_rhi.cpp b/common/rhi/yacreader_comic_flow_rhi.cpp index bf7bafaa5..6117114ea 100644 --- a/common/rhi/yacreader_comic_flow_rhi.cpp +++ b/common/rhi/yacreader_comic_flow_rhi.cpp @@ -37,8 +37,7 @@ void YACReaderComicFlow3D::updateImageData() // Create QRhiTexture from the loaded image if (m_rhi) { - QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, - (performance == high || performance == ultraHigh) ? QRhiTexture::MipMapped : QRhiTexture::UsedAsTransferSource); + QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips); if (texture->create()) { PendingTextureUpload upload; @@ -48,8 +47,7 @@ void YACReaderComicFlow3D::updateImageData() upload.y = 1 * (float(img.height()) / img.width()); pendingTextureUploads.append(upload); - QString s = "cover"; - replace(s.toLocal8Bit().data(), texture, upload.x, upload.y, idx); + replace(texture, upload.x, upload.y, idx); } } } diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index 14e058180..e325f1c26 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -121,9 +121,10 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) if (!scene.defaultTexture) { QImage defaultImage(":/images/defaultCover.png"); - scene.defaultTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, defaultImage.size(), 1, QRhiTexture::MipMapped)); + scene.defaultTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, defaultImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips)); scene.defaultTexture->create(); getResourceBatch()->uploadTexture(scene.defaultTexture.get(), defaultImage); + getResourceBatch()->generateMips(scene.defaultTexture.get()); qDebug() << "YACReaderFlow3D: Created defaultTexture" << defaultImage.size(); } @@ -132,18 +133,20 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) if (!scene.markTexture) { QImage markImage(":/images/readRibbon.png"); if (!markImage.isNull()) { - scene.markTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, markImage.size(), 1, QRhiTexture::MipMapped)); + scene.markTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, markImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips)); scene.markTexture->create(); getResourceBatch()->uploadTexture(scene.markTexture.get(), markImage); + getResourceBatch()->generateMips(scene.markTexture.get()); } } if (!scene.readingTexture) { QImage readingImage(":/images/readingRibbon.png"); if (!readingImage.isNull()) { - scene.readingTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, readingImage.size(), 1, QRhiTexture::MipMapped)); + scene.readingTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, readingImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips)); scene.readingTexture->create(); getResourceBatch()->uploadTexture(scene.readingTexture.get(), readingImage); + getResourceBatch()->generateMips(scene.readingTexture.get()); } } #endif @@ -178,13 +181,12 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) scene.alignedUniformSize = m_rhi->ubufAligned(sizeof(UniformData)); } - // Create sampler + // Create sampler with trilinear filtering (like the OpenGL version) if (!scene.sampler) { - // Use no mipmap sampling to avoid LOD changes with camera Z scene.sampler.reset(m_rhi->newSampler( - QRhiSampler::Linear, - QRhiSampler::Linear, - QRhiSampler::None, + QRhiSampler::Linear, // mag filter + QRhiSampler::Linear, // min filter + QRhiSampler::Linear, // mipmap filter (trilinear) QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge)); scene.sampler->create(); @@ -498,6 +500,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) for (const auto &upload : std::as_const(pendingTextureUploads)) { if (upload.index >= 0 && upload.index < images.size() && images[upload.index].texture) { batch->uploadTexture(images[upload.index].texture, upload.image); + batch->generateMips(images[upload.index].texture); } } pendingTextureUploads.clear(); @@ -824,11 +827,10 @@ void YACReaderFlow3D::updatePositions() stopAnimationTimer(); } -void YACReaderFlow3D::insert(char *name, QRhiTexture *texture, float x, float y, int item) +void YACReaderFlow3D::insert(QRhiTexture *texture, float x, float y, int item) { startAnimationTimer(); - Q_UNUSED(name) if (item == -1) { images.push_back(YACReader3DImageRHI()); item = numObjects; @@ -883,7 +885,6 @@ void YACReaderFlow3D::add(int item) { float x = 1; float y = 1 * (700.f / 480.0f); - QString s = "cover"; images.insert(item, YACReader3DImageRHI()); loaded.insert(item, false); @@ -894,7 +895,7 @@ void YACReaderFlow3D::add(int item) images[i].index++; } - insert(s.toLocal8Bit().data(), scene.defaultTexture.get(), x, y, item); + insert(scene.defaultTexture.get(), x, y, item); } YACReader3DImageRHI YACReaderFlow3D::getCurrentSelected() @@ -902,11 +903,10 @@ YACReader3DImageRHI YACReaderFlow3D::getCurrentSelected() return images[currentSelected]; } -void YACReaderFlow3D::replace(char *name, QRhiTexture *texture, float x, float y, int item) +void YACReaderFlow3D::replace(QRhiTexture *texture, float x, float y, int item) { startAnimationTimer(); - Q_UNUSED(name) if (images[item].index == item) { images[item].texture = texture; images[item].width = x; @@ -928,8 +928,7 @@ void YACReaderFlow3D::populate(int n) int i; for (i = 0; i < n; i++) { - QString s = "cover"; - insert(s.toLocal8Bit().data(), scene.defaultTexture.get(), x, y); + insert(scene.defaultTexture.get(), x, y); } loaded = QVector(n, false); diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index 1b481c781..7c02b8f88 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -266,10 +266,10 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement void cleanupAnimation(); void draw(); void updatePositions(); - void insert(char *name, QRhiTexture *texture, float x, float y, int item = -1); + void insert(QRhiTexture *texture, float x, float y, int item = -1); virtual void remove(int item); void add(int item); - void replace(char *name, QRhiTexture *texture, float x, float y, int item); + void replace(QRhiTexture *texture, float x, float y, int item); void populate(int n); YACReader3DImageRHI getCurrentSelected(); diff --git a/common/rhi/yacreader_page_flow_rhi.cpp b/common/rhi/yacreader_page_flow_rhi.cpp index 87da6e6ab..f2e9b3984 100644 --- a/common/rhi/yacreader_page_flow_rhi.cpp +++ b/common/rhi/yacreader_page_flow_rhi.cpp @@ -40,8 +40,7 @@ void YACReaderPageFlow3D::updateImageData() // Create QRhiTexture from the loaded image and queue the pixel upload if (m_rhi) { - QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, - (performance == high || performance == ultraHigh) ? QRhiTexture::MipMapped : QRhiTexture::UsedAsTransferSource); + QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips); if (texture->create()) { // Queue the image upload so it happens together with other resource updates @@ -52,8 +51,7 @@ void YACReaderPageFlow3D::updateImageData() upload.y = 1 * (float(img.height()) / img.width()); pendingTextureUploads.append(upload); - QString s = "cover"; - replace(s.toLocal8Bit().data(), texture, upload.x, upload.y, idx); + replace(texture, upload.x, upload.y, idx); } } } From 41b02725d7d7e115ed5f5c16ba757239e7d44198 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 18 Jan 2026 18:23:04 +0100 Subject: [PATCH 015/187] Use the fragment shader to calculate the shading effect for a more uniform shading than the one based on vertex --- YACReader/YACReader.pro | 5 ++++- YACReaderLibrary/YACReaderLibrary.pro | 5 ++++- common/rhi/shaders/flow.frag | 31 ++++++++++++++++++++------ common/rhi/shaders/flow.frag.qsb | Bin 1990 -> 2682 bytes common/rhi/shaders/flow.vert | 25 ++++++++++----------- common/rhi/shaders/flow.vert.qsb | Bin 2957 -> 2892 bytes common/rhi/yacreader_flow_rhi.cpp | 24 +++++++++++--------- 7 files changed, 58 insertions(+), 32 deletions(-) diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro index 940ea7231..42f781841 100644 --- a/YACReader/YACReader.pro +++ b/YACReader/YACReader.pro @@ -157,7 +157,10 @@ SOURCES += ../common/comic.cpp \ SOURCES += ../common/rhi/yacreader_flow_rhi.cpp SOURCES += ../common/rhi/yacreader_comic_flow_rhi.cpp \ ../common/rhi/yacreader_page_flow_rhi.cpp - RESOURCES += ../common/rhi/shaders/shaders.qrc + RESOURCES += ../common/rhi/shaders/shaders.qrc + # Make raw GLSL shader sources editable in Qt Creator + OTHER_FILES += ../common/rhi/shaders/flow.vert \ + ../common/rhi/shaders/flow.frag } } diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 11952c353..1a79aadb5 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -253,7 +253,10 @@ SOURCES += comic_flow.cpp \ SOURCES += ../common/rhi/yacreader_flow_rhi.cpp SOURCES += ../common/rhi/yacreader_comic_flow_rhi.cpp \ ../common/rhi/yacreader_page_flow_rhi.cpp - RESOURCES += ../common/rhi/shaders/shaders.qrc + RESOURCES += ../common/rhi/shaders/shaders.qrc + # Make raw GLSL shader sources editable in Qt Creator + OTHER_FILES += ../common/rhi/shaders/flow.vert \ + ../common/rhi/shaders/flow.frag } } diff --git a/common/rhi/shaders/flow.frag b/common/rhi/shaders/flow.frag index 01b474d9a..5e6f6c406 100644 --- a/common/rhi/shaders/flow.frag +++ b/common/rhi/shaders/flow.frag @@ -2,8 +2,11 @@ // Inputs from vertex shader layout(location = 0) in vec2 vTexCoord; -layout(location = 1) in vec4 vColor; -layout(location = 2) in float vIsReflection; +layout(location = 1) in flat vec4 vInstanceShading; +layout(location = 2) in flat float vInstanceOpacity; +layout(location = 3) in flat float vIsReflection; +layout(location = 4) in flat float vInstanceRotation; +layout(location = 5) in vec2 vLocalPos; // Output layout(location = 0) out vec4 fragColor; @@ -29,16 +32,30 @@ void main() { vec4 texColor = texture(coverTexture, vTexCoord); - // Apply shading: multiply texture by vColor.r to darken - float shadingAmount = vColor.r; + // Compute per-pixel shading using per-instance corner shading values + float leftUp = vInstanceShading.x; + float leftDown = vInstanceShading.y; + float rightUp = vInstanceShading.z; + float rightDown = vInstanceShading.w; - // For reflections, apply gradient fade (darker at bottom, fading to black) + // Use interpolated local vertex position to match original vertex-based shading. + // position.y in vertex ranges [-0.5..0.5], so map to [0..1] with +0.5 + float y = clamp(vLocalPos.y + 0.5, 0.0, 1.0); + float x = clamp(vLocalPos.x + 0.5, 0.0, 1.0); + float leftShading = mix(leftDown, leftUp, y); + float rightShading = mix(rightDown, rightUp, y); + float shading = mix(leftShading, rightShading, x); + + // Combine with per-instance opacity (opacity only darkens RGB, alpha preserved) + float shadingAmount = shading * vInstanceOpacity; + + // For reflections, apply a gradient fade using reflection uniforms (darker further away) if (vIsReflection > 0.5) { - // vTexCoord.y goes from 1 (top of reflection, near cover) to 0 (bottom, far from cover) - // We want it brightest near the cover and fading away + // Legacy reflection fade: ramp from 0.0 to 0.33 using texture V coordinate float gradientFade = mix(0.0, 0.33, vTexCoord.y); shadingAmount *= gradientFade; } + // Final color: shaded RGB, keep source alpha fragColor = vec4(texColor.rgb * shadingAmount, texColor.a); } diff --git a/common/rhi/shaders/flow.frag.qsb b/common/rhi/shaders/flow.frag.qsb index f50613bb41bc80d1f8194c9a3d4b5aabc6de262b..02f9d8a6c07cb8e469453d7f1acaa3e452d97988 100644 GIT binary patch literal 2682 zcmV-=3WfCm050`-ob6icbKAxdKfNtF&eL(?JY3jnQc7lNk`gW3vgC&pN2=vY*276H zD>MWG5-gJ70H8!Ub9!VXxs zK{y0)4-^XVfnMTQ66UZ5!bru{4E9pf$D`mt)J+H(u0V~ife2pD73kwmY=RvZ6rfO@ z-DfR$c3>{3;tZ>>A}g?Icy20^xcpg|zYDlS2)hr`FJb|B#J%u=Y6JEx$=y|SyeS_p zu^k@xeV9KgYJqq)=E(qwzLw-g2Iko0SyLdNmZkIh^*#h!O)%ZY>i63yl8tBSHvEKq z*yQ0u!RKj$A0-Mdz~^C<3DtC~ZfYjJ4)rZ z0Et2Q*4InPaj#+et}0V*5A=_Xp#HOvpf%#Y1-l+Co&^#7{(O0TIUj`8{8Sn90-`Vw z&HfEonGc7o_3!Y(SX*3Z&l$967QM98zSCwg*QyRs=^x~-k!ocL%bUKyiaSy z6k4v)J21`R>ozXO8N@TPtu>#+RFJ&D0tNKbD{o@q^~LVk>(qd{rb)f*8HfQxNeb81BzaU$tpI;j~OGh&KRdXic=r=|18ff#7I5z zTi$!h8oZ$RxMU0Ied1k*Jnd(l(u(u>3vh-Ai}^LG_;H@kCr*E?(U&#)6OA6%=#oZH zYxHf6zNgU-H2N{ovp{2BW4$>?H0JHwOyukr;3eYTAq?{8AOfSry9eXAE*~bb<{i2n^>kj@hi_r`0m>d2FaimNn^`=mfN#%WyIm?Rr&jHZY$ZIp?p+PJRRC~G!K zG%oespj?ymP0B?{-=f@-x@Smto@8$l26a!2&pDDWU6Mlho-=lFU`#BT)LDEZ1)T`f6%zr_cC6a$Y zJc-ACi1qCEfX7<)OXA@g{TcAs8}a%Z;Bjn)iGGPSVntd1b;hFeh19)4eCgMw;uo&- z8ewo=k7-=WK4D@XOZp2Y_PO-yOX59I{6gMeVP0~6t0a$m9Q*kwpZ^(NE4PXFjQr!T zRf@f@$lkYL5AhX}`HFnTI`f=#s{7C+{$rZw4#_fwXA!SY;Z=#(&*MA7=WLU_MdK#< z`jp1L0}VGsXCI{VqCAaLyC1qXc3}H~>otsGp^$0%w&ika&)wZ?8cxkK!q578k-H*@%;MzmgCrd=Ie|BSKSP!j04v`T=l&dwiSZtBQx~f_6#3Bu&qgB$F%l$ zeXrH1&U-b_7bD!DQE8ghf&vZp%&ObiO~e&dhHpDHVQ#aT%wO;h8)5{UFx+4*8qpP( zW-_n9%a(92?xs;G7N(U!5thKLH*2wN)?BWW}r_;gzOox#3X?DCTo7HEUjI3RLF6 zbE^iXPfy@9~X&S%E>6`LP3`a(vXYk%Ngw?v3qscqag@OH4_Pm#y6B>WMkQ7%%Sh& zd{87!NBOP~%Irq?z^vLdF&?5qesZ#aS8=jfoGg@zH_C9UebdFdct@p(?n z#&iqVEB?7#t32?{-32o=w+h>s0g%I4nZx<^(M#|xrY#p`c>WM9zRF~@Qrc$GHTYep zl$HvojCJKI1IgBK2Wi!~e}<80GsvT?g@1z0|3Lqu*FNq6)-o!YwE>yKWHL zes-rIw~g-|R_f*pm<5l-RC|ioj!IH-1Pu`3ea~?MJIq?K?3ol|TG7-breZ6~1+bFp zDDI-JS*@{}KsixuQAfqq3Y=PyHT?BnXufGRe3S-Qxj9}f-(BdJiL)+s;rMz($=i_U zyW3)==3=#6UEL5@W?hv0btsv(QBk24>ISMvfFjT_p}tyTMzNlt4kR@NO|a7%)PaPJ zstv~)L)@m)9g=k_&4C*K`s&i!lghmB1wm!0(QJj3^16EvhmFs^oL^a4TcD=i@L&mT zzvd#_Nf(cd{3qMEbF4njrzRrRqmw)T(pD}K{DjTCd!vcNZC431AVj-%#l`37zC)Nc;ctCxoED(YM)su3ExQ{rQ~Wra)89b4M?vg#6DZ$90HEyYNu6Ueop5+oQ2 zu@-7PP6&|7$;Xzr(}(!+$%YEm&=kB<4`+ic_BT_*Yh!N1sBfmEX?{EPwR>Q2@0YuL>xK!`|7Kx5>>94qSv^w5PE`k4>ueszc2DN~J zPHRM4TNZw23*+0{36gFj?GUiF)e7JsRP(HckX6)oZ5;(%9M2i}z8Vwh-VlmJDMdov z4GMfR39fc;1zV21#)#CRRCOXIp0Y9y_u__Lj+WB&8OTJNKcyjV5 zg&1fZShxf<#*yREPcCvEc+VPNzlw!8?LZ(@WxK58VE*~xJQB{Y|5!137UE^ zNCJ1A4IDEFZ`~5j9tBSDik~X_<9ydw!`XFC;Di6pH-0tce%MLD)7#03PYX)d@kF!1 oZZpKU7yTBX{T?9x)EuvbKRngiQ`euRC;j=JF2k>X0FS3dKKxc${{R30 literal 1990 zcmV;%2RZlv03F$Qob6d#Zxcrp9$%7xxkI=^x)2Huq|W*l0>LJblr~aO(p+ez5Sfj= zb{1@}wYzo#C{kbg+Q}mWm6>dZ%`zK)999A}3>W*I7VEJNgBS`_xrk5~+DqU92+T8=ErYEx zh?%U&JZ6D-9YxXRUg9C{Y8h-9tkPw9Pgg_S`Wo1=KmiKX*hAKY`!aZeDh64BO|lH! zH556_QXIUtfNPsA0jJHL`}}?k&Uk=ZkUho@k=%@;>pWvmQ zf^+b>-R^@@f2&sC209AYRzJZ`WGS*y?Z+xth}$cI_7-mvaYQ_*8wLQ4LERSGOUZuM zAbpn<=<`T;bO`kyVh7j*LQlZKM2m+&1iwF8SXoH8UMZ2uVqZWOB5m)FK?6rA%$i}< zg*;@ckjw1$Rf_`wGcR`YPE*8s$e6`Yh3s|1!~Gq9=U(5tgUDk6|xQ z_yDH|+Vl_;$413Q>04qU!e$gKOxS{gMF?9`uqa_q6>Na8X9_k*SV_T#2-{My1B6v6 z<{8Q%Q)rpPQ{ZKo??)s|NnZqgIErE< zFV8w+(?lO34DB5wePQB1&Sd`xexy$jhWo?h%OKHbXm5!4&oI$rh@A%d9L0v~7SZR4 zM)?cGJ4o_KUnUIs5r0px-ya4qH3ffP(TntTxW4`I>%6pcL-9MoL_bJBk)9w7^PrOt z5yj6e(dU4^N3v0hD@Spm{t?J7_5$)qJ@Q*#IVETJDc^bW1?d^WCZVswtTUd_{?C96 z5HI$_K_!l1?vJ0oMsyBntou=_d5-FRl4|-XXhptL#B-AS6yf?2djR`bkBd~(^P~gg zxI{SepC(%FjZh800eQ^P6~eHNKLNiy&%Xjc?&0|ur8uuDcH`vd4Mq1D;fEm;NZ+Iy zB&Z**6A$`zjrOJNEy|6g$0>JTfIXx?AncYB7h=DFU(&x(lE=IysTPai3)VYDSd!uk zQB9@2G}-$S>>+=KWYQG#Ft5MRnN{R&6aESLIYqKe!R`+uT_Zw)K64N9~&kgxhrV$efjkZk3wd}f<)b&`yF^d+bwyerlLn~Kp!<+7ctvY}) z*K?XhPg|>7W!tGeY?jNW6MG%gVATvSqqQt^d&#k%n?(;q9~+)y?M(CSmRU?|n?~_P z#j%_9(yU#z9kIg=YK4YT(iK*B%P3j(N>9F|3OHuDD$K1ldgF8Uc3td15SryKw|9by zQ`50sh_Wfd^M|PwCNs*O$ck&!8dcLt&1pp&lDcZ{cumIywwB?%1ottPl-2@#*0!C} zw2DKvC^`uWM_Thf4`VIcDrs2C_!y;{3wx*&#I+pWqS@43T=inSV|PpqlrsCE26ga2 zT6mG5I$32c?(;y)YkDF(#y5rej;e|Ss?56g$S9ehsb=lO^@KhS0_n7lE16Cv(|Rg7 zmDRIT**odmS;ecwOY#es->aKBpKign%RejC!XwA1%o(1su5Y0Kkd3&^Mq=mXEA6IV z+ju)yiEXgB8;b=F#|~?+@b{g=k<#Bad}r@ntN#~T{VS!_zw5Mm_Fb#*r`4@`SC}|X03C1#1lz8{w@BfExZztw&H+q=f%V-V!P}~${_80vw^ijofJ=2MA>aqZi zyS0Az#93bP4A0aGDrqY-(gobI!9hbgU8-4p`Lvjw<}BY z%TEfkj_taI`Ff-2Q6C14gO{rxem1+fxICvT`I25J+rA0vKk*$Vnua}`SZsO$FBHE) z!^)Gws^L^jPZuiq3`2&3Z;+9sGRoB4Cq!A|Jqz+y=UaJS0}iYeZA?z46fS6x{&Rjatce*&k|@#g)!Ck1AVN)sqDlc?&8uj zNCimBcHY<+Z~wkg5>K1J!)AS5zMrAPbFBSdE&aeNr@h{t-p}w9 zs^VQ%#=-x@{$?jKc8yO2|Is%@)xEzqK<(f#c;g|e%nVzM3Y--KycG2A7keu{pNK7gW~xt-W(DF9CgVgVF<@YcWt!ZVbnbS@V1 zT?p0#|DXuZu{32Tro1Lz!0$%L-|lCBEX~M;n2}}hUV~q_`a_Ci{Kv(y3K>8uN*@|| zE6vClJg3E;cw|jtYUWXG5#V+3*b*yY>7-g}l^sxfkeWc5zSIKRjMx&Gx|Kc*jdUSx zu4uv%Tu|0im%4#2Sz@qPAa(l;g^{cS*n=oA`#a*6=)vzM80>^Ks)}h*fnU2!52s5G zLht~!59!B^_EKBJQW!`Fr~|+rC%v1@#wqpVg4hak_X^UFhI*jh2-~3*h9oy4s-Cc| zAqx@ih7~N(iWY^eV(fDc^2Lj7`dAt4qewoUCj01EO1j?P-p`X1&s!C5ha*fCvytr8 zOKhf-@VrP;j8;}6AFU+lfBG4sZ)J3hz8frxKV^m|#u0j49D^mu&pWW8QTaHi;P<`7 zwZ(ilXyhx?SZY{Urtjcwai;HNr{>|h!&2hnvC~e&gGzJo+=u6(kbQzB-w?8%&)})T zQ-h~Y0p0_PXy<~E;|1xHL}!RTMf3>Kr->d7>5Rye?tS3oX>DppDBck9h8S;{cp1ja z5O0KRSNgU`!ry}YB3{wslmpJ2VE!xQ7kM`sZ9tqI;knXuoKtSf-M+@C)N{;5iHU zaf%Q1&%vL^D29;`GZNYvr}ZMO`VM)sM4up@qE8z1DT6*u^p`-R@Aty&|K=M-zfbje zALuVBRzY~Ar%3-i&{rt_sc_w6Vc)AYU7-i#{)+OKr#O%<5D)zn$&ZQ)=@R+HJeA32 zCiHW>-+PL$zSUEtZ}dG)xv!9Kq-ThS@~iY)<@jrgqfB_D=ZJ^$+Z4w*#deo`DSP)w zewXx-zE3=qKOkF5j`TxTBg8K<{4&YLNRIRh@!kWktAu+@ItqtzZV*q^{wec=_-9Ox zcB_WG#^gxX4Sa*}Gq6K({p#RA%-?`BN?7dUEahyD`u=A^_O7De7P5C0{f>~mtLS%y z?A`CcDz5Pi*$|9(mUu&qcaC_&jQ0WYGK}{j#lY=-L_BWqJn^`_kBP_aU7$5^d!G=G z+jEG=?Oh}uw|9wh!0k;CkK4OUJZ|q(;>oMic$m-6D2Hb$M;|cR=ai3+XuTgZS&r8B z3B`Vq$tEez35w%WlHuO^f_#2XHV``x5oJmCEyRj@@tTnPvqZH=-Rs0x^bH~V>Gz<6 z^eka+5T+d3mit!a;2Yxc{M{rT&)>Ji8)oaeMfx{Mjx+OjfJfN^`M*VLzH zHQpiI9L_eotNU}Ma+usQ}7ybw_;7nK}9?tW> z0)CzJ{{eWEJ%R^$xKAHZ?6}8&DdfDGVz!?U|F@K*Ur`R8Fum`Y9>(`Q;r?^4Z}}Z5X}0`Y;8b^OjRJ#qU(_02d)taDaz@8( zwxqlDT|57_zu%S;uN^pEceO7u4VPxKuV=H_o?M>3Os6_s0a-18HEs0*7sIT8#coh* z*WD$*;kK$Be;?K`2vQsjDGi2{4M^G9^}C*2)n2W02+2cs$=Q449xV8Nr(r0RoS-kz z6&C$^t+nEJxq?iRisEj|gJd^bz+$RU{|5wEljTcX2FZ(t5$UCGWqG$&_kzRZIQjsq z6|K@~epdaUCQ(U_B1Cr2_Zkjvm)s<8eXT&wT*%Dfnsf0UnVfR$l47Eylqe}rPRc&s zZdF&P1;Bp}`ZaIckIol*tdqb9Evx>Sa*Fu^+3YtDSd7{wl&CHNiPFp;9MVQ>Iyv4e z&c!*W07gThOqymre+X8Cf zA6{p(#{4`G{STj?rK99XN*sfPw~atEJY)8uX42e?dDI6USB(!li{YqkW0sF5 z+|h)4lLeW= zGbv!4ye2$9qX`8@zp9Ed0lM3i*| zpX;2j4R>7-B=Fgs=K^Eb=;6g@y*>PB|7xb=^WN&&E;S~;-Eg#tt(Mu$r<=*z%7fL% z)rF4V?N%SOcY6WtTqE1iK#%S`Sy*0PytlW{5EmJS$oW8-D`CVg4=sg)viMQ zlgqpgDM3#DuwROjWW^L&DMglWHQMR5R2bTwrwOJ|rrDWFJcK9zD|e*kz)Mo||MQj< z-;?qd9UH0+C~vz}4}Yt^vJA#Kj?3FlT&rSnkYX`Gu{21rl%QB1q)2;uH|kIhkIrxe z1yQeYkluG%TiKmQ1&qycyMo?7=1{lmXsr|*-gcd+XTt7^CX8fQx=32_LqdW$C$H~) z?a~&*@~zD7NO2t7*z9T)$Hn(!{8p5#6=gSm8M0{UTh+J%C3|57v0RP9znQo}uhTXX z{hI&12mb*C`*(@s#R;!nZ}l3k^YxA!)LPYU&}eyE^Vx{s^>!Lx;UD=I^Vw{#i|J|C zcHAzk&~-ws+0=JJ{j($%$b5lFUV;#uAMI9VJ6d1M?!}4xpz;cq&ew#6HMF;bH2}4bri{e{)V?zx{1jW+k zwG-~>8yo$%*|~xlMi8YoLKV$0EQb=umj>dC8ooRbU()cEf%vk9kEJm-`8j&VsG~XY zIreG-Haveg@LB?p^+p7~KB+2-r+|A9Z3Ou%rz#9)Kv5kgo10Tk-46{LbK^6-$^lZo zk_oFGy~0zb@tJdecs;Ann8Ej1%N2xQO)VFVba5$N+`rrUu`}*Rz50t>*xvv7#-Ru> z{i@*`ry;Xr+;p|8N5Tt1%^iCwXz=-!*S8BIfb8hDa)n+ literal 2957 zcmV;83v%=T05|q{ob6lbavR4H9v&hUNU`NxzE_qH(57KrloipmWJ#7KM+|8lzGxW+ zfd#n|h^2uA4>^o1J4${hKk_Ka6XXr@BX5$UDwTBae1q+s-34Sjl~gKZ)e7kDufOT( zndxb4*-EJ&DgDQvFDg%UR8Iw}PM;0sszv3iCVjS5O?Bz}wki^ClAiH@;!mag-49U- zL=!)hs0^aXA4*gK(Scz^N7N>Pdqfw|;}aQ8fepi*0vc&Yog)XIMr(2c=@}d5bTkq2 z1q#-q@yU^%gTtJig!5IkPT!lMer=HbsbM6~B}kTN^g4ax+3zBb>0uO{nupbvx|TZs zp-DSTZtTzwU39oZ6ZRB2T%vHV&{!>Ub1BehkvP<$n|3UuxK3b?+-U?gqz_q7cryD$Xw#@C}m3S2z!j>(PNY_#%I}MbW_&i`d|xxk>&VI zs^j_an3~0GW{>J+?t%yCS&@+?JVf`{TsulA)Uf!GlCrc)5Q4kX@(wB2i32k zeTWVWJ0Bt!{(SH9)ysum&@5Evc&TY(6N3RBq$6hr*{FM+kX7l)^G;(cJ1x+2k)HSI zS)}JvdhXD3m!5k(1~IVTb4njqmLGsT0r?2zNyraFJ`l-HNrAtBBjkEpVE>(9!VI^O*M?*iBq_RkXJ_o_nyLp!3SS zrjWDlucSEuEbr@_iuN(b{)r`jZpn2^b}iYn9b?xhm<}$ zMt(%;v-1JXf^+jYIF!&m0o|C;9ffXO=$?dbLg=1C43h6@=p^4W&`G{$p_6>iVGfe- zdFUjc1D)hM2A$-40XdL-$DxyaFG45zUV=`yPSasNUq%j}K#raiwpWmkr!n7Wg)NV{ zJ&)Lr3EK?fJdQYCf{oAis~GbYa4`05iYN!$I}|I|f|E+uhcecleSZSIkxwbTe}79p zEYAaT3YbdBt?P!#!D;AZ{?0%r^Y;#P<6>TC;eQ5puGzmKJloD;{Ii$?pVN1huCHax z@m=5+P_KTfbj@MgMaT;{^FLF%-u!{MmXyBFS;zOnUkHB%bND;qm&3SKsN?hf0b=0V za1~?B3hryre~YU|rplAP2ARBxQ zcp29h&@=vX$Ohj4epTR`&@;Xc+2GfJZwdT5^o(~Q8{18#Yn_pADP0QK#=8Oi zUF6Y+j_dVd+L5d?KO+hl;}&ong9p3e9b(Zuq`d`kpZIH_G(; zn*Up1SZ~heFQJzYbKil@aQ#Z@bH%oMkpDrEozy>jCh=Ru{CLA}p#y(BzU6j%p5Jjw z#bPek3%dPA;9T!`Ex)^Qw%=;G-P~6>hyFI|LDkvv-0kJAf75LQ=FzwLLmrPcQ9fm7S8H;V$=Tdz00&RQz2Bo$q^)z-sZ-%Qt^_qRLR z;&lSY>s=XGY~u2KZf`!9>+9*or|Hz@s${DNG^f>m;BuH%V(bO=PQzXFn{K<-^|xsb zqadZxkn(6q#e!6vO~2>qS#8z3yOcaumz}L^?#?;i?=~%mvJ<2jbTZ6n7uw!tW++$n z5|v`((H_8>WpOTT)*D{18+mE-)}`3OF}=1&&VAX%Y(BJD)T&UKDiV#vrf9D zlxZnvS}HR$db_N(Ys<(qji0A&QApeN&a3fQXGjq;n`N4HN`)dg2Wv!((W-=7w&mpI zYB3RcIGWKpQ0i7-Pqal z*4Bs9-%h|s@Ne7kMA!{)CvQbK8=v6p;A~KOUZecY%_PQ;^VuQIT5}q~*h>T#=Si~c z#8~thBKL5|7`9jKGi1>6=!oR$)4P|;Sp|Ma4gO?-FYg!l{Q|#V;P(sseu4iVFYvz; z1^#wa;OF)WJlVWXc4g1Bm4?{LLu?gelhxbr2Z_q9QL{LQ8tAJY$)mSiW`Ddy|v}jqlhl3xZT`Rsf2@@DrU7WD>O4#moHuUuy(HN_j%Vx^liK);F4*0LTUhZi3C|h)Z~MJu@hX4yy!N z2Ui~2^uhJANbul}NOy>CZs}w$jC7yD#T{;tsM=~p%7)M+ekf>=)D+@%FxFZnu(GU) zP9}*PwE5!YL>yu5Y^(7IyK*<^cRN=2d$Q-BRI&d`cl!6oy-uUuZ@SJ~8*Wf<*Lp#- z?XA9@i}XEjqxlB^Q&@jHm+SZV2zKflZjZ9+I-%G6(04e4+bsJ%4)?HbvxesA{$A+B zeg2zob})BNago!W)o84&^n3Ixs_i#A#hDv7(wYqcDa9dHWfQ=%%_aBe%8EI-3`#`n zbu#+Wm6gG(^t=_UXig=nWQUPbEG0e>c1n$u_{vCpIfk!}#8+bYxh(vkB1!ZKYjx~O zB(ZO1V8gm7fhT9oB5{>+ccLw&zva!M5d}G#T6g2dtkdvAQtJf1%xxDT^$+`SA){Al zhMJ!R=c~Q>_-P&8d#2oWvW-l+(}tVN!_9*})KApl@AT>|8Y1oen{O3uf~B>iu^TMo zObDH!R-Jd3Xe&EYFu_*t(_j992@B0;kFN4^aJ4m#%nz5Ro>u#8&UY5m#k|)VK+J(7ykVV6%*1N D8729a diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index e325f1c26..d3b7b715f 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -194,9 +194,9 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) // Create instance buffer for per-draw instance data if (!scene.instanceBuffer) { - // Allocate buffer for per-instance data (model matrix + shading + opacity + flipFlag) - // mat4 (16 floats) + vec4 (4 floats) + float (1 float) + float (1 float) = 22 floats - scene.instanceBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, 22 * sizeof(float))); + // Allocate buffer for per-instance data (model matrix + shading + opacity + flipFlag + rotation) + // mat4 (16 floats) + vec4 (4 floats) + float (opacity) + float (flipFlag) + float (rotation) = 23 floats + scene.instanceBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, 23 * sizeof(float))); scene.instanceBuffer->create(); } @@ -333,7 +333,7 @@ void YACReaderFlow3D::ensurePipeline() QRhiVertexInputLayout inputLayout; inputLayout.setBindings({ { 5 * sizeof(float) }, // Per-vertex data (position + texCoord) - { 22 * sizeof(float), QRhiVertexInputBinding::PerInstance } // Per-instance data + { 23 * sizeof(float), QRhiVertexInputBinding::PerInstance } // Per-instance data }); inputLayout.setAttributes({ // Per-vertex attributes @@ -347,7 +347,8 @@ void YACReaderFlow3D::ensurePipeline() { 1, 5, QRhiVertexInputAttribute::Float4, 12 * sizeof(float) }, // row 3 { 1, 6, QRhiVertexInputAttribute::Float4, 16 * sizeof(float) }, // shading vec4 { 1, 7, QRhiVertexInputAttribute::Float, 20 * sizeof(float) }, // opacity - { 1, 8, QRhiVertexInputAttribute::Float, 21 * sizeof(float) } // flipFlag (1.0 = reflection) + { 1, 8, QRhiVertexInputAttribute::Float, 21 * sizeof(float) }, // flipFlag (1.0 = reflection) + { 1, 9, QRhiVertexInputAttribute::Float, 22 * sizeof(float) } // rotation }); scene.pipeline->setVertexInputLayout(inputLayout); @@ -408,7 +409,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) bool isReflection; bool isMark; QRhiTexture *texture; - float instanceData[22]; + float instanceData[23]; UniformData uniformData; }; @@ -482,7 +483,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) } // Ensure instance buffer is large enough for all draws - auto requiredInstanceSize = static_cast(draws.size() * 22 * sizeof(float)); + auto requiredInstanceSize = static_cast(draws.size() * 23 * sizeof(float)); if (!scene.instanceBuffer || scene.instanceBuffer->size() < requiredInstanceSize) { scene.instanceBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, requiredInstanceSize)); if (!scene.instanceBuffer->create()) { @@ -514,8 +515,8 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) // Update instance buffer with all instance data for (int i = 0; i < draws.size(); ++i) { - int offset = i * 22 * sizeof(float); - batch->updateDynamicBuffer(scene.instanceBuffer.get(), offset, 22 * sizeof(float), draws[i].instanceData); + int offset = i * 23 * sizeof(float); + batch->updateDynamicBuffer(scene.instanceBuffer.get(), offset, 23 * sizeof(float), draws[i].instanceData); } // === PHASE 2: RENDER (DURING PASS) === @@ -601,6 +602,9 @@ void YACReaderFlow3D::prepareDrawData(const YACReader3DImageRHI &image, bool isR outInstanceData[i] = matData[i]; } + // Store per-instance rotation in the instance data (new slot at index 22) + outInstanceData[22] = image.current.rot; + // Prepare uniform data outUniformData.viewProjectionMatrix = viewProjectionMatrix; outUniformData.backgroundColor = QVector3D(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF()); @@ -637,7 +641,7 @@ void YACReaderFlow3D::executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture * // Bind vertex buffers with offset into instance buffer const QRhiCommandBuffer::VertexInput vbufBindings[] = { { scene.vertexBuffer.get(), 0 }, - { scene.instanceBuffer.get(), quint32(uniformSlot * 22 * sizeof(float)) } + { scene.instanceBuffer.get(), quint32(uniformSlot * 23 * sizeof(float)) } }; cb->setVertexInput(0, 2, vbufBindings); From 720d58533cf56793395b28cd86d49b4a97ee2c15 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 19 Jan 2026 19:23:57 +0100 Subject: [PATCH 016/187] Fix the fragment shader to work with any background color There now some dither to avoid banding in the gradients. --- common/rhi/shaders/flow.frag | 16 +++++++--- common/rhi/shaders/flow.frag.qsb | Bin 2682 -> 3176 bytes common/rhi/yacreader_comic_flow_rhi.cpp | 4 +-- common/rhi/yacreader_flow_rhi.cpp | 38 ++++++++++++++++-------- common/rhi/yacreader_flow_rhi.h | 12 ++++---- common/rhi/yacreader_page_flow_rhi.cpp | 4 +-- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/common/rhi/shaders/flow.frag b/common/rhi/shaders/flow.frag index 5e6f6c406..411204f45 100644 --- a/common/rhi/shaders/flow.frag +++ b/common/rhi/shaders/flow.frag @@ -51,11 +51,19 @@ void main() // For reflections, apply a gradient fade using reflection uniforms (darker further away) if (vIsReflection > 0.5) { - // Legacy reflection fade: ramp from 0.0 to 0.33 using texture V coordinate - float gradientFade = mix(0.0, 0.33, vTexCoord.y); + float gradientFade = mix(reflectionUp, reflectionDown, vTexCoord.y); shadingAmount *= gradientFade; } - // Final color: shaded RGB, keep source alpha - fragColor = vec4(texColor.rgb * shadingAmount, texColor.a); + // Subtle dithering to break up bands (very low amplitude, within 8-bit quantization) + float rnd = fract(sin(dot(gl_FragCoord.xy, vec2(12.9898,78.233))) * 43758.5453); + // scale to roughly +/- 0.5/255 range (adjust strength if needed) + float dither = (rnd - 0.5) / 255.0; + + float shadedAmountDithered = clamp(shadingAmount + dither, 0.0, 1.0); + + fragColor = vec4( + mix(backgroundColor, texColor.rgb, shadedAmountDithered), + texColor.a + ); } diff --git a/common/rhi/shaders/flow.frag.qsb b/common/rhi/shaders/flow.frag.qsb index 02f9d8a6c07cb8e469453d7f1acaa3e452d97988..cf44ec8e09e01c919c5dbf0718a69effc82d7d90 100644 GIT binary patch literal 3176 zcmV-u443l&05|-2ob6ldcN5nUzkY*&kOv_luP%^K2^1mA7B(20haDcp)CSu?D_pUb zcI^d8tL(098E^wl(j+bY*3(b@OZrdrTmOuH?d$ZkGxyG2-Mv}~)02>MQg6A54`BubF2=}B^Wzkn>a2S>Sp8}Zp3Fd zLD`1UEl>_X-35a}y|0`4k(fE$1ZAY6X8OCC>EThZA?hZC3|FAS*FXfX>k9O6CzfCw z2MnN6m0e^Fc(!3KXkw5R**F`6r@Eqti=TwqJAm4NpnITuKjQv%?t=$Z6R>+o@4RB; zRr&A%Tj61U0JBF!4Nxyf{OBXqy>UJyV1{*`Gg!uPOU?03X{4fa18*aIr~dwF(Y zHsc57%xE5S1R~O>46=_8f_K$)YC@l}x8Obw_Z7IW!EM9+8182bQ@4-fhtM`W?StRL zWKYsZXf8;jy$?dVkK2BQWN(p7>K-S0fUs8->=lyrlI)ryyGF7;k}VPL3dojd>;X;> zg!B*-+fd~lrC-VGA>Mg~*Gs%vh1W;Cd4<Bp-FX3NhtxYmP^lQXJ`2m{CAkha& zHbnS?OyoH7-URw>@(r&OL?0p=_1_`vpdy!fE9oONKS>{BA}{3pjw^Vy^RY00PSPip z@sZ}6l|4B(LE~Q`eMw&<`T&f2o#Cm}4`-n8v7h3$Ky&URKNrc*9zOp)Jg-nk;^eQq z7nK;^BL9|X4oKftd`9dYCUP9{KO@oY0e8uoS%{W6wINQwGL&p z@ps@15El2qZe^?kJmyjQeT_b>(I07aN~3ccJ*LrTHTr@^U()Cs8f|Ixry9LZ^d!)@ zSMmJVM>MX_>rCv!+YlARy+Ih{PeH_X6Ym1ZF}CkAu@4WC4P3wXh>!R;iI(^u5&i=O zZxA2x?-MQYM+tvK!GB16#2+SF;(tu|V+uY=e8hi5w8WoaEUZ})pC1EEDFgg82pUWgZn73wtq% zxkr2%A5)1>fo$9(|89_6>aH+xen`5+#Q7rQQzqVu5+CIK1N@VI&XYc#75Kty^EeFg zvt*5Us}v`k*YC-8h2#(T+y^)-`Wuh+4fqj(!ig-_zxb`Y@{G5q%ejX^qe?dHX?oc8dp6_ zzast(^8ahH!xY{(ifzgJ4e@&UyoR`6za{-|Nd6VY=rPIu4Hm{l$JtNsHu5c!+R(wN zqwALEJ8sPw&Sn#J&nh{bT60#{>V{o$&0wO9?bLvo@B^<=3XG+iW4m7UV#BsAFYzd0 zz*RMaQDfb)Hs(F|zEui9^|~2&PIH2b*R9fsv0|1Uta@&vR-Se%t|ugXK%-bU%UK2L zubE}1wi=5YRvDgUSHy5j^?3e_yHOJoaKdo>o1sKEoSR5&ftL;8UeryaI6kJxL{xmU zTCZ4MZpJ9N5Y$Dh88kc#VC$y03DZYka>hFFr(M@8PbBOL45bJmWLIl`VAe|3g7A1k z)17roW@X;>HC-|3PJiYCLL zXEu!!MmCdA!ynnSF`UUpd}_vMG`nh`do(!cR-I;2I-I5mrH##0+x(*{p-X8Q1zpK+ z8-gsPBlglpGfwS76}D&q%F@j7m_+0I$u^Ra>@ud%_Y@b3q-hyn^}v`_3oe;uizWtJ zDx>b-v=QY9AH#ggNGI`%&h_|Y#J+%SsbQ>@VNlyMOF`0yq%ONbax=vyffJ zT!-D7ltI=G-gLN)!R?3K?~!EOEK(^2x&cFNB@$X?X|nJd+}o-wx$I80Xvuc!#7>>q zsS`VO;{Ui#{GnAR2L9Em6ZxGwv7I{M)Z$Bo;Kx;mP(v#W!0%cU6nVraw-Jb;Y`ztE z06Q4`U#i1SZP=*|JGJ5atqtMMeo18kziZ`MWnoXUv?310=n;7aPTf_<4=gXal9k7Z z=WZ0M=6#qe_kXlGitApCD-~b>67GR(+rAYfOOeeq!nHL2G=BNiVoubX?E3e zqv7*$Mu&A!)F_9kxvs%abpi9!OM{1d0V^27)hgBoei%37TpNrpGo1X3vg}q0@@K# z-iiMz<3ah(_Ghr&T#W01m!F_@ZojaSn@1)TmNZIZUr88oI5}a;5Ox*3hl88?h~`P6ykO zeH7h8x<=dkdV8_yFi5L9%fz7bUNBeSnr`D-WD-;?& zw6PVpR1><2`L>OufQM6foSH#IrG0xS8o3S{>fTV`BXMxGzf!RI&})oH6>3B)V&W+& z>Gg$Yg@8y38Q?qTG zpTk_eHjBOw11@S*+_$lm-u@AETc5|2lJAO2kEMQqA3*fIO#5ag{>2?$G5-Qb>kYbM O8PU29zy1q$U~MWG5-gJ70H8!Ub9!VXxs zK{y0)4-^XVfnMTQ66UZ5!bru{4E9pf$D`mt)J+H(u0V~ife2pD73kwmY=RvZ6rfO@ z-DfR$c3>{3;tZ>>A}g?Icy20^xcpg|zYDlS2)hr`FJb|B#J%u=Y6JEx$=y|SyeS_p zu^k@xeV9KgYJqq)=E(qwzLw-g2Iko0SyLdNmZkIh^*#h!O)%ZY>i63yl8tBSHvEKq z*yQ0u!RKj$A0-Mdz~^C<3DtC~ZfYjJ4)rZ z0Et2Q*4InPaj#+et}0V*5A=_Xp#HOvpf%#Y1-l+Co&^#7{(O0TIUj`8{8Sn90-`Vw z&HfEonGc7o_3!Y(SX*3Z&l$967QM98zSCwg*QyRs=^x~-k!ocL%bUKyiaSy z6k4v)J21`R>ozXO8N@TPtu>#+RFJ&D0tNKbD{o@q^~LVk>(qd{rb)f*8HfQxNeb81BzaU$tpI;j~OGh&KRdXic=r=|18ff#7I5z zTi$!h8oZ$RxMU0Ied1k*Jnd(l(u(u>3vh-Ai}^LG_;H@kCr*E?(U&#)6OA6%=#oZH zYxHf6zNgU-H2N{ovp{2BW4$>?H0JHwOyukr;3eYTAq?{8AOfSry9eXAE*~bb<{i2n^>kj@hi_r`0m>d2FaimNn^`=mfN#%WyIm?Rr&jHZY$ZIp?p+PJRRC~G!K zG%oespj?ymP0B?{-=f@-x@Smto@8$l26a!2&pDDWU6Mlho-=lFU`#BT)LDEZ1)T`f6%zr_cC6a$Y zJc-ACi1qCEfX7<)OXA@g{TcAs8}a%Z;Bjn)iGGPSVntd1b;hFeh19)4eCgMw;uo&- z8ewo=k7-=WK4D@XOZp2Y_PO-yOX59I{6gMeVP0~6t0a$m9Q*kwpZ^(NE4PXFjQr!T zRf@f@$lkYL5AhX}`HFnTI`f=#s{7C+{$rZw4#_fwXA!SY;Z=#(&*MA7=WLU_MdK#< z`jp1L0}VGsXCI{VqCAaLyC1qXc3}H~>otsGp^$0%w&ika&)wZ?8cxkK!q578k-H*@%;MzmgCrd=Ie|BSKSP!j04v`T=l&dwiSZtBQx~f_6#3Bu&qgB$F%l$ zeXrH1&U-b_7bD!DQE8ghf&vZp%&ObiO~e&dhHpDHVQ#aT%wO;h8)5{UFx+4*8qpP( zW-_n9%a(92?xs;G7N(U!5thKLH*2wN)?BWW}r_;gzOox#3X?DCTo7HEUjI3RLF6 zbE^iXPfy@9~X&S%E>6`LP3`a(vXYk%Ngw?v3qscqag@OH4_Pm#y6B>WMkQ7%%Sh& zd{87!NBOP~%Irq?z^vLdF&?5qesZ#aS8=jfoGg@zH_C9UebdFdct@p(?n z#&iqVEB?7#t32?{-32o=w+h>s0g%I4nZx<^(M#|xrY#p`c>WM9zRF~@Qrc$GHTYep zl$HvojCJKI1IgBK2Wi!~e}<80GsvT?g@1z0|3Lqu*FNq6)-o!YwE>yKWHL zes-rIw~g-|R_f*pm<5l-RC|ioj!IH-1Pu`3ea~?MJIq?K?3ol|TG7-breZ6~1+bFp zDDI-JS*@{}KsixuQAfqq3Y=PyHT?BnXufGRe3S-Qxj9}f-(BdJiL)+s;rMz($=i_U zyW3)==3=#6UEL5@W?hv0btsv(QBk24>ISMvfFjT_p}tyTMzNlt4kR@NO|a7%)PaPJ zstv~)L)@m)9g=k_&4C*K`s&i!lghmB1wm!0(QJj3^16EvhmFs^oL^a4TcD=i@L&mT zzvd#_Nf(cd{3qMEbF4njrzRrRqmw)T(pD}K{DjTCd!vcNZC431AVj-%#l`37zC)Nc;ctCxoED(YM)su3ExQ{rQ~Wra)89b4M?vg#6DZ$90HEyYNu6Ueop5+oQ2 zu@-7PP6&|7$;Xzr(}(!+$%YEm&=kB<4`+ic_BT_*Yh!N1sBfmEX?{EPwR>Q2@0YuL>xK!`|7Kx5>>94qSv^w5PE`k4>ueszc2DN~J zPHRM4TNZw23*+0{36gFj?GUiF)e7JsRP(HckX6)oZ5;(%9M2i}z8Vwh-VlmJDMdov z4GMfR39fc;1zV21#)#CRRCOXIp0Y9y_u__Lj+WB&8OTJNKcyjV5 zg&1fZShxf<#*yREPcCvEc+VPNzlw!8?LZ(@WxK58VE*~xJQB{Y|5!137UE^ zNCJ1A4IDEFZ`~5j9tBSDik~X_<9ydw!`XFC;Di6pH-0tce%MLD)7#03PYX)d@kF!1 oZZpKU7yTBX{T?9x)EuvbKRngiQ`euRC;j=JF2k>X0FS3dKKxc${{R30 diff --git a/common/rhi/yacreader_comic_flow_rhi.cpp b/common/rhi/yacreader_comic_flow_rhi.cpp index 6117114ea..a5ec18fed 100644 --- a/common/rhi/yacreader_comic_flow_rhi.cpp +++ b/common/rhi/yacreader_comic_flow_rhi.cpp @@ -37,7 +37,7 @@ void YACReaderComicFlow3D::updateImageData() // Create QRhiTexture from the loaded image if (m_rhi) { - QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips); + QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::RGBA8, img.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips); if (texture->create()) { PendingTextureUpload upload; @@ -168,7 +168,7 @@ QImage ImageLoader3D::loadImage(const QString &fileName) break; } - return image; + return image.convertToFormat(QImage::Format_RGBA8888); } ImageLoader3D::ImageLoader3D(YACReaderFlow3D *flow) diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index d3b7b715f..f3c0a33ce 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -37,8 +37,8 @@ YACReaderFlow3D::YACReaderFlow3D(QWidget *parent, struct Preset p) shadingTop = 0.8f; shadingBottom = 0.02f; - reflectionUp = 0.f; - reflectionBottom = 0.6f; + reflectionUp = 0.0f; + reflectionBottom = 0.33f; setBackgroundColor(Qt::black); @@ -119,9 +119,9 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) // Initialize default texture from image if (!scene.defaultTexture) { - QImage defaultImage(":/images/defaultCover.png"); + QImage defaultImage = QImage(":/images/defaultCover.png").convertToFormat(QImage::Format_RGBA8888); - scene.defaultTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, defaultImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips)); + scene.defaultTexture.reset(m_rhi->newTexture(QRhiTexture::RGBA8, defaultImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips)); scene.defaultTexture->create(); getResourceBatch()->uploadTexture(scene.defaultTexture.get(), defaultImage); getResourceBatch()->generateMips(scene.defaultTexture.get()); @@ -131,9 +131,9 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) #ifdef YACREADER_LIBRARY // Initialize mark textures if (!scene.markTexture) { - QImage markImage(":/images/readRibbon.png"); + QImage markImage = QImage(":/images/readRibbon.png").convertToFormat(QImage::Format_RGBA8888); if (!markImage.isNull()) { - scene.markTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, markImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips)); + scene.markTexture.reset(m_rhi->newTexture(QRhiTexture::RGBA8, markImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips)); scene.markTexture->create(); getResourceBatch()->uploadTexture(scene.markTexture.get(), markImage); getResourceBatch()->generateMips(scene.markTexture.get()); @@ -141,9 +141,9 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) } if (!scene.readingTexture) { - QImage readingImage(":/images/readingRibbon.png"); + QImage readingImage = QImage(":/images/readingRibbon.png").convertToFormat(QImage::Format_RGBA8888); if (!readingImage.isNull()) { - scene.readingTexture.reset(m_rhi->newTexture(QRhiTexture::BGRA8, readingImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips)); + scene.readingTexture.reset(m_rhi->newTexture(QRhiTexture::RGBA8, readingImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips)); scene.readingTexture->create(); getResourceBatch()->uploadTexture(scene.readingTexture.get(), readingImage); getResourceBatch()->generateMips(scene.readingTexture.get()); @@ -605,13 +605,25 @@ void YACReaderFlow3D::prepareDrawData(const YACReader3DImageRHI &image, bool isR // Store per-instance rotation in the instance data (new slot at index 22) outInstanceData[22] = image.current.rot; - // Prepare uniform data - outUniformData.viewProjectionMatrix = viewProjectionMatrix; - outUniformData.backgroundColor = QVector3D(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF()); - outUniformData.shadingColor = QVector3D(shadingColor.redF(), shadingColor.greenF(), shadingColor.blueF()); + // Prepare uniform data (copy float data into POD arrays) + const float *vp = viewProjectionMatrix.constData(); + for (int m = 0; m < 16; ++m) + outUniformData.viewProjectionMatrix[m] = vp[m]; + + outUniformData.backgroundColor[0] = backgroundColor.redF(); + outUniformData.backgroundColor[1] = backgroundColor.greenF(); + outUniformData.backgroundColor[2] = backgroundColor.blueF(); + outUniformData._pad0 = 0.0f; + + outUniformData.shadingColor[0] = shadingColor.redF(); + outUniformData.shadingColor[1] = shadingColor.greenF(); + outUniformData.shadingColor[2] = shadingColor.blueF(); + outUniformData._pad1 = 0.0f; + outUniformData.reflectionUp = reflectionUp; outUniformData.reflectionDown = reflectionBottom; - outUniformData.isReflection = isReflection ? 1 : 0; + outUniformData.isReflection = isReflection ? 1.0f : 0.0f; + outUniformData._pad2 = 0.0f; } void YACReaderFlow3D::executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture *texture, diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index 7c02b8f88..44e5e60d9 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -112,14 +112,14 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement // Uniform buffer data structure (must match shader layout) struct UniformData { - QMatrix4x4 viewProjectionMatrix; - QVector3D backgroundColor; - float _pad0; - QVector3D shadingColor; - float _pad1; + float viewProjectionMatrix[16]; // column-major 4x4 + float backgroundColor[3]; + float _pad0; // pad to vec4 + float shadingColor[3]; + float _pad1; // pad to vec4 float reflectionUp; float reflectionDown; - int isReflection; + float isReflection; float _pad2; }; diff --git a/common/rhi/yacreader_page_flow_rhi.cpp b/common/rhi/yacreader_page_flow_rhi.cpp index f2e9b3984..d32200716 100644 --- a/common/rhi/yacreader_page_flow_rhi.cpp +++ b/common/rhi/yacreader_page_flow_rhi.cpp @@ -40,7 +40,7 @@ void YACReaderPageFlow3D::updateImageData() // Create QRhiTexture from the loaded image and queue the pixel upload if (m_rhi) { - QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::BGRA8, img.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips); + QRhiTexture *texture = m_rhi->newTexture(QRhiTexture::RGBA8, img.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips); if (texture->create()) { // Queue the image upload so it happens together with other resource updates @@ -136,7 +136,7 @@ QImage ImageLoaderByteArray3D::loadImage(const QByteArray &raw) break; } - return image; + return image.convertToFormat(QImage::Format_RGBA8888); } ImageLoaderByteArray3D::ImageLoaderByteArray3D(YACReaderFlow3D *flow) From ea80a550dd988ec50c56dcebc5df3cdc5aac35c2 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 19 Jan 2026 22:26:35 +0100 Subject: [PATCH 017/187] Clean unused stuff --- common/rhi/shaders/flow.frag | 5 +--- common/rhi/shaders/flow.frag.qsb | Bin 3176 -> 3066 bytes common/rhi/shaders/flow.vert | 13 +++----- common/rhi/shaders/flow.vert.qsb | Bin 2892 -> 2688 bytes common/rhi/yacreader_flow_rhi.cpp | 48 ++++++++---------------------- common/rhi/yacreader_flow_rhi.h | 3 +- 6 files changed, 18 insertions(+), 51 deletions(-) diff --git a/common/rhi/shaders/flow.frag b/common/rhi/shaders/flow.frag index 411204f45..686ad279f 100644 --- a/common/rhi/shaders/flow.frag +++ b/common/rhi/shaders/flow.frag @@ -5,7 +5,6 @@ layout(location = 0) in vec2 vTexCoord; layout(location = 1) in flat vec4 vInstanceShading; layout(location = 2) in flat float vInstanceOpacity; layout(location = 3) in flat float vIsReflection; -layout(location = 4) in flat float vInstanceRotation; layout(location = 5) in vec2 vLocalPos; // Output @@ -17,12 +16,10 @@ layout(std140, binding = 0) uniform UniformBuffer mat4 viewProjectionMatrix; vec3 backgroundColor; float _pad0; - vec3 shadingColor; - float _pad1; float reflectionUp; float reflectionDown; int isReflection; - float _pad2; + float _pad1; }; // Texture and sampler diff --git a/common/rhi/shaders/flow.frag.qsb b/common/rhi/shaders/flow.frag.qsb index cf44ec8e09e01c919c5dbf0718a69effc82d7d90..0cbd54fc9872fd6cfd24ddfcb79c650c656bcd2c 100644 GIT binary patch literal 3066 zcmV&D!VIN2HZd%P15FLPe1kakLbsK=%@Y-{WE&{t&ekh+L?RjuI^r~ggGZ6=MZns zT01kpnR{pM+_|%xgfX^@G1d?F0Nk&!b+*VX)?`!6g?~I&25v9h?0OFk=HiXLrUomtQ9z5Z7*Uhz{5AU-T z9W0IK2qHi=R*Q!Sm%qKC68vM>-zN;SZfdQ5~vHs`A&-O#wt$3-;HpM z7CVpXbX?q*;lABTvE|t?jd7xN+Vj`G-XlW@-_2fP-w^jz*i>j>H>lw6<=KVVj31OUqj_9Eh)AC@$R0ij-c{47 z34O-ig!>rWSKz)1w+;6rhAGv@v6!Bh;b|}Y9wJ+kK1}mK8g0EF(tX_S%Orb~WK#DS z(F26NqF}F(te0e071>pi^^t6ea92RKL}L$ddLX2SnAjdF?+E=$UJvokE4*If%__V; z;>|0(e&Q`EyaD3fR(ONNyFoB`suHVP!gwF@y3CA$_ zn)Y+Q2Wfr={C$aHf%ic;DiS2uvscpZfIS>PLHe>@Aa8=`y~M-u_L03_!oR{=$vr{z ztHeY3ewxc5(FaI2MECBBTXNgt&(mGe8M z;L*;9!u&Z&pHRj}nr|}p_}m1Ie}(iVeU<3_FzPji)ubP4m+-Nl; z|6M$HP)FkAy{N?QCi%5QV(HAuOl15+GXiK9%*64Mj zCxOO2i8XRB(YPM3F|prnK~xa;I$@B179zHbco#s9x%v(h`|Tjv!1a2U_=talXo>$3 z;on#A2JsR99?=qigz$$I{Evx`_(McX{7(pfRKX{SkN6LWmiXh0h3AUIr-}arFi2;J zhx>XDWC`+QJ8+!jxW}_JMvCNej1d|`jnOFai`91q ziitfS>1ihRjI{lcV*4WDr^)sOl1tsoOza;?&oEJIzo3}^lrS@-e~EY!k7qd6;y(i( z>+sKrhimjtz~gz2*M9(yvNx(f6~u+(#KkXZ+SM4 z!w|0}Ys6cnIN`j0N46^@zt87B$az)5>?OIJhfA`Wf|c(J36kUdEaFRl@Vy0jpOGD( zc({IF5wAh~fNXqBJZWQtVj^jLl|qc%x0{4%Dr@k7we~H_)qT58a$Hk9n?9j+-=Z<_ zoO(=r8P_LFoJ(_HALXAC?}-xEUS*D-F;VB|fkOP}#FO_Pvh#(KE04+U=QKAwD}GJm zs;$J8Kzal$K;eD;xmb~8(ub0nji2LbZ?tdCIN0o{;bXjbhy_ zXH|x0*%e`CsUFXtb~kE50+TZw|3)a$4G&KwwqW)RG41H|jpF#2A`{;FX0=|iyxg== zav@lYRx@aL7Qog`Z_}x*qB}Wb9r#nO>y;-Gb_Iq~gb<3Enje_8lC`jAmVrB=>CU<( zvoi1cny#31s61CUOHQ!a0TgjLvF4SZDSH2(U078QgticawMfj zu4382QXSNES29fERogtmjh2W_}c7B^JnCLl@`SgT|h&djE9+{k9~Y50>( z8^f7w#HVJAMzgC1x<`Y9Zq;cfrNe28P}35=nCq}xlQPI!sZ594 z7~Foq{T@li%_5ajpc^pMRwALD1x*%S1Al3q1-a}Gp}y}__MOVUQ`vVa`wLmwf3H;b zKeZ}*{)b)JomzZR7yP(-9%^W%9Qa+UxFV1EI(}ez$(5`uBc8iateW>=uH668<|wXvF|NXc z0Z6#}u5J5PkSs+u(+Jnn{L>UhBMX9fJPdRY_b&=l(^7-yyMTG2(cod);#q=l^*m_< zKZu+0a2t%T2o&i>*;k(tu{;|&T-5jn7`z2>1}y|;U>QXfTBPGiRq;^;PG&Q3O0-sn zx@jgNvd94zRcb%MG{x3ArV3)pjwX(rV$m_xql}u1h54BqH;YrA>-)u-TD=iaLh93p z7%YBtdund(#x!lznhT3(d36^~QCzhSekqE>T@>5=QuK1&^`faGl}08ae#mGlh`fS` zE+T*yZWaOUh$wEw$7`+;XaQ3~ENm>A-l`R3g$dq0AfOm&AxKkcBGe?zi2O{(X66go zS=hXi+q{(9+ifm7D@FSY2wMGF8w{@VEFDHT$n$J5>}~ZJd}?|%Psfz(Z@tOr++&D6 z+NsO19KyPcR*v*#J2B3gL^g>18uKBceu?qmRS%gF!>Lorhd0tlJv8 zbvj0D%fq9C?Z`fg?jc>H{ROvGxCJ9-F@y=169S}iGLa-{oyEKXw4konGy_{|d)dz- z|5fVHACEY-Ql$aA`b^ad%u3M@$`xnjY@)^Yooe|6{>iMJg_mw0qh2$smJeaD46fDv zUl4}PXy;E2*n?T+BDJ62^EU@_1tXTlD0VuV3xyK?CbOyKi?}}wa>pJ}U IKdx@9re5s<^8f$< literal 3176 zcmV-u443l&05|-2ob6ldcN5nUzkY*&kOv_luP%^K2^1mA7B(20haDcp)CSu?D_pUb zcI^d8tL(098E^wl(j+bY*3(b@OZrdrTmOuH?d$ZkGxyG2-Mv}~)02>MQg6A54`BubF2=}B^Wzkn>a2S>Sp8}Zp3Fd zLD`1UEl>_X-35a}y|0`4k(fE$1ZAY6X8OCC>EThZA?hZC3|FAS*FXfX>k9O6CzfCw z2MnN6m0e^Fc(!3KXkw5R**F`6r@Eqti=TwqJAm4NpnITuKjQv%?t=$Z6R>+o@4RB; zRr&A%Tj61U0JBF!4Nxyf{OBXqy>UJyV1{*`Gg!uPOU?03X{4fa18*aIr~dwF(Y zHsc57%xE5S1R~O>46=_8f_K$)YC@l}x8Obw_Z7IW!EM9+8182bQ@4-fhtM`W?StRL zWKYsZXf8;jy$?dVkK2BQWN(p7>K-S0fUs8->=lyrlI)ryyGF7;k}VPL3dojd>;X;> zg!B*-+fd~lrC-VGA>Mg~*Gs%vh1W;Cd4<Bp-FX3NhtxYmP^lQXJ`2m{CAkha& zHbnS?OyoH7-URw>@(r&OL?0p=_1_`vpdy!fE9oONKS>{BA}{3pjw^Vy^RY00PSPip z@sZ}6l|4B(LE~Q`eMw&<`T&f2o#Cm}4`-n8v7h3$Ky&URKNrc*9zOp)Jg-nk;^eQq z7nK;^BL9|X4oKftd`9dYCUP9{KO@oY0e8uoS%{W6wINQwGL&p z@ps@15El2qZe^?kJmyjQeT_b>(I07aN~3ccJ*LrTHTr@^U()Cs8f|Ixry9LZ^d!)@ zSMmJVM>MX_>rCv!+YlARy+Ih{PeH_X6Ym1ZF}CkAu@4WC4P3wXh>!R;iI(^u5&i=O zZxA2x?-MQYM+tvK!GB16#2+SF;(tu|V+uY=e8hi5w8WoaEUZ})pC1EEDFgg82pUWgZn73wtq% zxkr2%A5)1>fo$9(|89_6>aH+xen`5+#Q7rQQzqVu5+CIK1N@VI&XYc#75Kty^EeFg zvt*5Us}v`k*YC-8h2#(T+y^)-`Wuh+4fqj(!ig-_zxb`Y@{G5q%ejX^qe?dHX?oc8dp6_ zzast(^8ahH!xY{(ifzgJ4e@&UyoR`6za{-|Nd6VY=rPIu4Hm{l$JtNsHu5c!+R(wN zqwALEJ8sPw&Sn#J&nh{bT60#{>V{o$&0wO9?bLvo@B^<=3XG+iW4m7UV#BsAFYzd0 zz*RMaQDfb)Hs(F|zEui9^|~2&PIH2b*R9fsv0|1Uta@&vR-Se%t|ugXK%-bU%UK2L zubE}1wi=5YRvDgUSHy5j^?3e_yHOJoaKdo>o1sKEoSR5&ftL;8UeryaI6kJxL{xmU zTCZ4MZpJ9N5Y$Dh88kc#VC$y03DZYka>hFFr(M@8PbBOL45bJmWLIl`VAe|3g7A1k z)17roW@X;>HC-|3PJiYCLL zXEu!!MmCdA!ynnSF`UUpd}_vMG`nh`do(!cR-I;2I-I5mrH##0+x(*{p-X8Q1zpK+ z8-gsPBlglpGfwS76}D&q%F@j7m_+0I$u^Ra>@ud%_Y@b3q-hyn^}v`_3oe;uizWtJ zDx>b-v=QY9AH#ggNGI`%&h_|Y#J+%SsbQ>@VNlyMOF`0yq%ONbax=vyffJ zT!-D7ltI=G-gLN)!R?3K?~!EOEK(^2x&cFNB@$X?X|nJd+}o-wx$I80Xvuc!#7>>q zsS`VO;{Ui#{GnAR2L9Em6ZxGwv7I{M)Z$Bo;Kx;mP(v#W!0%cU6nVraw-Jb;Y`ztE z06Q4`U#i1SZP=*|JGJ5atqtMMeo18kziZ`MWnoXUv?310=n;7aPTf_<4=gXal9k7Z z=WZ0M=6#qe_kXlGitApCD-~b>67GR(+rAYfOOeeq!nHL2G=BNiVoubX?E3e zqv7*$Mu&A!)F_9kxvs%abpi9!OM{1d0V^27)hgBoei%37TpNrpGo1X3vg}q0@@K# z-iiMz<3ah(_Ghr&T#W01m!F_@ZojaSn@1)TmNZIZUr88oI5}a;5Ox*3hl88?h~`P6ykO zeH7h8x<=dkdV8_yFi5L9%fz7bUNBeSnr`D-WD-;?& zw6PVpR1><2`L>OufQM6foSH#IrG0xS8o3S{>fTV`BXMxGzf!RI&})oH6>3B)V&W+& z>Gg$Yg@8y38Q?qTG zpTk_eHjBOw11@S*+_$lm-u@AETc5|2lJAO2kEMQqA3*fIO#5ag{>2?$G5-Qb>kYbM O8PU29zy1q$U~4*L+{nOe82-=z3S>Ej4gK2}JL2CjR-pu^wu`{!? zE5<^ImxTP__Xoli9nllMu;IHQ9I+xi(S+}|sEaPVABhs+vha-lgFYhW^J5H^$x!B} z8mf??>`ygRB|~FrhR%xv0QbP0503}NUIg_SrMU>aYQ+RI%{JlZ;$J2~lju=@5?>4;Q>Q5++i8K>q@LUjwVk36_sYye% zWq>!pV_U2RS(j?51+qYGDRu2XqJiU##H~HGdEX9<^uz;DZov{9P!5|0)l*w`BrvfF zU>DReZTsT3=)-#pOm#sz4y`*QYVh`i=}o|s2iGp3jv#N?+|M-UE3gh9_%4)0h_j@3 zi`h7@UM`E>VA0PZZ)m6w>dl~z?I0xC{HXeJ+!}Ha;X#o460K;N(jWOug0*O#HV5s# zmZW$oR`E`-rB$LglD)c#6*>pcR+3`4vNHL2lmz{EKO^+5jE>WHlSMI^8J(Iy=vi?F zf|s9HVV9utSx~|6ua?)Bi#@+ttj%B z&wU|lh~?O(RX>KO4v&q#z!K_T7ILp5eU9i1(dUWI5`BT_v4GBqBIzyyr$}p3U8;B^ z#2aC}QQ~D7FGIX6*{%(2XM=Y^ei5(e30gbnO)>v9@{7D%j5kWWWyZ@8Z;kP?#M@xJ zG2(48-Z=3dQJ${B_Z5mm(eE>Qj`FDJMT5Ri^a#<*THdokj7XoMTw#6Bk!;(j=_8`Y z3Hz8~9~Fm~3#5 znV>Zwt$GA`vqZm4JVl=~=<^1Bf#^?xM&EMB{Qe6?zd<>E1L#jFRzY~Ar%C@3&{rw` z>0sUCL6536U8M)({*3Zhq&Sc+5fA;8$&ZQ)=?eM9JXOhNCh+r8&`+2X#aB<6zR~9l z<-A5dk-kPelwYTJmD|tBf0gh^&k+yhcgX()#dME+DSKa${2u8ey+}NiFOe-JNBTai z4dRy>ewAe7Bu9FUc&~%k2ZVb_ItqtzZWB+{{1Nkm_{U6+cI$@RCiykkO}IWaw2}8W z;EWL#`!h#5nWKLGg^)d|=vRd7NkzXZWKSykH6eTQYp{xIc#~`h#=A(o5yqP&-YDa} zMZ65-y-hK2d+!jB+q*_gyB-)7svn*sm~If#RH^I6fp9?wwD_=f`9N zvGWj7j$~g#thm>12)X|%RD0C@CGiz~Q^`*j*#pgQCKIp92e%C#o4aA2|qiXHijput^uit4dcx|sMC9Sq+ z`&RwHZk9Ns>$KX^%;rHn|BiRmkrKD#TW;^cKw=s$&*n~NbGg0@TMyr=&(uI>`w;7H z-*+(58d&W4cBkR2cul8W?|MfN+b~FZIHWQhQZ*n|>%i-|a#e?R_r&e&A-iH7ZaBva zp4V*}3Kh#A2y}&IuVJ^>ydGDONm5bVYrBx_RvTDM73#V~fc2+#6S#@XAbHs^BE1Z( ztRC16*FQ;)V*rS?qE$L~=($Y`+c#g}t*9l|nhThDj5QyvZDHDqmy{DFl|)IkP>}t% z*RHQo>A-&;`m7kYKdevmSPQ@iEUUUtTjgSjYz~SJ7Q-?J5>;K0D9z&W32l&;mFG3K zuFP2_Fd7JD(lqPE6R-kat*e|TZJkPYMn?cX+5;MpYRZ6vDoY$ID+9@vJk8~dDRnFc zA3mijFQ(LsDfMDXy_ixzk16$MHl?nIQ)=dadP=#Ss@QewAnn}|o;!z(fT=m6B`9B{iqays}4nAks8oP4i>D%xo z?Cd?a=R4i}Zb>xoodH5+^+T5%G|Ud!slMA)pPuOL)9SAs|H%e^f44_ z1#M~o9w(9sDjr2(d{7zinG`TiFB4uoDTD(J;e4n?z`u)&xEz6D#5nz6c-y|)piJ_H zpEX2rGjIr^JQPtGim2)cJ{vh-8<4udPvEmz$puE+>fuG_WqkPI2GUGNXJ)MDc&Rxx z>DXOgTYB)YzR>l0z4}t;pzqTzG13JcuyJ>5VRiMv9e$#Q>0y8}1H=`cK`ZIdGJ{sr zp%n(Lr9-O>Iui?3`Degud|w!uX0YpVuwdYZm>Y8M#1vq)?;90hjTtRL$AdlXbPqf@ zAF)OWT^7xEtYUOfN0OhUr%#l)GO+!Un0O~?9t z-|_8sz2`UE?(TdpR){K_VZ=;wj;{>Gmo4IfEkWL$FeHKT^+nB>^&3D{t0bKs4FDiV%R=QwOv`Ic8j0~4UA2Jz0$wAJte zqsC_a2rnvtlz)2%g$#dzQKs>kv%Wo@)i?I=+gi*~%r9Os2X4B!k}e+H+`PyE@h|;y z6S|1|`NlI&6oBbRu4f!2%#Lx7(~jVT-*Yr~>^B{Q&o6Xd{29gk=_j}se>yR|c0PGA u$C9xY?O^icd4vbjSkP4T>yPmZ(BL0_3i_wP#;FyNE1ro9KK}&kHto&Lf?lEk literal 2892 zcmV-S3$ye905yMjob6kCZyU!EUx|7+wCgxdVmpcBoGmAz5}Dyk@keu{pNK7gW~xt-W(DF9CgVgVF<@YcWt!ZVbnbS@V1 zT?p0#|DXuZu{32Tro1Lz!0$%L-|lCBEX~M;n2}}hUV~q_`a_Ci{Kv(y3K>8uN*@|| zE6vClJg3E;cw|jtYUWXG5#V+3*b*yY>7-g}l^sxfkeWc5zSIKRjMx&Gx|Kc*jdUSx zu4uv%Tu|0im%4#2Sz@qPAa(l;g^{cS*n=oA`#a*6=)vzM80>^Ks)}h*fnU2!52s5G zLht~!59!B^_EKBJQW!`Fr~|+rC%v1@#wqpVg4hak_X^UFhI*jh2-~3*h9oy4s-Cc| zAqx@ih7~N(iWY^eV(fDc^2Lj7`dAt4qewoUCj01EO1j?P-p`X1&s!C5ha*fCvytr8 zOKhf-@VrP;j8;}6AFU+lfBG4sZ)J3hz8frxKV^m|#u0j49D^mu&pWW8QTaHi;P<`7 zwZ(ilXyhx?SZY{Urtjcwai;HNr{>|h!&2hnvC~e&gGzJo+=u6(kbQzB-w?8%&)})T zQ-h~Y0p0_PXy<~E;|1xHL}!RTMf3>Kr->d7>5Rye?tS3oX>DppDBck9h8S;{cp1ja z5O0KRSNgU`!ry}YB3{wslmpJ2VE!xQ7kM`sZ9tqI;knXuoKtSf-M+@C)N{;5iHU zaf%Q1&%vL^D29;`GZNYvr}ZMO`VM)sM4up@qE8z1DT6*u^p`-R@Aty&|K=M-zfbje zALuVBRzY~Ar%3-i&{rt_sc_w6Vc)AYU7-i#{)+OKr#O%<5D)zn$&ZQ)=@R+HJeA32 zCiHW>-+PL$zSUEtZ}dG)xv!9Kq-ThS@~iY)<@jrgqfB_D=ZJ^$+Z4w*#deo`DSP)w zewXx-zE3=qKOkF5j`TxTBg8K<{4&YLNRIRh@!kWktAu+@ItqtzZV*q^{wec=_-9Ox zcB_WG#^gxX4Sa*}Gq6K({p#RA%-?`BN?7dUEahyD`u=A^_O7De7P5C0{f>~mtLS%y z?A`CcDz5Pi*$|9(mUu&qcaC_&jQ0WYGK}{j#lY=-L_BWqJn^`_kBP_aU7$5^d!G=G z+jEG=?Oh}uw|9wh!0k;CkK4OUJZ|q(;>oMic$m-6D2Hb$M;|cR=ai3+XuTgZS&r8B z3B`Vq$tEez35w%WlHuO^f_#2XHV``x5oJmCEyRj@@tTnPvqZH=-Rs0x^bH~V>Gz<6 z^eka+5T+d3mit!a;2Yxc{M{rT&)>Ji8)oaeMfx{Mjx+OjfJfN^`M*VLzH zHQpiI9L_eotNU}Ma+usQ}7ybw_;7nK}9?tW> z0)CzJ{{eWEJ%R^$xKAHZ?6}8&DdfDGVz!?U|F@K*Ur`R8Fum`Y9>(`Q;r?^4Z}}Z5X}0`Y;8b^OjRJ#qU(_02d)taDaz@8( zwxqlDT|57_zu%S;uN^pEceO7u4VPxKuV=H_o?M>3Os6_s0a-18HEs0*7sIT8#coh* z*WD$*;kK$Be;?K`2vQsjDGi2{4M^G9^}C*2)n2W02+2cs$=Q449xV8Nr(r0RoS-kz z6&C$^t+nEJxq?iRisEj|gJd^bz+$RU{|5wEljTcX2FZ(t5$UCGWqG$&_kzRZIQjsq z6|K@~epdaUCQ(U_B1Cr2_Zkjvm)s<8eXT&wT*%Dfnsf0UnVfR$l47Eylqe}rPRc&s zZdF&P1;Bp}`ZaIckIol*tdqb9Evx>Sa*Fu^+3YtDSd7{wl&CHNiPFp;9MVQ>Iyv4e z&c!*W07gThOqymre+X8Cf zA6{p(#{4`G{STj?rK99XN*sfPw~atEJY)8uX42e?dDI6USB(!li{YqkW0sF5 z+|h)4lLeW= zGbv!4ye2$9qX`8@zp9Ed0lM3i*| zpX;2j4R>7-B=Fgs=K^Eb=;6g@y*>PB|7xb=^WN&&E;S~;-Eg#tt(Mu$r<=*z%7fL% z)rF4V?N%SOcY6WtTqE1iK#%S`Sy*0PytlW{5EmJS$oW8-D`CVg4=sg)viMQ zlgqpgDM3#DuwROjWW^L&DMglWHQMR5R2bTwrwOJ|rrDWFJcK9zD|e*kz)Mo||MQj< z-;?qd9UH0+C~vz}4}Yt^vJA#Kj?3FlT&rSnkYX`Gu{21rl%QB1q)2;uH|kIhkIrxe z1yQeYkluG%TiKmQ1&qycyMo?7=1{lmXsr|*-gcd+XTt7^CX8fQx=32_LqdW$C$H~) z?a~&*@~zD7NO2t7*z9T)$Hn(!{8p5#6=gSm8M0{UTh+J%C3|57v0RP9znQo}uhTXX z{hI&12mb*C`*(@s#R;!nZ}l3k^YxA!)LPYU&}eyE^Vx{s^>!Lx;UD=I^Vw{#i|J|C zcHAzk&~-ws+0=JJ{j($%$b5lFUV;#uAMI9VJ6d1M?!}4xpz;cq&ew#6HMF;bH2}4bri{e{)V?zx{1jW+k zwG-~>8yo$%*|~xlMi8YoLKV$0EQb=umj>dC8ooRbU()cEf%vk9kEJm-`8j&VsG~XY zIreG-Haveg@LB?p^+p7~KB+2-r+|A9Z3Ou%rz#9)Kv5kgo10Tk-46{LbK^6-$^lZo zk_oFGy~0zb@tJdecs;Ann8Ej1%N2xQO)VFVba5$N+`rrUu`}*Rz50t>*xvv7#-Ru> z{i@*`ry;Xr+;p|8N5Tt1%^iCwXz=-!*S8BIfb8hDa)n+ diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index f3c0a33ce..d05c72fa4 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -194,9 +194,9 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) // Create instance buffer for per-draw instance data if (!scene.instanceBuffer) { - // Allocate buffer for per-instance data (model matrix + shading + opacity + flipFlag + rotation) - // mat4 (16 floats) + vec4 (4 floats) + float (opacity) + float (flipFlag) + float (rotation) = 23 floats - scene.instanceBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, 23 * sizeof(float))); + // Allocate buffer for per-instance data (model matrix + shading + opacity + flipFlag) + // mat4 (16 floats) + vec4 (4 floats) + float (opacity) + float (flipFlag) = 22 floats + scene.instanceBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, 22 * sizeof(float))); scene.instanceBuffer->create(); } @@ -333,7 +333,7 @@ void YACReaderFlow3D::ensurePipeline() QRhiVertexInputLayout inputLayout; inputLayout.setBindings({ { 5 * sizeof(float) }, // Per-vertex data (position + texCoord) - { 23 * sizeof(float), QRhiVertexInputBinding::PerInstance } // Per-instance data + { 22 * sizeof(float), QRhiVertexInputBinding::PerInstance } // Per-instance data }); inputLayout.setAttributes({ // Per-vertex attributes @@ -348,7 +348,7 @@ void YACReaderFlow3D::ensurePipeline() { 1, 6, QRhiVertexInputAttribute::Float4, 16 * sizeof(float) }, // shading vec4 { 1, 7, QRhiVertexInputAttribute::Float, 20 * sizeof(float) }, // opacity { 1, 8, QRhiVertexInputAttribute::Float, 21 * sizeof(float) }, // flipFlag (1.0 = reflection) - { 1, 9, QRhiVertexInputAttribute::Float, 22 * sizeof(float) } // rotation + // rotation removed }); scene.pipeline->setVertexInputLayout(inputLayout); @@ -409,7 +409,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) bool isReflection; bool isMark; QRhiTexture *texture; - float instanceData[23]; + float instanceData[22]; UniformData uniformData; }; @@ -483,7 +483,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) } // Ensure instance buffer is large enough for all draws - auto requiredInstanceSize = static_cast(draws.size() * 23 * sizeof(float)); + auto requiredInstanceSize = static_cast(draws.size() * 22 * sizeof(float)); if (!scene.instanceBuffer || scene.instanceBuffer->size() < requiredInstanceSize) { scene.instanceBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, requiredInstanceSize)); if (!scene.instanceBuffer->create()) { @@ -515,8 +515,8 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) // Update instance buffer with all instance data for (int i = 0; i < draws.size(); ++i) { - int offset = i * 23 * sizeof(float); - batch->updateDynamicBuffer(scene.instanceBuffer.get(), offset, 23 * sizeof(float), draws[i].instanceData); + int offset = i * 22 * sizeof(float); + batch->updateDynamicBuffer(scene.instanceBuffer.get(), offset, 22 * sizeof(float), draws[i].instanceData); } // === PHASE 2: RENDER (DURING PASS) === @@ -602,9 +602,6 @@ void YACReaderFlow3D::prepareDrawData(const YACReader3DImageRHI &image, bool isR outInstanceData[i] = matData[i]; } - // Store per-instance rotation in the instance data (new slot at index 22) - outInstanceData[22] = image.current.rot; - // Prepare uniform data (copy float data into POD arrays) const float *vp = viewProjectionMatrix.constData(); for (int m = 0; m < 16; ++m) @@ -615,15 +612,12 @@ void YACReaderFlow3D::prepareDrawData(const YACReader3DImageRHI &image, bool isR outUniformData.backgroundColor[2] = backgroundColor.blueF(); outUniformData._pad0 = 0.0f; - outUniformData.shadingColor[0] = shadingColor.redF(); - outUniformData.shadingColor[1] = shadingColor.greenF(); - outUniformData.shadingColor[2] = shadingColor.blueF(); - outUniformData._pad1 = 0.0f; + // shadingColor removed from uniform buffer; keep CPU-side shadingColor member intact outUniformData.reflectionUp = reflectionUp; outUniformData.reflectionDown = reflectionBottom; outUniformData.isReflection = isReflection ? 1.0f : 0.0f; - outUniformData._pad2 = 0.0f; + outUniformData._pad1 = 0.0f; } void YACReaderFlow3D::executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture *texture, @@ -653,7 +647,7 @@ void YACReaderFlow3D::executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture * // Bind vertex buffers with offset into instance buffer const QRhiCommandBuffer::VertexInput vbufBindings[] = { { scene.vertexBuffer.get(), 0 }, - { scene.instanceBuffer.get(), quint32(uniformSlot * 23 * sizeof(float)) } + { scene.instanceBuffer.get(), quint32(uniformSlot * 22 * sizeof(float)) } }; cb->setVertexInput(0, 2, vbufBindings); @@ -1168,24 +1162,6 @@ void YACReaderFlow3D::setFlowRightToLeft(bool b) void YACReaderFlow3D::setBackgroundColor(const QColor &color) { backgroundColor = color; - - // Auto-calculate shadingColor based on background brightness - qreal luminance = (backgroundColor.redF() * 0.299 + - backgroundColor.greenF() * 0.587 + - backgroundColor.blueF() * 0.114); - - if (luminance < 0.5) { - // Dark background - shade towards white - shadingColor = QColor(255, 255, 255); - shadingTop = 0.8f; - shadingBottom = 0.02f; - } else { - // Light background - shade towards black - shadingColor = QColor(0, 0, 0); - shadingTop = 0.95f; - shadingBottom = 0.3f; - } - update(); } diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index 44e5e60d9..15a61530f 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -115,8 +115,7 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement float viewProjectionMatrix[16]; // column-major 4x4 float backgroundColor[3]; float _pad0; // pad to vec4 - float shadingColor[3]; - float _pad1; // pad to vec4 + float reflectionUp; float reflectionDown; float isReflection; From d4fbbd560391431cfddfb9aa7e306d82678b0dd8 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 19 Jan 2026 22:55:08 +0100 Subject: [PATCH 018/187] More cleaning --- common/rhi/yacreader_flow_rhi.cpp | 9 --------- common/rhi/yacreader_flow_rhi.h | 5 +---- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index d05c72fa4..f6a5e24bb 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -23,7 +23,6 @@ YACReaderFlow3D::YACReaderFlow3D(QWidget *parent, struct Preset p) hasBeenInitialized(false), backgroundColor(Qt::black), textColor(Qt::white), - shadingColor(Qt::black), flowRightToLeft(false) { updateCount = 0; @@ -612,8 +611,6 @@ void YACReaderFlow3D::prepareDrawData(const YACReader3DImageRHI &image, bool isR outUniformData.backgroundColor[2] = backgroundColor.blueF(); outUniformData._pad0 = 0.0f; - // shadingColor removed from uniform buffer; keep CPU-side shadingColor member intact - outUniformData.reflectionUp = reflectionUp; outUniformData.reflectionDown = reflectionBottom; outUniformData.isReflection = isReflection ? 1.0f : 0.0f; @@ -1176,12 +1173,6 @@ void YACReaderFlow3D::setTextColor(const QColor &color) update(); } -void YACReaderFlow3D::setShadingColor(const QColor &color) -{ - shadingColor = color; - update(); -} - // Event handlers void YACReaderFlow3D::wheelEvent(QWheelEvent *event) { diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index 15a61530f..387366d7a 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -115,11 +115,10 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement float viewProjectionMatrix[16]; // column-major 4x4 float backgroundColor[3]; float _pad0; // pad to vec4 - float reflectionUp; float reflectionDown; float isReflection; - float _pad2; + float _pad1; }; // Pending texture uploads (for async image loading) @@ -215,7 +214,6 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement /*** Theme Colors ***/ QColor backgroundColor; QColor textColor; - QColor shadingColor; /*** System info ***/ float viewRotate; @@ -295,7 +293,6 @@ public slots: // Theme color setters void setBackgroundColor(const QColor &color); void setTextColor(const QColor &color); - void setShadingColor(const QColor &color); virtual void updateImageData() = 0; From d913fa137ed43b44d50b6ae8552a9f8bb62f1513 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Tue, 20 Jan 2026 08:09:01 +0100 Subject: [PATCH 019/187] Add a CPU based frustum culling that's good enough for flow use case --- common/rhi/yacreader_flow_rhi.cpp | 70 ++++++++++++++++++++++++++++++- common/rhi/yacreader_flow_rhi.h | 5 +++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index f6a5e24bb..b5bc4a92a 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -412,6 +412,65 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) UniformData uniformData; }; + auto isVisibleInNDC = [&](const YACReader3DImageRHI &image, bool isReflection, bool isMark) { + QMatrix4x4 modelMatrix; + modelMatrix.translate(image.current.x, image.current.y, image.current.z); + modelMatrix.rotate(image.current.rot, 0, 1, 0); + + if (isMark) { + float markWidth = 0.15f; + float markHeight = 0.2f; + float markCenterX = image.width / 2.0f - 0.125f; + float markCenterY = -0.588f + image.height; + modelMatrix.translate(markCenterX, markCenterY, 0.001f); + modelMatrix.scale(markWidth, markHeight, 1.0f); + } else { + if (isReflection) { + modelMatrix.translate(0.0f, -0.5f - image.height / 2.0f, 0.0f); + } else { + modelMatrix.translate(0.0f, -0.5f + image.height / 2.0f, 0.0f); + } + modelMatrix.scale(image.width, image.height, 1.0f); + } + + QVector4D center = modelMatrix * QVector4D(0, 0, 0, 1); + QVector4D clip = viewProjectionMatrix * center; + if (clip.w() == 0.0f) + return true; // be conservative + + // Project a world-space edge to estimate a projected radius in NDC. + // Use the modelMatrix's X axis (includes rotation+scale) as direction, + // normalize it and multiply by cached boundingRadius (world units). + QVector4D rightV = modelMatrix * QVector4D(1, 0, 0, 0); // direction (w=0) + QVector3D right3(rightV.x(), rightV.y(), rightV.z()); + float len = right3.length(); + if (len == 0.0f) + return true; // conservative + right3 /= len; + + float worldRadius = image.boundingRadius; + if (isMark) { + float markWidth = 0.15f; + float markHeight = 0.2f; + worldRadius = 0.5f * std::sqrt(markWidth * markWidth + markHeight * markHeight); + } + + QVector4D edgeWorld = center + QVector4D(right3 * worldRadius, 0.0f); + QVector4D edgeClip = viewProjectionMatrix * edgeWorld; + if (edgeClip.w() == 0.0f) + return true; + + QVector2D nc(clip.x() / clip.w(), clip.y() / clip.w()); + QVector2D ne(edgeClip.x() / edgeClip.w(), edgeClip.y() / edgeClip.w()); + float projectedRadius = (ne - nc).length(); + + const float margin = isMark ? 0.6f : 1.2f; + if (nc.x() + projectedRadius < -1.0f - margin || nc.x() - projectedRadius > 1.0f + margin || + nc.y() + projectedRadius < -1.0f - margin || nc.y() - projectedRadius > 1.0f + margin) + return false; + return true; + }; + // Collect all draws we need to make // Important: OpenGL draws reflections FIRST, then covers+marks (for correct depth sorting) QVector draws; @@ -421,11 +480,15 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) if (idx < 0 || idx >= images.size() || !images[idx].texture) continue; + if (!isVisibleInNDC(images[idx], true, false)) + continue; + DrawInfo reflDraw; reflDraw.imageIndex = idx; reflDraw.isReflection = true; reflDraw.isMark = false; reflDraw.texture = images[idx].texture; + prepareDrawData(images[idx], true, false, viewProjectionMatrix, reflDraw.instanceData, reflDraw.uniformData); draws.append(reflDraw); } @@ -435,7 +498,10 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) if (idx < 0 || idx >= images.size() || !images[idx].texture) continue; - // Add cover draw + if (!isVisibleInNDC(images[idx], false, false)) { + continue; + } + DrawInfo coverDraw; coverDraw.imageIndex = idx; coverDraw.isReflection = false; @@ -454,6 +520,8 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) if (showMarks && loaded[idx] && marks[idx] != Unread) { QRhiTexture *markTex = (marks[idx] == Read) ? scene.markTexture.get() : scene.readingTexture.get(); if (markTex) { + if (!isVisibleInNDC(images[idx], false, true)) + continue; DrawInfo markDraw; markDraw.imageIndex = idx; markDraw.isReflection = false; diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index 387366d7a..08081d973 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -38,6 +38,9 @@ struct YACReader3DImageRHI { float width; float height; + // Precomputed bounding sphere radius (world-space) for fast culling + float boundingRadius; + int index; YACReader3DVector current; @@ -245,6 +248,8 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement void prepareDrawData(const YACReader3DImageRHI &image, bool isReflection, bool isMark, const QMatrix4x4 &viewProjectionMatrix, float *outInstanceData, UniformData &outUniformData); + QMatrix4x4 buildModelMatrix(const YACReader3DImageRHI &image, bool isReflection, bool isMark); + QMatrix4x4 buildModelMatrixNoScale(const YACReader3DImageRHI &image, bool isReflection, bool isMark); void executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture *texture, const float *instanceData, int uniformSlot); From f2b3a696a9a1826246b8fc36268bec43d52e375e Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Tue, 20 Jan 2026 08:19:09 +0100 Subject: [PATCH 020/187] Add performance measurement --- common/rhi/yacreader_flow_rhi.cpp | 58 +++++++++++++++++++++++++++++++ common/rhi/yacreader_flow_rhi.h | 12 +++++++ 2 files changed, 70 insertions(+) diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index b5bc4a92a..e5320f4eb 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -1,5 +1,8 @@ #include "yacreader_flow_rhi.h" #include +#if defined(YACREADER_RHI_PERF) +#include +#endif #include /*** Preset Configurations ***/ @@ -56,6 +59,16 @@ YACReaderFlow3D::YACReaderFlow3D(QWidget *parent, struct Preset p) indexLabel->setAttribute(Qt::WA_TransparentForMouseEvents); indexLabel->setAutoFillBackground(false); updateIndexLabelStyle(); + +#if defined(YACREADER_RHI_PERF) + // Create performance label (shows averaged render time) + perfLabel = new QLabel(this); + perfLabel->setAttribute(Qt::WA_TransparentForMouseEvents); + perfLabel->setAutoFillBackground(false); + perfLabel->setText(QString()); + perfLabel->hide(); + // Style will be applied by updateIndexLabelStyle() +#endif } YACReaderFlow3D::~YACReaderFlow3D() @@ -475,6 +488,12 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) // Important: OpenGL draws reflections FIRST, then covers+marks (for correct depth sorting) QVector draws; + // Start timing for this render call (measures CPU time spent in this function) +#if defined(YACREADER_RHI_PERF) + QElapsedTimer perfTimer; + perfTimer.start(); +#endif + // Phase 1: Add all reflections for (int idx : drawOrder) { if (idx < 0 || idx >= images.size() || !images[idx].texture) @@ -599,6 +618,33 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) } cb->endPass(); + + // Measure elapsed CPU time for render and update perf label periodically +#if defined(YACREADER_RHI_PERF) + qint64 ns = perfTimer.nsecsElapsed(); + double ms = double(ns) / 1e6; + + perfAccumMs += ms; + perfAccumCount += 1; + perfFrameCounter += 1; + + if (perfFrameCounter >= perfUpdateEvery) { + // compute average + if (perfAccumCount > 0) + lastRenderMs = perfAccumMs / perfAccumCount; + + // reset accumulators + perfAccumMs = 0.0; + perfAccumCount = 0; + perfFrameCounter = 0; + + if (perfLabel) { + perfLabel->setText(QString("R: %1 ms").arg(lastRenderMs, 0, 'f', 2)); + perfLabel->adjustSize(); + perfLabel->show(); + } + } +#endif } void YACReaderFlow3D::prepareDrawData(const YACReader3DImageRHI &image, bool isReflection, bool isMark, @@ -1394,6 +1440,18 @@ void YACReaderFlow3D::updateIndexLabelStyle() indexLabel->move(10, 10); indexLabel->adjustSize(); + + // Position and style performance label below index label +#if defined(YACREADER_RHI_PERF) + if (perfLabel) { + perfLabel->setFont(font); + QPalette p = perfLabel->palette(); + p.setColor(QPalette::WindowText, textColor); + perfLabel->setPalette(p); + perfLabel->move(10, 10 + indexLabel->height() + 4); + perfLabel->adjustSize(); + } +#endif } QSize YACReaderFlow3D::minimumSizeHint() const diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index 08081d973..6f850a8bc 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -186,6 +186,18 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement QLabel *indexLabel = nullptr; IndexLabelState indexLabelState; +#if defined(YACREADER_RHI_PERF) + // Performance label (shows averaged render time) + QLabel *perfLabel = nullptr; + + // Performance measurement state + double perfAccumMs = 0.0; // accumulated ms over samples + int perfAccumCount = 0; // number of samples accumulated + int perfFrameCounter = 0; // frames since last label update + int perfUpdateEvery = 30; // update label every N frames (reduce overhead) + double lastRenderMs = 0.0; // last averaged render time in ms +#endif + void timerEvent(QTimerEvent *) override; int numObjects; From 8c04235987bab41a29d810ce4f0d3250457649e3 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Tue, 20 Jan 2026 08:35:49 +0100 Subject: [PATCH 021/187] Remove comments --- common/rhi/yacreader_flow_rhi.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index e5320f4eb..1391e3ea1 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -5,10 +5,6 @@ #endif #include -/*** Preset Configurations ***/ -// Note: The preset configurations are already defined in yacreader_flow_gl.cpp -// We just reference them here as extern to avoid duplicate symbols - int YACReaderFlow3D::updateInterval = 16; static QShader getShader(const QString &name) @@ -766,10 +762,6 @@ void YACReaderFlow3D::executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture * cb->draw(6); } -// Note: The old drawCover() and drawMark() methods have been removed. -// Rendering now uses prepareDrawData() and executeDrawWithOffset() which properly -// batch all resource updates before the render pass begins, following Qt RHI best practices. - void YACReaderFlow3D::releaseResources() { scene.reset(); From 283475bee21ad115ca428064dd82623d4a805ed8 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 23 Jan 2026 19:27:15 +0100 Subject: [PATCH 022/187] Remove software and opengl flow implementations This simplifies the code base A LOT. --- YACReader/YACReader.pro | 63 +- YACReader/goto_flow.cpp | 297 --- YACReader/goto_flow.h | 99 - YACReader/goto_flow_gl.cpp | 164 -- YACReader/goto_flow_gl.h | 46 - YACReader/goto_flow_widget.cpp | 172 +- YACReader/goto_flow_widget.h | 40 +- YACReader/mouse_handler.cpp | 8 +- YACReader/options_dialog.cpp | 34 +- YACReader/viewer.cpp | 36 +- YACReaderLibrary/YACReaderLibrary.pro | 64 +- YACReaderLibrary/classic_comics_view.cpp | 9 +- YACReaderLibrary/comic_flow.cpp | 159 -- YACReaderLibrary/comic_flow.h | 48 - YACReaderLibrary/comic_flow_widget.cpp | 264 +-- YACReaderLibrary/comic_flow_widget.h | 142 +- YACReaderLibrary/comics_view.cpp | 5 - YACReaderLibrary/folder_content_view.cpp | 5 - YACReaderLibrary/library_window.cpp | 26 - YACReaderLibrary/library_window.h | 1 - YACReaderLibrary/main.cpp | 38 - YACReaderLibrary/options_dialog.cpp | 20 +- .../yacreader_content_views_manager.cpp | 1 + common/gl/yacreader_flow_gl.cpp | 1999 ----------------- common/gl/yacreader_flow_gl.h | 372 --- common/opengl_checker.cpp | 74 - common/opengl_checker.h | 18 - common/pictureflow.cpp | 1410 ------------ common/pictureflow.h | 233 -- common/rhi/flow_types.cpp | 182 ++ common/rhi/flow_types.h | 75 + common/rhi/yacreader_comic_flow_rhi.cpp | 2 +- common/rhi/yacreader_flow_rhi.cpp | 10 +- common/rhi/yacreader_flow_rhi.h | 56 +- config.pri | 11 - custom_widgets/custom_widgets_yacreader.pri | 24 +- .../custom_widgets_yacreaderlibrary.pri | 18 +- custom_widgets/help_about_dialog.cpp | 3 - ...pp => yacreader_3d_flow_config_widget.cpp} | 13 +- ...et.h => yacreader_3d_flow_config_widget.h} | 12 +- custom_widgets/yacreader_flow.cpp | 17 - custom_widgets/yacreader_flow.h | 21 - .../yacreader_flow_config_widget.cpp | 52 - custom_widgets/yacreader_flow_config_widget.h | 19 - custom_widgets/yacreader_options_dialog.cpp | 139 +- custom_widgets/yacreader_options_dialog.h | 17 +- 46 files changed, 613 insertions(+), 5905 deletions(-) delete mode 100644 YACReader/goto_flow.cpp delete mode 100644 YACReader/goto_flow.h delete mode 100644 YACReader/goto_flow_gl.cpp delete mode 100644 YACReader/goto_flow_gl.h delete mode 100644 YACReaderLibrary/comic_flow.cpp delete mode 100644 YACReaderLibrary/comic_flow.h delete mode 100644 common/gl/yacreader_flow_gl.cpp delete mode 100644 common/gl/yacreader_flow_gl.h delete mode 100644 common/opengl_checker.cpp delete mode 100644 common/opengl_checker.h delete mode 100644 common/pictureflow.cpp delete mode 100644 common/pictureflow.h create mode 100644 common/rhi/flow_types.cpp create mode 100644 common/rhi/flow_types.h rename custom_widgets/{yacreader_gl_flow_config_widget.cpp => yacreader_3d_flow_config_widget.cpp} (96%) rename custom_widgets/{yacreader_gl_flow_config_widget.h => yacreader_3d_flow_config_widget.h} (79%) delete mode 100644 custom_widgets/yacreader_flow.cpp delete mode 100644 custom_widgets/yacreader_flow.h delete mode 100644 custom_widgets/yacreader_flow_config_widget.cpp delete mode 100644 custom_widgets/yacreader_flow_config_widget.h diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro index 42f781841..612112e48 100644 --- a/YACReader/YACReader.pro +++ b/YACReader/YACReader.pro @@ -24,24 +24,13 @@ SOURCES += main.cpp INCLUDEPATH += ../common \ ../custom_widgets +INCLUDEPATH += ../common/rhi -!CONFIG(no_opengl) { - INCLUDEPATH += ../common/gl - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - INCLUDEPATH += ../common/rhi - DEFINES += YACREADER_USE_RHI - } -} +HEADERS += ../common/rhi/flow_types.h +SOURCES += ../common/rhi/flow_types.cpp win32 { - LIBS += -loleaut32 -lole32 -lshell32 -luser32 - # When using RHI (Qt 6.7+), don't link OpenGL directly - QRhiWidget handles graphics APIs - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - message("RHI mode: not linking opengl32 (using QRhiWidget)") - } else { - LIBS += -lopengl32 - } - + LIBS += -loleaut32 -lole32 -lshell32 -luser32 msvc { QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL QMAKE_LFLAGS_RELEASE += /LTCG @@ -59,7 +48,7 @@ macx { QT += network widgets core multimedia svg -greaterThan(QT_MAJOR_VERSION, 5): QT += openglwidgets core5compat +greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { QT += gui-private @@ -76,7 +65,6 @@ HEADERS += ../common/comic.h \ main_window_viewer.h \ mouse_handler.h \ viewer.h \ - goto_flow.h \ options_dialog.h \ ../common/bookmarks.h \ bookmarks_dialog.h \ @@ -87,7 +75,6 @@ HEADERS += ../common/comic.h \ goto_flow_toolbar.h \ width_slider.h \ notifications_label_widget.h \ - ../common/pictureflow.h \ ../common/custom_widgets.h \ ../common/check_new_version.h \ ../common/qnaturalsorting.h \ @@ -100,20 +87,12 @@ HEADERS += ../common/comic.h \ ../common/http_worker.h \ ../common/exit_check.h \ ../common/scroll_management.h \ - ../common/opengl_checker.h \ ../common/pdf_comic.h \ ../common/global_info_provider.h \ + ../common/rhi/yacreader_flow_rhi.h \ + ../common/rhi/yacreader_comic_flow_rhi.h \ + ../common/rhi/yacreader_page_flow_rhi.h -!CONFIG(no_opengl) { - HEADERS += ../common/gl/yacreader_flow_gl.h \ - goto_flow_gl.h - - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - HEADERS += ../common/rhi/yacreader_flow_rhi.h - HEADERS += ../common/rhi/yacreader_comic_flow_rhi.h \ - ../common/rhi/yacreader_page_flow_rhi.h - } -} SOURCES += ../common/comic.cpp \ configuration.cpp \ @@ -122,7 +101,6 @@ SOURCES += ../common/comic.cpp \ main_window_viewer.cpp \ mouse_handler.cpp \ viewer.cpp \ - goto_flow.cpp \ options_dialog.cpp \ ../common/bookmarks.cpp \ bookmarks_dialog.cpp \ @@ -133,7 +111,6 @@ SOURCES += ../common/comic.cpp \ goto_flow_toolbar.cpp \ width_slider.cpp \ notifications_label_widget.cpp \ - ../common/pictureflow.cpp \ ../common/custom_widgets.cpp \ ../common/check_new_version.cpp \ ../common/qnaturalsorting.cpp \ @@ -146,23 +123,15 @@ SOURCES += ../common/comic.cpp \ ../common/yacreader_global_gui.cpp \ ../common/exit_check.cpp \ ../common/scroll_management.cpp \ - ../common/opengl_checker.cpp \ ../common/global_info_provider.cpp \ - -!CONFIG(no_opengl) { - SOURCES += ../common/gl/yacreader_flow_gl.cpp \ - goto_flow_gl.cpp - - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - SOURCES += ../common/rhi/yacreader_flow_rhi.cpp - SOURCES += ../common/rhi/yacreader_comic_flow_rhi.cpp \ - ../common/rhi/yacreader_page_flow_rhi.cpp - RESOURCES += ../common/rhi/shaders/shaders.qrc - # Make raw GLSL shader sources editable in Qt Creator - OTHER_FILES += ../common/rhi/shaders/flow.vert \ - ../common/rhi/shaders/flow.frag - } -} + ../common/rhi/yacreader_flow_rhi.cpp \ + ../common/rhi/yacreader_comic_flow_rhi.cpp \ + ../common/rhi/yacreader_page_flow_rhi.cpp + +RESOURCES += ../common/rhi/shaders/shaders.qrc +# Make raw GLSL shader sources editable in Qt Creator +OTHER_FILES += ../common/rhi/shaders/flow.vert \ + ../common/rhi/shaders/flow.frag include(../custom_widgets/custom_widgets_yacreader.pri) diff --git a/YACReader/goto_flow.cpp b/YACReader/goto_flow.cpp deleted file mode 100644 index 96e42e84f..000000000 --- a/YACReader/goto_flow.cpp +++ /dev/null @@ -1,297 +0,0 @@ -#include "goto_flow.h" -#include "configuration.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "yacreader_flow.h" - -#include "goto_flow_toolbar.h" - -GoToFlow::GoToFlow(QWidget *parent, FlowType flowType) - : GoToFlowWidget(parent), ready(false) -{ - updateTimer = new QTimer; - connect(updateTimer, &QTimer::timeout, this, &GoToFlow::updateImageData); - - worker = new PageLoader(&mutexGoToFlow); - - flow = new YACReaderFlow(this, flowType); - flow->setReflectionEffect(PictureFlow::PlainReflection); - imageSize = Configuration::getConfiguration().getGotoSlideSize(); - - flow->setSlideSize(imageSize); - connect(flow, &PictureFlow::centerIndexChanged, this, &GoToFlowWidget::setPageNumber); - connect(flow, &YACReaderFlow::selected, this, &GoToFlow::goToPage); - connect(flow, &PictureFlow::centerIndexChanged, this, &GoToFlow::preload); - connect(flow, &PictureFlow::centerIndexChangedSilent, this, &GoToFlow::preload); - - connect(toolBar, &GoToFlowToolBar::goToPage, this, &GoToFlow::goToPage); - connect(toolBar, &GoToFlowToolBar::setCenter, flow, &PictureFlow::showSlide); - - mainLayout->addWidget(flow); - toolBar->raise(); - - resize(static_cast(5 * imageSize.width()), toolBar->height() + static_cast(imageSize.height() * 1.7)); - - this->setCursor(QCursor(Qt::ArrowCursor)); -} - -GoToFlow::~GoToFlow() -{ - delete flow; - delete updateTimer; - worker->deleteLater(); -} - -void GoToFlow::keyPressEvent(QKeyEvent *event) -{ - switch (event->key()) { - case Qt::Key_Left: - case Qt::Key_Right: - case Qt::Key_Up: - QApplication::sendEvent(flow, event); - return; - default: - break; - } - - GoToFlowWidget::keyPressEvent(event); -} - -void GoToFlow::resizeEvent(QResizeEvent *event) -{ - QWidget::resizeEvent(event); - - toolBar->move(0, event->size().height() - toolBar->height()); - toolBar->setFixedWidth(width()); -} - -void GoToFlow::centerSlide(int slide) -{ - if (flow->centerIndex() != slide) { - flow->setCenterIndex(slide); - if (ready) // load images if pages are loaded. - { - // worker->reset(); //BUG FIXED : image didn't load if worker was working - preload(); - } - } -} - -void GoToFlow::setNumSlides(unsigned int slides) -{ - // numPagesLabel->setText(tr("Total pages : ")+QString::number(slides)); - // numPagesLabel->adjustSize(); - imagesReady.clear(); - imagesReady.fill(false, slides); - - rawImages.clear(); - rawImages.resize(slides); - - toolBar->setTop(slides); - - imagesLoaded.clear(); - imagesLoaded.fill(false, slides); - - imagesSetted.clear(); - imagesSetted.fill(false, slides); - - numImagesLoaded = 0; - - ready = true; - worker->reset(); - - flow->clear(); - for (unsigned int i = 0; i < slides; i++) - flow->addSlide(QImage()); - flow->setCenterIndex(0); -} - -void GoToFlow::reset() -{ - updateTimer->stop(); - /*imagesLoaded.clear(); - numImagesLoaded = 0; - imagesReady.clear(); - rawImages.clear();*/ - ready = false; -} - -void GoToFlow::setImageReady(int index, const QByteArray &image) -{ - rawImages[index] = image; - imagesReady[index] = true; - preload(); -} - -void GoToFlow::preload() -{ - if (numImagesLoaded < imagesLoaded.size()) - updateTimer->start(30); // TODO comprobar rendimiento, antes era 70 -} - -void GoToFlow::updateImageData() -{ - // can't do anything, wait for the next possibility - if (worker->busy()) - return; - - // set image of last one - int idx = worker->index(); - if (idx >= 0 && !worker->result().isNull()) { - if (!imagesSetted[idx]) { - flow->setSlide(idx, worker->result()); - imagesSetted[idx] = true; - numImagesLoaded++; - rawImages[idx].clear(); - ; // release memory - imagesLoaded[idx] = true; - } - } - - // try to load only few images on the left and right side - // i.e. all visible ones plus some extra -#define COUNT 8 - int indexes[2 * COUNT + 1]; - int center = flow->centerIndex(); - indexes[0] = center; - for (int j = 0; j < COUNT; j++) { - indexes[j * 2 + 1] = center + j + 1; - indexes[j * 2 + 2] = center - j - 1; - } - for (int c = 0; c < 2 * COUNT + 1; c++) { - int i = indexes[c]; - if ((i >= 0) && (i < flow->slideCount())) - if (!imagesLoaded[i] && imagesReady[i]) // slide(i).isNull()) - { - // schedule thumbnail generation - - worker->generate(i, flow->slideSize(), rawImages[i]); - return; - } - } - - // no need to generate anything? stop polling... - updateTimer->stop(); -} - -void GoToFlow::wheelEvent(QWheelEvent *event) -{ - if (event->angleDelta().y() < 0) - flow->showNext(); - else - flow->showPrevious(); - event->accept(); -} - -void GoToFlow::setFlowType(YACReader::FlowType flowType) -{ - flow->setFlowType(flowType); -} - -void GoToFlow::updateConfig(QSettings *settings) -{ - GoToFlowWidget::updateConfig(settings); - - imageSize = Configuration::getConfiguration().getGotoSlideSize(); - flow->setFlowType(Configuration::getConfiguration().getFlowType()); - resize(5 * imageSize.width(), toolBar->height() + imageSize.height() * 1.7); - updateSize(); -} - -void GoToFlow::setFlowRightToLeft(bool b) -{ - flow->setFlowRightToLeft(b); -} - -//----------------------------------------------------------------------------- -// PageLoader -//----------------------------------------------------------------------------- - -PageLoader::PageLoader(QMutex *m) - : QThread(), mutex(m), restart(false), working(false), idx(-1) -{ -} - -PageLoader::~PageLoader() -{ - // TODO this destructor never runs. If it is ever called, it will hang, because - // the implementation is broken due to the absolutely endless loop in run(). - mutex->lock(); - condition.wakeOne(); - mutex->unlock(); - wait(); -} - -bool PageLoader::busy() const -{ - return isRunning() ? working.load() : false; -} - -void PageLoader::generate(int index, QSize size, const QByteArray &rImage) -{ - mutex->lock(); - this->idx = index; - // this->img = QImage(); - this->size = size; - this->rawImage = rImage; - mutex->unlock(); - - if (!isRunning()) - start(); - else { - mutex->lock(); - // already running, wake up whenever ready - restart = true; - condition.wakeOne(); - mutex->unlock(); - } -} - -void PageLoader::run() -{ - for (;;) { - // copy necessary data - mutex->lock(); - this->working = true; - // int idx = this->idx; - - QImage image; - image.loadFromData(this->rawImage); - // let everyone knows it is ready - image = image.scaled(this->size, Qt::KeepAspectRatio, Qt::SmoothTransformation); - - mutex->unlock(); - - mutex->lock(); - this->img = image; - this->working = false; - mutex->unlock(); - - // put to sleep - mutex->lock(); - while (!this->restart) - condition.wait(mutex); - restart = false; - mutex->unlock(); - } -} diff --git a/YACReader/goto_flow.h b/YACReader/goto_flow.h deleted file mode 100644 index 14b52929c..000000000 --- a/YACReader/goto_flow.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef __GOTO_FLOW_H -#define __GOTO_FLOW_H - -#include "goto_flow_widget.h" -#include "yacreader_global_gui.h" - -#include - -#include -#include - -#include - -class QLineEdit; -class QPushButton; -class QPixmap; -class QThread; -class QSize; -class QIntValidator; -class QWaitCondition; -class QEvent; -class QLabel; - -class Comic; -class PageLoader; -class YACReaderFlow; -class PictureFlow; -class QKeyEvent; - -class GoToFlow : public GoToFlowWidget -{ - Q_OBJECT -public: - GoToFlow(QWidget *parent = nullptr, FlowType flowType = CoverFlowLike); - ~GoToFlow() override; - bool ready; // comic is ready for read. -private: - YACReaderFlow *flow; - void keyPressEvent(QKeyEvent *event) override; - // Comic * comic; - QSize imageSize; - - QVector imagesLoaded; - QVector imagesSetted; - int numImagesLoaded; - QVector imagesReady; - QVector rawImages; - QTimer *updateTimer; - PageLoader *worker; - void wheelEvent(QWheelEvent *event) override; - QMutex mutexGoToFlow; - -private slots: - void preload(); - void updateImageData(); - void resizeEvent(QResizeEvent *event) override; - -public slots: - void centerSlide(int slide) override; - void reset() override; - void setNumSlides(unsigned int slides) override; - void setImageReady(int index, const QByteArray &image) override; - void setFlowType(YACReader::FlowType flowType) override; - void updateConfig(QSettings *settings) override; - void setFlowRightToLeft(bool b) override; -}; - -//----------------------------------------------------------------------------- -// PageLoader -//----------------------------------------------------------------------------- -class PageLoader : public QThread -{ -public: - PageLoader(QMutex *m); - ~PageLoader() override; - // returns FALSE if worker is still busy and can't take the task - bool busy() const; - void generate(int index, QSize size, const QByteArray &rImage); - void reset() { idx = -1; }; - int index() const { return idx; } - QImage result() const { return img; } - -protected: - void run() override; - -private: - QMutex *mutex; - QWaitCondition condition; - - bool restart; - std::atomic working; - int idx; - - QSize size; - QImage img; - QByteArray rawImage; -}; - -#endif diff --git a/YACReader/goto_flow_gl.cpp b/YACReader/goto_flow_gl.cpp deleted file mode 100644 index 27772e216..000000000 --- a/YACReader/goto_flow_gl.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include "goto_flow_gl.h" - -#include -#include -#include -#include -#include -#include - -#include "configuration.h" - -#include "goto_flow_toolbar.h" - -GoToFlowGL::GoToFlowGL(QWidget *parent, FlowType flowType) - : GoToFlowWidget(parent) -{ - Q_UNUSED(flowType) - flow = new YACReaderPageFlowImpl(this); - flow->setShowMarks(false); - - imageSize = Configuration::getConfiguration().getGotoSlideSize(); - - flow->setSlideSize(imageSize); - connect(flow, &YACReaderPageFlowImpl::centerIndexChanged, this, &GoToFlowWidget::setPageNumber); - connect(flow, &YACReaderPageFlowImpl::selected, this, &GoToFlowGL::goToPage); - - connect(toolBar, &GoToFlowToolBar::goToPage, this, &GoToFlowGL::goToPage); - connect(toolBar, &GoToFlowToolBar::setCenter, flow, &YACReaderPageFlowImpl::setCenterIndex); - - mainLayout->addWidget(flow); - toolBar->raise(); - - resize(static_cast(5 * imageSize.width()), toolBar->height() + static_cast(imageSize.height() * 1.7)); - - this->setCursor(QCursor(Qt::ArrowCursor)); -} - -GoToFlowGL::~GoToFlowGL() -{ - delete flow; -} - -void GoToFlowGL::reset() -{ - flow->reset(); -} - -void GoToFlowGL::centerSlide(int slide) -{ - if (flow->centerIndex() != slide) { - flow->setCenterIndex(slide); - } -} - -void GoToFlowGL::setFlowType(FlowType flowType) -{ - if (flowType == CoverFlowLike) - flow->setPreset(presetYACReaderFlowClassicConfig); - else if (flowType == Strip) - flow->setPreset(presetYACReaderFlowStripeConfig); - else if (flowType == StripOverlapped) - flow->setPreset(presetYACReaderFlowOverlappedStripeConfig); - else - flow->setPreset(defaultYACReaderFlowConfig); -} - -void GoToFlowGL::setNumSlides(unsigned int slides) -{ - flow->populate(slides); - toolBar->setTop(slides); -} -void GoToFlowGL::setImageReady(int index, const QByteArray &imageData) -{ - flow->rawImages[index] = imageData; - flow->imagesReady[index] = true; -} - -void GoToFlowGL::updateConfig(QSettings *settings) -{ - GoToFlowWidget::updateConfig(settings); - - Performance performance = medium; - switch (settings->value(PERFORMANCE).toInt()) { - case 0: - performance = low; - break; - case 1: - performance = medium; - break; - case 2: - performance = high; - break; - case 3: - performance = ultraHigh; - break; - } - - imageSize = Configuration::getConfiguration().getGotoSlideSize(); - resize(5 * imageSize.width(), toolBar->height() + imageSize.height() * 1.7); - updateSize(); - - flow->setPerformance(performance); - - switch (settings->value(FLOW_TYPE_GL).toInt()) { - case FlowType::CoverFlowLike: - flow->setPreset(presetYACReaderFlowClassicConfig); - break; - case FlowType::Strip: - flow->setPreset(presetYACReaderFlowStripeConfig); - break; - case FlowType::StripOverlapped: - flow->setPreset(presetYACReaderFlowOverlappedStripeConfig); - break; - case FlowType::Modern: - flow->setPreset(defaultYACReaderFlowConfig); - break; - case FlowType::Roulette: - flow->setPreset(pressetYACReaderFlowDownConfig); - break; - case FlowType::Custom: - flow->setCF_RX(settings->value(X_ROTATION).toInt()); - flow->setCF_Y(settings->value(Y_POSITION).toInt()); - flow->setX_Distance(settings->value(COVER_DISTANCE).toInt()); - flow->setCenter_Distance(settings->value(CENTRAL_DISTANCE).toInt()); - flow->setCF_Z(settings->value(ZOOM_LEVEL).toInt()); - flow->setY_Distance(settings->value(Y_COVER_OFFSET).toInt()); - flow->setZ_Distance(settings->value(Z_COVER_OFFSET).toInt()); - flow->setRotation(settings->value(COVER_ROTATION).toInt()); - flow->setFadeOutDist(settings->value(FADE_OUT_DIST).toInt()); - flow->setLightStrenght(settings->value(LIGHT_STRENGTH).toInt()); - flow->setMaxAngle(settings->value(MAX_ANGLE).toInt()); - break; - } - if (Configuration::getConfiguration().getQuickNaviMode()) - flow->setFadeOutDist(20); -} - -void GoToFlowGL::keyPressEvent(QKeyEvent *event) -{ - switch (event->key()) { - case Qt::Key_Left: - case Qt::Key_Right: - case Qt::Key_Up: - QApplication::sendEvent(flow, event); - return; - default: - break; - } - - GoToFlowWidget::keyPressEvent(event); -} - -void GoToFlowGL::resizeEvent(QResizeEvent *event) -{ - QWidget::resizeEvent(event); - - toolBar->move(0, event->size().height() - toolBar->height()); - toolBar->setFixedWidth(width()); -} - -void GoToFlowGL::setFlowRightToLeft(bool b) -{ - flow->setFlowRightToLeft(b); -} diff --git a/YACReader/goto_flow_gl.h b/YACReader/goto_flow_gl.h deleted file mode 100644 index 8afc0ce3b..000000000 --- a/YACReader/goto_flow_gl.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __GOTO_FLOW_GL_H -#define __GOTO_FLOW_GL_H - -#include "yacreader_global.h" -#include "goto_flow_widget.h" - -// Conditional include based on Qt version and RHI availability -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) -#include "yacreader_page_flow_rhi.h" -using YACReaderPageFlowImpl = YACReaderPageFlow3D; -#else -#include "yacreader_flow_gl.h" -using YACReaderPageFlowImpl = YACReaderPageFlowGL; -#endif - -class QLineEdit; -class QIntValidator; -class QPushButton; -class QPushButton; -class QSize; -class QKeyEvent; - -class GoToFlowGL : public GoToFlowWidget -{ - Q_OBJECT -public: - GoToFlowGL(QWidget *parent = nullptr, FlowType flowType = CoverFlowLike); - ~GoToFlowGL() override; - void reset() override; - void centerSlide(int slide) override; - void setFlowType(FlowType flowType) override; - void setNumSlides(unsigned int slides) override; - void setImageReady(int index, const QByteArray &image) override; - - void updateConfig(QSettings *settings) override; - void setFlowRightToLeft(bool b) override; - -private: - YACReaderPageFlowImpl *flow; - void keyPressEvent(QKeyEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - // Comic * comic; - QSize imageSize; -}; - -#endif diff --git a/YACReader/goto_flow_widget.cpp b/YACReader/goto_flow_widget.cpp index 0b32bf7dc..1fc339d35 100644 --- a/YACReader/goto_flow_widget.cpp +++ b/YACReader/goto_flow_widget.cpp @@ -1,16 +1,19 @@ #include "goto_flow_widget.h" -#include #include #include #include +#include +#include #include "goto_flow_toolbar.h" #include "configuration.h" -GoToFlowWidget::GoToFlowWidget(QWidget *parent) +GoToFlowWidget::GoToFlowWidget(QWidget *parent, FlowType flowType) : QWidget(parent) { + Q_UNUSED(flowType) + mainLayout = new QVBoxLayout(this); mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->setSpacing(0); @@ -19,19 +22,151 @@ GoToFlowWidget::GoToFlowWidget(QWidget *parent) setLayout(mainLayout); - // toolBar->installEventFilter(this); + flow = new YACReaderPageFlow3D(this); + flow->setShowMarks(false); + + imageSize = Configuration::getConfiguration().getGotoSlideSize(); + + flow->setSlideSize(imageSize); + connect(flow, &YACReaderPageFlow3D::centerIndexChanged, this, &GoToFlowWidget::setPageNumber); + connect(flow, &YACReaderPageFlow3D::selected, this, &GoToFlowWidget::goToPage); + + connect(toolBar, &GoToFlowToolBar::goToPage, this, &GoToFlowWidget::goToPage); + connect(toolBar, &GoToFlowToolBar::setCenter, flow, &YACReaderPageFlow3D::setCenterIndex); + + mainLayout->addWidget(flow); + toolBar->raise(); + + resize(static_cast(5 * imageSize.width()), toolBar->height() + static_cast(imageSize.height() * 1.7)); + + this->setCursor(QCursor(Qt::ArrowCursor)); } -GoToFlowWidget::~GoToFlowWidget() { } +GoToFlowWidget::~GoToFlowWidget() +{ + delete flow; +} + +void GoToFlowWidget::reset() +{ + flow->reset(); +} + +void GoToFlowWidget::centerSlide(int slide) +{ + if (flow->centerIndex() != slide) { + flow->setCenterIndex(slide); + } +} void GoToFlowWidget::setPageNumber(int page) { toolBar->setPage(page); } +void GoToFlowWidget::setFlowType(FlowType flowType) +{ + if (flowType == CoverFlowLike) + flow->setPreset(presetYACReaderFlowClassicConfig); + else if (flowType == Strip) + flow->setPreset(presetYACReaderFlowStripeConfig); + else if (flowType == StripOverlapped) + flow->setPreset(presetYACReaderFlowOverlappedStripeConfig); + else + flow->setPreset(defaultYACReaderFlowConfig); +} + +void GoToFlowWidget::setNumSlides(unsigned int slides) +{ + flow->populate(slides); + toolBar->setTop(slides); +} + +void GoToFlowWidget::setImageReady(int index, const QByteArray &imageData) +{ + flow->rawImages[index] = imageData; + flow->imagesReady[index] = true; +} + +void GoToFlowWidget::updateSize() +{ + if (Configuration::getConfiguration().getQuickNaviMode() && parentWidget() != nullptr) + resize(parentWidget()->width(), height()); +} + +void GoToFlowWidget::updateConfig(QSettings *settings) +{ + toolBar->updateOptions(); + + Performance performance = medium; + switch (settings->value(PERFORMANCE).toInt()) { + case 0: + performance = low; + break; + case 1: + performance = medium; + break; + case 2: + performance = high; + break; + case 3: + performance = ultraHigh; + break; + } + + imageSize = Configuration::getConfiguration().getGotoSlideSize(); + resize(5 * imageSize.width(), toolBar->height() + imageSize.height() * 1.7); + updateSize(); + + flow->setPerformance(performance); + + switch (settings->value(FLOW_TYPE_GL).toInt()) { + case FlowType::CoverFlowLike: + flow->setPreset(presetYACReaderFlowClassicConfig); + break; + case FlowType::Strip: + flow->setPreset(presetYACReaderFlowStripeConfig); + break; + case FlowType::StripOverlapped: + flow->setPreset(presetYACReaderFlowOverlappedStripeConfig); + break; + case FlowType::Modern: + flow->setPreset(defaultYACReaderFlowConfig); + break; + case FlowType::Roulette: + flow->setPreset(pressetYACReaderFlowDownConfig); + break; + case FlowType::Custom: + flow->setCF_RX(settings->value(X_ROTATION).toInt()); + flow->setCF_Y(settings->value(Y_POSITION).toInt()); + flow->setX_Distance(settings->value(COVER_DISTANCE).toInt()); + flow->setCenter_Distance(settings->value(CENTRAL_DISTANCE).toInt()); + flow->setCF_Z(settings->value(ZOOM_LEVEL).toInt()); + flow->setY_Distance(settings->value(Y_COVER_OFFSET).toInt()); + flow->setZ_Distance(settings->value(Z_COVER_OFFSET).toInt()); + flow->setRotation(settings->value(COVER_ROTATION).toInt()); + flow->setFadeOutDist(settings->value(FADE_OUT_DIST).toInt()); + flow->setLightStrenght(settings->value(LIGHT_STRENGTH).toInt()); + flow->setMaxAngle(settings->value(MAX_ANGLE).toInt()); + break; + } + if (Configuration::getConfiguration().getQuickNaviMode()) + flow->setFadeOutDist(20); +} + +void GoToFlowWidget::setFlowRightToLeft(bool b) +{ + flow->setFlowRightToLeft(b); +} + void GoToFlowWidget::keyPressEvent(QKeyEvent *event) { switch (event->key()) { + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Up: + QApplication::sendEvent(flow, event); + return; case Qt::Key_Return: case Qt::Key_Enter: toolBar->goTo(); @@ -48,31 +183,10 @@ void GoToFlowWidget::keyPressEvent(QKeyEvent *event) event->accept(); } -void GoToFlowWidget::updateConfig(QSettings *settings) +void GoToFlowWidget::resizeEvent(QResizeEvent *event) { - Q_UNUSED(settings) - toolBar->updateOptions(); -} + QWidget::resizeEvent(event); -void GoToFlowWidget::updateSize() -{ - // called by parent in resizeEvent - // no need to update width when QuickNaviMode disabled - // height is set in updateConfig - if (Configuration::getConfiguration().getQuickNaviMode() && parentWidget() != nullptr) - resize(parentWidget()->width(), height()); + toolBar->move(0, event->size().height() - toolBar->height()); + toolBar->setFixedWidth(width()); } - -/*bool GoToFlowWidget::eventFilter(QObject * target, QEvent * event) -{ - if(event->type() == QEvent::KeyPress) - { - QKeyEvent * e = static_cast(event); - if(e->key()==Qt::Key_S || e->key() == Qt::Key_Space) - { - this->keyPressEvent(e); - return true; - } - } - return QWidget::eventFilter(target,event); -}*/ diff --git a/YACReader/goto_flow_widget.h b/YACReader/goto_flow_widget.h index 1cb26d14b..f8f93fc7a 100644 --- a/YACReader/goto_flow_widget.h +++ b/YACReader/goto_flow_widget.h @@ -3,40 +3,48 @@ #include #include +#include "yacreader_global.h" #include "yacreader_global_gui.h" +#include "yacreader_page_flow_rhi.h" + using namespace YACReader; class QSettings; class GoToFlowToolBar; class QVBoxLayout; +class QKeyEvent; class GoToFlowWidget : public QWidget { Q_OBJECT -protected: - QVBoxLayout *mainLayout; - GoToFlowToolBar *toolBar; - public: - GoToFlowWidget(QWidget *paret = nullptr); - ~GoToFlowWidget() override = 0; + GoToFlowWidget(QWidget *parent = nullptr, FlowType flowType = CoverFlowLike); + ~GoToFlowWidget() override; + public slots: - virtual void reset() = 0; - virtual void centerSlide(int slide) = 0; - virtual void setPageNumber(int page); - virtual void setFlowType(YACReader::FlowType flowType) = 0; - virtual void setNumSlides(unsigned int slides) = 0; - virtual void setImageReady(int index, const QByteArray &image) = 0; - virtual void updateSize(); - virtual void updateConfig(QSettings *settings); - virtual void setFlowRightToLeft(bool b) = 0; + void reset(); + void centerSlide(int slide); + void setPageNumber(int page); + void setFlowType(FlowType flowType); + void setNumSlides(unsigned int slides); + void setImageReady(int index, const QByteArray &image); + void updateSize(); + void updateConfig(QSettings *settings); + void setFlowRightToLeft(bool b); + signals: void goToPage(unsigned int); protected: void keyPressEvent(QKeyEvent *event) override; - // bool eventFilter(QObject *, QEvent *); + void resizeEvent(QResizeEvent *event) override; + +private: + QVBoxLayout *mainLayout; + GoToFlowToolBar *toolBar; + YACReaderPageFlow3D *flow; + QSize imageSize; }; #endif diff --git a/YACReader/mouse_handler.cpp b/YACReader/mouse_handler.cpp index d4b7a6c1a..331d33f26 100644 --- a/YACReader/mouse_handler.cpp +++ b/YACReader/mouse_handler.cpp @@ -3,17 +3,11 @@ #include #include "configuration.h" +#include "goto_flow_widget.h" #include "magnifying_glass.h" #include "render.h" #include "viewer.h" -#include "goto_flow.h" -#ifndef NO_OPENGL -#include "goto_flow_gl.h" -#else -#include -#endif - using namespace YACReader; YACReader::MouseHandler::MouseHandler(Viewer *viewer) diff --git a/YACReader/options_dialog.cpp b/YACReader/options_dialog.cpp index 611ce8d38..10d73439a 100644 --- a/YACReader/options_dialog.cpp +++ b/YACReader/options_dialog.cpp @@ -14,10 +14,7 @@ #include #include "yacreader_spin_slider_widget.h" -#include "yacreader_flow_config_widget.h" -#ifndef NO_OPENGL -#include "yacreader_gl_flow_config_widget.h" -#endif +#include "yacreader_3d_flow_config_widget.h" OptionsDialog::OptionsDialog(QWidget *parent) : YACReaderOptionsDialog(parent) @@ -120,19 +117,13 @@ OptionsDialog::OptionsDialog(QWidget *parent) quickNavi = new QCheckBox(tr("Quick Navigation Mode")); disableShowOnMouseOver = new QCheckBox(tr("Disable mouse over activation")); - layoutFlow->addWidget(sw); -#ifndef NO_OPENGL layoutFlow->addWidget(gl); - layoutFlow->addWidget(useGL); -#endif + layoutFlow->addWidget(quickNavi); layoutFlow->addWidget(disableShowOnMouseOver); layoutFlow->addStretch(); - // disable vSyncCheck -#ifndef NO_OPENGL gl->vSyncCheck->hide(); -#endif // PAGE FLOW END ------------------------------------- @@ -249,13 +240,6 @@ void OptionsDialog::saveOptions() { settings->setValue(GO_TO_FLOW_SIZE, QSize(static_cast(slideSize->sliderPosition() / SLIDE_ASPECT_RATIO), slideSize->sliderPosition())); - if (sw->radio1->isChecked()) - settings->setValue(FLOW_TYPE_SW, 0); - if (sw->radio2->isChecked()) - settings->setValue(FLOW_TYPE_SW, 1); - if (sw->radio3->isChecked()) - settings->setValue(FLOW_TYPE_SW, 2); - settings->setValue(PATH, pathEdit->text()); Configuration::getConfiguration().setShowTimeInInformation(showTimeInInformationLabel->isChecked()); @@ -289,20 +273,6 @@ void OptionsDialog::restoreOptions(QSettings *settings) YACReaderOptionsDialog::restoreOptions(settings); slideSize->setSliderPosition(settings->value(GO_TO_FLOW_SIZE).toSize().height()); - switch (settings->value(FLOW_TYPE_SW).toInt()) { - case 0: - sw->radio1->setChecked(true); - break; - case 1: - sw->radio2->setChecked(true); - break; - case 2: - sw->radio3->setChecked(true); - break; - default: - sw->radio1->setChecked(true); - break; - } pathEdit->setText(settings->value(PATH).toString()); diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index c4e4bfb53..d689e90b1 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -1,12 +1,7 @@ #include "viewer.h" #include "configuration.h" #include "magnifying_glass.h" -#include "goto_flow.h" -#ifndef NO_OPENGL -#include "goto_flow_gl.h" -#else -#include -#endif +#include "goto_flow_widget.h" #include "bookmarks_dialog.h" #include "render.h" #include "goto_dialog.h" @@ -16,8 +11,6 @@ #include "comic_db.h" #include "shortcuts_manager.h" -#include "opengl_checker.h" - #include #include @@ -81,34 +74,9 @@ Viewer::Viewer(QWidget *parent) goToDialog = new GoToDialog(this); - QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReader.ini", QSettings::IniFormat); - // CONFIG GOTO_FLOW-------------------------------------------------------- -#ifndef NO_OPENGL - -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) - // When using RHI, don't check OpenGL - assume hardware acceleration is available - bool openGLAvailable = true; - - if (!settings->contains(USE_OPEN_GL)) - settings->setValue(USE_OPEN_GL, 2); -#else - 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 + goToFlow = new GoToFlowWidget(this, Configuration::getConfiguration().getFlowType()); - if ((settings->value(USE_OPEN_GL).toBool() == true)) - goToFlow = new GoToFlowGL(this, Configuration::getConfiguration().getFlowType()); - else - goToFlow = new GoToFlow(this, Configuration::getConfiguration().getFlowType()); -#else - goToFlow = new GoToFlow(this, Configuration::getConfiguration().getFlowType()); -#endif goToFlow->setFocusPolicy(Qt::StrongFocus); goToFlow->hide(); showGoToFlowAnimation = new QPropertyAnimation(goToFlow, "pos"); diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 1a79aadb5..12726d285 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -18,21 +18,10 @@ DEFINES += SERVER_RELEASE YACREADER_LIBRARY include (../config.pri) include (../dependencies/pdf_backend.pri) -INCLUDEPATH += ../common/gl +INCLUDEPATH += ../common/rhi -greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - INCLUDEPATH += ../common/rhi - DEFINES += YACREADER_USE_RHI -} win32 { - LIBS += -loleaut32 -lole32 -lshell32 -luser32 - # When using RHI (Qt 6.7+), don't link OpenGL directly - QRhiWidget handles graphics APIs - message("RHI mode: not linking opengl32 (using QRhiWidget)") - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - } else { - LIBS += -lopengl32 - } - + LIBS += -loleaut32 -lole32 -lshell32 -luser32 msvc { QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL QMAKE_LFLAGS_RELEASE += /LTCG @@ -59,16 +48,16 @@ macx { CONFIG -= flat QT += sql network widgets svg quickcontrols2 -greaterThan(QT_MAJOR_VERSION, 5): QT += openglwidgets core5compat +greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { QT += gui-private } # Input -HEADERS += comic_flow.h \ +HEADERS += \ ../common/concurrent_queue.h \ - ../common/cover_utils.h \ + ../common/cover_utils.h \ create_library_dialog.h \ db/comic_query_result_processor.h \ db/folder_query_result_processor.h \ @@ -105,7 +94,6 @@ HEADERS += comic_flow.h \ ../common/library_item.h \ ../common/comic.h \ ../common/bookmarks.h \ - ../common/pictureflow.h \ ../common/release_acquire_atomic.h \ ../common/worker_thread.h \ ../common/custom_widgets.h \ @@ -142,7 +130,6 @@ HEADERS += comic_flow.h \ empty_special_list.h \ empty_reading_list_widget.h \ ../common/scroll_management.h \ - ../common/opengl_checker.h \ info_comics_view.h \ yacreader_comics_selection_helper.h \ yacreader_comic_info_helper.h \ @@ -151,18 +138,12 @@ HEADERS += comic_flow.h \ current_comic_view_helper.h \ ip_config_helper.h \ ../common/global_info_provider.h \ + ../common/rhi/flow_types.h \ + ../common/rhi/yacreader_flow_rhi.h \ + ../common/rhi/yacreader_comic_flow_rhi.h \ + ../common/rhi/yacreader_page_flow_rhi.h -!CONFIG(no_opengl) { - HEADERS += ../common/gl/yacreader_flow_gl.h - - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - HEADERS += ../common/rhi/yacreader_flow_rhi.h - HEADERS += ../common/rhi/yacreader_comic_flow_rhi.h \ - ../common/rhi/yacreader_page_flow_rhi.h - } -} - -SOURCES += comic_flow.cpp \ +SOURCES += \ ../common/concurrent_queue.cpp \ ../common/cover_utils.cpp \ create_library_dialog.cpp \ @@ -202,7 +183,6 @@ SOURCES += comic_flow.cpp \ ../common/library_item.cpp \ ../common/comic.cpp \ ../common/bookmarks.cpp \ - ../common/pictureflow.cpp \ ../common/custom_widgets.cpp \ ../common/qnaturalsorting.cpp \ no_libraries_widget.cpp \ @@ -236,7 +216,6 @@ SOURCES += comic_flow.cpp \ empty_special_list.cpp \ empty_reading_list_widget.cpp \ ../common/scroll_management.cpp \ - ../common/opengl_checker.cpp \ info_comics_view.cpp \ yacreader_comics_selection_helper.cpp \ yacreader_comic_info_helper.cpp\ @@ -245,20 +224,15 @@ SOURCES += comic_flow.cpp \ db/query_parser.cpp \ ip_config_helper.cpp \ ../common/global_info_provider.cpp \ - -!CONFIG(no_opengl) { - SOURCES += ../common/gl/yacreader_flow_gl.cpp - - greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - SOURCES += ../common/rhi/yacreader_flow_rhi.cpp - SOURCES += ../common/rhi/yacreader_comic_flow_rhi.cpp \ - ../common/rhi/yacreader_page_flow_rhi.cpp - RESOURCES += ../common/rhi/shaders/shaders.qrc - # Make raw GLSL shader sources editable in Qt Creator - OTHER_FILES += ../common/rhi/shaders/flow.vert \ - ../common/rhi/shaders/flow.frag - } -} + ../common/rhi/flow_types.cpp \ + ../common/rhi/yacreader_flow_rhi.cpp \ + ../common/rhi/yacreader_comic_flow_rhi.cpp \ + ../common/rhi/yacreader_page_flow_rhi.cpp + + RESOURCES += ../common/rhi/shaders/shaders.qrc + # Make raw GLSL shader sources editable in Qt Creator + OTHER_FILES += ../common/rhi/shaders/flow.vert \ + ../common/rhi/shaders/flow.frag macx { HEADERS += trayhandler.h diff --git a/YACReaderLibrary/classic_comics_view.cpp b/YACReaderLibrary/classic_comics_view.cpp index 9368779d1..e3280f1ee 100644 --- a/YACReaderLibrary/classic_comics_view.cpp +++ b/YACReaderLibrary/classic_comics_view.cpp @@ -19,14 +19,7 @@ ClassicComicsView::ClassicComicsView(QWidget *parent) settings->beginGroup("libraryConfig"); // FLOW----------------------------------------------------------------------- //--------------------------------------------------------------------------- -#ifndef NO_OPENGL - if ((settings->value(USE_OPEN_GL).toBool() == true)) - comicFlow = new ComicFlowWidgetGL(0); - else - comicFlow = new ComicFlowWidgetSW(0); -#else - comicFlow = new ComicFlowWidgetSW(0); -#endif + comicFlow = new ComicFlowWidget(0); comicFlow->updateConfig(settings); comicFlow->setFocusPolicy(Qt::StrongFocus); comicFlow->setShowMarks(true); diff --git a/YACReaderLibrary/comic_flow.cpp b/YACReaderLibrary/comic_flow.cpp deleted file mode 100644 index a746ecd7f..000000000 --- a/YACReaderLibrary/comic_flow.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#include "comic_flow.h" -#include "worker_thread.h" - -#include "yacreader_global.h" - -ComicFlow::ComicFlow(QWidget *parent, FlowType flowType) - : YACReaderFlow(parent, flowType), worker(new WorkerThread) -{ - resetWorkerIndex(); - connect(&updateTimer, &QTimer::timeout, this, &ComicFlow::updateImageData); - - connect(this, &PictureFlow::centerIndexChanged, this, &ComicFlow::preload); - connect(this, &PictureFlow::centerIndexChangedSilent, this, &ComicFlow::preload); - - setReflectionEffect(PlainReflection); -} - -ComicFlow::~ComicFlow() = default; - -void ComicFlow::setImagePaths(const QStringList &paths) -{ - clear(); - - imageFiles = paths; - imagesLoaded.clear(); - imagesLoaded.fill(false, imageFiles.size()); - numImagesLoaded = 0; - - imagesSetted.clear(); - imagesSetted.fill(false, imageFiles.size()); - - // populate with empty images - QImage img; // TODO remove - QString s; - for (int i = 0; i < (int)imageFiles.size(); i++) { - addSlide(img); - s = imageFiles.at(i); - s.remove(s.size() - 4, 4); - if (QFileInfo::exists(s + ".r")) - markSlide(i); - } - - setCenterIndex(0); - - resetWorkerIndex(); - preload(); -} - -void ComicFlow::preload() -{ - if (numImagesLoaded < imagesLoaded.size()) - updateTimer.start(30); // TODO comprobar rendimiento, originalmente era 70 -} - -void ComicFlow::updateImageData() -{ - // can't do anything, wait for the next possibility - if (worker->busy()) - return; - - // set image of last one - const int idx = workerIndex; - if (idx >= 0) { - const QImage result = worker->extractResult(); - if (!result.isNull() && !imagesSetted[idx]) { - setSlide(idx, result); - imagesSetted[idx] = true; - numImagesLoaded++; - imagesLoaded[idx] = true; - } - } - - // try to load only few images on the left and right side - // i.e. all visible ones plus some extra -#define COUNT 8 - int indexes[2 * COUNT + 1]; - int center = centerIndex(); - indexes[0] = center; - for (int j = 0; j < COUNT; j++) { - indexes[j * 2 + 1] = center + j + 1; - indexes[j * 2 + 2] = center - j - 1; - } - for (int c = 0; c < 2 * COUNT + 1; c++) { - int i = indexes[c]; - if ((i >= 0) && (i < slideCount())) - if (!imagesLoaded[i]) // slide(i).isNull()) - { - // schedule thumbnail generation - QString fname = imageFiles[i]; - - workerIndex = i; - worker->performTask([fname] { return QImage { fname }; }); - return; - } - } - - // no need to generate anything? stop polling... - updateTimer.stop(); -} - -void ComicFlow::keyPressEvent(QKeyEvent *event) -{ - PictureFlow::keyPressEvent(event); -} - -void ComicFlow::wheelEvent(QWheelEvent *event) -{ - if (event->angleDelta().y() < 0) - showNext(); - else - showPrevious(); - event->accept(); -} - -void ComicFlow::insertSlide(const QString &path, int index) -{ - imageFiles.insert(index, path); - imagesLoaded.insert(index, false); - imagesSetted.insert(index, false); - - YACReaderFlow::insertSlide(index); - - resetWorkerIndex(); - preload(); -} - -void ComicFlow::removeSlide(int cover) -{ - imageFiles.removeAt(cover); - if (imagesLoaded[cover]) - numImagesLoaded--; - imagesLoaded.remove(cover); - imagesSetted.remove(cover); - - YACReaderFlow::removeSlide(cover); - - resetWorkerIndex(); - preload(); -} - -void ComicFlow::resortCovers(QList newOrder) -{ - YACReaderFlow::resortCovers(newOrder); - - QStringList imageFilesNew; - QVector imagesLoadedNew; - QVector imagesSettedNew; - foreach (int index, newOrder) { - imageFilesNew << imageFiles.at(index); - imagesLoadedNew << imagesLoaded.at(index); - imagesSettedNew << imagesSetted.at(index); - } - - imageFiles = imageFilesNew; - imagesLoaded = imagesLoadedNew; - imagesSetted = imagesSettedNew; - - resetWorkerIndex(); -} diff --git a/YACReaderLibrary/comic_flow.h b/YACReaderLibrary/comic_flow.h deleted file mode 100644 index f8cc9a4d9..000000000 --- a/YACReaderLibrary/comic_flow.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef __COMICFLOW_H -#define __COMICFLOW_H - -#include "yacreader_flow.h" - -#include -#include -#include -#include -#include - -#include - -template -class WorkerThread; - -class ComicFlow : public YACReaderFlow -{ - Q_OBJECT -public: - ComicFlow(QWidget *parent = nullptr, FlowType flowType = CoverFlowLike); - ~ComicFlow() override; - - void setImagePaths(const QStringList &paths); - // bool eventFilter(QObject *target, QEvent *event); - void keyPressEvent(QKeyEvent *event) override; - void insertSlide(const QString &path, int index); - void removeSlide(int cover); - void resortCovers(QList newOrder); - -private slots: - void preload(); - void updateImageData(); - -private: - void resetWorkerIndex() { workerIndex = -1; } - - QStringList imageFiles; - QVector imagesLoaded; - QVector imagesSetted; - int numImagesLoaded; - int workerIndex; - QTimer updateTimer; - std::unique_ptr> worker; - virtual void wheelEvent(QWheelEvent *event) override; -}; - -#endif diff --git a/YACReaderLibrary/comic_flow_widget.cpp b/YACReaderLibrary/comic_flow_widget.cpp index f0bc487cb..5df9bd08f 100644 --- a/YACReaderLibrary/comic_flow_widget.cpp +++ b/YACReaderLibrary/comic_flow_widget.cpp @@ -1,281 +1,138 @@ #include "comic_flow_widget.h" #include + ComicFlowWidget::ComicFlowWidget(QWidget *parent) : QWidget(parent) { -} - -ComicFlowWidgetSW::ComicFlowWidgetSW(QWidget *parent) - : ComicFlowWidget(parent) -{ - flow = new ComicFlow(parent); - - connect(flow, &PictureFlow::centerIndexChanged, this, &ComicFlowWidget::centerIndexChanged); - connect(flow, &YACReaderFlow::selected, this, &ComicFlowWidget::selected); - - auto l = new QVBoxLayout; - l->addWidget(flow); - setLayout(l); - - // TODO eleminar "padding" - QPalette Pal(palette()); - // set black background - Pal.setColor(QPalette::Window, Qt::black); - setAutoFillBackground(true); - setPalette(Pal); - - // config - QTransform m; - m.rotate(-90); - m.scale(-1, 1); - QImage image(":/images/setRead.png"); - QImage imageTransformed = image.transformed(m, Qt::SmoothTransformation); - setMarkImage(imageTransformed); -} - -QSize ComicFlowWidgetSW::minimumSizeHint() const -{ - return flow->minimumSizeHint(); -} -QSize ComicFlowWidgetSW::sizeHint() const -{ - return flow->sizeHint(); -} - -void ComicFlowWidgetSW::setShowMarks(bool value) -{ - flow->setShowMarks(value); -} -void ComicFlowWidgetSW::setMarks(QVector marks) -{ - flow->setMarks(marks); -} -void ComicFlowWidgetSW::setMarkImage(QImage &image) -{ - flow->setMarkImage(image); -} -void ComicFlowWidgetSW::markSlide(int index, YACReaderComicReadStatus status) -{ - flow->markSlide(index, status); -} -void ComicFlowWidgetSW::unmarkSlide(int index) -{ - flow->unmarkSlide(index); -} -void ComicFlowWidgetSW::setSlideSize(QSize size) -{ - flow->setSlideSize(size); -} -void ComicFlowWidgetSW::clear() -{ - flow->clear(); -} -void ComicFlowWidgetSW::setImagePaths(QStringList paths) -{ - flow->setImagePaths(paths); -} -void ComicFlowWidgetSW::setCenterIndex(int index) -{ - flow->setCenterIndex(index); -} -void ComicFlowWidgetSW::showSlide(int index) -{ - flow->showSlide(index); -} -int ComicFlowWidgetSW::centerIndex() -{ - return flow->centerIndex(); -} -void ComicFlowWidgetSW::updateMarks() -{ - flow->updateMarks(); -} -void ComicFlowWidgetSW::setFlowType(FlowType flowType) -{ - flow->setFlowType(flowType); -} -void ComicFlowWidgetSW::render() -{ - flow->render(); -} -void ComicFlowWidgetSW::keyPressEvent(QKeyEvent *event) -{ - flow->keyPressEvent(event); -} -void ComicFlowWidgetSW::paintEvent(QPaintEvent *event) -{ - ComicFlowWidget::paintEvent(event); -} -void ComicFlowWidgetSW::mousePressEvent(QMouseEvent *event) -{ - flow->mousePressEvent(event); -} -void ComicFlowWidgetSW::resizeEvent(QResizeEvent *event) -{ - flow->resizeEvent(event); -} -void ComicFlowWidgetSW::mouseDoubleClickEvent(QMouseEvent *event) -{ - flow->mouseDoubleClickEvent(event); -} -void ComicFlowWidgetSW::updateConfig(QSettings *settings) -{ - switch (settings->value(FLOW_TYPE_SW).toInt()) { - case CoverFlowLike: - flow->setFlowType(CoverFlowLike); - return; - case Strip: - flow->setFlowType(Strip); - return; - case StripOverlapped: - flow->setFlowType(StripOverlapped); - return; - } -} + flow = new YACReaderComicFlow3D(this); -void ComicFlowWidgetSW::add(const QString &path, int index) -{ - flow->insertSlide(path, index); -} - -void ComicFlowWidgetSW::remove(int cover) -{ - flow->removeSlide(cover); -} - -void ComicFlowWidgetSW::resortCovers(QList newOrder) -{ - flow->resortCovers(newOrder); -} - -#ifndef NO_OPENGL -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -/// OpenGL ComicFlow -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -ComicFlowWidgetGL::ComicFlowWidgetGL(QWidget *parent) - : ComicFlowWidget(parent) -{ -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) - qDebug() << "ComicFlowWidgetGL: Creating YACReaderComicFlow3D (RHI implementation)"; -#else - qDebug() << "ComicFlowWidgetGL: Creating YACReaderComicFlowGL (OpenGL implementation)"; -#endif - flow = new YACReaderComicFlowImpl(this); - - connect(flow, &YACReaderComicFlowImpl::centerIndexChanged, this, &ComicFlowWidget::centerIndexChanged); - connect(flow, &YACReaderComicFlowImpl::selected, this, &ComicFlowWidget::selected); + connect(flow, &YACReaderComicFlow3D::centerIndexChanged, this, &ComicFlowWidget::centerIndexChanged); + connect(flow, &YACReaderComicFlow3D::selected, this, &ComicFlowWidget::selected); auto l = new QVBoxLayout; l->addWidget(flow); l->setContentsMargins(0, 0, 0, 0); setLayout(l); - // TODO eleminar "padding" QPalette Pal(palette()); - // set black background Pal.setColor(QPalette::Window, Qt::black); setAutoFillBackground(true); setPalette(Pal); } -QSize ComicFlowWidgetGL::minimumSizeHint() const +QSize ComicFlowWidget::minimumSizeHint() const { return flow->minimumSizeHint(); } -QSize ComicFlowWidgetGL::sizeHint() const + +QSize ComicFlowWidget::sizeHint() const { return flow->sizeHint(); } -void ComicFlowWidgetGL::setShowMarks(bool value) +void ComicFlowWidget::setShowMarks(bool value) { flow->setShowMarks(value); } -void ComicFlowWidgetGL::setMarks(QVector marks) + +void ComicFlowWidget::setMarks(QVector marks) { flow->setMarks(marks); } -void ComicFlowWidgetGL::setMarkImage(QImage &image) + +void ComicFlowWidget::setMarkImage(QImage &image) { flow->setMarkImage(image); } -void ComicFlowWidgetGL::markSlide(int index, YACReaderComicReadStatus status) + +void ComicFlowWidget::markSlide(int index, YACReader::YACReaderComicReadStatus status) { flow->markSlide(index, status); } -void ComicFlowWidgetGL::unmarkSlide(int index) + +void ComicFlowWidget::unmarkSlide(int index) { flow->unmarkSlide(index); } -void ComicFlowWidgetGL::setSlideSize(QSize size) + +void ComicFlowWidget::setSlideSize(QSize size) { flow->setSlideSize(size); } -void ComicFlowWidgetGL::clear() + +void ComicFlowWidget::clear() { flow->clear(); } -void ComicFlowWidgetGL::setImagePaths(QStringList paths) + +void ComicFlowWidget::setImagePaths(QStringList paths) { flow->setImagePaths(paths); } -void ComicFlowWidgetGL::setCenterIndex(int index) + +void ComicFlowWidget::setCenterIndex(int index) { flow->setCenterIndex(index); } -void ComicFlowWidgetGL::showSlide(int index) + +void ComicFlowWidget::showSlide(int index) { flow->showSlide(index); } -int ComicFlowWidgetGL::centerIndex() + +int ComicFlowWidget::centerIndex() { return flow->centerIndex(); } -void ComicFlowWidgetGL::updateMarks() + +void ComicFlowWidget::updateMarks() { flow->updateMarks(); } -void ComicFlowWidgetGL::setFlowType(FlowType flowType) + +void ComicFlowWidget::setFlowType(YACReader::FlowType flowType) { - if (flowType == CoverFlowLike) + if (flowType == YACReader::CoverFlowLike) flow->setPreset(presetYACReaderFlowClassicConfig); - else if (flowType == Strip) + else if (flowType == YACReader::Strip) flow->setPreset(presetYACReaderFlowStripeConfig); - else if (flowType == StripOverlapped) + else if (flowType == YACReader::StripOverlapped) flow->setPreset(presetYACReaderFlowOverlappedStripeConfig); else flow->setPreset(defaultYACReaderFlowConfig); } -void ComicFlowWidgetGL::render() + +void ComicFlowWidget::render() { flow->render(); } -void ComicFlowWidgetGL::keyPressEvent(QKeyEvent *event) + +void ComicFlowWidget::keyPressEvent(QKeyEvent *event) { flow->keyPressEvent(event); } -void ComicFlowWidgetGL::paintEvent(QPaintEvent *event) + +void ComicFlowWidget::paintEvent(QPaintEvent *event) { - // flow->paintEvent(event); - ComicFlowWidget::paintEvent(event); + QWidget::paintEvent(event); } -void ComicFlowWidgetGL::mousePressEvent(QMouseEvent *event) + +void ComicFlowWidget::mousePressEvent(QMouseEvent *event) { flow->mousePressEvent(event); } -void ComicFlowWidgetGL::resizeEvent(QResizeEvent *event) + +void ComicFlowWidget::resizeEvent(QResizeEvent *event) { flow->resizeGL(event->size().width(), event->size().height()); } -void ComicFlowWidgetGL::mouseDoubleClickEvent(QMouseEvent *event) + +void ComicFlowWidget::mouseDoubleClickEvent(QMouseEvent *event) { flow->mouseDoubleClickEvent(event); } -void ComicFlowWidgetGL::updateConfig(QSettings *settings) +void ComicFlowWidget::updateConfig(QSettings *settings) { Performance performance = medium; @@ -319,7 +176,6 @@ void ComicFlowWidgetGL::updateConfig(QSettings *settings) } // custom config - flow->setCF_RX(settings->value(X_ROTATION).toInt()); flow->setCF_Y(settings->value(Y_POSITION).toInt()); flow->setX_Distance(settings->value(COVER_DISTANCE).toInt()); @@ -331,35 +187,19 @@ void ComicFlowWidgetGL::updateConfig(QSettings *settings) flow->setFadeOutDist(settings->value(FADE_OUT_DIST).toInt()); flow->setLightStrenght(settings->value(LIGHT_STRENGTH).toInt()); flow->setMaxAngle(settings->value(MAX_ANGLE).toInt()); - - /* flow->setVisibility(settings->value("visibilityDistance").toInt()); - flow->setLightStrenght(settings->value("lightStrength").toInt())*/ - ; } -void ComicFlowWidgetGL::add(const QString &path, int index) +void ComicFlowWidget::add(const QString &path, int index) { flow->add(path, index); } -void ComicFlowWidgetGL::remove(int cover) +void ComicFlowWidget::remove(int cover) { flow->remove(cover); } -void ComicFlowWidgetGL::resortCovers(QList newOrder) +void ComicFlowWidget::resortCovers(QList newOrder) { flow->resortCovers(newOrder); } -#endif -// void ComicFlowWidgetGL::setCF_RX(int value){ flow->setCF_RX(value);} -// void ComicFlowWidgetGL::setCF_RY(int value){ flow->setCF_RY(value);} -// void ComicFlowWidgetGL::setCF_RZ(int value){ flow->setCF_RZ(value);} -// void ComicFlowWidgetGL::setZoom(int zoom){ flow->setZoom(zoom);} -// void ComicFlowWidgetGL::setRotation(int angle){ flow->setRotation(angle);} -// void ComicFlowWidgetGL::setX_Distance(int distance){ flow->setX_Distance(distance);} -// void ComicFlowWidgetGL::setCenter_Distance(int distance){ flow->setCenter_Distance(distance);} -// void ComicFlowWidgetGL::setZ_Distance(int distance){ flow->setZ_Distance(distance);} -// void ComicFlowWidgetGL::setCF_Y(int value){ flow->setCF_Y(value);} -// void ComicFlowWidgetGL::setY_Distance(int value){ flow->setY_Distance(value);} -// void ComicFlowWidgetGL::setPreset(const Preset & p){ flow->setPreset(p);} diff --git a/YACReaderLibrary/comic_flow_widget.h b/YACReaderLibrary/comic_flow_widget.h index 51217cc46..b99c90a8d 100644 --- a/YACReaderLibrary/comic_flow_widget.h +++ b/YACReaderLibrary/comic_flow_widget.h @@ -3,75 +3,40 @@ #include -#include "pictureflow.h" -#include "comic_flow.h" -#ifndef NO_OPENGL -// Conditional include based on Qt version and RHI availability -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) +#include "yacreader_global.h" + #include "yacreader_comic_flow_rhi.h" -using YACReaderComicFlowImpl = YACReaderComicFlow3D; -#else -#include "yacreader_flow_gl.h" -using YACReaderComicFlowImpl = YACReaderComicFlowGL; -#endif -#endif +#include "yacreader_global_gui.h" + class ComicFlowWidget : public QWidget { Q_OBJECT public: - ComicFlowWidget(QWidget *paret = nullptr); + ComicFlowWidget(QWidget *parent = nullptr); public slots: - virtual void setShowMarks(bool value) = 0; - virtual void setMarks(QVector marks) = 0; - virtual void setMarkImage(QImage &image) = 0; - virtual void markSlide(int index, YACReaderComicReadStatus status) = 0; - virtual void unmarkSlide(int index) = 0; - virtual void setSlideSize(QSize size) = 0; - virtual void clear() = 0; - virtual void setImagePaths(QStringList paths) = 0; - virtual void setCenterIndex(int index) = 0; - virtual void showSlide(int index) = 0; - virtual int centerIndex() = 0; - virtual void updateMarks() = 0; - virtual void setFlowType(FlowType flowType) = 0; - virtual void render() = 0; - virtual void updateConfig(QSettings *settings) = 0; - virtual void add(const QString &path, int index) = 0; - virtual void remove(int cover) = 0; - virtual void resortCovers(QList newOrder) = 0; + void setShowMarks(bool value); + void setMarks(QVector marks); + void setMarkImage(QImage &image); + void markSlide(int index, YACReader::YACReaderComicReadStatus status); + void unmarkSlide(int index); + void setSlideSize(QSize size); + void clear(); + void setImagePaths(QStringList paths); + void setCenterIndex(int index); + void showSlide(int index); + int centerIndex(); + void updateMarks(); + void setFlowType(YACReader::FlowType flowType); + void render(); + void updateConfig(QSettings *settings); + void add(const QString &path, int index); + void remove(int cover); + void resortCovers(QList newOrder); + signals: void centerIndexChanged(int); void selected(unsigned int); -}; - -class ComicFlowWidgetSW : public ComicFlowWidget -{ - Q_OBJECT -private: - ComicFlow *flow; - -public: - ComicFlowWidgetSW(QWidget *parent = nullptr); - - void setShowMarks(bool value) override; - void setMarks(QVector marks) override; - void setMarkImage(QImage &image) override; - void markSlide(int index, YACReaderComicReadStatus status) override; - void unmarkSlide(int index) override; - void setSlideSize(QSize size) override; - void clear() override; - void setImagePaths(QStringList paths) override; - void setCenterIndex(int index) override; - void showSlide(int index) override; - int centerIndex() override; - void updateMarks() override; - void setFlowType(FlowType flowType) override; - void render() override; - void updateConfig(QSettings *settings) override; - void add(const QString &path, int index) override; - void remove(int cover) override; - void resortCovers(QList newOrder) override; protected: void keyPressEvent(QKeyEvent *event) override; @@ -81,64 +46,9 @@ class ComicFlowWidgetSW : public ComicFlowWidget void mouseDoubleClickEvent(QMouseEvent *event) override; QSize minimumSizeHint() const override; QSize sizeHint() const override; - QSize slideSizeW; - QSize slideSizeF; -}; -#ifndef NO_OPENGL -class ComicFlowWidgetGL : public ComicFlowWidget -{ - Q_OBJECT private: - YACReaderComicFlowImpl *flow; - -public: - ComicFlowWidgetGL(QWidget *parent = nullptr); - - void setShowMarks(bool value) override; - void setMarks(QVector marks) override; - void setMarkImage(QImage &image) override; - void markSlide(int index, YACReaderComicReadStatus status) override; - void unmarkSlide(int index) override; - void setSlideSize(QSize size) override; - void clear() override; - void setImagePaths(QStringList paths) override; - void setCenterIndex(int index) override; - void showSlide(int index) override; - int centerIndex() override; - void updateMarks() override; - void setFlowType(FlowType flowType) override; - void render() override; - void updateConfig(QSettings *settings) override; - void add(const QString &path, int index) override; - void remove(int cover) override; - void resortCovers(QList newOrder) override; - // public slots: - // void setCF_RX(int value); - // //the Y Rotation of the Coverflow - // void setCF_RY(int value); - // //the Z Rotation of the Coverflow - // void setCF_RZ(int value); - // //perspective - // void setZoom(int zoom); - // void setRotation(int angle); - // //sets the distance between the covers - // void setX_Distance(int distance); - // //sets the distance between the centered and the non centered covers - // void setCenter_Distance(int distance); - // //sets the pushback amount - // void setZ_Distance(int distance); - // void setCF_Y(int value); - // void setY_Distance(int value); - // void setPreset(const Preset & p); -protected: - void keyPressEvent(QKeyEvent *event) override; - void paintEvent(QPaintEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - void mouseDoubleClickEvent(QMouseEvent *event) override; - QSize minimumSizeHint() const override; - QSize sizeHint() const override; + YACReaderComicFlow3D *flow; }; -#endif + #endif diff --git a/YACReaderLibrary/comics_view.cpp b/YACReaderLibrary/comics_view.cpp index 88ac2e6ed..f3e705f12 100644 --- a/YACReaderLibrary/comics_view.cpp +++ b/YACReaderLibrary/comics_view.cpp @@ -17,11 +17,6 @@ ComicsView::ComicsView(QWidget *parent) view = new QQuickWidget(); - // In Qt 6, QQuickWidget supports Qt RHI and can use any graphics backend - // (Vulkan, Metal, Direct3D, OpenGL, or software rendering). - // The backend can be configured via QQuickWindow::setGraphicsApi() or QSG_RHI_BACKEND env var. - // Note: All widgets in the same top-level window must use the same graphics API. - view->setResizeMode(QQuickWidget::SizeRootObjectToView); connect( view, &QQuickWidget::statusChanged, this, diff --git a/YACReaderLibrary/folder_content_view.cpp b/YACReaderLibrary/folder_content_view.cpp index 8d31844e9..d3cc901d0 100644 --- a/YACReaderLibrary/folder_content_view.cpp +++ b/YACReaderLibrary/folder_content_view.cpp @@ -26,11 +26,6 @@ FolderContentView::FolderContentView(QAction *toogleRecentVisibilityAction, QWid view = new QQuickWidget(); - // In Qt 6, QQuickWidget supports Qt RHI and can use any graphics backend - // (Vulkan, Metal, Direct3D, OpenGL, or software rendering). - // The backend can be configured via QQuickWindow::setGraphicsApi() or QSG_RHI_BACKEND env var. - // Note: All widgets in the same top-level window must use the same graphics API. - view->setResizeMode(QQuickWidget::SizeRootObjectToView); connect( view, &QQuickWidget::statusChanged, this, diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 158a20106..2ae2f521c 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -71,7 +71,6 @@ #include "db_helper.h" #include "reading_list_item.h" -#include "opengl_checker.h" #include "yacreader_content_views_manager.h" #include "folder_content_view.h" @@ -198,33 +197,8 @@ void LibraryWindow::createSettings() settings->beginGroup("libraryConfig"); } -void LibraryWindow::setupOpenglSetting() -{ -#ifndef NO_OPENGL - // FLOW----------------------------------------------------------------------- - //--------------------------------------------------------------------------- - -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) - // When using RHI, assume hardware acceleration is available - bool openGLAvailable = true; - if (!settings->contains(USE_OPEN_GL)) - settings->setValue(USE_OPEN_GL, 2); -#else - 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 -#endif -} - void LibraryWindow::setupUI() { - setupOpenglSetting(); - setUnifiedTitleAndToolBarOnMac(true); libraryCreator = new LibraryCreator(settings); diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index b78a149ce..4f153a542 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -189,7 +189,6 @@ class LibraryWindow : public QMainWindow NavigationStatus status; void createSettings(); - void setupOpenglSetting(); void setupUI(); void createToolBars(); void createMenus(); diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index e60e9ae69..1697e0ae2 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -21,7 +21,6 @@ #include "db_helper.h" #include "yacreader_libraries.h" #include "exit_check.h" -#include "opengl_checker.h" #ifdef Q_OS_MACOS #include "trayhandler.h" #endif @@ -77,19 +76,6 @@ void logSystemAndConfig() else QLOG_INFO() << "server : disabled"; - if (settings.value(USE_OPEN_GL).toBool()) - QLOG_INFO() << "OpenGL : enabled" - << " - " << (settings.value(V_SYNC).toBool() ? "VSync on" : "VSync off"); - else - QLOG_INFO() << "OpenGL : disabled"; - -#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) && defined(YACREADER_USE_RHI) - QLOG_INFO() << "Using RHI (Qt Rendering Hardware Interface) - graphics backend will be auto-selected"; -#else - OpenGLChecker checker; - QLOG_INFO() << "OpenGL version : " << checker.textVersionDescription(); -#endif - auto libraries = DBHelper::getLibraries().getLibraries(); QLOG_INFO() << "Libraries: "; for (auto library : libraries) { @@ -199,32 +185,8 @@ int main(int argc, char **argv) parser.addHelpOption(); parser.addVersionOption(); parser.addOption({ "loglevel", "Set log level. Valid values: trace, info, debug, warn, error.", "loglevel", "warning" }); -#ifdef Q_OS_WIN - parser.addOption({ "opengl", "Set opengl renderer. Valid values: desktop, es, software.", "gl_renderer" }); -#endif parser.process(app); -// When using RHI (Qt 6.7+), don't allow OpenGL attribute overrides -#if !defined(YACREADER_USE_RHI) || QT_VERSION < QT_VERSION_CHECK(6, 7, 0) -#ifdef Q_OS_WIN - if (parser.isSet("opengl")) { - QTextStream qout(stdout); - if (parser.value("opengl") == "desktop") { - app.setAttribute(Qt::AA_UseDesktopOpenGL); - } else if (parser.value("opengl") == "es") { - app.setAttribute(Qt::AA_UseOpenGLES); - } else if (parser.value("opengl") == "software") { - qout << "Warning! This will be slow as hell. Only use this setting for" - "testing or as a last resort."; - app.setAttribute(Qt::AA_UseSoftwareOpenGL); - } else { - qout << "Invalid value:" << parser.value("gl_renderer"); - parser.showHelp(); - } - } -#endif -#endif - if (parser.isSet("loglevel")) { if (parser.value("loglevel") == "trace") { logger.setLoggingLevel(QsLogging::TraceLevel); diff --git a/YACReaderLibrary/options_dialog.cpp b/YACReaderLibrary/options_dialog.cpp index dd7026750..53210ac8f 100644 --- a/YACReaderLibrary/options_dialog.cpp +++ b/YACReaderLibrary/options_dialog.cpp @@ -1,17 +1,11 @@ #include "options_dialog.h" -#ifndef NO_OPENGL -#include "yacreader_flow_gl.h" -#include "yacreader_gl_flow_config_widget.h" -#endif -#include "yacreader_flow_config_widget.h" +#include "yacreader_3d_flow_config_widget.h" #include "api_key_dialog.h" #include "yacreader_global_gui.h" -#ifndef NO_OPENGL FlowType flowType = Strip; -#endif OptionsDialog::OptionsDialog(QWidget *parent) : YACReaderOptionsDialog(parent) @@ -25,9 +19,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) tabWidget->addTab(generalW, tr("General")); tabWidget->addTab(librariesW, tr("Libraries")); tabWidget->addTab(comicFlowW, tr("Comic Flow")); -#ifndef NO_OPENGL tabWidget->addTab(gridViewW, tr("Grid view")); -#endif auto buttons = new QHBoxLayout(); buttons->addStretch(); @@ -333,21 +325,11 @@ QWidget *OptionsDialog::createFlowTab() { auto switchFlowType = new QHBoxLayout(); switchFlowType->addStretch(); -#ifndef NO_OPENGL - switchFlowType->addWidget(useGL); -#endif auto flowLayout = new QVBoxLayout; - flowLayout->addWidget(sw); -#ifndef NO_OPENGL flowLayout->addWidget(gl); -#endif flowLayout->addLayout(switchFlowType); -#ifndef NO_OPENGL - sw->hide(); -#endif - auto comicFlowW = new QWidget; comicFlowW->setLayout(flowLayout); diff --git a/YACReaderLibrary/yacreader_content_views_manager.cpp b/YACReaderLibrary/yacreader_content_views_manager.cpp index 294a072c7..e2597cb1e 100644 --- a/YACReaderLibrary/yacreader_content_views_manager.cpp +++ b/YACReaderLibrary/yacreader_content_views_manager.cpp @@ -126,6 +126,7 @@ void YACReaderContentViewsManager::showComicsView() { comicsViewStack->setCurrentWidget(comicsView); + // TODO: check if this is still needed in the rhi implementation // BUG, ugly workaround for glitch when QOpenGLWidget (flow) is used just after any other widget in the views stack // Somehow QOpenGLWidget is messing with the rendering of the side bar (wrong buffer swapping) libraryWindow->sideBar->update(); diff --git a/common/gl/yacreader_flow_gl.cpp b/common/gl/yacreader_flow_gl.cpp deleted file mode 100644 index aba6dffbe..000000000 --- a/common/gl/yacreader_flow_gl.cpp +++ /dev/null @@ -1,1999 +0,0 @@ -#include "yacreader_flow_gl.h" - -#include -#include -#include - -// Structure for per-instance data -struct InstanceData { - QMatrix4x4 modelMatrix; - float leftUpShading; - float leftDownShading; - float rightUpShading; - float rightDownShading; - float opacity; - float padding[3]; // Align to 16 bytes -}; - -/*** Preset Configurations ***/ - -int YACReaderFlowGL::updateInterval = 16; - -struct Preset defaultYACReaderFlowConfig = { - 0.08f, // Animation_step sets the speed of the animation - 1.5f, // Animation_speedup sets the acceleration of the animation - 0.1f, // Animation_step_max sets the maximum speed of the animation - 3.f, // Animation_Fade_out_dis sets the distance of view - - 1.5f, // pre_rotation sets the rotation increasion - 3.f, // View_rotate_light_strenght sets the light strenght on rotation - 0.01f, // View_rotate_add sets the speed of the rotation - 0.02f, // View_rotate_sub sets the speed of reversing the rotation - 20.f, // View_angle sets the maximum view angle - - 0.f, // CF_X the X Position of the Coverflow - 0.f, // CF_Y the Y Position of the Coverflow - -8.f, // CF_Z the Z Position of the Coverflow - - 15.f, // CF_RX the X Rotation of the Coverflow - 0.f, // CF_RY the Y Rotation of the Coverflow - 0.f, // CF_RZ the Z Rotation of the Coverflow - - -50.f, // Rotation sets the rotation of each cover - 0.18f, // X_Distance sets the distance between the covers - 1.f, // Center_Distance sets the distance between the centered and the non centered covers - 0.1f, // Z_Distance sets the pushback amount - 0.0f, // Y_Distance sets the elevation amount - - 30.f // zoom level - -}; - -struct Preset presetYACReaderFlowClassicConfig = { - 0.08f, // Animation_step sets the speed of the animation - 1.5f, // Animation_speedup sets the acceleration of the animation - 0.1f, // Animation_step_max sets the maximum speed of the animation - 2.f, // Animation_Fade_out_dis sets the distance of view - - 1.5f, // pre_rotation sets the rotation increasion - 3.f, // View_rotate_light_strenght sets the light strenght on rotation - 0.08f, // View_rotate_add sets the speed of the rotation - 0.08f, // View_rotate_sub sets the speed of reversing the rotation - 30.f, // View_angle sets the maximum view angle - - 0.f, // CF_X the X Position of the Coverflow - -0.2f, // CF_Y the Y Position of the Coverflow - -7.f, // CF_Z the Z Position of the Coverflow - - 0.f, // CF_RX the X Rotation of the Coverflow - 0.f, // CF_RY the Y Rotation of the Coverflow - 0.f, // CF_RZ the Z Rotation of the Coverflow - - -40.f, // Rotation sets the rotation of each cover - 0.18f, // X_Distance sets the distance between the covers - 1.f, // Center_Distance sets the distance between the centered and the non centered covers - 0.1f, // Z_Distance sets the pushback amount - 0.0f, // Y_Distance sets the elevation amount - - 22.f // zoom level - -}; - -struct Preset presetYACReaderFlowStripeConfig = { - 0.08f, // Animation_step sets the speed of the animation - 1.5f, // Animation_speedup sets the acceleration of the animation - 0.1f, // Animation_step_max sets the maximum speed of the animation - 6.f, // Animation_Fade_out_dis sets the distance of view - - 1.5f, // pre_rotation sets the rotation increasion - 4.f, // View_rotate_light_strenght sets the light strenght on rotation - 0.08f, // View_rotate_add sets the speed of the rotation - 0.08f, // View_rotate_sub sets the speed of reversing the rotation - 30.f, // View_angle sets the maximum view angle - - 0.f, // CF_X the X Position of the Coverflow - -0.2f, // CF_Y the Y Position of the Coverflow - -7.f, // CF_Z the Z Position of the Coverflow - - 0.f, // CF_RX the X Rotation of the Coverflow - 0.f, // CF_RY the Y Rotation of the Coverflow - 0.f, // CF_RZ the Z Rotation of the Coverflow - - 0.f, // Rotation sets the rotation of each cover - 1.1f, // X_Distance sets the distance between the covers - 0.2f, // Center_Distance sets the distance between the centered and the non centered covers - 0.01f, // Z_Distance sets the pushback amount - 0.0f, // Y_Distance sets the elevation amount - - 22.f // zoom level - -}; - -struct Preset presetYACReaderFlowOverlappedStripeConfig = { - 0.08f, // Animation_step sets the speed of the animation - 1.5f, // Animation_speedup sets the acceleration of the animation - 0.1f, // Animation_step_max sets the maximum speed of the animation - 2.f, // Animation_Fade_out_dis sets the distance of view - - 1.5f, // pre_rotation sets the rotation increasion - 3.f, // View_rotate_light_strenght sets the light strenght on rotation - 0.08f, // View_rotate_add sets the speed of the rotation - 0.08f, // View_rotate_sub sets the speed of reversing the rotation - 30.f, // View_angle sets the maximum view angle - - 0.f, // CF_X the X Position of the Coverflow - -0.2f, // CF_Y the Y Position of the Coverflow - -7.f, // CF_Z the Z Position of the Coverflow - - 0.f, // CF_RX the X Rotation of the Coverflow - 0.f, // CF_RY the Y Rotation of the Coverflow - 0.f, // CF_RZ the Z Rotation of the Coverflow - - 0.f, // Rotation sets the rotation of each cover - 0.18f, // X_Distance sets the distance between the covers - 1.f, // Center_Distance sets the distance between the centered and the non centered covers - 0.1f, // Z_Distance sets the pushback amount - 0.0f, // Y_Distance sets the elevation amount - - 22.f // zoom level - -}; - -struct Preset pressetYACReaderFlowUpConfig = { - 0.08f, // Animation_step sets the speed of the animation - 1.5f, // Animation_speedup sets the acceleration of the animation - 0.1f, // Animation_step_max sets the maximum speed of the animation - 2.5f, // Animation_Fade_out_dis sets the distance of view - - 1.5f, // pre_rotation sets the rotation increasion - 3.f, // View_rotate_light_strenght sets the light strenght on rotation - 0.08f, // View_rotate_add sets the speed of the rotation - 0.08f, // View_rotate_sub sets the speed of reversing the rotation - 5.f, // View_angle sets the maximum view angle - - 0.f, // CF_X the X Position of the Coverflow - -0.2f, // CF_Y the Y Position of the Coverflow - -7.f, // CF_Z the Z Position of the Coverflow - - 0.f, // CF_RX the X Rotation of the Coverflow - 0.f, // CF_RY the Y Rotation of the Coverflow - 0.f, // CF_RZ the Z Rotation of the Coverflow - - -50.f, // Rotation sets the rotation of each cover - 0.18f, // X_Distance sets the distance between the covers - 1.f, // Center_Distance sets the distance between the centered and the non centered covers - 0.1f, // Z_Distance sets the pushback amount - -0.1f, // Y_Distance sets the elevation amount - - 22.f // zoom level - -}; - -struct Preset pressetYACReaderFlowDownConfig = { - 0.08f, // Animation_step sets the speed of the animation - 1.5f, // Animation_speedup sets the acceleration of the animation - 0.1f, // Animation_step_max sets the maximum speed of the animation - 2.5f, // Animation_Fade_out_dis sets the distance of view - - 1.5f, // pre_rotation sets the rotation increasion - 3.f, // View_rotate_light_strenght sets the light strenght on rotation - 0.08f, // View_rotate_add sets the speed of the rotation - 0.08f, // View_rotate_sub sets the speed of reversing the rotation - 5.f, // View_angle sets the maximum view angle - - 0.f, // CF_X the X Position of the Coverflow - -0.2f, // CF_Y the Y Position of the Coverflow - -7.f, // CF_Z the Z Position of the Coverflow - - 0.f, // CF_RX the X Rotation of the Coverflow - 0.f, // CF_RY the Y Rotation of the Coverflow - 0.f, // CF_RZ the Z Rotation of the Coverflow - - -50.f, // Rotation sets the rotation of each cover - 0.18f, // X_Distance sets the distance between the covers - 1.f, // Center_Distance sets the distance between the centered and the non centered covers - 0.1f, // Z_Distance sets the pushback amount - 0.1f, // Y_Distance sets the elevation amount - - 22.f // zoom level -}; -/*Constructor*/ -YACReaderFlowGL::YACReaderFlowGL(QWidget *parent, struct Preset p) - : QOpenGLWidget(parent), numObjects(0), lazyPopulateObjects(-1), hasBeenInitialized(false), bUseVSync(false), flowRightToLeft(false) -{ - updateCount = 0; - config = p; - currentSelected = 0; - - centerPos.x = 0.f; - centerPos.y = 0.f; - centerPos.z = 1.f; - centerPos.rot = 0.f; - - shadingTop = 0.8f; - shadingBottom = 0.02f; - reflectionUp = 0.f; - reflectionBottom = 0.6f; - - setBackgroundColor(Qt::black); - - numObjects = 0; - viewRotate = 0.f; - viewRotateActive = 0; - stepBackup = config.animationStep / config.animationSpeedUp; - - QSurfaceFormat f = format(); - f.setSamples(4); - f.setSwapInterval(0); - - // Detect if we should use OpenGL ES - // Check if app-level ES is forced (via Qt::AA_UseOpenGLES) - bool forceES = QCoreApplication::testAttribute(Qt::AA_UseOpenGLES); - - if (forceES) { - // Use OpenGL ES 3.0 - f.setRenderableType(QSurfaceFormat::OpenGLES); - f.setVersion(3, 0); - qDebug() << "YACReaderFlowGL: Requesting OpenGL ES 3.0 context"; - } else { - // Use Desktop OpenGL 3.3 Core - f.setRenderableType(QSurfaceFormat::OpenGL); - f.setVersion(3, 3); - f.setProfile(QSurfaceFormat::CoreProfile); - qDebug() << "YACReaderFlowGL: Requesting Desktop OpenGL 3.3 Core context"; - } - - setFormat(f); - - timerId = startTimer(updateInterval); -} - -void YACReaderFlowGL::timerEvent(QTimerEvent *event) -{ - if (timerId == event->timerId()) - update(); -} - -void YACReaderFlowGL::startAnimationTimer() -{ - if (timerId == -1) - timerId = startTimer(updateInterval); -} - -void YACReaderFlowGL::stopAnimationTimer() -{ - if (timerId != -1) { - killTimer(timerId); - timerId = -1; - } -} - -YACReaderFlowGL::~YACReaderFlowGL() -{ - makeCurrent(); - - delete vao; - delete vbo; - delete instanceVBO; - delete shaderProgram; - - if (defaultTexture) { - if (defaultTexture->isCreated()) - defaultTexture->destroy(); - delete defaultTexture; - } - -#ifdef YACREADER_LIBRARY - if (markTexture) { - if (markTexture->isCreated()) - markTexture->destroy(); - delete markTexture; - } - - if (readingTexture) { - if (readingTexture->isCreated()) - readingTexture->destroy(); - delete readingTexture; - } -#endif - - doneCurrent(); -} - -QSize YACReaderFlowGL::minimumSizeHint() const -{ - return QSize(320, 200); -} - -void YACReaderFlowGL::setupShaders() -{ - bool isES = QOpenGLContext::currentContext()->isOpenGLES(); - - // Vertex Shader - Desktop GL 3.3 - const char *vertexShaderSourceGL = R"( - #version 330 core - layout(location = 0) in vec3 position; - layout(location = 1) in vec2 texCoord; - layout(location = 2) in mat4 instanceModel; - layout(location = 6) in vec4 instanceShading1; - layout(location = 7) in float instanceOpacity; - - out vec2 vTexCoord; - out vec4 vColor; - - uniform mat4 viewProjectionMatrix; - - void main() - { - gl_Position = viewProjectionMatrix * instanceModel * vec4(position, 1.0); - vTexCoord = texCoord; - - float leftUpShading = instanceShading1.x; - float leftDownShading = instanceShading1.y; - float rightUpShading = instanceShading1.z; - float rightDownShading = instanceShading1.w; - - float leftShading = mix(leftDownShading, leftUpShading, (position.y + 0.5)); - float rightShading = mix(rightDownShading, rightUpShading, (position.y + 0.5)); - float shading = mix(leftShading, rightShading, (position.x + 0.5)); - - vColor = vec4(shading * instanceOpacity); - } - )"; - - // Vertex Shader - OpenGL ES 3.0 - const char *vertexShaderSourceES = R"( - #version 300 es - precision highp float; - - layout(location = 0) in vec3 position; - layout(location = 1) in vec2 texCoord; - layout(location = 2) in mat4 instanceModel; - layout(location = 6) in vec4 instanceShading1; - layout(location = 7) in float instanceOpacity; - - out vec2 vTexCoord; - out vec4 vColor; - - uniform mat4 viewProjectionMatrix; - - void main() - { - gl_Position = viewProjectionMatrix * instanceModel * vec4(position, 1.0); - vTexCoord = texCoord; - - float leftUpShading = instanceShading1.x; - float leftDownShading = instanceShading1.y; - float rightUpShading = instanceShading1.z; - float rightDownShading = instanceShading1.w; - - float leftShading = mix(leftDownShading, leftUpShading, (position.y + 0.5)); - float rightShading = mix(rightDownShading, rightUpShading, (position.y + 0.5)); - float shading = mix(leftShading, rightShading, (position.x + 0.5)); - - vColor = vec4(shading * instanceOpacity); - } - )"; - - // Fragment Shader - Desktop GL 3.3 - const char *fragmentShaderSourceGL = R"( - #version 330 core - in vec2 vTexCoord; - in vec4 vColor; - - out vec4 fragColor; - - uniform sampler2D texture; - uniform bool isReflection; - uniform float reflectionUp; - uniform float reflectionDown; - uniform vec3 backgroundColor; - uniform vec3 shadingColor; - - void main() - { - vec2 texCoord = vTexCoord; - - if (isReflection) { - texCoord.y = 1.0 - vTexCoord.y; - vec4 texColor = texture2D(texture, texCoord); - float gradientFade = mix(1.0/3.0, reflectionUp / 2.0, vTexCoord.y); - float shadingAmount = vColor.r * gradientFade; - vec3 shadedColor = mix(backgroundColor, texColor.rgb, shadingAmount); - fragColor = vec4(shadedColor, texColor.a); - } else { - vec4 texColor = texture2D(texture, texCoord); - float shadingAmount = vColor.r; - vec3 shadedColor = mix(backgroundColor, texColor.rgb, shadingAmount); - fragColor = vec4(shadedColor, texColor.a); - } - } - )"; - - // Fragment Shader - OpenGL ES 3.0 - const char *fragmentShaderSourceES = R"( - #version 300 es - precision highp float; - - in vec2 vTexCoord; - in vec4 vColor; - - out vec4 fragColor; - - uniform sampler2D texture; - uniform bool isReflection; - uniform float reflectionUp; - uniform float reflectionDown; - uniform vec3 backgroundColor; - uniform vec3 shadingColor; - - void main() - { - vec2 texCoord = vTexCoord; - - if (isReflection) { - texCoord.y = 1.0 - vTexCoord.y; - vec4 texColor = texture(texture, texCoord); - float gradientFade = mix(1.0/3.0, reflectionUp / 2.0, vTexCoord.y); - float shadingAmount = vColor.r * gradientFade; - vec3 shadedColor = mix(backgroundColor, texColor.rgb, shadingAmount); - fragColor = vec4(shadedColor, texColor.a); - } else { - vec4 texColor = texture(texture, texCoord); - float shadingAmount = vColor.r; - vec3 shadedColor = mix(backgroundColor, texColor.rgb, shadingAmount); - fragColor = vec4(shadedColor, texColor.a); - } - } - )"; - - // Select shaders based on context type - const char *vertexShader = isES ? vertexShaderSourceES : vertexShaderSourceGL; - const char *fragmentShader = isES ? fragmentShaderSourceES : fragmentShaderSourceGL; - - qDebug() << "YACReaderFlowGL: Using" << (isES ? "OpenGL ES 3.0" : "Desktop OpenGL 3.3") << "shaders"; - - shaderProgram = new QOpenGLShaderProgram(this); - shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader); - shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader); - - if (!shaderProgram->link()) { - qWarning() << "YACReaderFlowGL: Shader linking failed:" << shaderProgram->log(); - } -} - -void YACReaderFlowGL::setupGeometry() -{ - // VAO for regular covers - vao = new QOpenGLVertexArrayObject(this); - vao->create(); - vao->bind(); - - vbo = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); - vbo->create(); - vbo->bind(); - - // Quad vertices with texture coordinates - GLfloat vertices[] = { - // Position (x, y, z), TexCoord (u, v) - -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-left - 0.5f, -0.5f, 0.0f, 1.0f, 1.0f, // Bottom-right - 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right - -0.5f, 0.5f, 0.0f, 0.0f, 0.0f // Top-left - }; - - vbo->allocate(vertices, sizeof(vertices)); - - // Position attribute - shaderProgram->enableAttributeArray(0); - shaderProgram->setAttributeBuffer(0, GL_FLOAT, 0, 3, 5 * sizeof(GLfloat)); - - // TexCoord attribute - shaderProgram->enableAttributeArray(1); - shaderProgram->setAttributeBuffer(1, GL_FLOAT, 3 * sizeof(GLfloat), 2, 5 * sizeof(GLfloat)); - - // Create instance buffer (will be filled per-frame) - instanceVBO = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); - instanceVBO->create(); - instanceVBO->bind(); - - // Per-instance attributes (model matrix = 4 vec4s, shading = 1 vec4, opacity = 1 float) - // Location 2-5: model matrix (mat4) - for (int i = 0; i < 4; i++) { - shaderProgram->enableAttributeArray(2 + i); - shaderProgram->setAttributeBuffer(2 + i, GL_FLOAT, i * 4 * sizeof(GLfloat), 4, 21 * sizeof(GLfloat)); - glVertexAttribDivisor(2 + i, 1); // Advance once per instance - } - - // Location 6: shading vec4 (leftUp, leftDown, rightUp, rightDown) - shaderProgram->enableAttributeArray(6); - shaderProgram->setAttributeBuffer(6, GL_FLOAT, 16 * sizeof(GLfloat), 4, 21 * sizeof(GLfloat)); - glVertexAttribDivisor(6, 1); - - // Location 7: opacity float - shaderProgram->enableAttributeArray(7); - shaderProgram->setAttributeBuffer(7, GL_FLOAT, 20 * sizeof(GLfloat), 1, 21 * sizeof(GLfloat)); - glVertexAttribDivisor(7, 1); - - vao->release(); - instanceVBO->release(); - vbo->release(); -} - -void YACReaderFlowGL::initializeGL() -{ - if (!context() || !context()->isValid()) { - qWarning() << "YACReaderFlowGL: Invalid OpenGL context"; - return; - } - - initializeOpenGLFunctions(); - - // Verify instancing support (available in OpenGL 3.3+ and ES 3.0+) - bool hasInstancing = context()->hasExtension(QByteArrayLiteral("GL_ARB_instanced_arrays")) || - context()->format().majorVersion() >= 3; - - if (!hasInstancing) { - qWarning() << "YACReaderFlowGL: Instanced rendering not supported!"; - qWarning() << "YACReaderFlowGL: OpenGL version:" << context()->format().majorVersion() << "." << context()->format().minorVersion(); - return; - } - - setupShaders(); - setupGeometry(); - - defaultTexture = new QOpenGLTexture(QImage(":/images/defaultCover.png")); - defaultTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear); - -#ifdef YACREADER_LIBRARY - markTexture = new QOpenGLTexture(QImage(":/images/readRibbon.png")); - markTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear); - - readingTexture = new QOpenGLTexture(QImage(":/images/readingRibbon.png")); - readingTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear); -#endif - - if (lazyPopulateObjects != -1) - populate(lazyPopulateObjects); - - hasBeenInitialized = true; -} - -void YACReaderFlowGL::paintGL() -{ - if (!context() || !context()->isValid() || !shaderProgram) - return; - - QPainter painter; - painter.begin(this); - painter.beginNativePainting(); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glEnable(GL_BLEND); - glEnable(GL_MULTISAMPLE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glClearColor(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF(), 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if (numObjects > 0) { - updatePositions(); - updatePerspective(width(), height()); - draw(); - } - - glDisable(GL_MULTISAMPLE); - glDisable(GL_BLEND); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - - painter.endNativePainting(); - - QFont font = painter.font(); - font.setFamily("Arial"); - font.setPointSize(fontSize); - painter.setFont(font); - painter.setPen(textColor); - painter.drawText(10, fontSize + 10, QString("%1/%2").arg(currentSelected + 1).arg(numObjects)); - - painter.end(); -} - -void YACReaderFlowGL::resizeGL(int width, int height) -{ - if (!context() || !context()->isValid()) - return; - - fontSize = (width + height) * 0.010; - if (fontSize < 10) - fontSize = 10; - - updatePerspective(width, height); - - if (numObjects > 0) - updatePositions(); -} - -void YACReaderFlowGL::updatePerspective(int width, int height) -{ - if (!context() || !context()->isValid()) - return; - - float pixelRatio = devicePixelRatioF(); - glViewport(0, 0, width * pixelRatio, height * pixelRatio); -} - -void YACReaderFlowGL::calcPos(YACReader3DImage &image, int pos) -{ - if (flowRightToLeft) { - pos = pos * -1; - } - - if (pos == 0) { - image.current = centerPos; - } else { - if (pos > 0) { - image.current.x = (config.centerDistance) + (config.xDistance * pos); - image.current.y = config.yDistance * pos * -1; - image.current.z = config.zDistance * pos * -1; - image.current.rot = config.rotation; - } else { - image.current.x = (config.centerDistance) * -1 + (config.xDistance * pos); - image.current.y = config.yDistance * pos; - image.current.z = config.zDistance * pos; - image.current.rot = config.rotation * -1; - } - } -} - -void YACReaderFlowGL::calcVector(YACReader3DVector &vector, int pos) -{ - calcPos(dummy, pos); - vector.x = dummy.current.x; - vector.y = dummy.current.y; - vector.z = dummy.current.z; - vector.rot = dummy.current.rot; -} - -bool YACReaderFlowGL::animate(YACReader3DVector ¤tVector, YACReader3DVector &toVector) -{ - float rotDiff = toVector.rot - currentVector.rot; - float xDiff = toVector.x - currentVector.x; - float yDiff = toVector.y - currentVector.y; - float zDiff = toVector.z - currentVector.z; - - if (fabs(rotDiff) < 0.01 && fabs(xDiff) < 0.001 && fabs(yDiff) < 0.001 && fabs(zDiff) < 0.001) - return true; - - currentVector.x = currentVector.x + (xDiff)*config.animationStep; - currentVector.y = currentVector.y + (yDiff)*config.animationStep; - currentVector.z = currentVector.z + (zDiff)*config.animationStep; - - if (fabs(rotDiff) > 0.01) { - currentVector.rot = currentVector.rot + (rotDiff) * (config.animationStep * config.preRotation); - } else { - viewRotateActive = 0; - } - - return false; -} - -void YACReaderFlowGL::drawCover(const YACReader3DImage &image) -{ - if (!shaderProgram || !vao || !image.texture) - return; - - float w = image.width; - float h = image.height; - - // Calculate opacity - original formula exactly - float opacity = 1 - 1 / (config.animationFadeOutDist + config.viewRotateLightStrenght * fabs(viewRotate)) * fabs(0 - image.current.x); - - // Setup matrices - QMatrix4x4 projectionMatrix; - projectionMatrix.perspective(config.zoom, GLdouble(width()) / (float)height(), 1.0, 200.0); - - QMatrix4x4 viewMatrix; - viewMatrix.translate(config.cfX, config.cfY, config.cfZ); - viewMatrix.rotate(config.cfRX, 1, 0, 0); - viewMatrix.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); - viewMatrix.rotate(config.cfRZ, 0, 0, 1); - - QMatrix4x4 modelMatrix; - modelMatrix.translate(image.current.x, image.current.y, image.current.z); - modelMatrix.rotate(image.current.rot, 0, 1, 0); - modelMatrix.translate(0.0f, -0.5f + h / 2.0f, 0.0f); - modelMatrix.scale(w, h, 1.0f); - - QMatrix4x4 mvpMatrix = projectionMatrix * viewMatrix * modelMatrix; - - // Calculate per-corner shading exactly as original - float LShading = ((config.rotation != 0) ? ((image.current.rot < 0) ? 1 - 1 / config.rotation * image.current.rot : 1) : 1); - float RShading = ((config.rotation != 0) ? ((image.current.rot > 0) ? 1 - 1 / (config.rotation * -1) * image.current.rot : 1) : 1); - float LUP = shadingTop + (1 - shadingTop) * LShading; - float LDOWN = shadingBottom + (1 - shadingBottom) * LShading; - float RUP = shadingTop + (1 - shadingTop) * RShading; - float RDOWN = shadingBottom + (1 - shadingBottom) * RShading; - - // Bind shader and set uniforms - shaderProgram->bind(); - shaderProgram->setUniformValue("mvpMatrix", mvpMatrix); - shaderProgram->setUniformValue("leftUpShading", LUP); - shaderProgram->setUniformValue("leftDownShading", LDOWN); - shaderProgram->setUniformValue("rightUpShading", RUP); - shaderProgram->setUniformValue("rightDownShading", RDOWN); - shaderProgram->setUniformValue("opacity", opacity); - shaderProgram->setUniformValue("isReflection", false); - - // Bind texture and VAO - image.texture->bind(); - vao->bind(); - - // Draw cover - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - // Draw marks if needed - if (showMarks && loaded[image.index] && marks[image.index] != Unread) { - QOpenGLTexture *markTex = (marks[image.index] == Read) ? markTexture : readingTexture; - - QMatrix4x4 markModel; - markModel.translate(image.current.x, image.current.y, image.current.z); - markModel.rotate(image.current.rot, 0, 1, 0); - - float markWidth = 0.15f; - float markHeight = 0.2f; - float markCenterX = w / 2.0f - 0.125f; - float markCenterY = -0.588f + h; - - markModel.translate(markCenterX, markCenterY, 0.001f); - markModel.scale(markWidth, markHeight, 1.0f); - - QMatrix4x4 mvpMark = projectionMatrix * viewMatrix * markModel; - - shaderProgram->setUniformValue("mvpMatrix", mvpMark); - shaderProgram->setUniformValue("leftUpShading", RUP * opacity); - shaderProgram->setUniformValue("leftDownShading", RUP * opacity); - shaderProgram->setUniformValue("rightUpShading", RUP * opacity); - shaderProgram->setUniformValue("rightDownShading", RUP * opacity); - shaderProgram->setUniformValue("opacity", 1.0f); - shaderProgram->setUniformValue("isReflection", false); - - markTex->bind(); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - vao->release(); - shaderProgram->release(); -} - -void YACReaderFlowGL::drawReflection(const YACReader3DImage &image) -{ - if (!shaderProgram || !vao || !image.texture) - return; - - float w = image.width; - float h = image.height; - - // Calculate opacity - original formula exactly - float opacity = 1 - 1 / (config.animationFadeOutDist + config.viewRotateLightStrenght * fabs(viewRotate)) * fabs(0 - image.current.x); - - // Setup matrices - QMatrix4x4 projectionMatrix; - projectionMatrix.perspective(config.zoom, GLdouble(width()) / (float)height(), 1.0, 200.0); - - QMatrix4x4 viewMatrix; - viewMatrix.translate(config.cfX, config.cfY, config.cfZ); - viewMatrix.rotate(config.cfRX, 1, 0, 0); - viewMatrix.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); - viewMatrix.rotate(config.cfRZ, 0, 0, 1); - - // Calculate per-corner shading exactly as original - float LShading = ((config.rotation != 0) ? ((image.current.rot < 0) ? 1 - 1 / config.rotation * image.current.rot : 1) : 1); - float RShading = ((config.rotation != 0) ? ((image.current.rot > 0) ? 1 - 1 / (config.rotation * -1) * image.current.rot : 1) : 1); - float LUP = shadingTop + (1 - shadingTop) * LShading; - float LDOWN = shadingBottom + (1 - shadingBottom) * LShading; - float RUP = shadingTop + (1 - shadingTop) * RShading; - float RDOWN = shadingBottom + (1 - shadingBottom) * RShading; - - // Draw reflection - // In the old code, the reflection quad had vertices from y=-0.5-h (bottom) to y=-0.5 (top) - // The OLD reflection shading was: - // - Bottom corners (y = -0.5-h): LUP*opacity*reflectionUp/2, RUP*opacity*reflectionUp/2 - // - Top corners (y = -0.5): LDOWN*opacity/3, RDOWN*opacity/3 - // This means the reflection uses INVERTED vertical shading (LUP/RUP at bottom, LDOWN/RDOWN at top) - // We need to pass swapped values to match this - QMatrix4x4 reflectionMatrix; - reflectionMatrix.translate(image.current.x, image.current.y, image.current.z); - reflectionMatrix.rotate(image.current.rot, 0, 1, 0); - reflectionMatrix.translate(0.0f, -0.5f - h / 2.0f, 0.0f); - reflectionMatrix.scale(w, h, 1.0f); - - QMatrix4x4 mvpReflection = projectionMatrix * viewMatrix * reflectionMatrix; - - shaderProgram->bind(); - shaderProgram->setUniformValue("mvpMatrix", mvpReflection); - // Swap UP and DOWN for reflection to match old behavior - shaderProgram->setUniformValue("leftUpShading", LDOWN); - shaderProgram->setUniformValue("leftDownShading", LUP); - shaderProgram->setUniformValue("rightUpShading", RDOWN); - shaderProgram->setUniformValue("rightDownShading", RUP); - shaderProgram->setUniformValue("opacity", opacity); - shaderProgram->setUniformValue("isReflection", true); - shaderProgram->setUniformValue("reflectionUp", reflectionUp); - shaderProgram->setUniformValue("reflectionDown", reflectionBottom); - - image.texture->bind(); - vao->bind(); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - vao->release(); - shaderProgram->release(); -} - -void YACReaderFlowGL::cleanupAnimation() -{ - config.animationStep = stepBackup; - viewRotateActive = 0; -} - -void YACReaderFlowGL::draw() -{ - if (!shaderProgram || !vao || numObjects == 0) - return; - - // Calculate view-projection matrix once - // Note: Old implementation used fixed 20.0 degrees FOV, not config.zoom - QMatrix4x4 projectionMatrix; - projectionMatrix.perspective(20.0, GLdouble(width()) / (float)height(), 1.0, 200.0); - - QMatrix4x4 viewMatrix; - viewMatrix.translate(config.cfX, config.cfY, config.cfZ); - viewMatrix.rotate(config.cfRX, 1, 0, 0); - viewMatrix.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); - viewMatrix.rotate(config.cfRZ, 0, 0, 1); - - QMatrix4x4 viewProjectionMatrix = projectionMatrix * viewMatrix; - - // Bind shader once - shaderProgram->bind(); - shaderProgram->setUniformValue("viewProjectionMatrix", viewProjectionMatrix); - shaderProgram->setUniformValue("backgroundColor", - QVector3D(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF())); - shaderProgram->setUniformValue("shadingColor", - QVector3D(shadingColor.redF(), shadingColor.greenF(), shadingColor.blueF())); - - int CS = currentSelected; - - // Prepare instance data for all covers - QVector instanceData; - QVector drawOrder; - - // Build draw order (back to front) - for (int count = numObjects - 1; count > -1; count--) { - if (count > CS) { - drawOrder.append(count); - } - } - for (int count = 0; count < numObjects - 1; count++) { - if (count < CS) { - drawOrder.append(count); - } - } - drawOrder.append(CS); - - // Draw reflections first - shaderProgram->setUniformValue("isReflection", true); - shaderProgram->setUniformValue("reflectionUp", reflectionUp); - shaderProgram->setUniformValue("reflectionDown", reflectionBottom); - - for (int idx : drawOrder) { - if (images[idx].texture) { - prepareInstanceData(images[idx], true, instanceData); - - instanceVBO->bind(); - instanceVBO->allocate(instanceData.data(), instanceData.size() * sizeof(GLfloat)); - - images[idx].texture->bind(); - vao->bind(); - glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, 1); - - instanceData.clear(); - } - } - - // Draw covers - shaderProgram->setUniformValue("isReflection", false); - - for (int idx : drawOrder) { - if (images[idx].texture) { - prepareInstanceData(images[idx], false, instanceData); - - instanceVBO->bind(); - instanceVBO->allocate(instanceData.data(), instanceData.size() * sizeof(GLfloat)); - - images[idx].texture->bind(); - vao->bind(); - glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, 1); - - // Draw marks if needed - if (showMarks && loaded[images[idx].index] && marks[images[idx].index] != Unread) { - drawMark(images[idx], viewProjectionMatrix); - } - - instanceData.clear(); - } - } - - vao->release(); - shaderProgram->release(); -} - -void YACReaderFlowGL::prepareInstanceData(const YACReader3DImage &image, bool isReflection, QVector &data) -{ - float w = image.width; - float h = image.height; - - // Calculate opacity - float opacity = 1 - 1 / (config.animationFadeOutDist + config.viewRotateLightStrenght * fabs(viewRotate)) * fabs(0 - image.current.x); - - // Calculate model matrix - QMatrix4x4 modelMatrix; - modelMatrix.translate(image.current.x, image.current.y, image.current.z); - modelMatrix.rotate(image.current.rot, 0, 1, 0); - - if (isReflection) { - modelMatrix.translate(0.0f, -0.5f - h / 2.0f, 0.0f); - } else { - modelMatrix.translate(0.0f, -0.5f + h / 2.0f, 0.0f); - } - modelMatrix.scale(w, h, 1.0f); - - // Calculate shading - float LShading = ((config.rotation != 0) ? ((image.current.rot < 0) ? 1 - 1 / config.rotation * image.current.rot : 1) : 1); - float RShading = ((config.rotation != 0) ? ((image.current.rot > 0) ? 1 - 1 / (config.rotation * -1) * image.current.rot : 1) : 1); - float LUP = shadingTop + (1 - shadingTop) * LShading; - float LDOWN = shadingBottom + (1 - shadingBottom) * LShading; - float RUP = shadingTop + (1 - shadingTop) * RShading; - float RDOWN = shadingBottom + (1 - shadingBottom) * RShading; - - // For reflection, swap vertical shading - if (isReflection) { - float temp = LUP; - LUP = LDOWN; - LDOWN = temp; - temp = RUP; - RUP = RDOWN; - RDOWN = temp; - } - - // Pack instance data: mat4 (16 floats) + vec4 shading (4 floats) + float opacity (1 float) = 21 floats - const float *matData = modelMatrix.constData(); - for (int i = 0; i < 16; i++) { - data.append(matData[i]); - } - data.append(LUP); - data.append(LDOWN); - data.append(RUP); - data.append(RDOWN); - data.append(opacity); -} - -void YACReaderFlowGL::drawMark(const YACReader3DImage &image, const QMatrix4x4 &viewProjectionMatrix) -{ - QOpenGLTexture *markTex = (marks[image.index] == Read) ? markTexture : readingTexture; - - float w = image.width; - float h = image.height; - float opacity = 1 - 1 / (config.animationFadeOutDist + config.viewRotateLightStrenght * fabs(viewRotate)) * fabs(0 - image.current.x); - - float LShading = ((config.rotation != 0) ? ((image.current.rot < 0) ? 1 - 1 / config.rotation * image.current.rot : 1) : 1); - float RShading = ((config.rotation != 0) ? ((image.current.rot > 0) ? 1 - 1 / (config.rotation * -1) * image.current.rot : 1) : 1); - float RUP = shadingTop + (1 - shadingTop) * RShading; - - QMatrix4x4 markModel; - markModel.translate(image.current.x, image.current.y, image.current.z); - markModel.rotate(image.current.rot, 0, 1, 0); - - float markWidth = 0.15f; - float markHeight = 0.2f; - float markCenterX = w / 2.0f - 0.125f; - float markCenterY = -0.588f + h; - - markModel.translate(markCenterX, markCenterY, 0.001f); - markModel.scale(markWidth, markHeight, 1.0f); - - // Prepare instance data for mark - QVector markData; - const float *matData = markModel.constData(); - for (int i = 0; i < 16; i++) { - markData.append(matData[i]); - } - float shadingValue = RUP * opacity; - markData.append(shadingValue); - markData.append(shadingValue); - markData.append(shadingValue); - markData.append(shadingValue); - markData.append(1.0f); - - instanceVBO->bind(); - instanceVBO->allocate(markData.data(), markData.size() * sizeof(GLfloat)); - - markTex->bind(); - vao->bind(); - glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, 1); -} - -void YACReaderFlowGL::showPrevious() -{ - startAnimationTimer(); - - if (currentSelected > 0) { - currentSelected--; - emit centerIndexChanged(currentSelected); - config.animationStep *= config.animationSpeedUp; - - if (config.animationStep > config.animationStepMax) { - config.animationStep = config.animationStepMax; - } - - if (viewRotateActive && viewRotate > -1) { - viewRotate -= config.viewRotateAdd; - } - - viewRotateActive = 1; - } -} - -void YACReaderFlowGL::showNext() -{ - startAnimationTimer(); - - if (currentSelected < numObjects - 1) { - currentSelected++; - emit centerIndexChanged(currentSelected); - config.animationStep *= config.animationSpeedUp; - - if (config.animationStep > config.animationStepMax) { - config.animationStep = config.animationStepMax; - } - - if (viewRotateActive && viewRotate < 1) { - viewRotate += config.viewRotateAdd; - } - - viewRotateActive = 1; - } -} - -void YACReaderFlowGL::setCurrentIndex(int pos) -{ - if (!(pos >= 0 && pos < images.length() && images.length() > 0)) - return; - if (pos >= images.length() && images.length() > 0) - pos = images.length() - 1; - - startAnimationTimer(); - - currentSelected = pos; - config.animationStep *= config.animationSpeedUp; - - if (config.animationStep > config.animationStepMax) { - config.animationStep = config.animationStepMax; - } - - if (viewRotateActive && viewRotate < 1) { - viewRotate += config.viewRotateAdd; - } - - viewRotateActive = 1; -} - -void YACReaderFlowGL::updatePositions() -{ - int count; - bool stopAnimation = true; - - for (count = numObjects - 1; count > -1; count--) { - calcVector(images[count].animEnd, count - currentSelected); - if (!animate(images[count].current, images[count].animEnd)) - stopAnimation = false; - } - - if (!viewRotateActive) { - viewRotate += (0 - viewRotate) * config.viewRotateSub; - } - - if (fabs(images[currentSelected].current.x - images[currentSelected].animEnd.x) < 1) { - cleanupAnimation(); - if (updateCount >= 0) { - updateCount = 0; - updateImageData(); - } else - updateCount++; - } else - updateCount++; - - if (stopAnimation) - stopAnimationTimer(); -} - -void YACReaderFlowGL::insert(char *name, QOpenGLTexture *texture, float x, float y, int item) -{ - startAnimationTimer(); - - Q_UNUSED(name) - if (item == -1) { - images.push_back(YACReader3DImage()); - item = numObjects; - numObjects++; - calcVector(images[item].current, item); - images[item].current.z = images[item].current.z - 1; - } - - images[item].texture = texture; - images[item].width = x; - images[item].height = y; - images[item].index = item; -} - -void YACReaderFlowGL::remove(int item) -{ - if (item < 0 || item >= images.size()) - return; - - startAnimationTimer(); - - loaded.remove(item); - marks.remove(item); - - if (item <= currentSelected && currentSelected != 0) { - currentSelected--; - } - - QOpenGLTexture *texture = images[item].texture; - - int count = item; - while (count <= numObjects - 1) { - images[count].index--; - count++; - } - images.removeAt(item); - - if (texture != defaultTexture) - delete (texture); - - numObjects--; -} - -void YACReaderFlowGL::add(int item) -{ - float x = 1; - float y = 1 * (700.f / 480.0f); - QString s = "cover"; - - images.insert(item, YACReader3DImage()); - loaded.insert(item, false); - marks.insert(item, Unread); - numObjects++; - - for (int i = item + 1; i < numObjects; i++) { - images[i].index++; - } - - insert(s.toLocal8Bit().data(), defaultTexture, x, y, item); -} - -YACReader3DImage YACReaderFlowGL::getCurrentSelected() -{ - return images[currentSelected]; -} - -void YACReaderFlowGL::replace(char *name, QOpenGLTexture *texture, float x, float y, int item) -{ - startAnimationTimer(); - - Q_UNUSED(name) - if (images[item].index == item) { - images[item].texture = texture; - images[item].width = x; - images[item].height = y; - loaded[item] = true; - } else - loaded[item] = false; -} - -void YACReaderFlowGL::populate(int n) -{ - emit centerIndexChanged(0); - - float x = 1; - float y = 1 * (700.f / 480.0f); - int i; - - for (i = 0; i < n; i++) { - QString s = "cover"; - insert(s.toLocal8Bit().data(), defaultTexture, x, y); - } - - loaded = QVector(n, false); -} - -void YACReaderFlowGL::reset() -{ - makeCurrent(); - startAnimationTimer(); - - currentSelected = 0; - loaded.clear(); - - for (int i = 0; i < numObjects; i++) { - if (images[i].texture != defaultTexture) - delete (images[i].texture); - } - - numObjects = 0; - images.clear(); - - if (!hasBeenInitialized) - lazyPopulateObjects = -1; - - doneCurrent(); -} - -void YACReaderFlowGL::reload() -{ - startAnimationTimer(); - int n = numObjects; - reset(); - populate(n); -} - -// Slot implementations -void YACReaderFlowGL::setCF_RX(int value) -{ - startAnimationTimer(); - config.cfRX = value; -} -void YACReaderFlowGL::setCF_RY(int value) -{ - startAnimationTimer(); - config.cfRY = value; -} -void YACReaderFlowGL::setCF_RZ(int value) -{ - startAnimationTimer(); - config.cfRZ = value; -} -void YACReaderFlowGL::setRotation(int angle) -{ - startAnimationTimer(); - config.rotation = -angle; -} -void YACReaderFlowGL::setX_Distance(int distance) -{ - startAnimationTimer(); - config.xDistance = distance / 100.0; -} -void YACReaderFlowGL::setCenter_Distance(int distance) -{ - startAnimationTimer(); - config.centerDistance = distance / 100.0; -} -void YACReaderFlowGL::setZ_Distance(int distance) -{ - startAnimationTimer(); - config.zDistance = distance / 100.0; -} -void YACReaderFlowGL::setCF_Y(int value) -{ - startAnimationTimer(); - config.cfY = value / 100.0; -} -void YACReaderFlowGL::setCF_Z(int value) -{ - startAnimationTimer(); - config.cfZ = value; -} -void YACReaderFlowGL::setY_Distance(int value) -{ - startAnimationTimer(); - config.yDistance = value / 100.0; -} -void YACReaderFlowGL::setFadeOutDist(int value) -{ - startAnimationTimer(); - config.animationFadeOutDist = value; -} -void YACReaderFlowGL::setLightStrenght(int value) -{ - startAnimationTimer(); - config.viewRotateLightStrenght = value; -} -void YACReaderFlowGL::setMaxAngle(int value) -{ - startAnimationTimer(); - config.viewAngle = value; -} -void YACReaderFlowGL::setPreset(const Preset &p) -{ - startAnimationTimer(); - config = p; -} - -void YACReaderFlowGL::setZoom(int zoom) -{ - startAnimationTimer(); - config.zoom = zoom; -} - -void YACReaderFlowGL::setPerformance(Performance performance) -{ - if (this->performance != performance) { - startAnimationTimer(); - this->performance = performance; - reload(); - } -} - -void YACReaderFlowGL::useVSync(bool b) -{ - if (bUseVSync != b) { - bUseVSync = b; - QSurfaceFormat f = format(); - f.setVersion(3, 3); - f.setProfile(QSurfaceFormat::CoreProfile); - f.setSwapInterval(b ? 1 : 0); - setFormat(f); - reset(); - } -} - -void YACReaderFlowGL::setShowMarks(bool value) -{ - startAnimationTimer(); - showMarks = value; -} -void YACReaderFlowGL::setMarks(QVector marks) -{ - startAnimationTimer(); - this->marks = marks; -} -void YACReaderFlowGL::setMarkImage(QImage &image) -{ - Q_UNUSED(image); -} -void YACReaderFlowGL::markSlide(int index, YACReader::YACReaderComicReadStatus status) -{ - startAnimationTimer(); - marks[index] = status; -} -void YACReaderFlowGL::unmarkSlide(int index) -{ - startAnimationTimer(); - marks[index] = YACReader::Unread; -} -void YACReaderFlowGL::setSlideSize(QSize size) -{ - Q_UNUSED(size); -} -void YACReaderFlowGL::clear() -{ - reset(); -} -void YACReaderFlowGL::setCenterIndex(unsigned int index) -{ - setCurrentIndex(index); -} -void YACReaderFlowGL::showSlide(int index) -{ - setCurrentIndex(index); -} -int YACReaderFlowGL::centerIndex() -{ - return currentSelected; -} -void YACReaderFlowGL::updateMarks() { } -void YACReaderFlowGL::render() { } -void YACReaderFlowGL::setFlowRightToLeft(bool b) -{ - flowRightToLeft = b; -} - -void YACReaderFlowGL::setBackgroundColor(const QColor &color) -{ - backgroundColor = color; - - // Auto-calculate shadingColor based on background brightness - qreal luminance = (backgroundColor.redF() * 0.299 + - backgroundColor.greenF() * 0.587 + - backgroundColor.blueF() * 0.114); - - if (luminance < 0.5) { - // Dark background - shade towards white - shadingColor = QColor(255, 255, 255); - // Use original shading values for dark backgrounds - shadingTop = 0.8f; - shadingBottom = 0.02f; - } else { - // Light background - shade towards black - shadingColor = QColor(0, 0, 0); - // Adjust shading range for better contrast on light backgrounds - shadingTop = 0.95f; - shadingBottom = 0.3f; - } - - update(); -} - -void YACReaderFlowGL::setTextColor(const QColor &color) -{ - textColor = color; - update(); -} - -void YACReaderFlowGL::setShadingColor(const QColor &color) -{ - shadingColor = color; - update(); -} - -// Event handlers -void YACReaderFlowGL::wheelEvent(QWheelEvent *event) -{ - Movement m = getMovement(event); - switch (m) { - case None: - return; - case Forward: - showNext(); - break; - case Backward: - showPrevious(); - break; - default: - break; - } -} - -void YACReaderFlowGL::keyPressEvent(QKeyEvent *event) -{ - if ((event->key() == Qt::Key_Left && !flowRightToLeft) || (event->key() == Qt::Key_Right && flowRightToLeft)) { - if (event->modifiers() == Qt::ControlModifier) - setCurrentIndex((currentSelected - 10 < 0) ? 0 : currentSelected - 10); - else - showPrevious(); - event->accept(); - return; - } - - if ((event->key() == Qt::Key_Right && !flowRightToLeft) || (event->key() == Qt::Key_Left && flowRightToLeft)) { - if (event->modifiers() == Qt::ControlModifier) - setCurrentIndex((currentSelected + 10 >= numObjects) ? numObjects - 1 : currentSelected + 10); - else - showNext(); - event->accept(); - return; - } - - if (event->key() == Qt::Key_Up) { - return; - } - - event->ignore(); -} - -void YACReaderFlowGL::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) { - QVector3D intersection = getPlaneIntersection(event->x(), event->y(), images[currentSelected]); - if ((intersection.x() > 0.5 && !flowRightToLeft) || (intersection.x() < -0.5 && flowRightToLeft)) { - showNext(); - } else if ((intersection.x() < -0.5 && !flowRightToLeft) || (intersection.x() > 0.5 && flowRightToLeft)) { - showPrevious(); - } - } else { - QOpenGLWidget::mousePressEvent(event); - } - doneCurrent(); -} - -void YACReaderFlowGL::mouseDoubleClickEvent(QMouseEvent *event) -{ - QVector3D intersection = getPlaneIntersection(event->x(), event->y(), images[currentSelected]); - - if (intersection.x() < 0.5 && intersection.x() > -0.5) { - emit selected(centerIndex()); - event->accept(); - } -} - -QVector3D YACReaderFlowGL::getPlaneIntersection(int x, int y, YACReader3DImage plane) -{ - if (!context() || !context()->isValid()) - return QVector3D(0, 0, 0); - - GLint viewport[4]; - QMatrix4x4 m_modelview; - QMatrix4x4 m_projection; - - makeCurrent(); - glGetIntegerv(GL_VIEWPORT, viewport); - - m_projection.perspective(config.zoom, GLdouble(width()) / (float)height(), 1.0, 200.0); - - m_modelview.translate(config.cfX, config.cfY, config.cfZ); - m_modelview.rotate(config.cfRX, 1, 0, 0); - m_modelview.rotate(viewRotate * config.viewAngle + config.cfRY, 0, 1, 0); - m_modelview.rotate(config.cfRZ, 0, 0, 1); - m_modelview.translate(plane.current.x, plane.current.y, plane.current.z); - m_modelview.rotate(plane.current.rot, 0, 1, 0); - m_modelview.scale(plane.width, plane.height, 1.0f); - - doneCurrent(); - - QVector3D ray_origin(x * devicePixelRatioF(), y * devicePixelRatioF(), 0); - QVector3D ray_end(x * devicePixelRatioF(), y * devicePixelRatioF(), 1.0); - - ray_origin = ray_origin.unproject(m_modelview, m_projection, QRect(viewport[0], viewport[1], viewport[2], viewport[3])); - ray_end = ray_end.unproject(m_modelview, m_projection, QRect(viewport[0], viewport[1], viewport[2], viewport[3])); - - QVector3D ray_vector = ray_end - ray_origin; - - QVector3D plane_origin(-0.5f, -0.5f, 0); - QVector3D plane_vektor_1 = QVector3D(0.5f, -0.5f, 0) - plane_origin; - QVector3D plane_vektor_2 = QVector3D(-0.5f, 0.5f, 0) - plane_origin; - - double intersection_LES_determinant = ((plane_vektor_1.x() * plane_vektor_2.y() * (-1) * ray_vector.z()) + - (plane_vektor_2.x() * (-1) * ray_vector.y() * plane_vektor_1.z()) + - ((-1) * ray_vector.x() * plane_vektor_1.y() * plane_vektor_2.z()) - - ((-1) * ray_vector.x() * plane_vektor_2.y() * plane_vektor_1.z()) - - (plane_vektor_1.x() * (-1) * ray_vector.y() * plane_vektor_2.z()) - - (plane_vektor_2.x() * plane_vektor_1.y() * (-1) * ray_vector.z())); - - QVector3D det = ray_origin - plane_origin; - - double intersection_ray_determinant = ((plane_vektor_1.x() * plane_vektor_2.y() * det.z()) + - (plane_vektor_2.x() * det.y() * plane_vektor_1.z()) + - (det.x() * plane_vektor_1.y() * plane_vektor_2.z()) - - (det.x() * plane_vektor_2.y() * plane_vektor_1.z()) - - (plane_vektor_1.x() * det.y() * plane_vektor_2.z()) - - (plane_vektor_2.x() * plane_vektor_1.y() * det.z())); - - return ray_origin + ray_vector * (intersection_ray_determinant / intersection_LES_determinant); -} - -// YACReaderComicFlowGL implementation -YACReaderComicFlowGL::YACReaderComicFlowGL(QWidget *parent, struct Preset p) - : YACReaderFlowGL(parent, p) -{ - worker = new ImageLoaderGL(this); - worker->flow = this; -} - -void YACReaderComicFlowGL::setImagePaths(QStringList paths) -{ - worker->reset(); - reset(); - numObjects = 0; - if (lazyPopulateObjects != -1 || hasBeenInitialized) - YACReaderFlowGL::populate(paths.size()); - lazyPopulateObjects = paths.size(); - this->paths = paths; -} - -void YACReaderComicFlowGL::updateImageData() -{ - if (worker->busy()) - return; - - int idx = worker->index(); - if (idx >= 0 && !worker->result().isNull()) { - if (!loaded[idx]) { - float x = 1; - QImage img = worker->result(); - QOpenGLTexture *texture = new QOpenGLTexture(img); - - if (performance == high || performance == ultraHigh) { - texture->setAutoMipMapGenerationEnabled(true); - texture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear); - } else { - texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); - } - - float y = 1 * (float(img.height()) / img.width()); - QString s = "cover"; - replace(s.toLocal8Bit().data(), texture, x, y, idx); - } - } - - int count = 8; - switch (performance) { - case low: - count = 8; - break; - case medium: - count = 10; - break; - case high: - count = 12; - break; - case ultraHigh: - count = 16; - break; - } - - int *indexes = new int[2 * count + 1]; - int center = currentSelected; - indexes[0] = center; - for (int j = 0; j < count; j++) { - indexes[j * 2 + 1] = center + j + 1; - indexes[j * 2 + 2] = center - j - 1; - } - - for (int c = 0; c < 2 * count + 1; c++) { - int i = indexes[c]; - if ((i >= 0) && (i < numObjects)) - if (!loaded[i]) { - if (paths.size() > 0) { - QString fname = paths.at(i); - worker->generate(i, fname); - } - delete[] indexes; - return; - } - } - - delete[] indexes; -} - -void YACReaderComicFlowGL::remove(int item) -{ - worker->lock(); - worker->reset(); - YACReaderFlowGL::remove(item); - if (item >= 0 && item < paths.size()) { - paths.removeAt(item); - } - worker->unlock(); -} - -void YACReaderComicFlowGL::add(const QString &path, int index) -{ - worker->lock(); - worker->reset(); - paths.insert(index, path); - YACReaderFlowGL::add(index); - worker->unlock(); -} - -void YACReaderComicFlowGL::resortCovers(QList newOrder) -{ - worker->lock(); - worker->reset(); - startAnimationTimer(); - - QList pathsNew; - QVector loadedNew; - QVector marksNew; - QVector imagesNew; - - int index = 0; - foreach (int i, newOrder) { - if (i < 0 || i >= images.size()) { - continue; - } - - pathsNew << paths.at(i); - loadedNew << loaded.at(i); - marksNew << marks.at(i); - imagesNew << images.at(i); - imagesNew.last().index = index++; - } - - paths = pathsNew; - loaded = loadedNew; - marks = marksNew; - images = imagesNew; - - worker->unlock(); -} - -// YACReaderPageFlowGL implementation -YACReaderPageFlowGL::YACReaderPageFlowGL(QWidget *parent, struct Preset p) - : YACReaderFlowGL(parent, p) -{ - worker = new ImageLoaderByteArrayGL(this); - worker->flow = this; -} - -YACReaderPageFlowGL::~YACReaderPageFlowGL() -{ - this->killTimer(timerId); - rawImages.clear(); - - makeCurrent(); - - for (auto &image : images) { - if (image.texture != defaultTexture) { - if (image.texture->isCreated()) { - image.texture->destroy(); - } - delete image.texture; - } - } - - if (defaultTexture != nullptr) { - if (defaultTexture->isCreated()) { - defaultTexture->destroy(); - } - delete defaultTexture; - } - - doneCurrent(); -} - -void YACReaderPageFlowGL::updateImageData() -{ - if (worker->busy()) - return; - - int idx = worker->index(); - if (idx >= 0 && !worker->result().isNull()) { - if (!loaded[idx]) { - float x = 1; - QImage img = worker->result(); - QOpenGLTexture *texture = new QOpenGLTexture(img); - - if (performance == high || performance == ultraHigh) { - texture->setAutoMipMapGenerationEnabled(true); - texture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear); - } else { - texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); - } - - float y = 1 * (float(img.height()) / img.width()); - QString s = "cover"; - replace(s.toLocal8Bit().data(), texture, x, y, idx); - loaded[idx] = true; - } - } - - int count = 8; - switch (performance) { - case low: - count = 8; - break; - case medium: - count = 10; - break; - case high: - count = 12; - break; - case ultraHigh: - count = 14; - break; - } - - int *indexes = new int[2 * count + 1]; - int center = currentSelected; - indexes[0] = center; - for (int j = 0; j < count; j++) { - indexes[j * 2 + 1] = center + j + 1; - indexes[j * 2 + 2] = center - j - 1; - } - - for (int c = 0; c < 2 * count + 1; c++) { - int i = indexes[c]; - if ((i >= 0) && (i < numObjects)) - if (rawImages.size() > 0) - if (!loaded[i] && imagesReady[i]) { - worker->generate(i, rawImages.at(i)); - delete[] indexes; - return; - } - } - - delete[] indexes; -} - -void YACReaderPageFlowGL::populate(int n) -{ - worker->reset(); - if (lazyPopulateObjects != -1 || hasBeenInitialized) - YACReaderFlowGL::populate(n); - lazyPopulateObjects = n; - imagesReady = QVector(n, false); - rawImages = QVector(n); - imagesSetted = QVector(n, false); -} - -// ImageLoaderGL implementation -QImage ImageLoaderGL::loadImage(const QString &fileName) -{ - QImage image; - - if (!image.load(fileName)) { - return QImage(); - } - - switch (flow->performance) { - case low: - image = image.scaledToWidth(200, Qt::SmoothTransformation); - break; - case medium: - image = image.scaledToWidth(256, Qt::SmoothTransformation); - break; - case high: - image = image.scaledToWidth(320, Qt::SmoothTransformation); - break; - case ultraHigh: - break; - } - - return image; -} - -ImageLoaderGL::ImageLoaderGL(YACReaderFlowGL *flow) - : QThread(), flow(flow), restart(false), working(false), idx(-1) -{ -} - -ImageLoaderGL::~ImageLoaderGL() -{ - mutex.lock(); - condition.wakeOne(); - mutex.unlock(); - wait(); -} - -bool ImageLoaderGL::busy() const -{ - return isRunning() ? working : false; -} - -void ImageLoaderGL::generate(int index, const QString &fileName) -{ - mutex.lock(); - this->idx = index; - this->fileName = fileName; - this->size = size; - this->img = QImage(); - mutex.unlock(); - - if (!isRunning()) - start(); - else { - restart = true; - condition.wakeOne(); - } -} - -void ImageLoaderGL::lock() -{ - mutex.lock(); -} - -void ImageLoaderGL::unlock() -{ - mutex.unlock(); -} - -void ImageLoaderGL::run() -{ - for (;;) { - mutex.lock(); - this->working = true; - QString fileName = this->fileName; - mutex.unlock(); - - QImage image = loadImage(fileName); - - mutex.lock(); - this->working = false; - this->img = image; - mutex.unlock(); - - mutex.lock(); - if (!this->restart) - condition.wait(&mutex); - restart = false; - mutex.unlock(); - } -} - -QImage ImageLoaderGL::result() -{ - return img; -} - -// ImageLoaderByteArrayGL implementation -QImage ImageLoaderByteArrayGL::loadImage(const QByteArray &raw) -{ - QImage image; - - if (!image.loadFromData(raw)) { - return QImage(); - } - - switch (flow->performance) { - case low: - image = image.scaledToWidth(128, Qt::SmoothTransformation); - break; - case medium: - image = image.scaledToWidth(196, Qt::SmoothTransformation); - break; - case high: - image = image.scaledToWidth(256, Qt::SmoothTransformation); - break; - case ultraHigh: - image = image.scaledToWidth(320, Qt::SmoothTransformation); - break; - } - - return image; -} - -ImageLoaderByteArrayGL::ImageLoaderByteArrayGL(YACReaderFlowGL *flow) - : QThread(), flow(flow), restart(false), working(false), idx(-1) -{ -} - -ImageLoaderByteArrayGL::~ImageLoaderByteArrayGL() -{ - mutex.lock(); - condition.wakeOne(); - mutex.unlock(); - wait(); -} - -bool ImageLoaderByteArrayGL::busy() const -{ - return isRunning() ? working : false; -} - -void ImageLoaderByteArrayGL::generate(int index, const QByteArray &raw) -{ - mutex.lock(); - this->idx = index; - this->rawData = raw; - this->size = size; - this->img = QImage(); - mutex.unlock(); - - if (!isRunning()) - start(); - else { - restart = true; - condition.wakeOne(); - } -} - -void ImageLoaderByteArrayGL::run() -{ - for (;;) { - mutex.lock(); - this->working = true; - QByteArray raw = this->rawData; - mutex.unlock(); - - QImage image = loadImage(raw); - - mutex.lock(); - this->working = false; - this->img = image; - mutex.unlock(); - - mutex.lock(); - if (!this->restart) - condition.wait(&mutex); - restart = false; - mutex.unlock(); - } -} - -QImage ImageLoaderByteArrayGL::result() -{ - return img; -} diff --git a/common/gl/yacreader_flow_gl.h b/common/gl/yacreader_flow_gl.h deleted file mode 100644 index 5571c24bd..000000000 --- a/common/gl/yacreader_flow_gl.h +++ /dev/null @@ -1,372 +0,0 @@ -// OpenGL Coverflow API by J.Roth - Modernized with Shaders -#ifndef __YACREADER_FLOW_GL_H -#define __YACREADER_FLOW_GL_H - -#include - -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) -#include -#include -#else -#include -#include -#endif - -#include -#include -#include -#include -#include -#include - -#include "pictureflow.h" -#include "scroll_management.h" - -class ImageLoaderGL; -class ImageLoaderByteArrayGL; - -enum Performance { - low = 0, - medium, - high, - ultraHigh -}; - -// Cover Vector -struct YACReader3DVector { - float x; - float y; - float z; - float rot; -}; - -// the image/texture info struct -struct YACReader3DImage { - QOpenGLTexture *texture; - - float width; - float height; - - int index; - - YACReader3DVector current; - YACReader3DVector animEnd; -}; - -struct Preset { - /*** Animation Settings ***/ - // sets the speed of the animation - float animationStep; - // sets the acceleration of the animation - float animationSpeedUp; - // sets the maximum speed of the animation - float animationStepMax; - // sets the distance of view - float animationFadeOutDist; - // sets the rotation increasion - float preRotation; - // sets the light strenght on rotation - float viewRotateLightStrenght; - // sets the speed of the rotation - float viewRotateAdd; - // sets the speed of reversing the rotation - float viewRotateSub; - // sets the maximum view angle - float viewAngle; - - /*** Position Configuration ***/ - // the X Position of the Coverflow - float cfX; - // the Y Position of the Coverflow - float cfY; - // the Z Position of the Coverflow - float cfZ; - // the X Rotation of the Coverflow - float cfRX; - // the Y Rotation of the Coverflow - float cfRY; - // the Z Rotation of the Coverflow - float cfRZ; - // sets the rotation of each cover - float rotation; - // sets the distance between the covers - float xDistance; - // sets the distance between the centered and the non centered covers - float centerDistance; - // sets the pushback amount - float zDistance; - // sets the elevation amount - float yDistance; - - float zoom; -}; - -extern struct Preset defaultYACReaderFlowConfig; -extern struct Preset presetYACReaderFlowClassicConfig; -extern struct Preset presetYACReaderFlowStripeConfig; -extern struct Preset presetYACReaderFlowOverlappedStripeConfig; -extern struct Preset pressetYACReaderFlowUpConfig; -extern struct Preset pressetYACReaderFlowDownConfig; - -class YACReaderFlowGL : public QOpenGLWidget, protected QOpenGLExtraFunctions, public ScrollManagement -{ - Q_OBJECT -protected: - int timerId; - /*** System variables ***/ - YACReader3DImage dummy; - int viewRotateActive; - float stepBackup; - - /*functions*/ - void calcPos(YACReader3DImage &image, int pos); - void calcVector(YACReader3DVector &vector, int pos); - bool animate(YACReader3DVector ¤tVector, YACReader3DVector &toVector); - void drawCover(const YACReader3DImage &image); - void drawReflection(const YACReader3DImage &image); - void prepareInstanceData(const YACReader3DImage &image, bool isReflection, QVector &data); - void drawMark(const YACReader3DImage &image, const QMatrix4x4 &viewProjectionMatrix); - - void updatePerspective(int width, int height); - - int updateCount; - int fontSize; - - QOpenGLTexture *defaultTexture = nullptr; - QOpenGLTexture *markTexture = nullptr; - QOpenGLTexture *readingTexture = nullptr; - - // Shader program and buffers - QOpenGLShaderProgram *shaderProgram = nullptr; - QOpenGLBuffer *vbo = nullptr; - QOpenGLBuffer *instanceVBO = nullptr; - QOpenGLVertexArrayObject *vao = nullptr; - - void initializeGL(); - void paintGL(); - void timerEvent(QTimerEvent *); - void setupShaders(); - void setupGeometry(); - - int numObjects; - int lazyPopulateObjects; - bool showMarks; - QVector loaded; - QVector marks; - - QVector images; - - bool hasBeenInitialized; - - Performance performance; - bool bUseVSync; - - /*** Animation Settings ***/ - Preset config; - - int currentSelected; - - YACReader3DVector centerPos; - - /*** Style ***/ - float shadingTop; - float shadingBottom; - - float reflectionUp; - float reflectionBottom; - - /*** Theme Colors ***/ - QColor backgroundColor; - QColor textColor; - QColor shadingColor; - - /*** System info ***/ - float viewRotate; - - static int updateInterval; - - bool flowRightToLeft; - - void startAnimationTimer(); - void stopAnimationTimer(); - -public: - YACReaderFlowGL(QWidget *parent = 0, struct Preset p = pressetYACReaderFlowDownConfig); - virtual ~YACReaderFlowGL(); - - QSize minimumSizeHint() const; - - void showPrevious(); - void showNext(); - void setCurrentIndex(int pos); - void cleanupAnimation(); - void draw(); - void updatePositions(); - void insert(char *name, QOpenGLTexture *texture, float x, float y, int item = -1); - virtual void remove(int item); - void add(int item); - void replace(char *name, QOpenGLTexture *texture, float x, float y, int item); - void populate(int n); - YACReader3DImage getCurrentSelected(); - -public slots: - void setCF_RX(int value); - void setCF_RY(int value); - void setCF_RZ(int value); - void setZoom(int zoom); - void setRotation(int angle); - void setX_Distance(int distance); - void setCenter_Distance(int distance); - void setZ_Distance(int distance); - void setCF_Y(int value); - void setCF_Z(int value); - void setY_Distance(int value); - void setFadeOutDist(int value); - void setLightStrenght(int value); - void setMaxAngle(int value); - void setPreset(const Preset &p); - void setPerformance(Performance performance); - void useVSync(bool b); - void setFlowRightToLeft(bool b); - - // Theme color setters - void setBackgroundColor(const QColor &color); - void setTextColor(const QColor &color); - void setShadingColor(const QColor &color); - - virtual void updateImageData() = 0; - - void reset(); - void reload(); - - void setShowMarks(bool value); - void setMarks(QVector marks); - void setMarkImage(QImage &image); - void markSlide(int index, YACReader::YACReaderComicReadStatus status); - void unmarkSlide(int index); - void setSlideSize(QSize size); - void clear(); - void setCenterIndex(unsigned int index); - void showSlide(int index); - int centerIndex(); - void updateMarks(); - void render(); - - QVector3D getPlaneIntersection(int x, int y, YACReader3DImage plane); - void mouseDoubleClickEvent(QMouseEvent *event); - void mousePressEvent(QMouseEvent *event); - void wheelEvent(QWheelEvent *event); - void keyPressEvent(QKeyEvent *event); - void resizeGL(int width, int height); - - friend class ImageLoaderGL; - friend class ImageLoaderByteArrayGL; - -signals: - void centerIndexChanged(int); - void selected(unsigned int); -}; - -class YACReaderComicFlowGL : public YACReaderFlowGL -{ -public: - YACReaderComicFlowGL(QWidget *parent = 0, struct Preset p = defaultYACReaderFlowConfig); - void setImagePaths(QStringList paths); - void updateImageData(); - void remove(int item); - void add(const QString &path, int index); - void resortCovers(QList newOrder); - friend class ImageLoaderGL; - -private: - ImageLoaderGL *worker; - -protected: - QList paths; -}; - -class YACReaderPageFlowGL : public YACReaderFlowGL -{ -public: - YACReaderPageFlowGL(QWidget *parent = 0, struct Preset p = defaultYACReaderFlowConfig); - ~YACReaderPageFlowGL(); - void updateImageData(); - void populate(int n); - QVector imagesReady; - QVector rawImages; - QVector imagesSetted; - friend class ImageLoaderByteArrayGL; - -private: - ImageLoaderByteArrayGL *worker; -}; - -class ImageLoaderGL : public QThread -{ -public: - ImageLoaderGL(YACReaderFlowGL *flow); - ~ImageLoaderGL(); - bool busy() const; - void generate(int index, const QString &fileName); - void reset() - { - idx = -1; - fileName = ""; - } - int index() const { return idx; } - void lock(); - void unlock(); - QImage result(); - YACReaderFlowGL *flow; - GLuint resultTexture; - QImage loadImage(const QString &fileName); - -protected: - void run(); - -private: - QMutex mutex; - QWaitCondition condition; - - bool restart; - bool working; - int idx; - QString fileName; - QSize size; - QImage img; -}; - -class ImageLoaderByteArrayGL : public QThread -{ -public: - ImageLoaderByteArrayGL(YACReaderFlowGL *flow); - ~ImageLoaderByteArrayGL(); - bool busy() const; - void generate(int index, const QByteArray &raw); - void reset() - { - idx = -1; - rawData.clear(); - } - int index() const { return idx; } - QImage result(); - YACReaderFlowGL *flow; - GLuint resultTexture; - QImage loadImage(const QByteArray &rawData); - -protected: - void run(); - -private: - QMutex mutex; - QWaitCondition condition; - - bool restart; - bool working; - int idx; - QByteArray rawData; - QSize size; - QImage img; -}; - -#endif diff --git a/common/opengl_checker.cpp b/common/opengl_checker.cpp deleted file mode 100644 index a6d1840f8..000000000 --- a/common/opengl_checker.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "opengl_checker.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"; - break; - - default: - case QSurfaceFormat::DefaultRenderableType: - type = "unknown"; - break; - } - - delete openGLContext; - - description = QString("%1.%2 %3").arg(majorVersion).arg(minorVersion).arg(type); - - // Check for Desktop OpenGL OR OpenGL ES 3.0+ - bool isDesktopGL = (format.renderableType() == QSurfaceFormat::OpenGL); - bool isOpenGLES = (format.renderableType() == QSurfaceFormat::OpenGLES); - - if (isDesktopGL) { - // Desktop OpenGL requirements -#ifdef Q_OS_WIN - if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 4)) - compatibleOpenGLVersion = false; -#else - if (majorVersion < 2) - compatibleOpenGLVersion = false; -#endif - } else if (isOpenGLES) { - // OpenGL ES requirements: 3.0 or higher - if (majorVersion < 3) - compatibleOpenGLVersion = false; - } else { - // Unknown or unsupported renderable type - compatibleOpenGLVersion = false; - } -} - -QString OpenGLChecker::textVersionDescription() -{ - return description; -} - -bool OpenGLChecker::hasCompatibleOpenGLVersion() -{ - return compatibleOpenGLVersion; -} diff --git a/common/opengl_checker.h b/common/opengl_checker.h deleted file mode 100644 index 0258ce795..000000000 --- a/common/opengl_checker.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef OPENGL_CHECKER_H -#define OPENGL_CHECKER_H - -#include - -class OpenGLChecker -{ -public: - OpenGLChecker(); - bool hasCompatibleOpenGLVersion(); - QString textVersionDescription(); - -private: - QString description; - bool compatibleOpenGLVersion; -}; - -#endif // OPENGL_CHECKER_H diff --git a/common/pictureflow.cpp b/common/pictureflow.cpp deleted file mode 100644 index 323db42ff..000000000 --- a/common/pictureflow.cpp +++ /dev/null @@ -1,1410 +0,0 @@ -/* - PictureFlow - animated image show widget - http://pictureflow.googlecode.com - - Copyright (C) 2008 Ariya Hidayat (ariya@kde.org) - Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#include "pictureflow.h" - -#include - -// detect Qt version -#if QT_VERSION >= 0x040000 -#define PICTUREFLOW_QT4 -#elif QT_VERSION >= 0x030000 -#define PICTUREFLOW_QT3 -#elif QT_VERSION >= 235 -#define PICTUREFLOW_QT2 -#else -#error PictureFlow widgets need Qt 2, Qt 3 or Qt 4 -#endif - -#ifdef PICTUREFLOW_QT4 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -#ifdef PICTUREFLOW_QT3 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define qMax(x, y) ((x) > (y)) ? (x) : (y) -#define qMin(x, y) ((x) < (y)) ? (x) : (y) - -#define QVector QValueVector - -#define toImage convertToImage -#define contains find -#define modifiers state -#define ControlModifier ControlButton -#endif - -#ifdef PICTUREFLOW_QT2 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define qMax(x, y) ((x) > (y)) ? (x) : (y) -#define qMin(x, y) ((x) < (y)) ? (x) : (y) - -#define QVector QArray - -#define toImage convertToImage -#define contains find -#define modifiers state -#define ControlModifier ControlButton -#define flush flushX -#endif - -// for fixed-point arithmetic, we need minimum 32-bit long -// long long (64-bit) might be useful for multiplication and division -typedef long PFreal; -#define PFREAL_SHIFT 10 -#define PFREAL_ONE (1 << PFREAL_SHIFT) - -#define IANGLE_MAX 1024 -#define IANGLE_MASK 1023 - -inline PFreal fmul(PFreal a, PFreal b) -{ - return ((long long)(a)) * ((long long)(b)) >> PFREAL_SHIFT; -} - -inline PFreal fdiv(PFreal num, PFreal den) -{ - long long p = (long long)(num) << (PFREAL_SHIFT * 2); - long long q = p / (long long)den; - long long r = q >> PFREAL_SHIFT; - - return r; -} - -inline PFreal fsin(int iangle) -{ - // warning: regenerate the table if IANGLE_MAX and PFREAL_SHIFT are changed! - static const PFreal tab[] = { - 3, 103, 202, 300, 394, 485, 571, 652, - 726, 793, 853, 904, 947, 980, 1004, 1019, - 1023, 1018, 1003, 978, 944, 901, 849, 789, - 721, 647, 566, 479, 388, 294, 196, 97, - -4, -104, -203, -301, -395, -486, -572, -653, - -727, -794, -854, -905, -948, -981, -1005, -1020, - -1024, -1019, -1004, -979, -945, -902, -850, -790, - -722, -648, -567, -480, -389, -295, -197, -98, - 3 - }; - - while (iangle < 0) - iangle += IANGLE_MAX; - iangle &= IANGLE_MASK; - - int i = (iangle >> 4); - PFreal p = tab[i]; - PFreal q = tab[(i + 1)]; - PFreal g = (q - p); - return p + g * (iangle - i * 16) / 16; -} - -inline PFreal fcos(int iangle) -{ - return fsin(iangle + (IANGLE_MAX >> 2)); -} - -/* ---------------------------------------------------------- - -PictureFlowState stores the state of all slides, i.e. all the necessary -information to be able to render them. - -PictureFlowAnimator is responsible to move the slides during the -transition between slides, to achieve the effect similar to Cover Flow, -by changing the state. - -PictureFlowSoftwareRenderer (or PictureFlowOpenGLRenderer) is -the actual 3-d renderer. It should render all slides given the state -(an instance of PictureFlowState). - -Instances of all the above three classes are stored in -PictureFlowPrivate. - -------------------------------------------------------- */ - -struct SlideInfo { - int slideIndex; - int angle; - PFreal cx; - PFreal cy; - int blend; -}; - -class PictureFlowState -{ -public: - PictureFlowState(int angle = 50, float spacingRatio = 0); - ~PictureFlowState(); - - void reposition(); - void reset(); - - QRgb backgroundColor; - int slideWidth; - int slideHeight; - PictureFlow::ReflectionEffect reflectionEffect; - QVector slideImages; - - QVector marks; - bool showMarks; - QImage mark; - - int angle; - int rawAngle; - int spacing; - float spacingRatio; - PFreal offsetX; - PFreal offsetY; - - SlideInfo centerSlide; - QVector leftSlides; - QVector rightSlides; - int centerIndex; - - bool flowRightToLeft; -}; - -class PictureFlowAnimator -{ -public: - PictureFlowAnimator(); - PictureFlowState *state; - - void start(int slide); - void stop(int slide); - void update(); - - int target; - int step; - int frame; - QTimer animateTimer; - bool animating; -}; - -class PictureFlowAbstractRenderer -{ -public: - PictureFlowAbstractRenderer() - : state(0), dirty(false), widget(0) { } - virtual ~PictureFlowAbstractRenderer() { } - - PictureFlowState *state; - bool dirty; - QWidget *widget; - - virtual void init() = 0; - virtual void paint() = 0; -}; - -class PictureFlowSoftwareRenderer : public PictureFlowAbstractRenderer -{ -public: - PictureFlowSoftwareRenderer(); - ~PictureFlowSoftwareRenderer(); - - virtual void init(); - virtual void paint(); - void render(); - -private: - QSize size; - QRgb bgcolor; - int effect; - QImage buffer; - QVector rays; - QImage *blankSurface; -#ifdef PICTUREFLOW_QT4 - QCache surfaceCache; - QHash imageHash; -#endif -#ifdef PICTUREFLOW_QT3 - QCache surfaceCache; - QMap imageHash; -#endif -#ifdef PICTUREFLOW_QT2 - QCache surfaceCache; - QIntDict imageHash; -#endif - - void renderSlides(); - QRect renderSlide(const SlideInfo &slide, int col1 = -1, int col2 = -1); - QImage *surface(int slideIndex); -}; - -// ------------- PictureFlowState --------------------------------------- - -PictureFlowState::PictureFlowState(int a, float sr) - : backgroundColor(0), slideWidth(150), slideHeight(200), reflectionEffect(PictureFlow::BlurredReflection), rawAngle(a), spacingRatio(sr), centerIndex(0), flowRightToLeft(false) -{ -} - -PictureFlowState::~PictureFlowState() -{ - for (int i = 0; i < (int)slideImages.count(); i++) - delete slideImages[i]; -} - -// readjust the settings, call this when slide dimension is changed -void PictureFlowState::reposition() -{ - // angle = 70 * IANGLE_MAX / 360; // approx. 70 degrees tilted - angle = rawAngle * IANGLE_MAX / 360; - offsetX = slideWidth / 2 * (PFREAL_ONE - fcos(angle)); - offsetY = slideWidth / 2 * fsin(angle); - offsetX += slideWidth * PFREAL_ONE; - offsetY += slideWidth * PFREAL_ONE / 3; - if (rawAngle < 45) - offsetX += offsetX / 4; - if (angle > 0) - spacing = slideWidth * 0.35; - else - spacing = slideWidth * spacingRatio + slideWidth * (spacingRatio ? 0.10 : 0.2); -} - -// adjust slides so that they are in "steady state" position -void PictureFlowState::reset() -{ - centerSlide.angle = 0; - centerSlide.cx = 0; - centerSlide.cy = 0; - centerSlide.slideIndex = centerIndex; - centerSlide.blend = 256; - - if (angle == 0 && spacingRatio) - leftSlides.resize(4); - else - leftSlides.resize(6); - for (int i = 0; i < (int)leftSlides.count(); i++) { - SlideInfo &si = leftSlides[i]; - si.angle = angle; - si.cx = -(offsetX + spacing * (i)*PFREAL_ONE); - si.cy = offsetY; - if (!flowRightToLeft) - si.slideIndex = centerIndex - 1 - i; - else - si.slideIndex = centerIndex + 1 + i; - si.blend = 200; - if (i == (int)leftSlides.count() - 2) - si.blend = 128; - if (i == (int)leftSlides.count() - 1) - si.blend = 0; - } - if (angle == 0 && spacingRatio) - rightSlides.resize(4); - else - rightSlides.resize(6); - for (int i = 0; i < (int)rightSlides.count(); i++) { - SlideInfo &si = rightSlides[i]; - si.angle = -angle; - si.cx = offsetX + spacing * (i)*PFREAL_ONE; - si.cy = offsetY; - if (!flowRightToLeft) - si.slideIndex = centerIndex + 1 + i; - else - si.slideIndex = centerIndex - 1 - i; - si.blend = 200; - if (i == (int)rightSlides.count() - 2) - si.blend = 128; - if (i == (int)rightSlides.count() - 1) - si.blend = 0; - } -} - -// ------------- PictureFlowAnimator --------------------------------------- - -PictureFlowAnimator::PictureFlowAnimator() - : state(0), target(0), step(0), frame(0), animating(false) -{ -} - -void PictureFlowAnimator::start(int slide) -{ - target = slide; - if (!animateTimer.isActive() && state) { - step = (target < state->centerSlide.slideIndex) ? -1 : 1; - animateTimer.setSingleShot(true); - animateTimer.start(30); // TODO comprobar rendimiento, originalmente era 30 - animating = true; - } -} - -void PictureFlowAnimator::stop(int slide) -{ - step = 0; - target = slide; - frame = slide << 16; - animateTimer.stop(); - animating = false; -} - -void PictureFlowAnimator::update() -{ - /*if(!animateTimer.isActive()) - return;*/ - if (step == 0) - return; - if (!state) - return; - - int speed = 16384 / 4; // TODO comprobar rendimiento, originalmente era /4 - -#if 1 - // deaccelerate when approaching the target - const int max = 2 * 65536; // TODO cambiado de 2 * a 4 * comprobar rendimiento - - int fi = frame; - fi -= (target << 16); - if (fi < 0) - fi = -fi; - fi = qMin(fi, max); - - int ia = IANGLE_MAX * (fi - max / 2) / (max * 2); - speed = 512 + 16384 * (PFREAL_ONE + fsin(ia)) / PFREAL_ONE; -#endif - - frame += speed * step; - - int index = frame >> 16; - int pos = frame & 0xffff; - int neg = 65536 - pos; - int tick = (step < 0) ? neg : pos; - PFreal ftick = (tick * PFREAL_ONE) >> 16; - - if (step < 0) - index++; - - if (state->centerIndex != index) { - state->centerIndex = index; - frame = index << 16; - state->centerSlide.slideIndex = state->centerIndex; - for (int i = 0; i < (int)state->leftSlides.count(); i++) { - if (!state->flowRightToLeft) - state->leftSlides[i].slideIndex = state->centerIndex - 1 - i; - else - state->leftSlides[i].slideIndex = state->centerIndex + 1 + i; - } - for (int i = 0; i < (int)state->rightSlides.count(); i++) { - if (!state->flowRightToLeft) - state->rightSlides[i].slideIndex = state->centerIndex + 1 + i; - else - state->rightSlides[i].slideIndex = state->centerIndex - 1 - i; - } - } - - if (!state->flowRightToLeft) { - state->centerSlide.angle = (step * tick * state->angle) >> 16; - state->centerSlide.cx = -step * fmul(state->offsetX, ftick); - } else { - state->centerSlide.angle = (-step * tick * state->angle) >> 16; - state->centerSlide.cx = step * fmul(state->offsetX, ftick); - } - state->centerSlide.cy = fmul(state->offsetY, ftick); - - if (state->centerIndex == target) { - stop(target); - state->reset(); - return; - } - - for (int i = 0; i < (int)state->leftSlides.count(); i++) { - SlideInfo &si = state->leftSlides[i]; - si.angle = state->angle; - if (!state->flowRightToLeft) - si.cx = -(state->offsetX + state->spacing * (i)*PFREAL_ONE + step * state->spacing * ftick); - else - si.cx = -(state->offsetX + state->spacing * (i)*PFREAL_ONE - step * state->spacing * ftick); - si.cy = state->offsetY; - } - - for (int i = 0; i < (int)state->rightSlides.count(); i++) { - SlideInfo &si = state->rightSlides[i]; - si.angle = -state->angle; - if (!state->flowRightToLeft) - si.cx = state->offsetX + state->spacing * (i)*PFREAL_ONE - step * state->spacing * ftick; - else - si.cx = state->offsetX + state->spacing * (i)*PFREAL_ONE + step * state->spacing * ftick; - si.cy = state->offsetY; - } - - if (step > 0 && !state->flowRightToLeft) { - PFreal ftick = (neg * PFREAL_ONE) >> 16; - state->rightSlides[0].angle = -(neg * state->angle) >> 16; - state->rightSlides[0].cx = fmul(state->offsetX, ftick); - state->rightSlides[0].cy = fmul(state->offsetY, ftick); - } else if (!state->flowRightToLeft) { - PFreal ftick = (pos * PFREAL_ONE) >> 16; - state->leftSlides[0].angle = (pos * state->angle) >> 16; - state->leftSlides[0].cx = -fmul(state->offsetX, ftick); - state->leftSlides[0].cy = fmul(state->offsetY, ftick); - } else if (step < 0) { - PFreal ftick = (pos * PFREAL_ONE) >> 16; - state->rightSlides[0].angle = -(pos * state->angle) >> 16; - state->rightSlides[0].cx = fmul(state->offsetX, ftick); - state->rightSlides[0].cy = fmul(state->offsetY, ftick); - } else { - PFreal ftick = (neg * PFREAL_ONE) >> 16; - state->leftSlides[0].angle = (neg * state->angle) >> 16; - state->leftSlides[0].cx = -fmul(state->offsetX, ftick); - state->leftSlides[0].cy = fmul(state->offsetY, ftick); - } - - // must change direction ? - if (target < index) - if (step > 0) - step = -1; - if (target > index) - if (step < 0) - step = 1; - - // the first and last slide must fade in/fade out - int nleft = state->leftSlides.count(); - int nright = state->rightSlides.count(); - int fade = pos / 256; - - for (int index = 0; index < nleft; index++) { - int blend = 200; - if (index == nleft - 1) - blend = (step > 0) ? 0 : 128 - fade / 2; - if (index == nleft - 2) - blend = (step > 0) ? 128 - fade / 2 : 200 - (0.5625 * fade / 2); - if (index == nleft - 3) - blend = (step > 0) ? 200 - (0.5625 * fade / 2) : 200; - if (index == 0) - blend = (step > 0) ? 200 : 200 + 56 - (0.4375 * fade / 2); - state->leftSlides[index].blend = blend; - } - for (int index = 0; index < nright; index++) { - int blend = (index < nright - 2) ? 200 : 128; - if (index == nright - 1) - blend = (step > 0) ? fade / 2 : 0; - if (index == nright - 2) - blend = (step > 0) ? 128 + (0.5625 * fade / 2) : (0.5625 * fade / 2); - if (index == nright - 3) - blend = (step > 0) ? 200 : 128 + (0.5625 * fade / 2); - if (index == 0) - blend = (step > 0) ? 200 + (0.4375 * fade / 2) : 200; - state->rightSlides[index].blend = blend; - } - - state->centerSlide.blend = (step > 0) ? 256 - (0.4375 * fade / 2) : 200 + (0.4375 * fade / 2); -} - -// ------------- PictureFlowSoftwareRenderer --------------------------------------- - -PictureFlowSoftwareRenderer::PictureFlowSoftwareRenderer() - : PictureFlowAbstractRenderer(), size(0, 0), bgcolor(0), effect(-1), blankSurface(0) -{ -#ifdef PICTUREFLOW_QT3 - surfaceCache.setAutoDelete(true); -#endif -} - -PictureFlowSoftwareRenderer::~PictureFlowSoftwareRenderer() -{ - surfaceCache.clear(); - buffer = QImage(); - delete blankSurface; -} - -void PictureFlowSoftwareRenderer::paint() -{ - if (!widget) - return; - - if (widget->size() != size) - init(); - - if (state->backgroundColor != bgcolor) { - bgcolor = state->backgroundColor; - surfaceCache.clear(); - } - - if ((int)(state->reflectionEffect) != effect) { - effect = (int)state->reflectionEffect; - surfaceCache.clear(); - } - - if (dirty) - render(); - - QPainter painter(widget); - painter.drawImage(QPoint(0, 0), buffer); -} - -void PictureFlowSoftwareRenderer::init() -{ - if (!widget) - return; - - surfaceCache.clear(); - blankSurface = 0; - - size = widget->size(); - int ww = size.width(); - int wh = size.height(); - int w = (ww + 1) / 2; - int h = (wh + 1) / 2; - if (h < 10) // TODO a partir de qué h es seguro?? - return; - -#ifdef PICTUREFLOW_QT4 - buffer = QImage(ww, wh, QImage::Format_RGB32); -#endif -#if defined(PICTUREFLOW_QT3) || defined(PICTUREFLOW_QT2) - buffer.create(ww, wh, 32); -#endif - buffer.fill(bgcolor); - - rays.resize(w * 2); - for (int i = 0; i < w; i++) { - PFreal gg = ((PFREAL_ONE >> 1) + i * PFREAL_ONE) / (2 * h); - rays[w - i - 1] = -gg; - rays[w + i] = gg; - } - - dirty = true; -} - -// TODO: optimize this with lookup tables -static QRgb blendColor(QRgb c1, QRgb c2, int blend) -{ - int r = qRed(c1) * blend / 256 + qRed(c2) * (256 - blend) / 256; - int g = qGreen(c1) * blend / 256 + qGreen(c2) * (256 - blend) / 256; - int b = qBlue(c1) * blend / 256 + qBlue(c2) * (256 - blend) / 256; - return qRgb(r, g, b); -} - -static QImage *prepareSurface(const QImage *slideImage, int w, int h, QRgb bgcolor, - PictureFlow::ReflectionEffect reflectionEffect) -{ - - int iw, ih; - iw = slideImage->width(); - ih = slideImage->height(); - int psw, psh; - if (iw > ih) { - psw = w; - psh = w * (1.0 * ih / iw); - } else { - int h1 = h; - psw = h1 * (1.0 * iw / ih); - psh = h1; - - while (psw > w) { - h1 -= 2; - psw = h1 * (1.0 * iw / ih); - psh = h1; - } - } - w = psw; - -#ifdef PICTUREFLOW_QT4 - Qt::TransformationMode mode = Qt::SmoothTransformation; - QImage img = slideImage->scaled(psw, psh, Qt::IgnoreAspectRatio, mode); -#endif -#if defined(PICTUREFLOW_QT3) || defined(PICTUREFLOW_QT2) - QImage img = slideImage->smoothScale(w, h); -#endif - - // slightly larger, to accomodate for the reflection - int hs = h * 2; - int hofs = h / 3; - - // offscreen buffer: black is sweet -#ifdef PICTUREFLOW_QT4 - QImage *result = new QImage(hs, w, QImage::Format_RGB32); -#endif -#if defined(PICTUREFLOW_QT3) || defined(PICTUREFLOW_QT2) - QImage *result = new QImage; - result->create(hs, w, 32); -#endif - result->fill(bgcolor); - - // transpose the image, this is to speed-up the rendering - // because we process one column at a time - // (and much better and faster to work row-wise, i.e in one scanline) - int lhof = (h - psh); - // int lwof = (w-psw)/2; - for (int x = 0; x < psw; x++) - for (int y = 0; y < psh; y++) - - result->setPixel(hofs + y + lhof, x, img.pixel(x, y)); - - if (reflectionEffect != PictureFlow::NoReflection) { - // create the reflection - int ht = hs - (h + hofs); - int hte = ht; - for (int x = 0; x < psw; x++) - for (int y = 0; y < ht; y++) { - QRgb color; - if (y < psh) - color = img.pixel(x, psh - y - 1); - else - color = bgcolor; - result->setPixel(h + hofs + y, x, blendColor(color, bgcolor, 80 * (hte - y) / hte)); - } - } - - return result; -} - -QImage *PictureFlowSoftwareRenderer::surface(int slideIndex) -{ - if (!state) - return 0; - if (slideIndex < 0) - return 0; - if (slideIndex >= (int)state->slideImages.count()) - return 0; - -#ifdef PICTUREFLOW_QT4 - int key = slideIndex; -#endif -#if defined(PICTUREFLOW_QT3) || defined(PICTUREFLOW_QT2) - QString key = QString::number(slideIndex); -#endif - - QImage *img = state->slideImages.at(slideIndex); - - bool empty = img ? img->isNull() : true; - if (empty) { - surfaceCache.remove(key); - imageHash.remove(slideIndex); - if (!blankSurface) { - int sw = state->slideWidth; - int sh = state->slideHeight; - -#ifdef PICTUREFLOW_QT4 - QImage img = QImage(sw, sh, QImage::Format_RGB32); - - QPainter painter(&img); - QPoint p1(sw * 4 / 10, 0); - QPoint p2(sw * 6 / 10, sh); - QLinearGradient linearGrad(p1, p2); - linearGrad.setColorAt(0, Qt::black); - linearGrad.setColorAt(1, Qt::white); - painter.setBrush(linearGrad); - painter.fillRect(0, 0, sw, sh, QBrush(linearGrad)); - - painter.end(); -#endif -#if defined(PICTUREFLOW_QT3) || defined(PICTUREFLOW_QT2) - QPixmap pixmap(sw, sh, 32); - QPainter painter(&pixmap); - painter.fillRect(pixmap.rect(), QColor(192, 192, 192)); - painter.fillRect(5, 5, sw - 10, sh - 10, QColor(64, 64, 64)); - painter.end(); - QImage img = pixmap.convertToImage(); -#endif - - blankSurface = prepareSurface(&img, sw, sh, bgcolor, state->reflectionEffect); - } - return blankSurface; - } - -#ifdef PICTUREFLOW_QT4 - bool exist = imageHash.contains(slideIndex); - if (exist) - if (img == imageHash.find(slideIndex).value()) -#endif -#ifdef PICTUREFLOW_QT3 - bool exist = imageHash.find(slideIndex) != imageHash.end(); - if (exist) - if (img == imageHash.find(slideIndex).data()) -#endif -#ifdef PICTUREFLOW_QT2 - if (img == imageHash[slideIndex]) -#endif - if (surfaceCache.contains(key)) - return surfaceCache[key]; - - QImage *sr = prepareSurface(img, state->slideWidth, state->slideHeight, bgcolor, state->reflectionEffect); - // check if this slide must be marked - // if(marks[slideIndex]) - if (state->showMarks) { - if (state->marks[slideIndex]) { - QPainter painter(sr); - painter.setPen(QColor(255, 0, 0).rgb()); - int sh = sr->height(); - int jInit = sh * 4 / 5; - int iInit = state->slideHeight + state->slideHeight / 3; - /*for(int j = jInit; j < sh; j ++) - { - for(int i = iInit-(j-jInit); i < iInit; i ++) - { - - painter.drawPoint(i,j); - } - }*/ - painter.drawImage(QRect(iInit - (sh - jInit), jInit, sh - jInit, sh - jInit), state->mark); - } - } - surfaceCache.insert(key, sr); - imageHash.insert(slideIndex, img); - - return sr; -} - -// Renders a slide to offscreen buffer. Returns a rect of the rendered area. -// col1 and col2 limit the column for rendering. -QRect PictureFlowSoftwareRenderer::renderSlide(const SlideInfo &slide, int col1, int col2) -{ - int blend = slide.blend; - if (!blend) - return QRect(); - - QImage *src = surface(slide.slideIndex); - if (!src) - return QRect(); - - QRect rect(0, 0, 0, 0); - - int sw = src->height(); - int sh = src->width(); - int h = buffer.height(); - int w = buffer.width(); - - if (col1 > col2) { - int c = col2; - col2 = col1; - col1 = c; - } - - col1 = (col1 >= 0) ? col1 : 0; - col2 = (col2 >= 0) ? col2 : w - 1; - col1 = qMin(col1, w - 1); - col2 = qMin(col2, w - 1); - - int zoom = 100; - int distance = h * 100 / zoom; - PFreal sdx = fcos(slide.angle); - PFreal sdy = fsin(slide.angle); - PFreal xs = slide.cx - state->slideWidth * sdx / 2; - PFreal ys = slide.cy - state->slideWidth * sdy / 2; - PFreal dist = distance * PFREAL_ONE; - - int xi = qMax((PFreal)0, ((w * PFREAL_ONE / 2) + fdiv(xs * h, dist + ys)) >> PFREAL_SHIFT); - if (xi >= w) - return rect; - - bool flag = false; - rect.setLeft(xi); - for (int x = qMax(xi, col1); x <= col2; x++) { - PFreal hity = 0; - PFreal fk = rays[x]; - if (sdy) { - fk = fk - fdiv(sdx, sdy); - hity = -fdiv((rays[x] * distance - slide.cx + slide.cy * sdx / sdy), fk); - } - - dist = distance * PFREAL_ONE + hity; - if (dist < 0) - continue; - - PFreal hitx = fmul(dist, rays[x]); - PFreal hitdist = fdiv(hitx - slide.cx, sdx); - - int column = sw / 2 + (hitdist >> PFREAL_SHIFT); - if (column >= sw) - break; - if (column < 0) - continue; - - rect.setRight(x); - if (!flag) - rect.setLeft(x); - flag = true; - - int y1 = h / 2; - int y2 = y1 + 1; - QRgb *pixel1 = (QRgb *)(buffer.scanLine(y1)) + x; - QRgb *pixel2 = (QRgb *)(buffer.scanLine(y2)) + x; - QRgb pixelstep = pixel2 - pixel1; - - int center = (sh / 2); - int dy = dist / h; - int p1 = center * PFREAL_ONE - dy / 2; - int p2 = center * PFREAL_ONE + dy / 2; - - const QRgb *ptr = (const QRgb *)(src->scanLine(column)); - if (blend == 256) - while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) { - *pixel1 = ptr[p1 >> PFREAL_SHIFT]; - *pixel2 = ptr[p2 >> PFREAL_SHIFT]; - p1 -= dy; - p2 += dy; - y1--; - y2++; - pixel1 -= pixelstep; - pixel2 += pixelstep; - } - else - while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) { - QRgb c1 = ptr[p1 >> PFREAL_SHIFT]; - QRgb c2 = ptr[p2 >> PFREAL_SHIFT]; - *pixel1 = blendColor(c1, bgcolor, blend); - *pixel2 = blendColor(c2, bgcolor, blend); - p1 -= dy; - p2 += dy; - y1--; - y2++; - pixel1 -= pixelstep; - pixel2 += pixelstep; - } - } - - rect.setTop(0); - rect.setBottom(h - 1); - return rect; -} - -void PictureFlowSoftwareRenderer::renderSlides() -{ - int nleft = state->leftSlides.count(); - int nright = state->rightSlides.count(); - - QRect r = renderSlide(state->centerSlide); - int c1 = r.left(); - int c2 = r.right(); - - for (int index = 0; index < nleft; index++) { - QRect rs = renderSlide(state->leftSlides[index], 0, c1 - 1); - if (!rs.isEmpty()) - c1 = rs.left(); - } - for (int index = 0; index < nright; index++) { - QRect rs = renderSlide(state->rightSlides[index], c2 + 1, buffer.width()); - if (!rs.isEmpty()) - c2 = rs.right(); - } -} - -// Render the slides. Updates only the offscreen buffer. -void PictureFlowSoftwareRenderer::render() -{ - buffer.fill(state->backgroundColor); - renderSlides(); - if (state->slideImages.size() > 0) { - int size = buffer.width() * 0.015; - int start = buffer.width() * 0.010; - - QPainter painter(&buffer); - painter.setPen(QColor(255, 255, 255).rgb() - state->backgroundColor); - painter.setFont(QFont("Arial", start + size * 0.5)); - painter.drawText(start, start + size, QString().setNum(state->centerIndex + 1) + "/" + QString().setNum(state->slideImages.size())); - } - dirty = false; -} - -// ----------------------------------------- - -class PictureFlowPrivate -{ -public: - PictureFlowState *state; - PictureFlowAnimator *animator; - PictureFlowAbstractRenderer *renderer; - QTimer triggerTimer; -}; - -PictureFlow::PictureFlow(QWidget *parent, FlowType flowType) - : QWidget(parent) -{ - d = new PictureFlowPrivate; - - switch (flowType) { - case CoverFlowLike: - d->state = new PictureFlowState(50, 0); - break; - case Strip: - d->state = new PictureFlowState(0, 1); - break; - case StripOverlapped: - d->state = new PictureFlowState(0, 0); - break; - default: - break; - } - - framesSkip = 0; - - d->state->reset(); - d->state->reposition(); - - d->renderer = new PictureFlowSoftwareRenderer; - d->renderer->state = d->state; - d->renderer->widget = this; - d->renderer->init(); - - d->animator = new PictureFlowAnimator; - d->animator->state = d->state; - QObject::connect(&d->animator->animateTimer, &QTimer::timeout, this, &PictureFlow::updateAnimation); - - QObject::connect(&d->triggerTimer, &QTimer::timeout, this, QOverload<>::of(&PictureFlow::render)); - -#ifdef PICTUREFLOW_QT4 - setAttribute(Qt::WA_StaticContents, true); - setAttribute(Qt::WA_OpaquePaintEvent, true); - setAttribute(Qt::WA_NoSystemBackground, true); -#endif -#ifdef PICTUREFLOW_QT3 - setWFlags(getWFlags() | Qt::WStaticContents); - setWFlags(getWFlags() | Qt::WNoAutoErase); -#endif -#ifdef PICTUREFLOW_QT2 - setWFlags(getWFlags() | Qt::WPaintClever); - setWFlags(getWFlags() | Qt::WRepaintNoErase); - setWFlags(getWFlags() | Qt::WResizeNoErase); -#endif -} - -PictureFlow::~PictureFlow() -{ - delete d->renderer; - delete d->animator; - delete d->state; - delete d; -} - -int PictureFlow::slideCount() const -{ - return d->state->slideImages.count(); -} - -QColor PictureFlow::backgroundColor() const -{ - return QColor(d->state->backgroundColor); -} - -void PictureFlow::setBackgroundColor(const QColor &c) -{ - d->state->backgroundColor = c.rgb(); - triggerRender(); -} - -QSize PictureFlow::slideSize() const -{ - return QSize(d->state->slideWidth, d->state->slideHeight); -} - -void PictureFlow::setSlideSize(QSize size) -{ - d->state->slideWidth = size.width(); - d->state->slideHeight = size.height(); - d->state->reposition(); - triggerRender(); -} - -PictureFlow::ReflectionEffect PictureFlow::reflectionEffect() const -{ - return d->state->reflectionEffect; -} - -void PictureFlow::setReflectionEffect(ReflectionEffect effect) -{ - d->state->reflectionEffect = effect; - triggerRender(); -} - -void PictureFlow::setFlowRightToLeft(bool b) -{ - d->state->flowRightToLeft = b; - d->state->reset(); - triggerRender(); -} - -QImage PictureFlow::slide(int index) const -{ - QImage *i = 0; - if ((index >= 0) && (index < slideCount())) - i = d->state->slideImages[index]; - return i ? QImage(*i) : QImage(); -} - -void PictureFlow::addSlide(const QImage &image) -{ - int c = d->state->slideImages.count(); - d->state->slideImages.resize(c + 1); - d->state->slideImages[c] = new QImage(image); - d->state->marks.resize(c + 1); - d->state->marks[c] = YACReader::Unread; - triggerRender(); -} - -void PictureFlow::addSlide(const QPixmap &pixmap) -{ - addSlide(pixmap.toImage()); -} - -void PictureFlow::insertSlide(int index) -{ - d->state->slideImages.insert(index, new QImage()); - d->state->marks.insert(index, YACReader::Unread); - triggerRender(); -} - -void PictureFlow::removeSlide(int index) -{ - int c = d->state->slideImages.count(); - if (index >= 0 && index < c) { - d->state->slideImages.remove(index); - d->state->marks.remove(index); - setCenterIndex(index); - } -} - -void PictureFlow::setSlide(int index, const QImage &image) -{ - if ((index >= 0) && (index < slideCount())) { - QImage *i = image.isNull() ? 0 : new QImage(image); - delete d->state->slideImages[index]; - d->state->slideImages[index] = i; - triggerRender(); - } -} - -void PictureFlow::setSlide(int index, const QPixmap &pixmap) -{ - setSlide(index, pixmap.toImage()); -} - -int PictureFlow::centerIndex() const -{ - return d->state->centerIndex; -} - -void PictureFlow::setCenterIndex(int index) -{ - index = qMin(index, slideCount() - 1); - index = qMax(index, 0); - d->state->centerIndex = index; - d->state->reset(); - d->animator->stop(index); - triggerRender(); -} - -void PictureFlow::clear() -{ - int c = d->state->slideImages.count(); - for (int i = 0; i < c; i++) - delete d->state->slideImages[i]; - d->state->slideImages.resize(0); - - d->state->marks.resize(0); - - d->state->reset(); - triggerRender(); -} - -void PictureFlow::render() -{ - d->renderer->dirty = true; - update(); -} - -void PictureFlow::triggerRender() -{ -#ifdef PICTUREFLOW_QT4 - d->triggerTimer.setSingleShot(true); - d->triggerTimer.start(0); -#endif -#if defined(PICTUREFLOW_QT3) || defined(PICTUREFLOW_QT2) - d->triggerTimer.start(0, true); -#endif -} - -void PictureFlow::showPrevious() -{ - int step = d->animator->step; - int center = d->state->centerIndex; - - if (step > 0) { - d->animator->start(center); - emit centerIndexChanged(center); - } - - if (step == 0) - if (center > 0) { - d->animator->start(center - 1); - emit centerIndexChanged(center - 1); - } - - if (step < 0) { - d->animator->target = qMax(0, center - 2); - emit centerIndexChanged(qMax(0, center - 2)); - } -} - -void PictureFlow::showNext() -{ - int step = d->animator->step; - int center = d->state->centerIndex; - - if (step < 0) { - d->animator->start(center); - emit centerIndexChanged(center); - } - - if (step == 0) - if (center < slideCount() - 1) { - d->animator->start(center + 1); - emit centerIndexChanged(center + 1); - } - - if (step > 0) { - d->animator->target = qMin(center + 2, slideCount() - 1); - emit centerIndexChanged(qMin(center + 2, slideCount() - 1)); - } -} - -void PictureFlow::showSlide(unsigned int index) -{ - index = qMax(index, 0); - index = qMin(slideCount() - 1, index); - if ((int)index == d->state->centerSlide.slideIndex) { - return; - } - - int distance = centerIndex() - index; - - if (abs(distance) > 10) { - if (distance < 0) - setCenterIndex(centerIndex() + (-distance) - 10); - else - setCenterIndex(centerIndex() - distance + 10); - } - - d->state->centerIndex = index; - d->animator->start(index); -} - -void PictureFlow::keyPressEvent(QKeyEvent *event) -{ - if ((event->key() == Qt::Key_Left && !(d->state->flowRightToLeft)) || (event->key() == Qt::Key_Right && d->state->flowRightToLeft)) { - /*if(event->modifiers() == Qt::ControlModifier) - showSlide(centerIndex()-10); - else*/ - showPrevious(); - event->accept(); - return; - } - - if ((event->key() == Qt::Key_Right && !(d->state->flowRightToLeft)) || (event->key() == Qt::Key_Left && d->state->flowRightToLeft)) { - /*if(event->modifiers() == Qt::ControlModifier) - showSlide(centerIndex()+10); - else*/ - showNext(); - event->accept(); - return; - } - - if (event->key() == Qt::Key_Up) { - // TODO emit selected signal - return; - } - - event->ignore(); -} - -void PictureFlow::mousePressEvent(QMouseEvent *event) -{ - mousePressEvent(event, 0); -} - -void PictureFlow::mousePressEvent(QMouseEvent *event, int slideWidth) -{ - if ((event->x() > (width() + slideWidth) / 2 && !(d->state->flowRightToLeft)) || (event->x() < (width() - slideWidth) / 2 && d->state->flowRightToLeft)) - showNext(); - else if ((event->x() < (width() - slideWidth) / 2 && !(d->state->flowRightToLeft)) || (event->x() > (width() + slideWidth) / 2 && d->state->flowRightToLeft)) - showPrevious(); - - // else (centered slide space) -} - -void PictureFlow::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - d->renderer->paint(); -} - -void PictureFlow::resizeEvent(QResizeEvent *event) -{ - int heightWidget = event->size().height(); - int height, width; - height = heightWidget * 0.55; - width = height * 0.65; - setSlideSize(QSize(width, height)); - - render(); - d->animator->start(centerIndex()); - QWidget::resizeEvent(event); -} -#include -void PictureFlow::updateAnimation() // bucle principal -{ - QElapsedTimer timer; - timer.start(); - bool frameSkiped = false; - - int old_center = d->state->centerIndex; - d->animator->update(); - if (framesSkip == 0) - render(); // triggerRender(); - else { - framesSkip--; - frameSkiped = true; - } - - if (d->state->centerIndex != old_center) - emit centerIndexChangedSilent(d->state->centerIndex); - if (d->animator->animating == true) { - int difference = 10 - timer.elapsed(); - if (difference >= 0 && !frameSkiped) - QTimer::singleShot(difference, this, &PictureFlow::updateAnimation); - else { - QTimer::singleShot(0, this, &PictureFlow::updateAnimation); - if (!frameSkiped) - framesSkip = -((difference - 10) / 10); - } - } -} - -void PictureFlow::setFlowType(FlowType flowType) -{ - switch (flowType) { - case CoverFlowLike: - d->state->rawAngle = 50; - d->state->spacingRatio = 0, - d->state->reposition(); - break; - case Strip: - d->state->rawAngle = 0; - d->state->spacingRatio = 1; - d->state->reposition(); - break; - case StripOverlapped: - d->state->rawAngle = 0; - d->state->spacingRatio = 0; - d->state->reposition(); - break; - default: - break; - } - d->state->reset(); - d->renderer->init(); -} - -void PictureFlow::setMarkImage(const QImage &m) -{ - d->state->mark = m; -} - -void PictureFlow::markSlide(int index, YACReader::YACReaderComicReadStatus readStatus) -{ - if (index < d->state->marks.size()) - d->state->marks[index] = readStatus; -} - -void PictureFlow::updateMarks() -{ - d->renderer->init(); - repaint(); -} - -void PictureFlow::unmarkSlide(int index) -{ - if (index < d->state->marks.size()) - d->state->marks[index] = YACReader::Unread; -} - -void PictureFlow::setMarks(const QVector &m) -{ - d->state->marks = m; - updateMarks(); -} - -void PictureFlow::setShowMarks(bool enable) -{ - d->state->showMarks = enable; - updateMarks(); -} - -QVector PictureFlow::getMarks() -{ - return d->state->marks; -} - -void PictureFlow::resortCovers(QList newOrder) -{ - QVector slideImagesNew; - - QVector marksNew; - - QVector slidesInfo; - slidesInfo << d->state->leftSlides << d->state->centerSlide << d->state->rightSlides; - QVector slidesInfoNew; - - int order = 0; - foreach (int index, newOrder) { - slideImagesNew << d->state->slideImages.at(index); - marksNew << d->state->marks.at(index); - slidesInfoNew << slidesInfo.at(index); - slidesInfoNew.last().slideIndex = order++; - } - - d->state->slideImages = slideImagesNew; - d->state->marks = marksNew; - d->state->leftSlides = slidesInfoNew.mid(0, d->state->leftSlides.length()); - d->state->centerSlide = slidesInfoNew.at(d->state->centerIndex); - d->state->leftSlides = slidesInfoNew.mid(d->state->centerIndex + 1, d->state->leftSlides.length()); - - setCenterIndex(d->state->centerIndex); -} diff --git a/common/pictureflow.h b/common/pictureflow.h deleted file mode 100644 index e1d9c68d6..000000000 --- a/common/pictureflow.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - PictureFlow - animated image show widget - http://pictureflow.googlecode.com - - Copyright (C) 2008 Ariya Hidayat (ariya@kde.org) - Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#ifndef PICTUREFLOW_H -#define PICTUREFLOW_H - -#include -#include "yacreader_global_gui.h" //FlowType - -class PictureFlowPrivate; - -using namespace YACReader; - -/*! - Class PictureFlow implements an image show widget with animation effect - like Apple's CoverFlow (in iTunes and iPod). Images are arranged in form - of slides, one main slide is shown at the center with few slides on - the left and right sides of the center slide. When the next or previous - slide is brought to the front, the whole slides flow to the right or - the right with smooth animation effect; until the new slide is finally - placed at the center. - - */ -class PictureFlow : public QWidget -{ - Q_OBJECT - - Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) - Q_PROPERTY(QSize slideSize READ slideSize WRITE setSlideSize) - Q_PROPERTY(int slideCount READ slideCount) - Q_PROPERTY(int centerIndex READ centerIndex WRITE setCenterIndex) - -public: - enum ReflectionEffect { - NoReflection, - PlainReflection, - BlurredReflection - }; - - /*! - Creates a new PictureFlow widget. - */ - PictureFlow(QWidget *parent = 0, FlowType flowType = CoverFlowLike); - - /*! - Destroys the widget. - */ - ~PictureFlow(); - - /*! - Returns the background color. - */ - QColor backgroundColor() const; - - /*! - Sets the background color. By default it is black. - */ - void setBackgroundColor(const QColor &c); - - /*! - Returns the dimension of each slide (in pixels). - */ - QSize slideSize() const; - - /*! - Sets the dimension of each slide (in pixels). - */ - void setSlideSize(QSize size); - - /*! - Returns the total number of slides. - */ - int slideCount() const; - - /*! - Returns QImage of specified slide. - */ - QImage slide(int index) const; - - /*! - Returns the index of slide currently shown in the middle of the viewport. - */ - int centerIndex() const; - - /*! - Returns the effect applied to the reflection. - */ - ReflectionEffect reflectionEffect() const; - - /*! - Sets the effect applied to the reflection. The default is PlainReflection. - */ - void setReflectionEffect(ReflectionEffect effect); - - /*! - Sets the flow direction right-to-left (manga mode) - */ - void setFlowRightToLeft(bool b); - -public slots: - - /*! - Adds a new slide. - */ - void addSlide(const QImage &image); - - /*! - Adds a new slide. - */ - void addSlide(const QPixmap &pixmap); - - /*! - Insert and empty slide at index. - */ - void insertSlide(int index); - - /*! - Removes an existing slide. - */ - void removeSlide(int index); - - /*! - Sets an image for specified slide. If the slide already exists, - it will be replaced. - */ - void setSlide(int index, const QImage &image); - - /*! - Sets a pixmap for specified slide. If the slide already exists, - it will be replaced. - */ - void setSlide(int index, const QPixmap &pixmap); - - /*! - Sets slide to be shown in the middle of the viewport. No animation - effect will be produced, unlike using showSlide. - */ - void setCenterIndex(int index); - - /*! - Clears all slides. - */ - void clear(); - - /*! - Shows previous slide using animation effect. - */ - void showPrevious(); - - /*! - Shows next slide using animation effect. - */ - void showNext(); - - /*! - Go to specified slide using animation effect. - */ - void showSlide(unsigned int index); - - /*! - Rerender the widget. Normally this function will be automatically invoked - whenever necessary, e.g. during the transition animation. - */ - void render(); - - /*! - Schedules a rendering update. Unlike render(), this function does not cause - immediate rendering. - */ - void triggerRender(); - - void setFlowType(YACReader::FlowType flowType); - - void setMarkImage(const QImage &mark); - - void markSlide(int index, YACReader::YACReaderComicReadStatus readStatus = Read); - - void updateMarks(); - - void unmarkSlide(int index); - - void setMarks(const QVector &marks); - - void setShowMarks(bool enable); - - QVector getMarks(); - - void resortCovers(QList newOrder); - -signals: - void centerIndexChanged(int index); - void centerIndexChangedSilent(int index); - -public: - void paintEvent(QPaintEvent *event); - void keyPressEvent(QKeyEvent *event); - void mousePressEvent(QMouseEvent *event); - void mousePressEvent(QMouseEvent *event, int slideWidth); - void resizeEvent(QResizeEvent *event); - -private slots: - void updateAnimation(); - -private: - PictureFlowPrivate *d; - QImage mark; - int framesSkip; -}; - -#endif // PICTUREFLOW_H diff --git a/common/rhi/flow_types.cpp b/common/rhi/flow_types.cpp new file mode 100644 index 000000000..9d9bd2008 --- /dev/null +++ b/common/rhi/flow_types.cpp @@ -0,0 +1,182 @@ +#include "flow_types.h" + +/*** Preset Configurations ***/ + +struct Preset defaultYACReaderFlowConfig = { + 0.08f, // Animation_step sets the speed of the animation + 1.5f, // Animation_speedup sets the acceleration of the animation + 0.1f, // Animation_step_max sets the maximum speed of the animation + 3.f, // Animation_Fade_out_dis sets the distance of view + + 1.5f, // pre_rotation sets the rotation increasion + 3.f, // View_rotate_light_strenght sets the light strenght on rotation + 0.01f, // View_rotate_add sets the speed of the rotation + 0.02f, // View_rotate_sub sets the speed of reversing the rotation + 20.f, // View_angle sets the maximum view angle + + 0.f, // CF_X the X Position of the Coverflow + 0.f, // CF_Y the Y Position of the Coverflow + -8.f, // CF_Z the Z Position of the Coverflow + + 15.f, // CF_RX the X Rotation of the Coverflow + 0.f, // CF_RY the Y Rotation of the Coverflow + 0.f, // CF_RZ the Z Rotation of the Coverflow + + -50.f, // Rotation sets the rotation of each cover + 0.18f, // X_Distance sets the distance between the covers + 1.f, // Center_Distance sets the distance between the centered and the non centered covers + 0.1f, // Z_Distance sets the pushback amount + 0.0f, // Y_Distance sets the elevation amount + + 30.f // zoom level + +}; + +struct Preset presetYACReaderFlowClassicConfig = { + 0.08f, // Animation_step sets the speed of the animation + 1.5f, // Animation_speedup sets the acceleration of the animation + 0.1f, // Animation_step_max sets the maximum speed of the animation + 2.f, // Animation_Fade_out_dis sets the distance of view + + 1.5f, // pre_rotation sets the rotation increasion + 3.f, // View_rotate_light_strenght sets the light strenght on rotation + 0.08f, // View_rotate_add sets the speed of the rotation + 0.08f, // View_rotate_sub sets the speed of reversing the rotation + 30.f, // View_angle sets the maximum view angle + + 0.f, // CF_X the X Position of the Coverflow + -0.2f, // CF_Y the Y Position of the Coverflow + -7.f, // CF_Z the Z Position of the Coverflow + + 0.f, // CF_RX the X Rotation of the Coverflow + 0.f, // CF_RY the Y Rotation of the Coverflow + 0.f, // CF_RZ the Z Rotation of the Coverflow + + -40.f, // Rotation sets the rotation of each cover + 0.18f, // X_Distance sets the distance between the covers + 1.f, // Center_Distance sets the distance between the centered and the non centered covers + 0.1f, // Z_Distance sets the pushback amount + 0.0f, // Y_Distance sets the elevation amount + + 22.f // zoom level + +}; + +struct Preset presetYACReaderFlowStripeConfig = { + 0.08f, // Animation_step sets the speed of the animation + 1.5f, // Animation_speedup sets the acceleration of the animation + 0.1f, // Animation_step_max sets the maximum speed of the animation + 6.f, // Animation_Fade_out_dis sets the distance of view + + 1.5f, // pre_rotation sets the rotation increasion + 4.f, // View_rotate_light_strenght sets the light strenght on rotation + 0.08f, // View_rotate_add sets the speed of the rotation + 0.08f, // View_rotate_sub sets the speed of reversing the rotation + 30.f, // View_angle sets the maximum view angle + + 0.f, // CF_X the X Position of the Coverflow + -0.2f, // CF_Y the Y Position of the Coverflow + -7.f, // CF_Z the Z Position of the Coverflow + + 0.f, // CF_RX the X Rotation of the Coverflow + 0.f, // CF_RY the Y Rotation of the Coverflow + 0.f, // CF_RZ the Z Rotation of the Coverflow + + 0.f, // Rotation sets the rotation of each cover + 1.1f, // X_Distance sets the distance between the covers + 0.2f, // Center_Distance sets the distance between the centered and the non centered covers + 0.01f, // Z_Distance sets the pushback amount + 0.0f, // Y_Distance sets the elevation amount + + 22.f // zoom level + +}; + +struct Preset presetYACReaderFlowOverlappedStripeConfig = { + 0.08f, // Animation_step sets the speed of the animation + 1.5f, // Animation_speedup sets the acceleration of the animation + 0.1f, // Animation_step_max sets the maximum speed of the animation + 2.f, // Animation_Fade_out_dis sets the distance of view + + 1.5f, // pre_rotation sets the rotation increasion + 3.f, // View_rotate_light_strenght sets the light strenght on rotation + 0.08f, // View_rotate_add sets the speed of the rotation + 0.08f, // View_rotate_sub sets the speed of reversing the rotation + 30.f, // View_angle sets the maximum view angle + + 0.f, // CF_X the X Position of the Coverflow + -0.2f, // CF_Y the Y Position of the Coverflow + -7.f, // CF_Z the Z Position of the Coverflow + + 0.f, // CF_RX the X Rotation of the Coverflow + 0.f, // CF_RY the Y Rotation of the Coverflow + 0.f, // CF_RZ the Z Rotation of the Coverflow + + 0.f, // Rotation sets the rotation of each cover + 0.18f, // X_Distance sets the distance between the covers + 1.f, // Center_Distance sets the distance between the centered and the non centered covers + 0.1f, // Z_Distance sets the pushback amount + 0.0f, // Y_Distance sets the elevation amount + + 22.f // zoom level + +}; + +struct Preset pressetYACReaderFlowUpConfig = { + 0.08f, // Animation_step sets the speed of the animation + 1.5f, // Animation_speedup sets the acceleration of the animation + 0.1f, // Animation_step_max sets the maximum speed of the animation + 2.5f, // Animation_Fade_out_dis sets the distance of view + + 1.5f, // pre_rotation sets the rotation increasion + 3.f, // View_rotate_light_strenght sets the light strenght on rotation + 0.08f, // View_rotate_add sets the speed of the rotation + 0.08f, // View_rotate_sub sets the speed of reversing the rotation + 5.f, // View_angle sets the maximum view angle + + 0.f, // CF_X the X Position of the Coverflow + -0.2f, // CF_Y the Y Position of the Coverflow + -7.f, // CF_Z the Z Position of the Coverflow + + 0.f, // CF_RX the X Rotation of the Coverflow + 0.f, // CF_RY the Y Rotation of the Coverflow + 0.f, // CF_RZ the Z Rotation of the Coverflow + + -50.f, // Rotation sets the rotation of each cover + 0.18f, // X_Distance sets the distance between the covers + 1.f, // Center_Distance sets the distance between the centered and the non centered covers + 0.1f, // Z_Distance sets the pushback amount + -0.1f, // Y_Distance sets the elevation amount + + 22.f // zoom level + +}; + +struct Preset pressetYACReaderFlowDownConfig = { + 0.08f, // Animation_step sets the speed of the animation + 1.5f, // Animation_speedup sets the acceleration of the animation + 0.1f, // Animation_step_max sets the maximum speed of the animation + 2.5f, // Animation_Fade_out_dis sets the distance of view + + 1.5f, // pre_rotation sets the rotation increasion + 3.f, // View_rotate_light_strenght sets the light strenght on rotation + 0.08f, // View_rotate_add sets the speed of the rotation + 0.08f, // View_rotate_sub sets the speed of reversing the rotation + 5.f, // View_angle sets the maximum view angle + + 0.f, // CF_X the X Position of the Coverflow + -0.2f, // CF_Y the Y Position of the Coverflow + -7.f, // CF_Z the Z Position of the Coverflow + + 0.f, // CF_RX the X Rotation of the Coverflow + 0.f, // CF_RY the Y Rotation of the Coverflow + 0.f, // CF_RZ the Z Rotation of the Coverflow + + -50.f, // Rotation sets the rotation of each cover + 0.18f, // X_Distance sets the distance between the covers + 1.f, // Center_Distance sets the distance between the centered and the non centered covers + 0.1f, // Z_Distance sets the pushback amount + 0.1f, // Y_Distance sets the elevation amount + + 22.f // zoom level +}; diff --git a/common/rhi/flow_types.h b/common/rhi/flow_types.h new file mode 100644 index 000000000..79fe08dce --- /dev/null +++ b/common/rhi/flow_types.h @@ -0,0 +1,75 @@ +// Shared types for YACReader Flow implementations (GL and RHI) +#ifndef __YACREADER_FLOW_TYPES_H +#define __YACREADER_FLOW_TYPES_H + +enum Performance { + low = 0, + medium, + high, + ultraHigh +}; + +// Cover Vector +struct YACReader3DVector { + float x; + float y; + float z; + float rot; +}; + +struct Preset { + /*** Animation Settings ***/ + // sets the speed of the animation + float animationStep; + // sets the acceleration of the animation + float animationSpeedUp; + // sets the maximum speed of the animation + float animationStepMax; + // sets the distance of view + float animationFadeOutDist; + // sets the rotation increasion + float preRotation; + // sets the light strenght on rotation + float viewRotateLightStrenght; + // sets the speed of the rotation + float viewRotateAdd; + // sets the speed of reversing the rotation + float viewRotateSub; + // sets the maximum view angle + float viewAngle; + + /*** Position Configuration ***/ + // the X Position of the Coverflow + float cfX; + // the Y Position of the Coverflow + float cfY; + // the Z Position of the Coverflow + float cfZ; + // the X Rotation of the Coverflow + float cfRX; + // the Y Rotation of the Coverflow + float cfRY; + // the Z Rotation of the Coverflow + float cfRZ; + // sets the rotation of each cover + float rotation; + // sets the distance between the covers + float xDistance; + // sets the distance between the centered and the non centered covers + float centerDistance; + // sets the pushback amount + float zDistance; + // sets the elevation amount + float yDistance; + + float zoom; +}; + +extern struct Preset defaultYACReaderFlowConfig; +extern struct Preset presetYACReaderFlowClassicConfig; +extern struct Preset presetYACReaderFlowStripeConfig; +extern struct Preset presetYACReaderFlowOverlappedStripeConfig; +extern struct Preset pressetYACReaderFlowUpConfig; +extern struct Preset pressetYACReaderFlowDownConfig; + +#endif // __YACREADER_FLOW_TYPES_H diff --git a/common/rhi/yacreader_comic_flow_rhi.cpp b/common/rhi/yacreader_comic_flow_rhi.cpp index a5ec18fed..c57d38e99 100644 --- a/common/rhi/yacreader_comic_flow_rhi.cpp +++ b/common/rhi/yacreader_comic_flow_rhi.cpp @@ -121,7 +121,7 @@ void YACReaderComicFlow3D::resortCovers(QList newOrder) QList pathsNew; QVector loadedNew; - QVector marksNew; + QVector marksNew; QVector imagesNew; int index = 0; diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index 1391e3ea1..8ef969ead 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -169,7 +169,6 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) // Two triangles forming a quad (triangle list): // Tri 1: bottom-left, bottom-right, top-right // Tri 2: bottom-left, top-right, top-left - // Texture coords flipped vertically to match OpenGL convention float vertices[] = { // Position (x, y, z), TexCoord (u, v) -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-left @@ -189,7 +188,7 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) scene.alignedUniformSize = m_rhi->ubufAligned(sizeof(UniformData)); } - // Create sampler with trilinear filtering (like the OpenGL version) + // Create sampler with trilinear filtering if (!scene.sampler) { scene.sampler.reset(m_rhi->newSampler( QRhiSampler::Linear, // mag filter @@ -481,7 +480,6 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) }; // Collect all draws we need to make - // Important: OpenGL draws reflections FIRST, then covers+marks (for correct depth sorting) QVector draws; // Start timing for this render call (measures CPU time spent in this function) @@ -532,8 +530,8 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) continue; // Add mark draw immediately after its cover - if (showMarks && loaded[idx] && marks[idx] != Unread) { - QRhiTexture *markTex = (marks[idx] == Read) ? scene.markTexture.get() : scene.readingTexture.get(); + if (showMarks && loaded[idx] && marks[idx] != YACReader::Unread) { + QRhiTexture *markTex = (marks[idx] == YACReader::Read) ? scene.markTexture.get() : scene.readingTexture.get(); if (markTex) { if (!isVisibleInNDC(images[idx], false, true)) continue; @@ -1001,7 +999,7 @@ void YACReaderFlow3D::add(int item) images.insert(item, YACReader3DImageRHI()); loaded.insert(item, false); - marks.insert(item, Unread); + marks.insert(item, YACReader::Unread); numObjects++; for (int i = item + 1; i < numObjects; i++) { diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index 6f850a8bc..b7b31fe40 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -12,25 +12,10 @@ #include #include -#include "pictureflow.h" +#include "flow_types.h" +#include "yacreader_global.h" #include "scroll_management.h" -// Reuse enums and structs from OpenGL version -enum Performance { - low = 0, - medium, - high, - ultraHigh -}; - -// Cover Vector -struct YACReader3DVector { - float x; - float y; - float z; - float rot; -}; - // the image/texture info struct struct YACReader3DImageRHI { QRhiTexture *texture; @@ -47,41 +32,6 @@ struct YACReader3DImageRHI { YACReader3DVector animEnd; }; -struct Preset { - /*** Animation Settings ***/ - float animationStep; - float animationSpeedUp; - float animationStepMax; - float animationFadeOutDist; - float preRotation; - float viewRotateLightStrenght; - float viewRotateAdd; - float viewRotateSub; - float viewAngle; - - /*** Position Configuration ***/ - float cfX; - float cfY; - float cfZ; - float cfRX; - float cfRY; - float cfRZ; - float rotation; - float xDistance; - float centerDistance; - float zDistance; - float yDistance; - - float zoom; -}; - -extern struct Preset defaultYACReaderFlowConfig; -extern struct Preset presetYACReaderFlowClassicConfig; -extern struct Preset presetYACReaderFlowStripeConfig; -extern struct Preset presetYACReaderFlowOverlappedStripeConfig; -extern struct Preset pressetYACReaderFlowUpConfig; -extern struct Preset pressetYACReaderFlowDownConfig; - class QLabel; class ImageLoader3D; class ImageLoaderByteArray3D; @@ -204,7 +154,7 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement int lazyPopulateObjects; bool showMarks; QVector loaded; - QVector marks; + QVector marks; QVector images; diff --git a/config.pri b/config.pri index 8d1b6be45..d76a258d6 100644 --- a/config.pri +++ b/config.pri @@ -49,17 +49,6 @@ CONFIG += silent isEmpty(QMAKE_TARGET.arch) { QMAKE_TARGET.arch = $$QMAKE_HOST.arch } -contains(QMAKE_TARGET.arch, arm.*)|contains(QMAKE_TARGET.arch, aarch.*) { - !macx:!win32 { # Apple silicon supports opengl (for now lets flag windows as experimental) - CONFIG += no_opengl - message("Building for ARM architecture. Disabling OpenGL coverflow. If you know that your ARM arquitecture supports opengl, please edit config.pri to enable it.") - } -} - -# build without opengl widget support -CONFIG(no_opengl) { - DEFINES += NO_OPENGL -} # default value for comic archive decompression backend unix:!macx:!CONFIG(unarr):!CONFIG(7zip):!CONFIG(libarchive) { diff --git a/custom_widgets/custom_widgets_yacreader.pri b/custom_widgets/custom_widgets_yacreader.pri index 51c9999d2..92e474aee 100644 --- a/custom_widgets/custom_widgets_yacreader.pri +++ b/custom_widgets/custom_widgets_yacreader.pri @@ -5,44 +5,30 @@ HEADERS += \ $$PWD/help_about_dialog.h \ $$PWD/yacreader_field_edit.h \ $$PWD/yacreader_field_plain_text_edit.h \ - $$PWD/yacreader_flow.h \ - $$PWD/yacreader_flow_config_widget.h \ $$PWD/yacreader_options_dialog.h \ $$PWD/yacreader_spin_slider_widget.h \ $$PWD/yacreader_tool_bar_stretch.h \ $$PWD/yacreader_busy_widget.h \ $$PWD/rounded_corners_dialog.h \ $$PWD/whats_new_dialog.h \ - $$PWD/whats_new_controller.h - -!CONFIG(no_opengl) { - HEADERS += $$PWD/yacreader_gl_flow_config_widget.h -} - + $$PWD/whats_new_controller.h \ + $$PWD/yacreader_3d_flow_config_widget.h macx{ HEADERS += $$PWD/yacreader_macosx_toolbar.h -} - - +} SOURCES += \ $$PWD/help_about_dialog.cpp \ $$PWD/yacreader_field_edit.cpp \ $$PWD/yacreader_field_plain_text_edit.cpp \ - $$PWD/yacreader_flow.cpp \ - $$PWD/yacreader_flow_config_widget.cpp \ $$PWD/yacreader_options_dialog.cpp \ $$PWD/yacreader_spin_slider_widget.cpp \ $$PWD/yacreader_tool_bar_stretch.cpp \ $$PWD/yacreader_busy_widget.cpp \ $$PWD/rounded_corners_dialog.cpp \ $$PWD/whats_new_dialog.cpp \ - $$PWD/whats_new_controller.cpp - -!CONFIG(no_opengl) { - SOURCES += $$PWD/yacreader_gl_flow_config_widget.cpp -} + $$PWD/whats_new_controller.cpp \ + $$PWD/yacreader_3d_flow_config_widget.cpp macx{ OBJECTIVE_SOURCES += $$PWD/yacreader_macosx_toolbar.mm } - diff --git a/custom_widgets/custom_widgets_yacreaderlibrary.pri b/custom_widgets/custom_widgets_yacreaderlibrary.pri index 1b218b77c..3341bd40c 100644 --- a/custom_widgets/custom_widgets_yacreaderlibrary.pri +++ b/custom_widgets/custom_widgets_yacreaderlibrary.pri @@ -8,8 +8,6 @@ HEADERS += \ $$PWD/whats_new_controller.h \ $$PWD/yacreader_field_edit.h \ $$PWD/yacreader_field_plain_text_edit.h \ - $$PWD/yacreader_flow.h \ - $$PWD/yacreader_flow_config_widget.h \ $$PWD/yacreader_options_dialog.h \ $$PWD/yacreader_search_line_edit.h \ $$PWD/yacreader_spin_slider_widget.h \ @@ -22,11 +20,8 @@ HEADERS += \ $$PWD/yacreader_library_item_widget.h \ $$PWD/yacreader_treeview.h \ $$PWD/yacreader_busy_widget.h \ - $$PWD/yacreader_cover_label.h -!CONFIG(no_opengl){ - HEADERS += $$PWD/yacreader_gl_flow_config_widget.h -} - + $$PWD/yacreader_cover_label.h \ + $$PWD/yacreader_3d_flow_config_widget.h macx{ HEADERS += $$PWD/yacreader_macosx_toolbar.h } @@ -38,8 +33,6 @@ SOURCES += \ $$PWD/whats_new_controller.cpp \ $$PWD/yacreader_field_edit.cpp \ $$PWD/yacreader_field_plain_text_edit.cpp \ - $$PWD/yacreader_flow.cpp \ - $$PWD/yacreader_flow_config_widget.cpp \ $$PWD/yacreader_options_dialog.cpp \ $$PWD/yacreader_search_line_edit.cpp \ $$PWD/yacreader_spin_slider_widget.cpp \ @@ -52,11 +45,8 @@ SOURCES += \ $$PWD/yacreader_library_item_widget.cpp \ $$PWD/yacreader_treeview.cpp \ $$PWD/yacreader_busy_widget.cpp \ - $$PWD/yacreader_cover_label.cpp -!CONFIG(no_opengl){ - SOURCES += $$PWD/yacreader_gl_flow_config_widget.cpp -} - + $$PWD/yacreader_cover_label.cpp \ + $$PWD/yacreader_3d_flow_config_widget.cpp macx{ OBJECTIVE_SOURCES += $$PWD/yacreader_macosx_toolbar.mm } diff --git a/custom_widgets/help_about_dialog.cpp b/custom_widgets/help_about_dialog.cpp index 2ba8bf6aa..25538c805 100644 --- a/custom_widgets/help_about_dialog.cpp +++ b/custom_widgets/help_about_dialog.cpp @@ -1,6 +1,5 @@ #include "help_about_dialog.h" -#include "opengl_checker.h" #include "global_info_provider.h" #include @@ -100,10 +99,8 @@ void HelpAboutDialog::loadSystemInfo() { auto text = YACReader::getGlobalInfo(); - auto openGLChecker = OpenGLChecker(); text.append("\nGRAPHIC INFORMATION\n"); text.append(QString("Screen pixel ratio: %1\n").arg(devicePixelRatioF())); - text.append(QString("OpenGL version: %1\n").arg(openGLChecker.textVersionDescription())); systemInfoText->setText(text); } diff --git a/custom_widgets/yacreader_gl_flow_config_widget.cpp b/custom_widgets/yacreader_3d_flow_config_widget.cpp similarity index 96% rename from custom_widgets/yacreader_gl_flow_config_widget.cpp rename to custom_widgets/yacreader_3d_flow_config_widget.cpp index 813f01c59..a3db5fefc 100644 --- a/custom_widgets/yacreader_gl_flow_config_widget.cpp +++ b/custom_widgets/yacreader_3d_flow_config_widget.cpp @@ -1,15 +1,16 @@ -#include "yacreader_gl_flow_config_widget.h" +#include "yacreader_3d_flow_config_widget.h" #include "yacreader_spin_slider_widget.h" -#include "yacreader_flow_gl.h" //TODO +#include #include #include #include #include #include +#include -YACReaderGLFlowConfigWidget::YACReaderGLFlowConfigWidget(QWidget *parent /* = 0 */) +YACReader3DFlowConfigWidget::YACReader3DFlowConfigWidget(QWidget *parent /* = 0 */) : QWidget(parent) { QVBoxLayout *layout = new QVBoxLayout(this); @@ -75,7 +76,7 @@ YACReaderGLFlowConfigWidget::YACReaderGLFlowConfigWidget(QWidget *parent /* = 0 showAdvancedOptions = new QPushButton(tr("Show advanced settings")); showAdvancedOptions->setCheckable(true); - connect(showAdvancedOptions, &QAbstractButton::toggled, this, &YACReaderGLFlowConfigWidget::avancedOptionToogled); + connect(showAdvancedOptions, &QAbstractButton::toggled, this, &YACReader3DFlowConfigWidget::avancedOptionToogled); vbox->addWidget(showAdvancedOptions, 0, Qt::AlignRight); @@ -213,7 +214,7 @@ YACReaderGLFlowConfigWidget::YACReaderGLFlowConfigWidget(QWidget *parent /* = 0 setLayout(layout); } -void YACReaderGLFlowConfigWidget::avancedOptionToogled(bool show) +void YACReader3DFlowConfigWidget::avancedOptionToogled(bool show) { if (show) optionsGroupBox->show(); @@ -221,7 +222,7 @@ void YACReaderGLFlowConfigWidget::avancedOptionToogled(bool show) optionsGroupBox->hide(); } -void YACReaderGLFlowConfigWidget::setValues(Preset preset) +void YACReader3DFlowConfigWidget::setValues(Preset preset) { xRotation->setValue(preset.cfRX); yPosition->setValue(preset.cfY * 100); diff --git a/custom_widgets/yacreader_gl_flow_config_widget.h b/custom_widgets/yacreader_3d_flow_config_widget.h similarity index 79% rename from custom_widgets/yacreader_gl_flow_config_widget.h rename to custom_widgets/yacreader_3d_flow_config_widget.h index b29a1abca..cdf855f95 100644 --- a/custom_widgets/yacreader_gl_flow_config_widget.h +++ b/custom_widgets/yacreader_3d_flow_config_widget.h @@ -1,7 +1,7 @@ -#ifndef YACREADER_GL_FLOW_CONFIG_WIDGET_H -#define YACREADER_GL_FLOW_CONFIG_WIDGET_H +#ifndef YACREADER_3D_FLOW_CONFIG_WIDGET_H +#define YACREADER_3D_FLOW_CONFIG_WIDGET_H -#include "yacreader_flow_gl.h" //TODO +#include "flow_types.h" //TODO #include class QRadioButton; @@ -11,11 +11,11 @@ class QCheckBox; class QPushButton; class QGroupBox; -class YACReaderGLFlowConfigWidget : public QWidget +class YACReader3DFlowConfigWidget : public QWidget { Q_OBJECT public: - YACReaderGLFlowConfigWidget(QWidget *parent = 0); + YACReader3DFlowConfigWidget(QWidget *parent = 0); // GL......................... QRadioButton *radioClassic; @@ -47,4 +47,4 @@ public slots: void avancedOptionToogled(bool show); }; -#endif // YACREADER_GL_FLOW_CONFIG_WIDGET_H \ No newline at end of file +#endif // YACREADER_3D_FLOW_CONFIG_WIDGET_H diff --git a/custom_widgets/yacreader_flow.cpp b/custom_widgets/yacreader_flow.cpp deleted file mode 100644 index f930136eb..000000000 --- a/custom_widgets/yacreader_flow.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "yacreader_flow.h" - -#include - -YACReaderFlow::YACReaderFlow(QWidget *parent, FlowType flowType) - : PictureFlow(parent, flowType) { } - -void YACReaderFlow::mousePressEvent(QMouseEvent *event) -{ - PictureFlow::mousePressEvent(event, slideSize().width()); -} - -void YACReaderFlow::mouseDoubleClickEvent(QMouseEvent *event) -{ - if ((event->x() > (width() - slideSize().width()) / 2) && (event->x() < (width() + slideSize().width()) / 2)) - emit selected(centerIndex()); -} diff --git a/custom_widgets/yacreader_flow.h b/custom_widgets/yacreader_flow.h deleted file mode 100644 index d08ae3a88..000000000 --- a/custom_widgets/yacreader_flow.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef YACREADER_FLOW_H -#define YACREADER_FLOW_H - -#include "pictureflow.h" - -class QMouseEvent; - -class YACReaderFlow : public PictureFlow -{ - Q_OBJECT -public: - YACReaderFlow(QWidget *parent, FlowType flowType = CoverFlowLike); - - void mousePressEvent(QMouseEvent *event); - void mouseDoubleClickEvent(QMouseEvent *event); - -signals: - void selected(unsigned int centerIndex); -}; - -#endif // YACREADER_FLOW_H \ No newline at end of file diff --git a/custom_widgets/yacreader_flow_config_widget.cpp b/custom_widgets/yacreader_flow_config_widget.cpp deleted file mode 100644 index cdf47cc58..000000000 --- a/custom_widgets/yacreader_flow_config_widget.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "yacreader_flow_config_widget.h" - -#include -#include -#include -#include - -YACReaderFlowConfigWidget::YACReaderFlowConfigWidget(QWidget *parent) - : QWidget(parent) -{ - QVBoxLayout *layout = new QVBoxLayout(this); - - QGroupBox *groupBox = new QGroupBox(tr("How to show covers:")); - - radio1 = new QRadioButton(tr("CoverFlow look")); - radio2 = new QRadioButton(tr("Stripe look")); - radio3 = new QRadioButton(tr("Overlapped Stripe look")); - - QVBoxLayout *vbox = new QVBoxLayout; - QHBoxLayout *opt1 = new QHBoxLayout; - opt1->addWidget(radio1); - QLabel *lOpt1 = new QLabel(); - lOpt1->setPixmap(QPixmap(":/images/flow1.png")); - opt1->addStretch(); - opt1->addWidget(lOpt1); - vbox->addLayout(opt1); - - QHBoxLayout *opt2 = new QHBoxLayout; - opt2->addWidget(radio2); - QLabel *lOpt2 = new QLabel(); - lOpt2->setPixmap(QPixmap(":/images/flow2.png")); - opt2->addStretch(); - opt2->addWidget(lOpt2); - vbox->addLayout(opt2); - - QHBoxLayout *opt3 = new QHBoxLayout; - opt3->addWidget(radio3); - QLabel *lOpt3 = new QLabel(); - lOpt3->setPixmap(QPixmap(":/images/flow3.png")); - opt3->addStretch(); - opt3->addWidget(lOpt3); - vbox->addLayout(opt3); - - // vbox->addStretch(1); - groupBox->setLayout(vbox); - - layout->addWidget(groupBox); - - layout->setContentsMargins(0, 0, 0, 0); - - setLayout(layout); -} \ No newline at end of file diff --git a/custom_widgets/yacreader_flow_config_widget.h b/custom_widgets/yacreader_flow_config_widget.h deleted file mode 100644 index 2d23d4620..000000000 --- a/custom_widgets/yacreader_flow_config_widget.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef YACREADER_FLOW_CONFIG_WIDGET_H -#define YACREADER_FLOW_CONFIG_WIDGET_H - -#include - -class QRadioButton; - -class YACReaderFlowConfigWidget : public QWidget -{ - Q_OBJECT -public: - QRadioButton *radio1; - QRadioButton *radio2; - QRadioButton *radio3; - - YACReaderFlowConfigWidget(QWidget *parent = 0); -}; - -#endif // YACREADER_FLOW_CONFIG_WIDGET_H \ No newline at end of file diff --git a/custom_widgets/yacreader_options_dialog.cpp b/custom_widgets/yacreader_options_dialog.cpp index 6f5178cc1..72f45ce8a 100644 --- a/custom_widgets/yacreader_options_dialog.cpp +++ b/custom_widgets/yacreader_options_dialog.cpp @@ -1,13 +1,8 @@ #include "yacreader_options_dialog.h" -#include "yacreader_flow_config_widget.h" -#ifndef NO_OPENGL -#include "yacreader_gl_flow_config_widget.h" -#else -#include "pictureflow.h" -#endif +#include "yacreader_3d_flow_config_widget.h" +#include "yacreader_global_gui.h" #include "yacreader_spin_slider_widget.h" -#include "yacreader_global.h" #include #include @@ -20,11 +15,7 @@ YACReaderOptionsDialog::YACReaderOptionsDialog(QWidget *parent) : QDialog(parent) { - - sw = new YACReaderFlowConfigWidget(this); -#ifndef NO_OPENGL - gl = new YACReaderGLFlowConfigWidget(this); -#endif + gl = new YACReader3DFlowConfigWidget(this); accept = new QPushButton(tr("Save")); cancel = new QPushButton(tr("Cancel")); @@ -42,15 +33,7 @@ YACReaderOptionsDialog::YACReaderOptionsDialog(QWidget *parent) connect(accept, &QAbstractButton::clicked, this, &YACReaderOptionsDialog::saveOptions); connect(cancel, &QAbstractButton::clicked, this, QOverload<>::of(&YACReaderOptionsDialog::restoreOptions)); connect(cancel, &QAbstractButton::clicked, this, &QWidget::close); -#ifndef NO_OPENGL - useGL = new QCheckBox(tr("Use hardware acceleration (restart needed)")); - connect(useGL, &QCheckBox::stateChanged, this, &YACReaderOptionsDialog::saveUseGL); -#endif - // sw CONNECTIONS - connect(sw->radio1, &QAbstractButton::toggled, this, &YACReaderOptionsDialog::setClassicConfigSW); - connect(sw->radio2, &QAbstractButton::toggled, this, &YACReaderOptionsDialog::setStripeConfigSW); - connect(sw->radio3, &QAbstractButton::toggled, this, &YACReaderOptionsDialog::setOverlappedStripeConfigSW); -#ifndef NO_OPENGL + // gl CONNECTIONS connect(gl->radioClassic, &QAbstractButton::toggled, this, &YACReaderOptionsDialog::setClassicConfig); connect(gl->radioStripe, &QAbstractButton::toggled, this, &YACReaderOptionsDialog::setStripeConfig); @@ -100,11 +83,9 @@ YACReaderOptionsDialog::YACReaderOptionsDialog(QWidget *parent) connect(gl->performanceSlider, &QAbstractSlider::valueChanged, this, &YACReaderOptionsDialog::savePerformance); connect(gl->performanceSlider, &QAbstractSlider::valueChanged, this, &YACReaderOptionsDialog::optionsChanged); - connect(gl->vSyncCheck, &QCheckBox::stateChanged, this, &YACReaderOptionsDialog::saveUseVSync); -#endif + connect(gl->vSyncCheck, &QCheckBox::checkStateChanged, this, &YACReaderOptionsDialog::saveUseVSync); } -#ifndef NO_OPENGL void YACReaderOptionsDialog::savePerformance(int value) { settings->setValue(PERFORMANCE, value); @@ -129,7 +110,6 @@ void YACReaderOptionsDialog::saveFlowParameters() settings->setValue(LIGHT_STRENGTH, gl->lightStrength->getValue()); settings->setValue(MAX_ANGLE, gl->maxAngle->getValue()); } -#endif void YACReaderOptionsDialog::saveOptions() { @@ -137,96 +117,68 @@ void YACReaderOptionsDialog::saveOptions() close(); } -#ifndef NO_OPENGL -void YACReaderOptionsDialog::saveUseGL(int b) -{ - - if (Qt::Checked == b) { - sw->setVisible(false); - gl->setVisible(true); - } else { - gl->setVisible(false); - sw->setVisible(true); - } - resize(0, 0); - - settings->setValue(USE_OPEN_GL, b); -} -#endif - -#ifndef NO_OPENGL void YACReaderOptionsDialog::saveXRotation(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(X_ROTATION, value); } void YACReaderOptionsDialog::saveYPosition(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(Y_POSITION, value); } void YACReaderOptionsDialog::saveCoverDistance(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(COVER_DISTANCE, value); } void YACReaderOptionsDialog::saveCentralDistance(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(CENTRAL_DISTANCE, value); } void YACReaderOptionsDialog::saveZoomLevel(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(ZOOM_LEVEL, value); } void YACReaderOptionsDialog::saveYCoverOffset(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(Y_COVER_OFFSET, value); } void YACReaderOptionsDialog::saveZCoverOffset(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(Z_COVER_OFFSET, value); } void YACReaderOptionsDialog::saveCoverRotation(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(COVER_ROTATION, value); } void YACReaderOptionsDialog::saveFadeOutDist(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(FADE_OUT_DIST, value); } void YACReaderOptionsDialog::saveLightStrength(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(LIGHT_STRENGTH, value); } void YACReaderOptionsDialog::saveMaxAngle(int value) { - settings->setValue(FLOW_TYPE_GL, Custom); + settings->setValue(FLOW_TYPE_GL, YACReader::Custom); settings->setValue(MAX_ANGLE, value); } -#endif + void YACReaderOptionsDialog::restoreOptions(QSettings *settings) { this->settings = settings; // FLOW CONFIG -#ifndef NO_OPENGL - if (settings->contains(USE_OPEN_GL) && settings->value(USE_OPEN_GL).toInt() == Qt::Checked) { - sw->setVisible(false); - gl->setVisible(true); - useGL->setChecked(true); - } else { - gl->setVisible(false); - sw->setVisible(true); - useGL->setChecked(false); - } if (!settings->contains(FLOW_TYPE_GL)) { setClassicConfig(); @@ -242,67 +194,66 @@ void YACReaderOptionsDialog::restoreOptions(QSettings *settings) gl->performanceSlider->setValue(settings->value(PERFORMANCE).toInt()); - FlowType flowType; + YACReader::FlowType flowType; switch (settings->value(FLOW_TYPE_GL).toInt()) { case 0: - flowType = CoverFlowLike; + flowType = YACReader::CoverFlowLike; break; case 1: - flowType = Strip; + flowType = YACReader::Strip; break; case 2: - flowType = StripOverlapped; + flowType = YACReader::StripOverlapped; break; case 3: - flowType = Modern; + flowType = YACReader::Modern; break; case 4: - flowType = Roulette; + flowType = YACReader::Roulette; break; case 5: - flowType = Custom; + flowType = YACReader::Custom; break; default: - flowType = CoverFlowLike; + flowType = YACReader::CoverFlowLike; } - if (flowType == Custom) { + if (flowType == YACReader::Custom) { loadConfig(); return; } - if (flowType == CoverFlowLike) { + if (flowType == YACReader::CoverFlowLike) { setClassicConfig(); gl->radioClassic->setChecked(true); return; } - if (flowType == Strip) { + if (flowType == YACReader::Strip) { setStripeConfig(); gl->radioStripe->setChecked(true); return; } - if (flowType == StripOverlapped) { + if (flowType == YACReader::StripOverlapped) { setOverlappedStripeConfig(); gl->radioOver->setChecked(true); return; } - if (flowType == Modern) { + if (flowType == YACReader::Modern) { setModernConfig(); gl->radionModern->setChecked(true); return; } - if (flowType == Roulette) { + if (flowType == YACReader::Roulette) { setRouletteConfig(); gl->radioDown->setChecked(true); return; } // END FLOW CONFIG -#endif } void YACReaderOptionsDialog::restoreOptions() @@ -310,7 +261,6 @@ void YACReaderOptionsDialog::restoreOptions() restoreOptions(settings); } -#ifndef NO_OPENGL void YACReaderOptionsDialog::loadConfig() { gl->xRotation->setValue(settings->value(X_ROTATION).toInt()); @@ -325,30 +275,14 @@ void YACReaderOptionsDialog::loadConfig() gl->lightStrength->setValue(settings->value(LIGHT_STRENGTH).toInt()); gl->maxAngle->setValue(settings->value(MAX_ANGLE).toInt()); } -#endif -void YACReaderOptionsDialog::setClassicConfigSW() -{ - settings->setValue(FLOW_TYPE_SW, CoverFlowLike); -} - -void YACReaderOptionsDialog::setStripeConfigSW() -{ - settings->setValue(FLOW_TYPE_SW, Strip); -} - -void YACReaderOptionsDialog::setOverlappedStripeConfigSW() -{ - settings->setValue(FLOW_TYPE_SW, StripOverlapped); -} -#ifndef NO_OPENGL void YACReaderOptionsDialog::setClassicConfig() { gl->setValues(presetYACReaderFlowClassicConfig); saveFlowParameters(); - settings->setValue(FLOW_TYPE_GL, CoverFlowLike); + settings->setValue(FLOW_TYPE_GL, YACReader::CoverFlowLike); } void YACReaderOptionsDialog::setStripeConfig() @@ -357,7 +291,7 @@ void YACReaderOptionsDialog::setStripeConfig() saveFlowParameters(); - settings->setValue(FLOW_TYPE_GL, Strip); + settings->setValue(FLOW_TYPE_GL, YACReader::Strip); } void YACReaderOptionsDialog::setOverlappedStripeConfig() @@ -366,7 +300,7 @@ void YACReaderOptionsDialog::setOverlappedStripeConfig() saveFlowParameters(); - settings->setValue(FLOW_TYPE_GL, StripOverlapped); + settings->setValue(FLOW_TYPE_GL, YACReader::StripOverlapped); } void YACReaderOptionsDialog::setModernConfig() @@ -375,7 +309,7 @@ void YACReaderOptionsDialog::setModernConfig() saveFlowParameters(); - settings->setValue(FLOW_TYPE_GL, Modern); + settings->setValue(FLOW_TYPE_GL, YACReader::Modern); } void YACReaderOptionsDialog::setRouletteConfig() @@ -384,6 +318,5 @@ void YACReaderOptionsDialog::setRouletteConfig() saveFlowParameters(); - settings->setValue(FLOW_TYPE_GL, Roulette); + settings->setValue(FLOW_TYPE_GL, YACReader::Roulette); } -#endif diff --git a/custom_widgets/yacreader_options_dialog.h b/custom_widgets/yacreader_options_dialog.h index 4669e0d6a..44a0b9a90 100644 --- a/custom_widgets/yacreader_options_dialog.h +++ b/custom_widgets/yacreader_options_dialog.h @@ -3,10 +3,7 @@ #include -class YACReaderFlowConfigWidget; -#ifndef NO_OPENGL -class YACReaderGLFlowConfigWidget; -#endif +class YACReader3DFlowConfigWidget; class QCheckBox; class QPushButton; class QSettings; @@ -16,11 +13,7 @@ class YACReaderOptionsDialog : public QDialog { Q_OBJECT protected: - YACReaderFlowConfigWidget *sw; -#ifndef NO_OPENGL - YACReaderGLFlowConfigWidget *gl; - QCheckBox *useGL; -#endif + YACReader3DFlowConfigWidget *gl; QPushButton *accept; QPushButton *cancel; @@ -37,10 +30,8 @@ public slots: virtual void restoreOptions(); virtual void saveOptions(); protected slots: -#ifndef NO_OPENGL virtual void savePerformance(int value); virtual void saveUseVSync(int b); - virtual void saveUseGL(int b); virtual void saveXRotation(int value); virtual void saveYPosition(int value); virtual void saveCoverDistance(int value); @@ -59,10 +50,6 @@ protected slots: virtual void setModernConfig(); virtual void setRouletteConfig(); virtual void saveFlowParameters(); -#endif - virtual void setClassicConfigSW(); - virtual void setStripeConfigSW(); - virtual void setOverlappedStripeConfigSW(); signals: void optionsChanged(); From 7fad1ebb3f0738cd331393b8d6d2b9ad3467e8a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20A=CC=81ngel=20San=20Marti=CC=81n=20Rodri=CC=81guez?= Date: Fri, 6 Feb 2026 17:52:19 +0100 Subject: [PATCH 023/187] Make compile_shaders.sh executable --- common/rhi/shaders/compile_shaders.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 common/rhi/shaders/compile_shaders.sh diff --git a/common/rhi/shaders/compile_shaders.sh b/common/rhi/shaders/compile_shaders.sh old mode 100644 new mode 100755 From 5ebf52bdb342cbc57b4b1cbfe3012648645e76a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20A=CC=81ngel=20San=20Marti=CC=81n=20Rodri=CC=81guez?= Date: Fri, 6 Feb 2026 17:53:19 +0100 Subject: [PATCH 024/187] Fix shaders, vertex shader output locations don't match the fragment shader input locations. --- common/rhi/shaders/flow.frag | 2 +- common/rhi/shaders/flow.frag.qsb | Bin 3066 -> 3066 bytes common/rhi/shaders/flow.vert | 8 ++++---- common/rhi/shaders/flow.vert.qsb | Bin 2688 -> 2689 bytes 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common/rhi/shaders/flow.frag b/common/rhi/shaders/flow.frag index 686ad279f..3a901b983 100644 --- a/common/rhi/shaders/flow.frag +++ b/common/rhi/shaders/flow.frag @@ -5,7 +5,7 @@ layout(location = 0) in vec2 vTexCoord; layout(location = 1) in flat vec4 vInstanceShading; layout(location = 2) in flat float vInstanceOpacity; layout(location = 3) in flat float vIsReflection; -layout(location = 5) in vec2 vLocalPos; +layout(location = 4) in vec2 vLocalPos; // Output layout(location = 0) out vec4 fragColor; diff --git a/common/rhi/shaders/flow.frag.qsb b/common/rhi/shaders/flow.frag.qsb index 0cbd54fc9872fd6cfd24ddfcb79c650c656bcd2c..e223ca0b7496a235b79bc8620c39d17b60b3e889 100644 GIT binary patch delta 657 zcmV;C0&e~K7y1{FwgTP%vA9YB0sXTB0)Gd8Q3VlQL;x+^ECSjQQQV4;*IXme0;Ysm z*jO~ZRV&B}6TEvsKrzxnkfzc^s7aU+`I(H(%onn=uz4l7c`3KI+gx;3iuM-}wED9) z7+mLBI*f3T=h1ShqEF>vW9RmWM|N+mU?~-9x%Y`wMQX za0^DvVh9s1Cj?04WFkq@I*WM&XhB_nuW1Ih)b_HUMgFVQp+6pRYNbj8cJ-O66_}Nx zACxQ3%GpGV?>p7<3H*~;I}0z}K1RJ}RxKaGU>RJi`@bLzo6*jn8n6em%0+5Fzvpib zZdgbX{@Kj*V9wxUKiHO+Pq&S{!ny@C=`KI;y^y z-+9z+tLUH4dzz!V^L+ delta 657 zcmV;C0&e~K7y1{FwgNryvA9YB0RyuG0)Gd8yn=`>B7hcd76I*uC~n2aYpxM!0aHRO zY%H4Isug5~3En**pcrW(NK9KyPcR*v z*#J2B3gL^g>18uKBceu?qmRS%gF!>Lorhd0tlJv8bvj0D%fq9C?Z`fg?jc>H{ROvG zxCJ9-F@y=169S}iGLa-{oyEKXw4knk*E9oLYJ1twBL7wD&>xRDwNj-4yZTJk3d~B; z56Ts1eSnr`D+pDij(%bb%GOR1><2`L+aCz{4plb7l~KQE5+G zMI+ZiL(N$QJ`x94`yK_G552~SRH1gaA|{@aG7k88q)?DMV|h6Zy$PSQmM=%~1OcRY z=c5Qh%6@Da>PT@UiJlu+` zSEq(c43=!0M;d~Wc}l;9i0!s~TyfYAT~{2mW8)PEZtJ~l(+^Ic7Ka=vJj3Umj;b%_ zcOEsIZG9LQe%D`n)U^A~KlpTS#-9HtA2r*y`QgXak6O`>VZg;P755b=rMG1S-PVU7 rrC`ykh=03GJxwie*IWI{f-Su5PTRY7IM1 diff --git a/common/rhi/shaders/flow.vert b/common/rhi/shaders/flow.vert index eb7c2087d..af9a6866b 100644 --- a/common/rhi/shaders/flow.vert +++ b/common/rhi/shaders/flow.vert @@ -15,10 +15,10 @@ layout(location = 8) in float instanceFlip; // Outputs to fragment shader layout(location = 0) out vec2 vTexCoord; -layout(location = 2) out flat vec4 vInstanceShading; -layout(location = 3) out flat float vInstanceOpacity; -layout(location = 4) out flat float vIsReflection; -layout(location = 5) out vec2 vLocalPos; +layout(location = 1) out flat vec4 vInstanceShading; +layout(location = 2) out flat float vInstanceOpacity; +layout(location = 3) out flat float vIsReflection; +layout(location = 4) out vec2 vLocalPos; // Uniform buffer layout(std140, binding = 0) uniform UniformBuffer diff --git a/common/rhi/shaders/flow.vert.qsb b/common/rhi/shaders/flow.vert.qsb index e17b39dd8941bb7f6a6e63bc7d85863ff966cf14..5194219b83f329b3a7900a5f9c35f2526bc6213c 100644 GIT binary patch delta 2685 zcmV-@3WD{36@e9yAAfixCA(IrIF{{5u2d;{xN2mXK9NWHY>Fq4M?D${D9~^H)_&-} z(m$;aplD}qXL)mb54H`82CWEOcr){x$Ii^ot{4j;UJ>$x-yaD_bVN^h!h-LHu*HgS zMH9Z;qAt4dek@9W%fd7IclwB!&p%_xBtw}WYN$+xvOm;Ng?|iwteygy%wGSso*&k0c zay?>X6}(&UhO0lNI406ejKOn79Er`?^`|Bc)s_L?0FQ04=4V~1rB>PiwWZXx%ay0* zKF&zo+EaJIyMMlso>&Lv7A(OA<)CR$J+=2od=py$c0e7|b|CJFKD@WUR2QV<(7H3C z3UAMt-UK{(aP0u<81jbA{UYRi1=isK-+__{agp@yG8>oG%XP8mFZw0q4Gr}{z3JDn z?S~|rA5~wCTSE>aJoHmvq7^Mu`Xir7uolhJ)}Y3>T^XNbN`be8BVM34D&MifbR5jaI!lj>5%8zJ5Z{?hIng?mnGgN=4n=>+ z=o;lw(Tf`Wi0Bcbm$f>q5q*Jjh4sBevK>wL34hV!gni1ePer)?b)qK-YcZ@Pg5G!o zG)Db3W_%jo--b8zVZd`0@Dt<{W1fWnULdmiWCRZ zC4b_fACvs3xR5TBU(8d5Y-W5vulW6hIZ=G|nDmW4XDH`Y@`>~;@lbw?-c@eDB>xq{ zBV8jN%I}l^35w|<`BL`2A^AhnM|zQXC|@F5N{;j+RvW}GGyE#a#z~I!8u8u)uj_<+ zOgajOaqbXL)%*$bgZQURj&|#s+#>lb?0;SVjzYCS-k*UpMp*369Oa}&{rnRlds5M_ z3E7j1eqG3(RP-A{_T;x<71!`K*$|9(m3SkJH%Yuv#(Rf&8OD2;V&L}PBObSRjdUXoc0``@kEfMVJT_NYqJe|3_%-=I1XU#mFvCo)nkJdR)XDZTvgMX~tmRH9t z-RF>Kioty{``f7_yW4Zzj$xKcxm?fd_8XqD)p1&G_uyW?)v~*}?{fxx4lJ)~969#! zTGxGHH$2c;vAnKxGUtnr>_)}dvl=h=yKcYJTyWcNS4vuK*Yb?|q17yLM%Qk&rJ1e6 zc>aC&xFaP_$1|MX`aq%^Hh<@GXLGq+UxpnH->A=2L1uXn>t5fpG14kn?0HtFVXwGN zyIt?P#}L~vh&dcm9uBE!kcx5W_8hsYBddGrboP;5HjXy!lLgo9HZ_H^;SB^~g=M#4 zwb$GpSCC0kQ9NurknC0)SWFe_xB^O<>!H6N{QVcLk7n2C~dqNGwN$o|`J*Vm|Y;6D$2R*c&p z#%JMJ3&8L#tGZ7cX0b#z2So>qL79DtsxC;BX7S{dHb~3J^BNmBYDNi+`a+qskoDpz zSOKrbP0o|H&ZIl7BYyxN?ST-GYRZ6vDoY$ID+9@vJj>;@DRm+SA3mkZ=Tqu@N}W%s z^C|V?m{NaWQ|eYQrDp!8r4D zxIv?br%f2tOqwnckKwVxRnJGt|M^H66~Qle@VU6w*pnMCynhYvz|P)xdY;|Q@0C<@ zK!xfD)(f{Q+o^g|#qC;;t;`(*B7Et#T0Ps#H&hLLy^61;O&?96S_n-Iz~e;HLB-<; zj1MXeK9d5*>7~Pqr-fjkA)F7j2>4fV5t|VhMvT)BhPUN84ay{M_&H4!Hv@+t%%O<# zP(&q+;IonQLw^G@EbtQeY*uoC*0$mBqVqC7{9prxOh;#Ctmk;CJ~ips-B?>%e_UVa zy1ia~sdL!(XqRZ|f)3bxu)VOlx_+OZs6l!dz+`~9!ZT<&9cnUYB^_F3&}urg!k{y; zP?diMoaOsM%QS=Cii7zBH^AJMdncv34b~+>}k7u=)(DkHA?8RXlY^< zqk}q9rzE}bM2V{y+b@ZQ;>YD3W8*QKC1>iGhnu5U51sXcA+DeIN|2W?@uz;0%uJD$ zQ)CHe|3Sa4!U!GeEii?$ke%to^QiD2xdgO^-U3=brfWcS!^q2DWRe-6xNp}Td{^BP zGmUB-SAUEkYEHzModFUBd$+K5a$%bn=^E4iD3C&W0!;|j_o{lH;Ce*8zy=! zNY)Ax6}=6_XodHZb_eip!?xG&cC>_@@w+zuUw>Kl50%FIQ%|%{tvv{>#4t z&{8mCCCp;d5x%q2@4+78*?ma rYY81pt~`(MKpOL#ihljkegPW%!%so~G*~;eB67vkasKBYQFraVRSj2Q delta 2684 zcmV-?3WN256@V3xAAk6g?OKuIShgd%Ql(gut45aT6M2-+rg#E*)T4ob0{zx+>4*L+ z{nOe82-=z3S>Ej4gK2}JL2CjR-pu^wu`{!?E5<^ImxTP__Xoli9nllMu;IHQ9I+xi z(S+}|sEaPVABhs+vha-lgFYhW^J5H^$x!B}8mf??>`ygRC4WO>X@<^=0|58HoDYu& z#$X93NLTW~)3I0p1rNM6F@f-mq$y2CLcRyVy5Jua;W?A0Y(E2_Q%tV zT#gu71@AVz;p$H)j)^oAWAI!Mhhigk{i#VqwPk=ez++pi1zDGBsRgn?Z7Fr_Kca!- zjKr-ywRztTjDPgR15j?k5*$ztn+DZWTXrNcu?b)o)G=-Q;^2pE})JeZ`j<=H0LX@4j=d~lthTLq<4$iIImtVi``(+&mnJUs1NGRppNYz zB-#9^`f}VFauDG`kopp>XqnO<`AmYfXr49)?Y@?zcz-EY@lLR%RiZbNy}F4NItR~I zl47{BGWmFv1pRkEBlN9|j?;IOMKPHfoti-CS#bt}m!DT*m!R@lP{Hr7me-eyJ-=D3 z&0rZ|VVQx0SH$ZBC;PUG>kdkZi^ndw01qn7!Lta@eIaXz<=CcGKZd6ckBz>-66#+T za<3wNj(_M3(dUWI5`BT_v4GBqBIzyyr$}p3U8;B^#2aC}QQ~D7FGIX6*{%(2XM=Y^ zei5(e30gbnO)>v9@{7D%j5kWWWyZ@8Z;kP?#M@xJG2(48-Z=3dQJ${B_Z5mm(eE>Q zj`FDJMT5Ri^a#<*THdokj7XoMTw#6Bk!;(j>3<`l#|itGVILdyt`j{$Ses#O5%$7s zV0|=LVJJd`hyEhR_#KC2Dlml=MQWaA`9dX0FmgVzUy zdq_G8hjDHbPu2Vp^Mm-uOpbQzhTJCkHGkMmxIQ(sk@q*?j1d<5Ge_gyB-)7svn*sm~If#RH^I6fp9?wwD_=f`9NvGWj7j$~g#thm>12)X|% zRD0C@CGiz~Q^&i)Cf*9gK0};5SMCd%&X%&tc@@KHZ?$aZmq7$ayr)Y;O_&50s+ekh5l<&e$hRwoB`rr!y7lAAcY#H{{hZ zOZPb>nqqLD%>Hre(CPMEuVa-#O>@MyJ8(~IL8Z~*KHaK70Vw8bcJQF zVYk=39#@b_Qc>J%yO8Ww8(2&g>bgXL^`~|dxQWXkdD$=`y$r0Z9)H*k*FQ;)V*rS? zqE$L~=($Y`+c#g}t*9l|nhThDj5QyvZDHDqmy{DFl|)IkP>}t%*RHQo>A-&;`m7kY zKdevmSPQ@iEUUUtTjgSjYz~SJ7Q-?J5>;K0D9z&W32l&;mFG3KuFP2_Fd7JD(lqPE z6R-kat*e|TZJkPYMt?^DKH38skZQ_+gDOiLD=P!ZmORbnj45?21|L49Dlewgiz)SD zO1+p;KaVN(XEvp-hf`|ie|k!}o#gS9C@ZJPDk-w6lJODb_5H~BktjZQLR2_&0F^jw z2p>0S%DWf9%W$2Hup_1MbXv>?LgUaQq}{Cq>zAkeD@TE_G-6lw)+Y5*Q5k_jpv zMPPhT8St4DFitNMUOXv;0}bJPs71iPi;K7%fnmfr{a|?8zT2Qo@`j%^L~%242%Igm?Ie%Xpkh;K6;ImoD1xDNI;YH_VeE8u8(o9EZW~}FUsW~<2*j-;+dhoEm z(Diz~`cmhh@6#?Z(ghu`ad&HBb@jm=exioyVSq9N#1)=FE9uZOgI3d_6$Y)PL#qrr z6AM-OXTWQGUl^HYu%U8GkK7$AdlXbPqf@AF)OWT^7xE ztYUOfN0OhUr%#l)GO+!Un0-K?R);ClEE%~4?%v|K^&xalh!Qp&ShCR zcrZNU74)t!CuzKn-XP%!kc^mykVd?KkRZ+}>YG!$wM4Ldudz!)6vuWRyBkDt(G3&5 z79?whiHhC^Vzl(VWZVIQ+py#JyB#B8r~Iys|9@AO{X?bk{*>EkwEIoR`h4HhRt z0JId$SP8S3bcAnj_j~ZiNZV_4N`;*r?f8o{1_M`gaCDe5Y&C-AO~8OP9mtPphMFmRCgs6QHOD@y^b))$jtN#%BEp zFDihPe|rao41a-9rtz7xzCE4QH}>$`T6N4(%r9Os2X4B!k}e+H+`PyE@h|;y6S|1| z`NlI&6oBbRu4f!2%#Lx7(~jVT-*Yr~>^B{Q&o6Xd{29gk=_j}se>yR|c0PGA$C9xY q?O^icd4vbjSkP4T>yPmZ(BL0_3i_wP#;FyNE1ro9KK}&kHto$R&|8}T From 0afa10f2cfc3a437b6d17d7421cbaf52dd1de862 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 19 Feb 2026 18:03:53 +0100 Subject: [PATCH 025/187] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1db2abc4e..8ad479323 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ Version counting is based on semantic versioning (Major.Feature.Patch) ## 10 (WIP) +### All GUI Apps +* Migrate Flow implementation from OpenGL to QRhi. This is a full new implementation with better performance and compatibility with operating systems and hardware. + ## 9.16.4 ### YACReaderLibrary From ecee7d0aa439d94fe1504ae5a3cb7b5c5954f679 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 12 Jan 2026 15:54:22 +0100 Subject: [PATCH 026/187] Add new pri files for including the theme related files --- YACReader/YACReader.pro | 2 ++ YACReader/themes/themes.pri | 1 + YACReaderLibrary/YACReaderLibrary.pro | 2 ++ YACReaderLibrary/themes/themes.pri | 1 + common/themes/themes_common.pri | 1 + 5 files changed, 7 insertions(+) create mode 100644 YACReader/themes/themes.pri create mode 100644 YACReaderLibrary/themes/themes.pri create mode 100644 common/themes/themes_common.pri diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro index 612112e48..2a9b3f69c 100644 --- a/YACReader/YACReader.pro +++ b/YACReader/YACReader.pro @@ -11,6 +11,8 @@ DEFINES += YACREADER #load default build flags include (../config.pri) include (../dependencies/pdf_backend.pri) +include (./themes/themes.pri) +include (../common/themes/themes_common.pri) contains(QMAKE_TARGET.arch, x86_64) { Release:DESTDIR = ../release64 diff --git a/YACReader/themes/themes.pri b/YACReader/themes/themes.pri new file mode 100644 index 000000000..aba082dde --- /dev/null +++ b/YACReader/themes/themes.pri @@ -0,0 +1 @@ +INCLUDEPATH += $$PWD diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 12726d285..eebe8a031 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -257,6 +257,8 @@ include(../third_party/QsLog/QsLog.pri) include(../shortcuts_management/shortcuts_management.pri) include(../third_party/QrCode/QrCode.pri) include(../third_party/KDToolBox/KDToolBox.pri) +include(./themes/themes.pri) +include(../common/themes/themes_common.pri) RESOURCES += images.qrc files.qrc win32:RESOURCES += images_win.qrc diff --git a/YACReaderLibrary/themes/themes.pri b/YACReaderLibrary/themes/themes.pri new file mode 100644 index 000000000..aba082dde --- /dev/null +++ b/YACReaderLibrary/themes/themes.pri @@ -0,0 +1 @@ +INCLUDEPATH += $$PWD diff --git a/common/themes/themes_common.pri b/common/themes/themes_common.pri new file mode 100644 index 000000000..aba082dde --- /dev/null +++ b/common/themes/themes_common.pri @@ -0,0 +1 @@ +INCLUDEPATH += $$PWD From 05338d8122987b1e97de7c2560d9af7204dd11ad Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 12 Jan 2026 18:20:49 +0100 Subject: [PATCH 027/187] Add an enum to identify themes We can add here all the built-in themes, plus a custom one that could be loaded from a file. --- common/themes/theme_id.h | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 common/themes/theme_id.h diff --git a/common/themes/theme_id.h b/common/themes/theme_id.h new file mode 100644 index 000000000..f42c30696 --- /dev/null +++ b/common/themes/theme_id.h @@ -0,0 +1,10 @@ +#ifndef THEME_ID_H +#define THEME_ID_H + +enum class ThemeId { + Classic, + Light, + Dark, +}; + +#endif // THEME_ID_H From 1df50ce7e624fad258a16e5ddc35d57a47544a7f Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 12 Jan 2026 18:33:22 +0100 Subject: [PATCH 028/187] Add the Theme struct to both projects --- YACReader/themes/theme.h | 7 +++++++ YACReader/themes/themes.pri | 3 +++ YACReaderLibrary/themes/theme.h | 7 +++++++ YACReaderLibrary/themes/themes.pri | 3 +++ 4 files changed, 20 insertions(+) create mode 100644 YACReader/themes/theme.h create mode 100644 YACReaderLibrary/themes/theme.h diff --git a/YACReader/themes/theme.h b/YACReader/themes/theme.h new file mode 100644 index 000000000..c770f3e2a --- /dev/null +++ b/YACReader/themes/theme.h @@ -0,0 +1,7 @@ +#ifndef THEME_H +#define THEME_H + +struct Theme { +}; + +#endif // THEME_H diff --git a/YACReader/themes/themes.pri b/YACReader/themes/themes.pri index aba082dde..9e42ad159 100644 --- a/YACReader/themes/themes.pri +++ b/YACReader/themes/themes.pri @@ -1 +1,4 @@ INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/theme.h \ diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h new file mode 100644 index 000000000..c770f3e2a --- /dev/null +++ b/YACReaderLibrary/themes/theme.h @@ -0,0 +1,7 @@ +#ifndef THEME_H +#define THEME_H + +struct Theme { +}; + +#endif // THEME_H diff --git a/YACReaderLibrary/themes/themes.pri b/YACReaderLibrary/themes/themes.pri index aba082dde..9e42ad159 100644 --- a/YACReaderLibrary/themes/themes.pri +++ b/YACReaderLibrary/themes/themes.pri @@ -1 +1,4 @@ INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/theme.h \ From cc753e1866850658db9d5eb3ea5399dfd07a112a Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 12 Jan 2026 18:35:59 +0100 Subject: [PATCH 029/187] Add ThemeManager It can listen to system changes and update the current theme, widgets can use it to get the current theme. --- common/themes/theme_manager.cpp | 50 +++++++++++++++++++++++++++++++++ common/themes/theme_manager.h | 37 ++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 common/themes/theme_manager.cpp create mode 100644 common/themes/theme_manager.h diff --git a/common/themes/theme_manager.cpp b/common/themes/theme_manager.cpp new file mode 100644 index 000000000..70c4d075c --- /dev/null +++ b/common/themes/theme_manager.cpp @@ -0,0 +1,50 @@ +#include "theme_manager.h" + +#include "theme.h" + +#include +#include + +ThemeManager::ThemeManager() +{ +} + +ThemeManager &ThemeManager::instance() +{ + static ThemeManager instance; + return instance; +} + +void ThemeManager::initialize() +{ + auto *styleHints = qGuiApp->styleHints(); + + auto colorScheme = styleHints->colorScheme(); + + // TODO: settings are needed to decide what theme to use + auto applyColorScheme = [this](Qt::ColorScheme scheme) { + setTheme(scheme == Qt::ColorScheme::Dark ? ThemeId::Dark : ThemeId::Light); + }; + + applyColorScheme(colorScheme); + + connect(styleHints, &QStyleHints::colorSchemeChanged, this, applyColorScheme, Qt::QueuedConnection); +} + +void ThemeManager::setTheme(ThemeId themeId) +{ + if (this->themeId == themeId) { + return; + } + + this->themeId = themeId; + + updateCurrentTheme(); + + emit themeChanged(); +} + +void ThemeManager::updateCurrentTheme() +{ + // TODO +} diff --git a/common/themes/theme_manager.h b/common/themes/theme_manager.h new file mode 100644 index 000000000..8bac2dad5 --- /dev/null +++ b/common/themes/theme_manager.h @@ -0,0 +1,37 @@ +#ifndef THEME_MANAGER_H +#define THEME_MANAGER_H + +#include "theme.h" +#include "theme_id.h" + +#include + +class ThemeManager : public QObject +{ + Q_OBJECT +public: + static ThemeManager &instance(); + + ThemeManager(const ThemeManager &) = delete; + ThemeManager &operator=(const ThemeManager &) = delete; + ThemeManager(ThemeManager &&) = delete; + ThemeManager &operator=(ThemeManager &&) = delete; + + void initialize(); + + void setTheme(ThemeId themeId); + + const Theme &getCurrentTheme() const { return currentTheme; } + +signals: + void themeChanged(); + +private: + explicit ThemeManager(); + ThemeId themeId = ThemeId::Classic; + Theme currentTheme; + + void updateCurrentTheme(); +}; + +#endif // THEME_MANAGER_H From 19a4037a1ac2210997f47e27f5c494559ecdd974 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 12 Jan 2026 18:47:41 +0100 Subject: [PATCH 030/187] Add an abstract class to be implemented by any class that needs theming --- common/themes/themable.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 common/themes/themable.h diff --git a/common/themes/themable.h b/common/themes/themable.h new file mode 100644 index 000000000..fd5f39120 --- /dev/null +++ b/common/themes/themable.h @@ -0,0 +1,24 @@ +#ifndef THEMABLE_H +#define THEMABLE_H + +#include "theme_manager.h" + +class Themable +{ +protected: + void initTheme(QObject *owner) + { + QObject::connect(&ThemeManager::instance(), + &ThemeManager::themeChanged, + owner, + [this]() { + applyTheme(); + }); + + applyTheme(); + } + + virtual void applyTheme() = 0; +}; + +#endif // THEMABLE_H From 390b24514cbc63f2f1840a43345ec4dda7f4aaf2 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 12 Jan 2026 18:48:06 +0100 Subject: [PATCH 031/187] Add helpers to tint svg files --- common/themes/icon_utils.cpp | 75 ++++++++++++++++++++++++++++++++++++ common/themes/icon_utils.h | 20 ++++++++++ 2 files changed, 95 insertions(+) create mode 100644 common/themes/icon_utils.cpp create mode 100644 common/themes/icon_utils.h diff --git a/common/themes/icon_utils.cpp b/common/themes/icon_utils.cpp new file mode 100644 index 000000000..826b31ef5 --- /dev/null +++ b/common/themes/icon_utils.cpp @@ -0,0 +1,75 @@ +#include "icon_utils.h" + +#include "yacreader_global.h" + +QString recolorSvgXML(QString &svg, + const QString &placeHolder, + const QColor &color) +{ + return svg.replace(placeHolder, color.name(QColor::HexRgb), Qt::CaseInsensitive); +} + +QString readSvg(const QString &resourcePath) +{ + QFile in(resourcePath); + if (!in.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning() << "Failed to open SVG resource:" << resourcePath; + return {}; + } + + QString svg = QString::fromUtf8(in.readAll()); + in.close(); + + return svg; +} + +QString writeSvg(const QString &svg, const QString &resourcePath, const QString &themeName, const QString &suffix = QString()) +{ + const QString basePath = YACReader::getSettingsPath() + "/themes/" + themeName; + + QDir().mkpath(basePath); + + QString fileName = QFileInfo(resourcePath).completeBaseName(); + if (!suffix.isEmpty()) { + fileName += suffix; + } + fileName += "." + QFileInfo(resourcePath).suffix(); + const QString outPath = basePath + "/" + fileName; + + QFile out(outPath); + if (!out.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { + qWarning() << "Failed to write SVG:" << outPath; + return {}; + } + + out.write(svg.toUtf8()); + out.close(); + + return outPath; +} + +QString recoloredSvgToThemeFile(const QString &resourcePath, + const QColor &color1, // #f0f (magenta) + const QColor &color2, // #0ff (cyan) + const QString &themeName, + const QString &suffix) +{ + auto svg = readSvg(resourcePath); + + recolorSvgXML(svg, "#f0f", color1); + recolorSvgXML(svg, "#0ff", color2); + + return writeSvg(svg, resourcePath, themeName, suffix); +} + +QString recoloredSvgToThemeFile(const QString &resourcePath, + const QColor &color, // #f0f (magenta) + const QString &themeName, + const QString &suffix) +{ + auto svg = readSvg(resourcePath); + + recolorSvgXML(svg, "#f0f", color); + + return writeSvg(svg, resourcePath, themeName, suffix); +} diff --git a/common/themes/icon_utils.h b/common/themes/icon_utils.h new file mode 100644 index 000000000..014a1b694 --- /dev/null +++ b/common/themes/icon_utils.h @@ -0,0 +1,20 @@ +#ifndef ICON_UTILS_H +#define ICON_UTILS_H + +#include + +QString recolorSvgXML(QString &svg, const QString &placeHolder, const QColor &color); +QString readSvg(const QString &resourcePath); +QString writeSvg(const QString &svg, const QString &resourcePath, const QString &themeName); +QString recoloredSvgToThemeFile(const QString &resourcePath, + const QColor &color1, // #f0f (magenta) + const QColor &color2, // #0ff (cyan) + const QString &themeName, + const QString &suffix = QString()); +QString recoloredSvgToThemeFile(const QString &resourcePath, + const QColor &color, // #f0f (magenta) + const QString &themeName, + const QString &suffix = QString()); +QString createMenuArrowSvg(const QColor &color, const QString &themeName); + +#endif // ICON_UTILS_H From 77240e67f2e262cc9fc053fc2f463e4118ece682 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 12 Jan 2026 18:49:47 +0100 Subject: [PATCH 032/187] Add a struct for the cases where we need to specify a icon size explicitly --- common/themes/yacreader_icon.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 common/themes/yacreader_icon.h diff --git a/common/themes/yacreader_icon.h b/common/themes/yacreader_icon.h new file mode 100644 index 000000000..152d46a00 --- /dev/null +++ b/common/themes/yacreader_icon.h @@ -0,0 +1,12 @@ +#ifndef YACREADER_ICON_H +#define YACREADER_ICON_H + +#include +#include + +struct YACReaderIcon { + QIcon icon; + QSize size; +}; + +#endif // YACREADER_ICON_H From 07eb103ce384311ecf1b88decaad9b5cf647ad80 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 12 Jan 2026 18:50:04 +0100 Subject: [PATCH 033/187] Add the new files to the projects --- common/themes/themes_common.pri | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/common/themes/themes_common.pri b/common/themes/themes_common.pri index aba082dde..67b11da3f 100644 --- a/common/themes/themes_common.pri +++ b/common/themes/themes_common.pri @@ -1 +1,13 @@ INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/icon_utils.h \ + $$PWD/theme_id.h \ + $$PWD/theme_manager.h \ + $$PWD/themable.h \ + $$PWD/yacreader_icon.h \ + + +SOURCES += \ + $$PWD/icon_utils.cpp \ + $$PWD/theme_manager.cpp From b9b8ad81a5de127944e4a03460aeed9e9756f4de Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 12 Jan 2026 19:01:39 +0100 Subject: [PATCH 034/187] Replace all the icons in the comic vine scraper with svg versions --- YACReaderLibrary/images.qrc | 16 ++++++++-------- images/comic_vine/downArrow.png | Bin 139 -> 0 bytes images/comic_vine/downArrow.svg | 11 +++++++++++ images/comic_vine/nextPage.png | Bin 166 -> 0 bytes images/comic_vine/nextPage.svg | 11 +++++++++++ images/comic_vine/previousPage.png | Bin 167 -> 0 bytes images/comic_vine/previousPage.svg | 11 +++++++++++ images/comic_vine/radioChecked.png | Bin 236 -> 0 bytes images/comic_vine/radioChecked.svg | 16 ++++++++++++++++ images/comic_vine/radioUnchecked.png | Bin 189 -> 0 bytes images/comic_vine/radioUnchecked.svg | 11 +++++++++++ images/comic_vine/rowDown.png | Bin 185 -> 0 bytes images/comic_vine/rowDown.svg | 11 +++++++++++ images/comic_vine/rowUp.png | Bin 186 -> 0 bytes images/comic_vine/rowUp.svg | 11 +++++++++++ images/comic_vine/upArrow.png | Bin 140 -> 0 bytes images/comic_vine/upArrow.svg | 11 +++++++++++ 17 files changed, 101 insertions(+), 8 deletions(-) delete mode 100644 images/comic_vine/downArrow.png create mode 100644 images/comic_vine/downArrow.svg delete mode 100644 images/comic_vine/nextPage.png create mode 100644 images/comic_vine/nextPage.svg delete mode 100644 images/comic_vine/previousPage.png create mode 100644 images/comic_vine/previousPage.svg delete mode 100644 images/comic_vine/radioChecked.png create mode 100644 images/comic_vine/radioChecked.svg delete mode 100644 images/comic_vine/radioUnchecked.png create mode 100644 images/comic_vine/radioUnchecked.svg delete mode 100644 images/comic_vine/rowDown.png create mode 100644 images/comic_vine/rowDown.svg delete mode 100644 images/comic_vine/rowUp.png create mode 100644 images/comic_vine/rowUp.svg delete mode 100644 images/comic_vine/upArrow.png create mode 100644 images/comic_vine/upArrow.svg diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index 56e90257a..ae8add4a1 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -2,14 +2,14 @@ ../images/accept_shortcut.svg ../images/clear_shortcut.svg - ../images/comic_vine/downArrow.png - ../images/comic_vine/nextPage.png - ../images/comic_vine/previousPage.png - ../images/comic_vine/radioChecked.png - ../images/comic_vine/radioUnchecked.png - ../images/comic_vine/rowDown.png - ../images/comic_vine/rowUp.png - ../images/comic_vine/upArrow.png + ../images/comic_vine/downArrow.svg + ../images/comic_vine/nextPage.svg + ../images/comic_vine/previousPage.svg + ../images/comic_vine/radioChecked.svg + ../images/comic_vine/radioUnchecked.svg + ../images/comic_vine/rowDown.svg + ../images/comic_vine/rowUp.svg + ../images/comic_vine/upArrow.svg ../images/comic_vine/checkBoxTick.svg ../images/comics_view_toolbar/asignNumber.svg ../images/comics_view_toolbar/big_size_grid_zoom.svg diff --git a/images/comic_vine/downArrow.png b/images/comic_vine/downArrow.png deleted file mode 100644 index ef5be7af84caf9a92bbf0abe81e722ec2cafde35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1d!3HGVjK4YnDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MY^6Yjv*Ddk`fLuNjyJ4zh2%$TcOi7fk~({gG+d(kgza6 jgQV~RCSiw~1_ovZDIU%&>v{bCK#dHZu6{1-oD!M<4AUbA diff --git a/images/comic_vine/downArrow.svg b/images/comic_vine/downArrow.svg new file mode 100644 index 000000000..a1fdff7d2 --- /dev/null +++ b/images/comic_vine/downArrow.svg @@ -0,0 +1,11 @@ + + + + + + + diff --git a/images/comic_vine/nextPage.png b/images/comic_vine/nextPage.png deleted file mode 100644 index 46aaa8c6274a0a1ed59aa9534d31719e87006cd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PI@$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1G9-c0aAr-fhDt>)=S))*vaDYjoQRx4|H>?hKG<0?UGR#(C z-ldc?$-tnolhIt@fLbL(hiv09wM`2+o8DM4h%?^WDK|Zwfr*D<^InCQ{AX8v1)9m= M>FVdQ&MBb@0R2TYn*aa+ diff --git a/images/comic_vine/nextPage.svg b/images/comic_vine/nextPage.svg new file mode 100644 index 000000000..d95d99bd5 --- /dev/null +++ b/images/comic_vine/nextPage.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/comic_vine/previousPage.png b/images/comic_vine/previousPage.png deleted file mode 100644 index 01365a899dbfa2536a0d7bdbe11ab58509acc284..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PI@$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1Go}Mm_Ar-fhQVuZ9v#Wi@u;fwX1s2hU5PJdkh95c}OJW(jm@UPGb(DAfQL5IN2U@_w;H~rBaf%nG%zqTu;q*Wjwspv3uq{V Mr>mdKI;Vst0Oz4J3jhEB diff --git a/images/comic_vine/previousPage.svg b/images/comic_vine/previousPage.svg new file mode 100644 index 000000000..47a2b2c90 --- /dev/null +++ b/images/comic_vine/previousPage.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/comic_vine/radioChecked.png b/images/comic_vine/radioChecked.png deleted file mode 100644 index a6134f924de6a1dc1710d84cc4b5f168aad01258..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X`aE46Ln>}1r8G2Ee}Biyu(C?QEWx3H+u_cNB}=w29!YG` z%4yI#!s;L;C9zO#UAh7f)65CJHl?pboLyX4n*00tXY8x`sBsLo zkXl($ArZDFg7LYrVzz5oM{oZki4-9_J7JTG0}Hlo6I;jN(){DZL64{m2j)E!8=MM` g7)%msW?*DvSRHK{sNZls3g|KhPgg&ebxsLQ0Qe13)Bpeg diff --git a/images/comic_vine/radioChecked.svg b/images/comic_vine/radioChecked.svg new file mode 100644 index 000000000..c5abedee8 --- /dev/null +++ b/images/comic_vine/radioChecked.svg @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/images/comic_vine/radioUnchecked.png b/images/comic_vine/radioUnchecked.png deleted file mode 100644 index 13c0a7bdf7d1c5a988313be4ee45e8b01f8f1f62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X;yqm)Ln>}1r8G2Ee}Biyu(C?QEWx3H+u_cNB}=w29!YG` z%4yI#!s;L;C9zO#UAh7f(@c&T9XzjQUbxf2FJWLffx#oJrqN@oxI>q8XULrsEW8Cy jQU?SNdwB6Mu}Cnu8p&vLbnNp1TE*b$>gTe~DWM4fJ|;R~ diff --git a/images/comic_vine/radioUnchecked.svg b/images/comic_vine/radioUnchecked.svg new file mode 100644 index 000000000..98f1bf29f --- /dev/null +++ b/images/comic_vine/radioUnchecked.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/comic_vine/rowDown.png b/images/comic_vine/rowDown.png deleted file mode 100644 index c89a816d83dcf8a06699cdb1e7f6c893c432276f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^96-#@!3HEvBYEP0lw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6JlqG(SS$B>F!Nj1N|ykucxYpY>6nB+|Nq+` z-kg4(kHPX=#w7NoOP0vYSTKi8XV<}`1XhQs3c_Mao_Z}^h6W2?{@^%TAbc>dfpI}J g&jPhWvU~yw3 + + + + + + \ No newline at end of file diff --git a/images/comic_vine/rowUp.png b/images/comic_vine/rowUp.png deleted file mode 100644 index 00c4b5486cc332ec8f5304833b48428484f11ae3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 186 zcmeAS@N?(olHy`uVBq!ia0vp^96-#@!3HEvBYEP0lw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6Jlq8LvX$B>F!Nq_$Tw`b_P z<`p}b0xq%(GP^PZD?2f%Y?yWefj}DCPy_3 gg9mJU42*0HM{H#8^TdCT0NTUg>FVdQ&MBb@030hdd;kCd diff --git a/images/comic_vine/rowUp.svg b/images/comic_vine/rowUp.svg new file mode 100644 index 000000000..f57f7fded --- /dev/null +++ b/images/comic_vine/rowUp.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/comic_vine/upArrow.png b/images/comic_vine/upArrow.png deleted file mode 100644 index a0c1303de836d829af181c51a3a286bff6797450..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1d!3HGVjK4YnDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MS7ktjv*Ddk`fLuNjM()^YgQGLx`<_xtf}qnE?|kPs5zg l9$dUL9k?!*oM-1SV5qsl8SpxOkqA&HgQu&X%Q~loCIGgDC + + + + + + \ No newline at end of file From df538fac8904bfe936f9c68f01a154041cd700d9 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 12 Jan 2026 19:04:31 +0100 Subject: [PATCH 035/187] Initialize the theme infrastructure in YACReaderLibrary --- YACReaderLibrary/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index 1697e0ae2..d7c357881 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -21,6 +21,7 @@ #include "db_helper.h" #include "yacreader_libraries.h" #include "exit_check.h" +#include "theme_manager.h" #ifdef Q_OS_MACOS #include "trayhandler.h" #endif @@ -140,6 +141,9 @@ int main(int argc, char **argv) app.setOrganizationName("YACReader"); app.setApplicationVersion(VERSION); + // Theme initialization + ThemeManager::instance().initialize(); + // Set window icon according to Freedesktop icon specification // This is mostly relevant for Linux and other Unix systems if (QIcon::hasThemeIcon("YACReaderLibrary")) { From 1b04b5cfa37f3b2773a148aca887a6a174d347bd Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 12 Jan 2026 19:06:33 +0100 Subject: [PATCH 036/187] Initialize the theme infrastructure in YACReader --- YACReader/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/YACReader/main.cpp b/YACReader/main.cpp index cc757ce7f..cb408d36d 100644 --- a/YACReader/main.cpp +++ b/YACReader/main.cpp @@ -7,6 +7,7 @@ #include "main_window_viewer.h" #include "configuration.h" #include "exit_check.h" +#include "theme_manager.h" #include "QsLog.h" #include "QsLogDest.h" @@ -115,6 +116,8 @@ int main(int argc, char *argv[]) app.setApplicationName("YACReader"); app.setOrganizationName("YACReader"); + ThemeManager::instance().initialize(); + if (QIcon::hasThemeIcon("YACReader")) { app.setWindowIcon(QIcon::fromTheme("YACReader")); } From b46f34adb109f5af6b4b78bdc1f4f4adf7be35cc Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 12 Jan 2026 21:37:38 +0100 Subject: [PATCH 037/187] Replace colors in the toolbar icons with placeholder color #f0f (magenta) so we can recolor them later consistently --- images/comic_vine/checkBoxTick.svg | 2 +- images/viewer_toolbar/bookmark.svg | 2 +- images/viewer_toolbar/bookmark_18x18.svg | 2 +- images/viewer_toolbar/close.svg | 2 +- images/viewer_toolbar/close_18x18.svg | 2 +- images/viewer_toolbar/doubleMangaPage.svg | 2 +- images/viewer_toolbar/doubleMangaPage_18x18.svg | 2 +- images/viewer_toolbar/doublePage.svg | 2 +- images/viewer_toolbar/doublePage_18x18.svg | 2 +- images/viewer_toolbar/fitToPage.svg | 2 +- images/viewer_toolbar/fitToPage_18x18.svg | 2 +- images/viewer_toolbar/flow.svg | 2 +- images/viewer_toolbar/flow_18x18.svg | 2 +- images/viewer_toolbar/full.svg | 2 +- images/viewer_toolbar/full_18x18.svg | 2 +- images/viewer_toolbar/goto.svg | 2 +- images/viewer_toolbar/goto_18x18.svg | 2 +- images/viewer_toolbar/help.svg | 2 +- images/viewer_toolbar/help_18x18.svg | 2 +- images/viewer_toolbar/info.svg | 2 +- images/viewer_toolbar/info_18x18.svg | 2 +- images/viewer_toolbar/magnifyingGlass.svg | 2 +- images/viewer_toolbar/magnifyingGlass_18x18.svg | 2 +- images/viewer_toolbar/next.svg | 2 +- images/viewer_toolbar/next_18x18.svg | 2 +- images/viewer_toolbar/open.svg | 2 +- images/viewer_toolbar/openFolder.svg | 2 +- images/viewer_toolbar/openFolder_18x18.svg | 2 +- images/viewer_toolbar/openNext.svg | 2 +- images/viewer_toolbar/openNext_18x18.svg | 2 +- images/viewer_toolbar/openPrevious.svg | 2 +- images/viewer_toolbar/openPrevious_18x18.svg | 2 +- images/viewer_toolbar/open_18x18.svg | 2 +- images/viewer_toolbar/options.svg | 2 +- images/viewer_toolbar/options_1.svg | 2 +- images/viewer_toolbar/options_18x18.svg | 2 +- images/viewer_toolbar/options_18x18_1.svg | 2 +- images/viewer_toolbar/previous.svg | 2 +- images/viewer_toolbar/previous_18x18.svg | 2 +- images/viewer_toolbar/rotateL.svg | 2 +- images/viewer_toolbar/rotateL_18x18.svg | 2 +- images/viewer_toolbar/rotateR.svg | 2 +- images/viewer_toolbar/rotateR_18x18.svg | 2 +- images/viewer_toolbar/save.svg | 2 +- images/viewer_toolbar/save_18x18.svg | 2 +- images/viewer_toolbar/shortcuts.svg | 2 +- images/viewer_toolbar/shortcuts_18x18.svg | 2 +- images/viewer_toolbar/showBookmarks.svg | 2 +- images/viewer_toolbar/showBookmarks_18x18.svg | 2 +- images/viewer_toolbar/toHeight.svg | 2 +- images/viewer_toolbar/toHeight_18x18.svg | 2 +- images/viewer_toolbar/toWidth.svg | 2 +- images/viewer_toolbar/toWidth_18x18.svg | 2 +- images/viewer_toolbar/translator.svg | 2 +- images/viewer_toolbar/translator_18x18.svg | 2 +- images/viewer_toolbar/zoom.svg | 2 +- images/viewer_toolbar/zoom_18x18.svg | 2 +- 57 files changed, 57 insertions(+), 57 deletions(-) diff --git a/images/comic_vine/checkBoxTick.svg b/images/comic_vine/checkBoxTick.svg index d6590f1b9..043c5e9d5 100644 --- a/images/comic_vine/checkBoxTick.svg +++ b/images/comic_vine/checkBoxTick.svg @@ -4,7 +4,7 @@ \ No newline at end of file + diff --git a/images/viewer_toolbar/bookmark_18x18.svg b/images/viewer_toolbar/bookmark_18x18.svg index edf0e4f81..43fa8da1d 100644 --- a/images/viewer_toolbar/bookmark_18x18.svg +++ b/images/viewer_toolbar/bookmark_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/close.svg b/images/viewer_toolbar/close.svg index 60a87915c..c46bb01ef 100644 --- a/images/viewer_toolbar/close.svg +++ b/images/viewer_toolbar/close.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/close_18x18.svg b/images/viewer_toolbar/close_18x18.svg index 82fad4058..d02a3606a 100644 --- a/images/viewer_toolbar/close_18x18.svg +++ b/images/viewer_toolbar/close_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/doubleMangaPage.svg b/images/viewer_toolbar/doubleMangaPage.svg index 58493cf4c..d8d4936cb 100644 --- a/images/viewer_toolbar/doubleMangaPage.svg +++ b/images/viewer_toolbar/doubleMangaPage.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/doubleMangaPage_18x18.svg b/images/viewer_toolbar/doubleMangaPage_18x18.svg index 781526a3f..3ce103e01 100644 --- a/images/viewer_toolbar/doubleMangaPage_18x18.svg +++ b/images/viewer_toolbar/doubleMangaPage_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/doublePage.svg b/images/viewer_toolbar/doublePage.svg index c12f5d4d9..0373f631d 100644 --- a/images/viewer_toolbar/doublePage.svg +++ b/images/viewer_toolbar/doublePage.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/doublePage_18x18.svg b/images/viewer_toolbar/doublePage_18x18.svg index c5c60e39b..3a80c5c83 100644 --- a/images/viewer_toolbar/doublePage_18x18.svg +++ b/images/viewer_toolbar/doublePage_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/fitToPage.svg b/images/viewer_toolbar/fitToPage.svg index 28b1675a0..4b92c11dd 100644 --- a/images/viewer_toolbar/fitToPage.svg +++ b/images/viewer_toolbar/fitToPage.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/fitToPage_18x18.svg b/images/viewer_toolbar/fitToPage_18x18.svg index 390220d92..fda948446 100644 --- a/images/viewer_toolbar/fitToPage_18x18.svg +++ b/images/viewer_toolbar/fitToPage_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/flow.svg b/images/viewer_toolbar/flow.svg index 779f27d7c..ad0034b15 100644 --- a/images/viewer_toolbar/flow.svg +++ b/images/viewer_toolbar/flow.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/flow_18x18.svg b/images/viewer_toolbar/flow_18x18.svg index 20c060d13..9a4089fe9 100644 --- a/images/viewer_toolbar/flow_18x18.svg +++ b/images/viewer_toolbar/flow_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/full.svg b/images/viewer_toolbar/full.svg index 10ffa55af..caea60b1c 100644 --- a/images/viewer_toolbar/full.svg +++ b/images/viewer_toolbar/full.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/full_18x18.svg b/images/viewer_toolbar/full_18x18.svg index 2a264091b..751362b8e 100644 --- a/images/viewer_toolbar/full_18x18.svg +++ b/images/viewer_toolbar/full_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/goto.svg b/images/viewer_toolbar/goto.svg index e2b346abd..3aa3d9ec4 100644 --- a/images/viewer_toolbar/goto.svg +++ b/images/viewer_toolbar/goto.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/goto_18x18.svg b/images/viewer_toolbar/goto_18x18.svg index 1005c9d6c..b03669e4f 100644 --- a/images/viewer_toolbar/goto_18x18.svg +++ b/images/viewer_toolbar/goto_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/help.svg b/images/viewer_toolbar/help.svg index 1a318207d..40dfc1fd2 100644 --- a/images/viewer_toolbar/help.svg +++ b/images/viewer_toolbar/help.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/help_18x18.svg b/images/viewer_toolbar/help_18x18.svg index a665d883a..59d9389e5 100644 --- a/images/viewer_toolbar/help_18x18.svg +++ b/images/viewer_toolbar/help_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/info.svg b/images/viewer_toolbar/info.svg index a2ea17257..0175b7934 100644 --- a/images/viewer_toolbar/info.svg +++ b/images/viewer_toolbar/info.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/info_18x18.svg b/images/viewer_toolbar/info_18x18.svg index 013a91ea3..8ef26e484 100644 --- a/images/viewer_toolbar/info_18x18.svg +++ b/images/viewer_toolbar/info_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/magnifyingGlass.svg b/images/viewer_toolbar/magnifyingGlass.svg index 06d16b1fd..8fd53ea62 100644 --- a/images/viewer_toolbar/magnifyingGlass.svg +++ b/images/viewer_toolbar/magnifyingGlass.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/magnifyingGlass_18x18.svg b/images/viewer_toolbar/magnifyingGlass_18x18.svg index 37610af84..b13536b51 100644 --- a/images/viewer_toolbar/magnifyingGlass_18x18.svg +++ b/images/viewer_toolbar/magnifyingGlass_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/next.svg b/images/viewer_toolbar/next.svg index 67d8de348..bca7b6514 100644 --- a/images/viewer_toolbar/next.svg +++ b/images/viewer_toolbar/next.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/next_18x18.svg b/images/viewer_toolbar/next_18x18.svg index 76993a677..78bc7ef7e 100644 --- a/images/viewer_toolbar/next_18x18.svg +++ b/images/viewer_toolbar/next_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/open.svg b/images/viewer_toolbar/open.svg index 66cc3bd6e..88ae9d84e 100644 --- a/images/viewer_toolbar/open.svg +++ b/images/viewer_toolbar/open.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/openFolder.svg b/images/viewer_toolbar/openFolder.svg index 9ebf90364..b76891912 100644 --- a/images/viewer_toolbar/openFolder.svg +++ b/images/viewer_toolbar/openFolder.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/openFolder_18x18.svg b/images/viewer_toolbar/openFolder_18x18.svg index dc6a2221f..f68344222 100644 --- a/images/viewer_toolbar/openFolder_18x18.svg +++ b/images/viewer_toolbar/openFolder_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/openNext.svg b/images/viewer_toolbar/openNext.svg index b35a8a55b..55d0a52e8 100644 --- a/images/viewer_toolbar/openNext.svg +++ b/images/viewer_toolbar/openNext.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/openNext_18x18.svg b/images/viewer_toolbar/openNext_18x18.svg index a3e827bfb..ea6143324 100644 --- a/images/viewer_toolbar/openNext_18x18.svg +++ b/images/viewer_toolbar/openNext_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/openPrevious.svg b/images/viewer_toolbar/openPrevious.svg index cc1a77e60..5595b3a35 100644 --- a/images/viewer_toolbar/openPrevious.svg +++ b/images/viewer_toolbar/openPrevious.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/openPrevious_18x18.svg b/images/viewer_toolbar/openPrevious_18x18.svg index d6fe899bb..c8d6100f6 100644 --- a/images/viewer_toolbar/openPrevious_18x18.svg +++ b/images/viewer_toolbar/openPrevious_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/open_18x18.svg b/images/viewer_toolbar/open_18x18.svg index 91c4d420c..cb8353bb5 100644 --- a/images/viewer_toolbar/open_18x18.svg +++ b/images/viewer_toolbar/open_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/options.svg b/images/viewer_toolbar/options.svg index eb25e4de7..9b8005c7d 100644 --- a/images/viewer_toolbar/options.svg +++ b/images/viewer_toolbar/options.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/options_1.svg b/images/viewer_toolbar/options_1.svg index eb25e4de7..9b8005c7d 100644 --- a/images/viewer_toolbar/options_1.svg +++ b/images/viewer_toolbar/options_1.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/options_18x18.svg b/images/viewer_toolbar/options_18x18.svg index f11fb32cb..3a84feb81 100644 --- a/images/viewer_toolbar/options_18x18.svg +++ b/images/viewer_toolbar/options_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/options_18x18_1.svg b/images/viewer_toolbar/options_18x18_1.svg index f11fb32cb..3a84feb81 100644 --- a/images/viewer_toolbar/options_18x18_1.svg +++ b/images/viewer_toolbar/options_18x18_1.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/previous.svg b/images/viewer_toolbar/previous.svg index f672d5a9f..1222a6c2b 100644 --- a/images/viewer_toolbar/previous.svg +++ b/images/viewer_toolbar/previous.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/previous_18x18.svg b/images/viewer_toolbar/previous_18x18.svg index 9b3b1ce18..18fb0d7e3 100644 --- a/images/viewer_toolbar/previous_18x18.svg +++ b/images/viewer_toolbar/previous_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/rotateL.svg b/images/viewer_toolbar/rotateL.svg index bbba31fa3..5e06ceb50 100644 --- a/images/viewer_toolbar/rotateL.svg +++ b/images/viewer_toolbar/rotateL.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/rotateL_18x18.svg b/images/viewer_toolbar/rotateL_18x18.svg index 9a4bf7489..a8e93ff16 100644 --- a/images/viewer_toolbar/rotateL_18x18.svg +++ b/images/viewer_toolbar/rotateL_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/rotateR.svg b/images/viewer_toolbar/rotateR.svg index 2b24771e3..9eaa50d65 100644 --- a/images/viewer_toolbar/rotateR.svg +++ b/images/viewer_toolbar/rotateR.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/rotateR_18x18.svg b/images/viewer_toolbar/rotateR_18x18.svg index 8c7464a73..21ac8af27 100644 --- a/images/viewer_toolbar/rotateR_18x18.svg +++ b/images/viewer_toolbar/rotateR_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/save.svg b/images/viewer_toolbar/save.svg index fb24afb54..179403c9d 100644 --- a/images/viewer_toolbar/save.svg +++ b/images/viewer_toolbar/save.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/save_18x18.svg b/images/viewer_toolbar/save_18x18.svg index 23b312248..b15d15d57 100644 --- a/images/viewer_toolbar/save_18x18.svg +++ b/images/viewer_toolbar/save_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/shortcuts.svg b/images/viewer_toolbar/shortcuts.svg index 4b798fb02..ec1e84d4a 100644 --- a/images/viewer_toolbar/shortcuts.svg +++ b/images/viewer_toolbar/shortcuts.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/shortcuts_18x18.svg b/images/viewer_toolbar/shortcuts_18x18.svg index 1036b8862..4768fde68 100644 --- a/images/viewer_toolbar/shortcuts_18x18.svg +++ b/images/viewer_toolbar/shortcuts_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/showBookmarks.svg b/images/viewer_toolbar/showBookmarks.svg index 33a4f6e5e..aaf160c26 100644 --- a/images/viewer_toolbar/showBookmarks.svg +++ b/images/viewer_toolbar/showBookmarks.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/showBookmarks_18x18.svg b/images/viewer_toolbar/showBookmarks_18x18.svg index 1a94eba9d..3514a4fb6 100644 --- a/images/viewer_toolbar/showBookmarks_18x18.svg +++ b/images/viewer_toolbar/showBookmarks_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/toHeight.svg b/images/viewer_toolbar/toHeight.svg index 4f63694e6..4f8fa86b4 100644 --- a/images/viewer_toolbar/toHeight.svg +++ b/images/viewer_toolbar/toHeight.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/toHeight_18x18.svg b/images/viewer_toolbar/toHeight_18x18.svg index 6c9729bbd..abe065f90 100644 --- a/images/viewer_toolbar/toHeight_18x18.svg +++ b/images/viewer_toolbar/toHeight_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/toWidth.svg b/images/viewer_toolbar/toWidth.svg index 62a6c8462..868b27e40 100644 --- a/images/viewer_toolbar/toWidth.svg +++ b/images/viewer_toolbar/toWidth.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/toWidth_18x18.svg b/images/viewer_toolbar/toWidth_18x18.svg index f796a3da6..e8eef8fde 100644 --- a/images/viewer_toolbar/toWidth_18x18.svg +++ b/images/viewer_toolbar/toWidth_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/translator.svg b/images/viewer_toolbar/translator.svg index 6ff468e29..b2f201dca 100644 --- a/images/viewer_toolbar/translator.svg +++ b/images/viewer_toolbar/translator.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/translator_18x18.svg b/images/viewer_toolbar/translator_18x18.svg index d78e22607..9f316dc25 100644 --- a/images/viewer_toolbar/translator_18x18.svg +++ b/images/viewer_toolbar/translator_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/zoom.svg b/images/viewer_toolbar/zoom.svg index 5f0856031..79252ee5d 100644 --- a/images/viewer_toolbar/zoom.svg +++ b/images/viewer_toolbar/zoom.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/viewer_toolbar/zoom_18x18.svg b/images/viewer_toolbar/zoom_18x18.svg index 270470fad..c7db044f8 100644 --- a/images/viewer_toolbar/zoom_18x18.svg +++ b/images/viewer_toolbar/zoom_18x18.svg @@ -1 +1 @@ - \ No newline at end of file + From 721da42c8cf145e02858cf5c86b3d1fd510dc291 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Wed, 14 Jan 2026 15:51:32 +0100 Subject: [PATCH 038/187] Add toolbar and background theming to YACReader --- YACReader/configuration.cpp | 2 - YACReader/configuration.h | 4 +- YACReader/magnifying_glass.cpp | 6 +- YACReader/main_window_viewer.cpp | 72 +++++++-- YACReader/main_window_viewer.h | 8 +- YACReader/options_dialog.cpp | 14 +- YACReader/options_dialog.h | 2 + YACReader/page_label_widget.cpp | 23 ++- YACReader/page_label_widget.h | 7 +- YACReader/themes/theme.h | 93 ++++++++++++ YACReader/themes/theme_factory.cpp | 223 ++++++++++++++++++++++++++++ YACReader/themes/theme_factory.h | 9 ++ YACReader/themes/themes.pri | 3 + YACReader/viewer.cpp | 24 ++- YACReader/viewer.h | 6 +- YACReader/yacreader_images.qrc | 1 + common/themes/theme_manager.cpp | 3 +- common/yacreader_global_gui.cpp | 5 +- common/yacreader_global_gui.h | 4 +- images/viewer_toolbar/menuArrow.svg | 12 ++ 20 files changed, 483 insertions(+), 38 deletions(-) create mode 100644 YACReader/themes/theme_factory.cpp create mode 100644 YACReader/themes/theme_factory.h create mode 100644 images/viewer_toolbar/menuArrow.svg diff --git a/YACReader/configuration.cpp b/YACReader/configuration.cpp index 15868a8f6..93a93d329 100644 --- a/YACReader/configuration.cpp +++ b/YACReader/configuration.cpp @@ -37,8 +37,6 @@ void Configuration::load(QSettings *settings) settings->setValue(MAXIMIZED, false); if (!settings->contains(DOUBLE_PAGE)) settings->setValue(DOUBLE_PAGE, false); - if (!settings->contains(BACKGROUND_COLOR)) - settings->setValue(BACKGROUND_COLOR, QColor(40, 40, 40)); if (!settings->contains(SHOW_TOOLBARS)) settings->setValue(SHOW_TOOLBARS, true); if (!settings->contains(QUICK_NAVI_MODE)) diff --git a/YACReader/configuration.h b/YACReader/configuration.h index 2845b1227..b70594bfd 100644 --- a/YACReader/configuration.h +++ b/YACReader/configuration.h @@ -85,8 +85,8 @@ class Configuration : public QObject bool getEnlargeImages() { return settings->value(ENLARGE_IMAGES, true).toBool(); } void setEnlargeImages(bool b) { settings->setValue(ENLARGE_IMAGES, b); } - QColor getBackgroundColor() { return settings->value(BACKGROUND_COLOR).value(); } - void setBackgroundColor(const QColor &color) { settings->value(BACKGROUND_COLOR, color); } + QColor getBackgroundColor(const QColor &color) { return settings->value(BACKGROUND_COLOR, color).value(); } + void setBackgroundColor(const QColor &color) { settings->setValue(BACKGROUND_COLOR, color); } bool getShowToolbars() { return settings->value(SHOW_TOOLBARS).toBool(); } void setShowToolbars(bool b) { settings->setValue(SHOW_TOOLBARS, b); } bool getShowInformation() { return settings->value(SHOW_INFO, false).toBool(); } diff --git a/YACReader/magnifying_glass.cpp b/YACReader/magnifying_glass.cpp index 05c919bec..3c166ff38 100644 --- a/YACReader/magnifying_glass.cpp +++ b/YACReader/magnifying_glass.cpp @@ -2,6 +2,8 @@ #include "viewer.h" #include "configuration.h" +#include "theme_manager.h" + #include MagnifyingGlass::MagnifyingGlass(int w, int h, float zoomLevel, QWidget *parent) @@ -77,7 +79,7 @@ void MagnifyingGlass::updateImage(int x, int y) if (outImage) { QImage img(zoomWidth, zoomHeight, QImage::Format_RGB32); img.setDevicePixelRatio(devicePixelRatioF()); - img.fill(Configuration::getConfiguration().getBackgroundColor()); + img.fill(Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor)); if (zw > 0 && zh > 0) { QPainter painter(&img); painter.drawPixmap(xOffset, yOffset, image.copy(xp, yp, zw, zh)); @@ -118,7 +120,7 @@ void MagnifyingGlass::updateImage(int x, int y) if (outImage) { QImage img(zoomWidth, zoomHeight, QImage::Format_RGB32); img.setDevicePixelRatio(devicePixelRatioF()); - img.fill(Configuration::getConfiguration().getBackgroundColor()); + img.fill(Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor)); if (zw > 0 && zh > 0) { QPainter painter(&img); painter.drawPixmap(xOffset, yOffset, image.copy(xp, yp, zw, zh)); diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 2c8331449..1c3e1981d 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -18,6 +18,7 @@ #include "yacreader_global.h" #include "edit_shortcuts_dialog.h" #include "shortcuts_manager.h" +#include "theme_manager.h" #include "whats_new_controller.h" @@ -40,11 +41,12 @@ #endif MainWindowViewer::MainWindowViewer() - : QMainWindow(), fullscreen(false), toolbars(true), currentDirectory("."), currentDirectoryImgDest("."), isClient(false) + : QMainWindow(), fullscreen(false), toolbars(true), currentDirectory("."), currentDirectoryImgDest("."), openToolButton(nullptr), isClient(false) { loadConfiguration(); setupUI(); afterLaunchTasks(); + initTheme(this); } void MainWindowViewer::afterLaunchTasks() @@ -503,16 +505,16 @@ void MainWindowViewer::createToolBars() recentmenu->addAction(clearRecentFilesAction); refreshRecentFilesActionList(); - auto tb = new QToolButton(); + openToolButton = new QToolButton(); auto open = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/open")), openAction); - tb->addAction(open); - tb->addAction(actionWithCustomIcon(QIcon(), openLatestComicAction)); - tb->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openFolder")), openFolderAction)); - tb->addAction(recentmenu->menuAction()); - tb->setPopupMode(QToolButton::MenuButtonPopup); - tb->setDefaultAction(open); - - comicToolBar->addWidget(tb); + openToolButton->addAction(open); + openToolButton->addAction(actionWithCustomIcon(QIcon(), openLatestComicAction)); + openToolButton->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openFolder")), openFolderAction)); + openToolButton->addAction(recentmenu->menuAction()); + openToolButton->setPopupMode(QToolButton::MenuButtonPopup); + openToolButton->setDefaultAction(open); + + comicToolBar->addWidget(openToolButton); #endif comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/save")), saveImageAction)); @@ -1554,6 +1556,56 @@ void MainWindowViewer::setLoadedComicActionsEnabled(bool enabled) a->setEnabled(enabled); } +void MainWindowViewer::applyTheme() +{ + const auto toolbarTheme = ThemeManager::instance().getCurrentTheme().toolbar; + + if (comicToolBar) { + comicToolBar->setStyleSheet(toolbarTheme.toolbarQSS); + } + + auto setIcon = [](QAction *action, const QIcon &icon, const QIcon &icon18x18) { + if (action) { + action->setIcon(icon); + + auto action18x18 = action->property("customIconAction").value(); + if (action18x18) { + + action18x18->setIcon(icon18x18); + } + } + }; + + setIcon(openAction, toolbarTheme.openAction, toolbarTheme.openAction18x18); + setIcon(openFolderAction, toolbarTheme.openFolderAction, toolbarTheme.openFolderAction18x18); + setIcon(openLatestComicAction, toolbarTheme.openLatestComicAction, toolbarTheme.openLatestComicAction18x18); + setIcon(saveImageAction, toolbarTheme.saveImageAction, toolbarTheme.saveImageAction18x18); + setIcon(openComicOnTheLeftAction, toolbarTheme.openComicOnTheLeftAction, toolbarTheme.openComicOnTheLeftAction18x18); + setIcon(openComicOnTheRightAction, toolbarTheme.openComicOnTheRightAction, toolbarTheme.openComicOnTheRightAction18x18); + setIcon(goToPageOnTheLeftAction, toolbarTheme.goToPageOnTheLeftAction, toolbarTheme.goToPageOnTheLeftAction18x18); + setIcon(goToPageOnTheRightAction, toolbarTheme.goToPageOnTheRightAction, toolbarTheme.goToPageOnTheRightAction18x18); + setIcon(adjustHeightAction, toolbarTheme.adjustHeightAction, toolbarTheme.adjustHeightAction18x18); + setIcon(adjustWidthAction, toolbarTheme.adjustWidthAction, toolbarTheme.adjustWidthAction18x18); + setIcon(leftRotationAction, toolbarTheme.leftRotationAction, toolbarTheme.leftRotationAction18x18); + setIcon(rightRotationAction, toolbarTheme.rightRotationAction, toolbarTheme.rightRotationAction18x18); + setIcon(doublePageAction, toolbarTheme.doublePageAction, toolbarTheme.doublePageAction18x18); + setIcon(doubleMangaPageAction, toolbarTheme.doubleMangaPageAction, toolbarTheme.doubleMangaPageAction18x18); + setIcon(showZoomSliderlAction, toolbarTheme.showZoomSliderlAction, toolbarTheme.showZoomSliderlAction18x18); + setIcon(goToPageAction, toolbarTheme.goToPageAction, toolbarTheme.goToPageAction18x18); + setIcon(optionsAction, toolbarTheme.optionsAction, toolbarTheme.optionsAction18x18); + setIcon(helpAboutAction, toolbarTheme.helpAboutAction, toolbarTheme.helpAboutAction18x18); + setIcon(showMagnifyingGlassAction, toolbarTheme.showMagnifyingGlassAction, toolbarTheme.showMagnifyingGlassAction18x18); + setIcon(setBookmarkAction, toolbarTheme.setBookmarkAction, toolbarTheme.setBookmarkAction18x18); + setIcon(showBookmarksAction, toolbarTheme.showBookmarksAction, toolbarTheme.showBookmarksAction18x18); + setIcon(showShorcutsAction, toolbarTheme.showShorcutsAction, toolbarTheme.showShorcutsAction18x18); + setIcon(showInfoAction, toolbarTheme.showInfoAction, toolbarTheme.showInfoAction18x18); + setIcon(closeAction, toolbarTheme.closeAction, toolbarTheme.closeAction18x18); + setIcon(showDictionaryAction, toolbarTheme.showDictionaryAction, toolbarTheme.showDictionaryAction18x18); + setIcon(adjustToFullSizeAction, toolbarTheme.adjustToFullSizeAction, toolbarTheme.adjustToFullSizeAction18x18); + setIcon(fitToPageAction, toolbarTheme.fitToPageAction, toolbarTheme.fitToPageAction18x18); + setIcon(showFlowAction, toolbarTheme.showFlowAction, toolbarTheme.showFlowAction18x18); +} + void MainWindowViewer::dropEvent(QDropEvent *event) { QList urlList; diff --git a/YACReader/main_window_viewer.h b/YACReader/main_window_viewer.h index b2d086636..ec6033b8a 100644 --- a/YACReader/main_window_viewer.h +++ b/YACReader/main_window_viewer.h @@ -3,12 +3,14 @@ #include #include #include +#include #include #include #include #include #include "yacreader_global.h" +#include "themable.h" #ifdef Y_MAC_UI #include "yacreader_macosx_toolbar.h" @@ -28,7 +30,7 @@ class EditShortcutsDialog; namespace YACReader { -class MainWindowViewer : public QMainWindow +class MainWindowViewer : public QMainWindow, protected Themable { Q_OBJECT @@ -153,6 +155,8 @@ public slots: QList mglassActions; QList loadedComicActions; + QToolButton *openToolButton; + YACReaderSlider *zoomSliderAction; HttpVersionChecker *versionChecker; @@ -170,6 +174,8 @@ public slots: void setMglassActionsEnabled(bool enabled); void setLoadedComicActionsEnabled(bool enabled); + void applyTheme() override; + //! Manejadores de evento: // void resizeEvent(QResizeEvent * event); void mouseDoubleClickEvent(QMouseEvent *event) override; diff --git a/YACReader/options_dialog.cpp b/YACReader/options_dialog.cpp index 10d73439a..6a987c069 100644 --- a/YACReader/options_dialog.cpp +++ b/YACReader/options_dialog.cpp @@ -12,6 +12,7 @@ #include #include #include +#include "theme_manager.h" #include "yacreader_spin_slider_widget.h" #include "yacreader_3d_flow_config_widget.h" @@ -65,10 +66,12 @@ OptionsDialog::OptionsDialog(QWidget *parent) // backgroundColor->setMinimumWidth(100); colorSelection->addWidget(backgroundColor); colorSelection->addWidget(selectBackgroundColorButton = new QPushButton(tr("Choose"))); + colorSelection->addWidget(clearBackgroundColorButton = new QPushButton(tr("Clear"))); colorSelection->setStretchFactor(backgroundColor, 1); colorSelection->setStretchFactor(selectBackgroundColorButton, 0); // colorSelection->addStretch(); connect(selectBackgroundColorButton, &QAbstractButton::clicked, this, &OptionsDialog::showColorDialog); + connect(clearBackgroundColorButton, &QAbstractButton::clicked, this, &OptionsDialog::clearBackgroundColor); colorBox->setLayout(colorSelection); auto scrollBox = new QGroupBox(tr("Scroll behaviour")); @@ -278,7 +281,7 @@ void OptionsDialog::restoreOptions(QSettings *settings) showTimeInInformationLabel->setChecked(Configuration::getConfiguration().getShowTimeInInformation()); - updateColor(settings->value(BACKGROUND_COLOR).value()); + updateColor(settings->value(BACKGROUND_COLOR, ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor).value()); // fitToWidthRatioS->setSliderPosition(settings->value(FIT_TO_WIDTH_RATIO).toFloat()*100); quickNavi->setChecked(settings->value(QUICK_NAVI_MODE).toBool()); @@ -324,8 +327,6 @@ void OptionsDialog::updateColor(const QColor &color) backgroundColor->setAutoFillBackground(true); currentColor = color; - settings->setValue(BACKGROUND_COLOR, color); - emit changedOptions(); } @@ -392,3 +393,10 @@ void OptionsDialog::setFilters(int brightness, int contrast, int gamma) else gammaS->setValue(100); } + +void OptionsDialog::clearBackgroundColor() +{ + settings->remove(BACKGROUND_COLOR); + + updateColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor); +} diff --git a/YACReader/options_dialog.h b/YACReader/options_dialog.h index 0f15e196b..f1d96767a 100644 --- a/YACReader/options_dialog.h +++ b/YACReader/options_dialog.h @@ -42,6 +42,7 @@ class OptionsDialog : public YACReaderOptionsDialog QLabel *backgroundColor; QPushButton *selectBackgroundColorButton; + QPushButton *clearBackgroundColorButton; QCheckBox *doNotTurnPageOnScroll; QCheckBox *useSingleScrollStepToTurnPage; @@ -72,6 +73,7 @@ public slots: void resetImageConfig(); void show(); void setFilters(int brightness, int contrast, int gamma); + void clearBackgroundColor(); signals: void changedOptions(); diff --git a/YACReader/page_label_widget.cpp b/YACReader/page_label_widget.cpp index 8fd6a4b96..afd60e9dc 100644 --- a/YACReader/page_label_widget.cpp +++ b/YACReader/page_label_widget.cpp @@ -2,6 +2,8 @@ #include +#include "theme_manager.h" + PageLabelWidget::PageLabelWidget(QWidget *parent) : QWidget(parent) { @@ -25,13 +27,13 @@ PageLabelWidget::PageLabelWidget(QWidget *parent) int contentMargin = 0; if (verticalRes <= 1024) { - textLabel->setStyleSheet("QLabel { color : white; font-size:12px; }"); + fontSizePx = 12; contentMargin = 12; } else if (verticalRes <= 1200) { - textLabel->setStyleSheet("QLabel { color : white; font-size:16px; }"); + fontSizePx = 16; contentMargin = 16; } else { - textLabel->setStyleSheet("QLabel { color : white; font-size:20px; }"); + fontSizePx = 20; contentMargin = 20; } @@ -47,6 +49,8 @@ PageLabelWidget::PageLabelWidget(QWidget *parent) if (parent != nullptr) move(QPoint((parent->geometry().size().width() - this->width()), -this->height())); + + initTheme(this); } void PageLabelWidget::show() @@ -90,7 +94,7 @@ void PageLabelWidget::paintEvent(QPaintEvent *) { QPainter painter(this); - painter.fillRect(0, 0, width(), height(), QColor(0xBB000000)); + painter.fillRect(rect(), infoBackgroundColor); } void PageLabelWidget::updatePosition() @@ -106,3 +110,14 @@ void PageLabelWidget::updatePosition() else move(QPoint((parent->geometry().size().width() - this->width()), -this->height())); } + +void PageLabelWidget::applyTheme() +{ + const auto viewerTheme = ThemeManager::instance().getCurrentTheme().viewer; + + infoBackgroundColor = viewerTheme.infoBackgroundColor; + + textLabel->setStyleSheet(viewerTheme.infoLabelQSS.arg(fontSizePx)); + + update(); +} diff --git a/YACReader/page_label_widget.h b/YACReader/page_label_widget.h index 35b0c94ed..f65cfd9c1 100644 --- a/YACReader/page_label_widget.h +++ b/YACReader/page_label_widget.h @@ -3,18 +3,23 @@ #include +#include "themable.h" + class QLabel; class QPropertyAnimation; -class PageLabelWidget : public QWidget +class PageLabelWidget : public QWidget, protected Themable { Q_OBJECT private: QLabel *textLabel; QPropertyAnimation *animation; + QColor infoBackgroundColor; + int fontSizePx = 0; protected: void paintEvent(QPaintEvent *) override; + void applyTheme() override; public: PageLabelWidget(QWidget *parent); diff --git a/YACReader/themes/theme.h b/YACReader/themes/theme.h index c770f3e2a..719ba61b5 100644 --- a/YACReader/themes/theme.h +++ b/YACReader/themes/theme.h @@ -1,7 +1,100 @@ #ifndef THEME_H #define THEME_H +#include + +struct ToolbarThemeTemplates { + QString toolbarQSS = "QToolBar { border: none; background: %1; }\n" + "QToolBar::separator { background: %2; width: 1px; margin: 5px 4px; }\n" + "QToolButton:checked { background-color: %3; }\n" + "QToolButton::menu-button {border: none; width: 18px; }\n" + "QToolButton::menu-arrow { image: url(%4); width: 8px; height: 8px; }\n"; + QString menuArrowPath = ":/images/viewer_toolbar/menuArrow.svg"; +}; + +struct ViewerThemeTemplates { + QString infoLabelQSS = "QLabel { color : %1; font-size:%2px; }"; +}; + +struct ToolbarTheme { + QString toolbarQSS; + + QIcon openAction; + QIcon openAction18x18; + QIcon openFolderAction; + QIcon openFolderAction18x18; + QIcon openLatestComicAction; + QIcon openLatestComicAction18x18; + QIcon saveImageAction; + QIcon saveImageAction18x18; + QIcon openComicOnTheLeftAction; + QIcon openComicOnTheLeftAction18x18; + QIcon openComicOnTheRightAction; + QIcon openComicOnTheRightAction18x18; + QIcon goToPageOnTheLeftAction; + QIcon goToPageOnTheLeftAction18x18; + QIcon goToPageOnTheRightAction; + QIcon goToPageOnTheRightAction18x18; + QIcon adjustHeightAction; + QIcon adjustHeightAction18x18; + QIcon adjustWidthAction; + QIcon adjustWidthAction18x18; + QIcon leftRotationAction; + QIcon leftRotationAction18x18; + QIcon rightRotationAction; + QIcon rightRotationAction18x18; + QIcon doublePageAction; + QIcon doublePageAction18x18; + QIcon doubleMangaPageAction; + QIcon doubleMangaPageAction18x18; + QIcon increasePageZoomAction; + QIcon increasePageZoomAction18x18; + QIcon decreasePageZoomAction; + QIcon decreasePageZoomAction18x18; + QIcon resetZoomAction; + QIcon resetZoomAction18x18; + QIcon showZoomSliderlAction; + QIcon showZoomSliderlAction18x18; + QIcon goToPageAction; + QIcon goToPageAction18x18; + QIcon optionsAction; + QIcon optionsAction18x18; + QIcon helpAboutAction; + QIcon helpAboutAction18x18; + QIcon showMagnifyingGlassAction; + QIcon showMagnifyingGlassAction18x18; + QIcon setBookmarkAction; + QIcon setBookmarkAction18x18; + QIcon showBookmarksAction; + QIcon showBookmarksAction18x18; + QIcon showShorcutsAction; + QIcon showShorcutsAction18x18; + QIcon showInfoAction; + QIcon showInfoAction18x18; + QIcon closeAction; + QIcon closeAction18x18; + QIcon showDictionaryAction; + QIcon showDictionaryAction18x18; + QIcon adjustToFullSizeAction; + QIcon adjustToFullSizeAction18x18; + QIcon fitToPageAction; + QIcon fitToPageAction18x18; + QIcon showFlowAction; + QIcon showFlowAction18x18; +}; + +struct ViewerTheme { + QColor defaultBackgroundColor; + QColor defaultTextColor; + + QColor infoBackgroundColor; + + QString infoLabelQSS; +}; + struct Theme { + ToolbarTheme toolbar; + ViewerTheme viewer; }; #endif // THEME_H diff --git a/YACReader/themes/theme_factory.cpp b/YACReader/themes/theme_factory.cpp new file mode 100644 index 000000000..04002b472 --- /dev/null +++ b/YACReader/themes/theme_factory.cpp @@ -0,0 +1,223 @@ +#include "theme_factory.h" + +#include "icon_utils.h" + +struct ToolbarParams { + ToolbarThemeTemplates t; + + QColor iconColor; + QColor iconDisabledColor; + QColor iconCheckedColor; + QColor backgroundColor; + QColor separatorColor; + QColor checkedButtonColor; + QColor menuIndicatorColor; +}; + +struct ViewerParams { + ViewerThemeTemplates t; + + QColor defaultBackgroundColor; + QColor defaultTextColor; + QColor infoBackgroundColor; + QColor infoTextColor; +}; + +struct ThemeParams { + QString themeName; + + ToolbarParams toolbarParams; + ViewerParams viewerParams; +}; + +void setToolbarIconPair(QIcon &icon, + QIcon &icon18, + const QString &basePath, + const QColor &iconColor, + const QColor &disabledColor, + const QColor &checkedColor, + const QString &themeName) +{ + QString path18 = basePath; + if (path18.endsWith(".svg")) + path18.insert(path18.size() - 4, "_18x18"); + else + path18.append("_18x18"); + + // Normal + const QString normalPath = recoloredSvgToThemeFile(basePath, iconColor, themeName); + const QString normalPath18 = recoloredSvgToThemeFile(path18, iconColor, themeName); + // Disabled + const QString disabledPath = recoloredSvgToThemeFile(basePath, disabledColor, themeName, "_disabled"); + const QString disabledPath18 = recoloredSvgToThemeFile(path18, disabledColor, themeName, "_disabled"); + // Checked (On state) + const QString checkedPath = recoloredSvgToThemeFile(basePath, checkedColor, themeName, "_checked"); + const QString checkedPath18 = recoloredSvgToThemeFile(path18, checkedColor, themeName, "_checked"); + + icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(disabledPath, QSize(), QIcon::Disabled, QIcon::Off); + icon.addFile(checkedPath, QSize(), QIcon::Normal, QIcon::On); + icon.addFile(disabledPath, QSize(), QIcon::Disabled, QIcon::On); + + icon18.addFile(normalPath18, QSize(), QIcon::Normal, QIcon::Off); + icon18.addFile(disabledPath18, QSize(), QIcon::Disabled, QIcon::Off); + icon18.addFile(checkedPath18, QSize(), QIcon::Normal, QIcon::On); + icon18.addFile(disabledPath18, QSize(), QIcon::Disabled, QIcon::On); +} + +Theme makeTheme(const ThemeParams ¶ms) +{ + Theme theme; + + // Toolbar & actions + theme.toolbar.toolbarQSS = params.toolbarParams.t.toolbarQSS.arg(params.toolbarParams.backgroundColor.name(), params.toolbarParams.separatorColor.name(), params.toolbarParams.checkedButtonColor.name(), recoloredSvgToThemeFile(params.toolbarParams.t.menuArrowPath, params.toolbarParams.menuIndicatorColor, params.themeName)); + + auto setToolbarIconPairT = [&](QIcon &icon, QIcon &icon18, const QString &basePath) { + setToolbarIconPair(icon, icon18, basePath, params.toolbarParams.iconColor, params.toolbarParams.iconDisabledColor, params.toolbarParams.iconCheckedColor, params.themeName); + }; + + setToolbarIconPairT(theme.toolbar.openAction, theme.toolbar.openAction18x18, ":/images/viewer_toolbar/open.svg"); + setToolbarIconPairT(theme.toolbar.openFolderAction, theme.toolbar.openFolderAction18x18, ":/images/viewer_toolbar/openFolder.svg"); + setToolbarIconPairT(theme.toolbar.openLatestComicAction, theme.toolbar.openLatestComicAction18x18, ":/images/viewer_toolbar/openNext.svg"); + setToolbarIconPairT(theme.toolbar.saveImageAction, theme.toolbar.saveImageAction18x18, ":/images/viewer_toolbar/save.svg"); + setToolbarIconPairT(theme.toolbar.openComicOnTheLeftAction, theme.toolbar.openComicOnTheLeftAction18x18, ":/images/viewer_toolbar/openPrevious.svg"); + setToolbarIconPairT(theme.toolbar.openComicOnTheRightAction, theme.toolbar.openComicOnTheRightAction18x18, ":/images/viewer_toolbar/openNext.svg"); + setToolbarIconPairT(theme.toolbar.goToPageOnTheLeftAction, theme.toolbar.goToPageOnTheLeftAction18x18, ":/images/viewer_toolbar/previous.svg"); + setToolbarIconPairT(theme.toolbar.goToPageOnTheRightAction, theme.toolbar.goToPageOnTheRightAction18x18, ":/images/viewer_toolbar/next.svg"); + setToolbarIconPairT(theme.toolbar.adjustHeightAction, theme.toolbar.adjustHeightAction18x18, ":/images/viewer_toolbar/toHeight.svg"); + setToolbarIconPairT(theme.toolbar.adjustWidthAction, theme.toolbar.adjustWidthAction18x18, ":/images/viewer_toolbar/toWidth.svg"); + setToolbarIconPairT(theme.toolbar.leftRotationAction, theme.toolbar.leftRotationAction18x18, ":/images/viewer_toolbar/rotateL.svg"); + setToolbarIconPairT(theme.toolbar.rightRotationAction, theme.toolbar.rightRotationAction18x18, ":/images/viewer_toolbar/rotateR.svg"); + setToolbarIconPairT(theme.toolbar.doublePageAction, theme.toolbar.doublePageAction18x18, ":/images/viewer_toolbar/doublePage.svg"); + setToolbarIconPairT(theme.toolbar.doubleMangaPageAction, theme.toolbar.doubleMangaPageAction18x18, ":/images/viewer_toolbar/doubleMangaPage.svg"); + setToolbarIconPairT(theme.toolbar.showZoomSliderlAction, theme.toolbar.showZoomSliderlAction18x18, ":/images/viewer_toolbar/zoom.svg"); + setToolbarIconPairT(theme.toolbar.goToPageAction, theme.toolbar.goToPageAction18x18, ":/images/viewer_toolbar/goto.svg"); + setToolbarIconPairT(theme.toolbar.optionsAction, theme.toolbar.optionsAction18x18, ":/images/viewer_toolbar/options.svg"); + setToolbarIconPairT(theme.toolbar.helpAboutAction, theme.toolbar.helpAboutAction18x18, ":/images/viewer_toolbar/help.svg"); + setToolbarIconPairT(theme.toolbar.showMagnifyingGlassAction, theme.toolbar.showMagnifyingGlassAction18x18, ":/images/viewer_toolbar/magnifyingGlass.svg"); + setToolbarIconPairT(theme.toolbar.setBookmarkAction, theme.toolbar.setBookmarkAction18x18, ":/images/viewer_toolbar/bookmark.svg"); + setToolbarIconPairT(theme.toolbar.showBookmarksAction, theme.toolbar.showBookmarksAction18x18, ":/images/viewer_toolbar/showBookmarks.svg"); + setToolbarIconPairT(theme.toolbar.showShorcutsAction, theme.toolbar.showShorcutsAction18x18, ":/images/viewer_toolbar/shortcuts.svg"); + setToolbarIconPairT(theme.toolbar.showInfoAction, theme.toolbar.showInfoAction18x18, ":/images/viewer_toolbar/info.svg"); + setToolbarIconPairT(theme.toolbar.closeAction, theme.toolbar.closeAction18x18, ":/images/viewer_toolbar/close.svg"); + setToolbarIconPairT(theme.toolbar.showDictionaryAction, theme.toolbar.showDictionaryAction18x18, ":/images/viewer_toolbar/translator.svg"); + setToolbarIconPairT(theme.toolbar.adjustToFullSizeAction, theme.toolbar.adjustToFullSizeAction18x18, ":/images/viewer_toolbar/full.svg"); + setToolbarIconPairT(theme.toolbar.fitToPageAction, theme.toolbar.fitToPageAction18x18, ":/images/viewer_toolbar/fitToPage.svg"); + setToolbarIconPairT(theme.toolbar.showFlowAction, theme.toolbar.showFlowAction18x18, ":/images/viewer_toolbar/flow.svg"); + // end Toolbar & actions + + // Viewer + theme.viewer.defaultBackgroundColor = params.viewerParams.defaultBackgroundColor; + theme.viewer.defaultTextColor = params.viewerParams.defaultTextColor; + theme.viewer.infoBackgroundColor = params.viewerParams.infoBackgroundColor; + theme.viewer.infoLabelQSS = params.viewerParams.t.infoLabelQSS.arg(params.viewerParams.infoTextColor.name()); + // end Viewer + + return theme; +} + +ThemeParams classicThemeParams(); +ThemeParams lightThemeParams(); +ThemeParams darkThemeParams(); + +Theme makeTheme(ThemeId themeId) +{ + switch (themeId) { + case ThemeId::Classic: + return makeTheme(classicThemeParams()); + case ThemeId::Light: + return makeTheme(lightThemeParams()); + case ThemeId::Dark: + return makeTheme(darkThemeParams()); + } +} + +ThemeParams classicThemeParams() +{ + ThemeParams params; + params.themeName = "classic"; + + ToolbarParams toolbarParams; + toolbarParams.iconColor = QColor(0x404040); + toolbarParams.iconDisabledColor = QColor(0x858585); + toolbarParams.iconCheckedColor = QColor(0x5A5A5A); + toolbarParams.backgroundColor = QColor(0xF3F3F3); + toolbarParams.separatorColor = QColor(0xCCCCCC); + toolbarParams.checkedButtonColor = QColor(0xCCCCCC); + toolbarParams.menuIndicatorColor = QColor(0x404040); + + params.toolbarParams = toolbarParams; + + ViewerParams viewerParams; + viewerParams.defaultBackgroundColor = QColor(0x282828); + viewerParams.defaultTextColor = Qt::white; + viewerParams.infoBackgroundColor = QColor::fromRgba(0xBB000000); + viewerParams.infoTextColor = Qt::white; + viewerParams.t = ViewerThemeTemplates(); + + params.viewerParams = viewerParams; + + return params; +} + +ThemeParams lightThemeParams() +{ + ThemeParams params; + params.themeName = "light"; + + ToolbarParams toolbarParams; + toolbarParams.iconColor = QColor(0x404040); + toolbarParams.iconDisabledColor = QColor(0xB0B0B0); + toolbarParams.iconCheckedColor = QColor(0x5A5A5A); + toolbarParams.backgroundColor = QColor(0xF3F3F3); + toolbarParams.separatorColor = QColor(0xCCCCCC); + toolbarParams.checkedButtonColor = QColor(0xCCCCCC); + toolbarParams.menuIndicatorColor = QColor(0x404040); + + params.toolbarParams = toolbarParams; + + ViewerParams viewerParams; + viewerParams.defaultBackgroundColor = QColor(0xF6F6F6); + viewerParams.defaultTextColor = QColor(0x202020); + viewerParams.infoBackgroundColor = QColor::fromRgba(0xBBFFFFFF); + viewerParams.infoTextColor = QColor(0x404040); + viewerParams.t = ViewerThemeTemplates(); + + params.viewerParams = viewerParams; + + return params; +} + +ThemeParams darkThemeParams() +{ + ThemeParams params; + params.themeName = "dark"; + + ToolbarParams toolbarParams; + toolbarParams.iconColor = QColor(0xCCCCCC); + toolbarParams.iconDisabledColor = QColor(0x444444); + toolbarParams.iconCheckedColor = QColor(0xDADADA); + toolbarParams.backgroundColor = QColor(0x202020); + toolbarParams.separatorColor = QColor(0x444444); + toolbarParams.checkedButtonColor = QColor(0x3A3A3A); + toolbarParams.menuIndicatorColor = QColor(0xCCCCCC); + + params.toolbarParams = toolbarParams; + + ViewerParams viewerParams; + viewerParams.defaultBackgroundColor = QColor(40, 40, 40); + viewerParams.defaultTextColor = Qt::white; + viewerParams.infoBackgroundColor = QColor::fromRgba(0xBB000000); + viewerParams.infoTextColor = QColor(0xB0B0B0); + viewerParams.t = ViewerThemeTemplates(); + + params.viewerParams = viewerParams; + + return params; +} + +// TODO +ThemeParams paramsFromFile(const QString &filePath) +{ + return {}; +} diff --git a/YACReader/themes/theme_factory.h b/YACReader/themes/theme_factory.h new file mode 100644 index 000000000..72cb4ca28 --- /dev/null +++ b/YACReader/themes/theme_factory.h @@ -0,0 +1,9 @@ +#ifndef THEME_FACTORY_H +#define THEME_FACTORY_H + +#include "theme.h" +#include "theme_id.h" + +Theme makeTheme(ThemeId themeId); + +#endif // THEME_FACTORY_H diff --git a/YACReader/themes/themes.pri b/YACReader/themes/themes.pri index 9e42ad159..eee35324e 100644 --- a/YACReader/themes/themes.pri +++ b/YACReader/themes/themes.pri @@ -2,3 +2,6 @@ INCLUDEPATH += $$PWD HEADERS += \ $$PWD/theme.h \ + $$PWD/theme_factory.h +SOURCES += \ + $$PWD/theme_factory.cpp diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index d689e90b1..c42458278 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -10,6 +10,7 @@ #include "notifications_label_widget.h" #include "comic_db.h" #include "shortcuts_manager.h" +#include "theme_manager.h" #include #include @@ -42,17 +43,12 @@ Viewer::Viewer(QWidget *parent) // current comic page content = new QLabel(this); configureContent(tr("Press 'O' to open comic.")); - // scroll area configuration - setBackgroundRole(QPalette::Dark); + setWidget(content); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setFrameStyle(QFrame::NoFrame); setAlignment(Qt::AlignCenter); - - QPalette palette; - palette.setColor(backgroundRole(), Configuration::getConfiguration().getBackgroundColor()); - setPalette(palette); //--------------------------------------- mglass = new MagnifyingGlass( Configuration::getConfiguration().getMagnifyingGlassSize(), @@ -116,6 +112,8 @@ Viewer::Viewer(QWidget *parent) informationLabel = new PageLabelWidget(this); setAcceptDrops(true); + + initTheme(this); } Viewer::~Viewer() @@ -1009,7 +1007,7 @@ void Viewer::showCursor() void Viewer::updateOptions() { goToFlow->setFlowType(Configuration::getConfiguration().getFlowType()); - updateBackgroundColor(Configuration::getConfiguration().getBackgroundColor()); + updateBackgroundColor(Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor)); updateContentSize(); updateInformation(); } @@ -1021,6 +1019,16 @@ void Viewer::updateBackgroundColor(const QColor &color) setPalette(palette); } +void Viewer::applyTheme() +{ + const auto viewerTheme = ThemeManager::instance().getCurrentTheme().viewer; + + updateBackgroundColor(Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor)); + + const QString textColor = viewerTheme.defaultTextColor.name(QColor::HexArgb); + content->setStyleSheet(QStringLiteral("QLabel { color : %1; background: transparent; }").arg(textColor)); +} + void Viewer::animateShowTranslator() { if (translator->isHidden() && translatorAnimation->state() != QPropertyAnimation::Running) { @@ -1084,7 +1092,7 @@ void Viewer::updateConfig(QSettings *settings) goToFlow->updateConfig(settings); QPalette palette; - palette.setColor(backgroundRole(), Configuration::getConfiguration().getBackgroundColor()); + palette.setColor(backgroundRole(), Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor)); setPalette(palette); } diff --git a/YACReader/viewer.h b/YACReader/viewer.h index c2bb183b3..e7dbaa5a6 100644 --- a/YACReader/viewer.h +++ b/YACReader/viewer.h @@ -18,6 +18,7 @@ #include "scroll_management.h" #include "mouse_handler.h" +#include "themable.h" class ComicDB; class Comic; @@ -32,7 +33,7 @@ class Bookmarks; class PageLabelWidget; class NotificationsLabelWidget; -class Viewer : public QScrollArea, public ScrollManagement +class Viewer : public QScrollArea, public ScrollManagement, protected Themable { Q_OBJECT public: @@ -186,6 +187,9 @@ public slots: //! Mouse handler std::unique_ptr mouseHandler; +protected: + void applyTheme() override; + public: Viewer(QWidget *parent = nullptr); ~Viewer(); diff --git a/YACReader/yacreader_images.qrc b/YACReader/yacreader_images.qrc index 8d94645f2..ef71304de 100644 --- a/YACReader/yacreader_images.qrc +++ b/YACReader/yacreader_images.qrc @@ -87,5 +87,6 @@ ../images/viewer_toolbar/toWidth_18x18.svg ../images/viewer_toolbar/translator_18x18.svg ../images/viewer_toolbar/zoom_18x18.svg + ../images/viewer_toolbar/menuArrow.svg diff --git a/common/themes/theme_manager.cpp b/common/themes/theme_manager.cpp index 70c4d075c..4bfabb21f 100644 --- a/common/themes/theme_manager.cpp +++ b/common/themes/theme_manager.cpp @@ -1,6 +1,7 @@ #include "theme_manager.h" #include "theme.h" +#include "theme_factory.h" #include #include @@ -46,5 +47,5 @@ void ThemeManager::setTheme(ThemeId themeId) void ThemeManager::updateCurrentTheme() { - // TODO + currentTheme = makeTheme(themeId); } diff --git a/common/yacreader_global_gui.cpp b/common/yacreader_global_gui.cpp index 7ad76dfae..abf4be555 100644 --- a/common/yacreader_global_gui.cpp +++ b/common/yacreader_global_gui.cpp @@ -32,7 +32,7 @@ QIcon YACReader::noHighlightedIcon(const QString &path) return icon; } -void YACReader::colorize(QImage &img, QColor &col) +void YACReader::colorize(QImage &img, const QColor &col) { QRgb *data = (QRgb *)img.bits(); QRgb *end = data + img.width() * img.height(); @@ -94,6 +94,9 @@ QAction *YACReader::actionWithCustomIcon(const QIcon &icon, QAction *action) QObject::connect(a, &QAction::toggled, action, &QAction::setChecked); QObject::connect(action, &QAction::toggled, a, &QAction::setChecked); + // asign a to action somehow so we can retrieve it later + action->setProperty("customIconAction", QVariant::fromValue(a)); + return a; } diff --git a/common/yacreader_global_gui.h b/common/yacreader_global_gui.h index a4e667e4a..84f8e64c4 100644 --- a/common/yacreader_global_gui.h +++ b/common/yacreader_global_gui.h @@ -24,7 +24,7 @@ #define DOUBLE_PAGE "DOUBLE_PAGE" #define DOUBLE_MANGA_PAGE "DOUBLE_MANGA_PAGE" #define COVER_IS_SP "COVER_IS_SP" -#define BACKGROUND_COLOR "BACKGROUND_COLOR" +#define BACKGROUND_COLOR "BACKGROUND_COLOR_10" #define SHOW_TOOLBARS "SHOW_TOOLBARS" #define BRIGHTNESS "BRIGHTNESS" #define CONTRAST "CONTRAST" @@ -108,7 +108,7 @@ enum LibraryUITheme { void addSperator(QWidget *w); QAction *createSeparator(); QIcon noHighlightedIcon(const QString &path); -void colorize(QImage &img, QColor &col); +void colorize(QImage &img, const QColor &col); QList mimeDataToComicsIds(const QMimeData *data); QString addExtensionToIconPath(const QString &path); QString addExtensionToIconPathInToolbar(const QString &path); diff --git a/images/viewer_toolbar/menuArrow.svg b/images/viewer_toolbar/menuArrow.svg new file mode 100644 index 000000000..077aad90f --- /dev/null +++ b/images/viewer_toolbar/menuArrow.svg @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file From 1cb2f50057644770ead941e85c2fea848e04d37d Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Wed, 14 Jan 2026 15:52:11 +0100 Subject: [PATCH 039/187] Make the YACReaderBusyWidget customizable (color) --- custom_widgets/yacreader_busy_widget.cpp | 14 ++++++++++---- custom_widgets/yacreader_busy_widget.h | 6 ++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/custom_widgets/yacreader_busy_widget.cpp b/custom_widgets/yacreader_busy_widget.cpp index 10550e34e..0ef081b30 100644 --- a/custom_widgets/yacreader_busy_widget.cpp +++ b/custom_widgets/yacreader_busy_widget.cpp @@ -9,10 +9,15 @@ YACReaderBusyWidget::YACReaderBusyWidget(QWidget *parent) : QWidget(parent) { setFixedSize(70, 70); - BusyIndicator *busy = new BusyIndicator(this); - busy->setIndicatorStyle(BusyIndicator::StyleArc); - busy->setColor(Qt::white); - busy->move(20, 20); + busyIndicator = new BusyIndicator(this); + busyIndicator->setIndicatorStyle(BusyIndicator::StyleArc); + busyIndicator->setColor(Qt::white); + busyIndicator->move(20, 20); +} + +void YACReaderBusyWidget::setColor(QColor color) +{ + busyIndicator->setColor(color); } BusyIndicator::BusyIndicator(QWidget *parent, int size) @@ -48,6 +53,7 @@ void BusyIndicator::setIndicatorStyle(IndicatorStyle style) void BusyIndicator::setColor(QColor color) { fillColor = color; + update(); } BusyIndicator::IndicatorStyle BusyIndicator::indicatorStyle() const diff --git a/custom_widgets/yacreader_busy_widget.h b/custom_widgets/yacreader_busy_widget.h index 5963c4d29..c7a37c6e9 100644 --- a/custom_widgets/yacreader_busy_widget.h +++ b/custom_widgets/yacreader_busy_widget.h @@ -4,11 +4,17 @@ #include #include +class BusyIndicator; + class YACReaderBusyWidget : public QWidget { Q_OBJECT public: explicit YACReaderBusyWidget(QWidget *parent = 0); + void setColor(QColor color); + +private: + BusyIndicator *busyIndicator; }; class BusyIndicator : public QWidget From 1bd4926b2574676a3a45a9a8ecf0a0b381aef6db Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Wed, 14 Jan 2026 19:58:43 +0100 Subject: [PATCH 040/187] Add a theme factory to YACReaderLibrary and theme the comic vine dialog --- .../comic_vine/comic_vine_dialog.cpp | 38 ++- .../comic_vine/comic_vine_dialog.h | 8 +- .../comic_vine/scraper_checkbox.cpp | 31 +- .../comic_vine/scraper_checkbox.h | 7 +- .../comic_vine/scraper_lineedit.cpp | 19 +- .../comic_vine/scraper_lineedit.h | 5 +- .../comic_vine/scraper_results_paginator.cpp | 32 +- .../comic_vine/scraper_results_paginator.h | 9 +- .../comic_vine/scraper_scroll_label.cpp | 26 +- .../comic_vine/scraper_scroll_label.h | 9 +- .../comic_vine/scraper_tableview.cpp | 32 +- .../comic_vine/scraper_tableview.h | 9 +- .../comic_vine/search_single_comic.cpp | 13 +- .../comic_vine/search_single_comic.h | 8 +- YACReaderLibrary/comic_vine/search_volume.cpp | 13 +- YACReaderLibrary/comic_vine/search_volume.h | 7 +- YACReaderLibrary/comic_vine/select_comic.cpp | 17 +- YACReaderLibrary/comic_vine/select_comic.h | 7 +- YACReaderLibrary/comic_vine/select_volume.cpp | 17 +- YACReaderLibrary/comic_vine/select_volume.h | 7 +- .../comic_vine/series_question.cpp | 23 +- YACReaderLibrary/comic_vine/series_question.h | 9 +- .../comic_vine/sort_volume_comics.cpp | 68 +++- .../comic_vine/sort_volume_comics.h | 47 +-- YACReaderLibrary/comic_vine/title_header.cpp | 15 +- YACReaderLibrary/comic_vine/title_header.h | 7 +- YACReaderLibrary/themes/theme.h | 122 +++++++ YACReaderLibrary/themes/theme_factory.cpp | 299 ++++++++++++++++++ YACReaderLibrary/themes/theme_factory.h | 9 + YACReaderLibrary/themes/themes.pri | 3 + 30 files changed, 739 insertions(+), 177 deletions(-) create mode 100644 YACReaderLibrary/themes/theme_factory.cpp create mode 100644 YACReaderLibrary/themes/theme_factory.h diff --git a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp index 1faa0aae1..d53b1e4c4 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp +++ b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp @@ -27,6 +27,8 @@ #include "db_helper.h" #include "response_parser.h" +#include "theme_manager.h" + #include "QsLog.h" ComicVineDialog::ComicVineDialog(QWidget *parent) @@ -38,6 +40,8 @@ ComicVineDialog::ComicVineDialog(QWidget *parent) doLayout(); doStackedWidgets(); doConnections(); + + initTheme(this); } void ComicVineDialog::closeEvent(QCloseEvent *event) @@ -49,12 +53,6 @@ void ComicVineDialog::closeEvent(QCloseEvent *event) void ComicVineDialog::doLayout() { - setStyleSheet("" - "QDialog {background-color: #404040; }" - ""); - - QString dialogButtonsStyleSheet = "QPushButton {border: 1px solid #242424; background: #2e2e2e; color:white; padding: 5px 26px 5px 26px; font-size:12px;font-family:Arial; font-weight:bold;}"; - skipButton = new QPushButton(tr("skip")); backButton = new QPushButton(tr("back")); nextButton = new QPushButton(tr("next")); @@ -66,12 +64,6 @@ void ComicVineDialog::doLayout() closeButton->setDefault(false); closeButton->setAutoDefault(false); - skipButton->setStyleSheet(dialogButtonsStyleSheet); - backButton->setStyleSheet(dialogButtonsStyleSheet); - nextButton->setStyleSheet(dialogButtonsStyleSheet); - searchButton->setStyleSheet(dialogButtonsStyleSheet); - closeButton->setStyleSheet(dialogButtonsStyleSheet); - content = new QStackedWidget(this); auto mainLayout = new QVBoxLayout; @@ -274,13 +266,11 @@ void ComicVineDialog::doLoading() QWidget *w = new QWidget; auto l = new QVBoxLayout; - auto bw = new YACReaderBusyWidget; + busyWidget = new YACReaderBusyWidget; loadingMessage = new QLabel; - loadingMessage->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}"); - l->addStretch(); - l->addWidget(bw, 0, Qt::AlignHCenter); + l->addWidget(busyWidget, 0, Qt::AlignHCenter); l->addStretch(); l->addWidget(loadingMessage); @@ -666,3 +656,19 @@ void ComicVineDialog::launchSearchComic() // if(comicInfo.isEmpty() && comicNumber == -1) searchVolume({ volumeInfo, 1, exactMatch }); } + +void ComicVineDialog::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + setStyleSheet(comicVineTheme.dialogQSS); + + skipButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); + backButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); + nextButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); + searchButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); + closeButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); + + loadingMessage->setStyleSheet(comicVineTheme.defaultLabelQSS); + busyWidget->setColor(comicVineTheme.busyIndicatorColor); +} diff --git a/YACReaderLibrary/comic_vine/comic_vine_dialog.h b/YACReaderLibrary/comic_vine/comic_vine_dialog.h index e6ccfc78a..b9626cd81 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_dialog.h +++ b/YACReaderLibrary/comic_vine/comic_vine_dialog.h @@ -5,6 +5,7 @@ #include "comic_db.h" #include "volume_search_query.h" +#include "themable.h" class QPushButton; class QStackedWidget; @@ -21,10 +22,11 @@ class SelectVolume; struct SelectedVolumeInfo; class SortVolumeComics; struct VolumeSearchQuery; +class YACReaderBusyWidget; // TODO this should use a QStateMachine //---------------------------------------- -class ComicVineDialog : public QDialog +class ComicVineDialog : public QDialog, protected Themable { Q_OBJECT public: @@ -107,6 +109,7 @@ protected slots: QWidget *singleComicBrowser; QLabel *loadingMessage; + YACReaderBusyWidget *busyWidget; void doLayout(); void doStackedWidgets(); @@ -124,6 +127,9 @@ protected slots: VolumeSearchQuery currentVolumeSearchQuery; QString currentVolumeId; + +protected: + void applyTheme() override; }; #endif // COMIC_VINE_DIALOG_H diff --git a/YACReaderLibrary/comic_vine/scraper_checkbox.cpp b/YACReaderLibrary/comic_vine/scraper_checkbox.cpp index 9a5381217..f7131d777 100644 --- a/YACReaderLibrary/comic_vine/scraper_checkbox.cpp +++ b/YACReaderLibrary/comic_vine/scraper_checkbox.cpp @@ -1,27 +1,16 @@ #include "scraper_checkbox.h" -#include "qwidget.h" + +#include "theme_manager.h" ScraperCheckBox::ScraperCheckBox(const QString &text, QWidget *parent) : QCheckBox(text, parent) { - setStyleSheet( - "QCheckBox {" - " color: white;" - " font-size: 12px;" - " font-family: Arial;" - " spacing: 10px;" - "}" - "QCheckBox::indicator {" - " width: 13px;" - " height: 13px;" - " border: 1px solid #242424;" - " background: #2e2e2e;" - "}" - "QCheckBox::indicator:checked {" - " image: url(:/images/comic_vine/checkBoxTick.svg);" - " background: #2e2e2e;" - "}" - "QCheckBox::indicator:unchecked {" - " background: #2e2e2e;" - "}"); + initTheme(this); +} + +void ScraperCheckBox::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + setStyleSheet(comicVineTheme.checkBoxQSS); } diff --git a/YACReaderLibrary/comic_vine/scraper_checkbox.h b/YACReaderLibrary/comic_vine/scraper_checkbox.h index ad6846709..ce2200c27 100644 --- a/YACReaderLibrary/comic_vine/scraper_checkbox.h +++ b/YACReaderLibrary/comic_vine/scraper_checkbox.h @@ -3,10 +3,15 @@ #include -class ScraperCheckBox : public QCheckBox +#include "themable.h" + +class ScraperCheckBox : public QCheckBox, protected Themable { public: ScraperCheckBox(const QString &text, QWidget *parent = nullptr); + +protected: + void applyTheme() override; }; #endif // SCRAPER_CHECKBOX_H diff --git a/YACReaderLibrary/comic_vine/scraper_lineedit.cpp b/YACReaderLibrary/comic_vine/scraper_lineedit.cpp index d12270859..a5b2fc34f 100644 --- a/YACReaderLibrary/comic_vine/scraper_lineedit.cpp +++ b/YACReaderLibrary/comic_vine/scraper_lineedit.cpp @@ -1,18 +1,17 @@ #include "scraper_lineedit.h" + +#include "theme_manager.h" + #include ScraperLineEdit::ScraperLineEdit(const QString &title, QWidget *widget) : QLineEdit(widget) { titleLabel = new QLabel(title, this); - titleLabel->setStyleSheet("QLabel {color:white;}"); - - setStyleSheet(QString("QLineEdit {" - "border:none; background-color: #2E2E2E; color : white; padding-left: %1; padding-bottom: 1px; margin-bottom: 0px;" - "}") - .arg(titleLabel->sizeHint().width() + 6)); setFixedHeight(22); + + initTheme(this); } void ScraperLineEdit::resizeEvent(QResizeEvent *) @@ -20,3 +19,11 @@ void ScraperLineEdit::resizeEvent(QResizeEvent *) QSize szl = titleLabel->sizeHint(); titleLabel->move(6, (rect().bottom() + 1 - szl.height()) / 2); } + +void ScraperLineEdit::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + titleLabel->setStyleSheet(comicVineTheme.scraperLineEditTitleLabelQSS); + setStyleSheet(comicVineTheme.scraperLineEditQSS.arg(titleLabel->sizeHint().width() + 6)); +} diff --git a/YACReaderLibrary/comic_vine/scraper_lineedit.h b/YACReaderLibrary/comic_vine/scraper_lineedit.h index 8de8b45df..e7d41d436 100644 --- a/YACReaderLibrary/comic_vine/scraper_lineedit.h +++ b/YACReaderLibrary/comic_vine/scraper_lineedit.h @@ -3,9 +3,11 @@ #include +#include "themable.h" + class QLabel; -class ScraperLineEdit : public QLineEdit +class ScraperLineEdit : public QLineEdit, protected Themable { Q_OBJECT public: @@ -13,6 +15,7 @@ class ScraperLineEdit : public QLineEdit protected: void resizeEvent(QResizeEvent *) override; + void applyTheme() override; private: QLabel *titleLabel; diff --git a/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp b/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp index 6dd5f1637..e2f562051 100644 --- a/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp +++ b/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp @@ -1,5 +1,6 @@ #include "scraper_results_paginator.h" #include "response_parser.h" +#include "theme_manager.h" #include #include @@ -10,27 +11,14 @@ ScraperResultsPaginator::ScraperResultsPaginator(QWidget *parent) { auto pagesButtonsLayout = new QHBoxLayout; - QString labelStylesheet = "QLabel {color:white; font-size:12px;font-family:Arial;}"; - nextPage = new QToolButton; - nextPage->setStyleSheet("QToolButton {border:none;}"); - QPixmap np(":/images/comic_vine/nextPage.png"); - nextPage->setIconSize(np.size()); - nextPage->setIcon(np); - previousPage = new QToolButton; - previousPage->setStyleSheet("QToolButton {border:none;}"); - QPixmap pp(":/images/comic_vine/previousPage.png"); - previousPage->setIconSize(pp.size()); - previousPage->setIcon(pp); connect(nextPage, &QAbstractButton::clicked, this, &ScraperResultsPaginator::loadNextPage); connect(previousPage, &QAbstractButton::clicked, this, &ScraperResultsPaginator::loadPreviousPage); numElements = new QLabel(tr("Number of volumes found : %1")); - numElements->setStyleSheet(labelStylesheet); numPages = new QLabel(tr("page %1 of %2")); - numPages->setStyleSheet(labelStylesheet); pagesButtonsLayout->addSpacing(15); pagesButtonsLayout->addWidget(numElements); @@ -43,6 +31,8 @@ ScraperResultsPaginator::ScraperResultsPaginator(QWidget *parent) pagesButtonsLayout->setContentsMargins(0, 0, 0, 0); setLayout(pagesButtonsLayout); + + initTheme(this); } void ScraperResultsPaginator::update(const QString &json) @@ -71,3 +61,19 @@ void ScraperResultsPaginator::setCustomLabel(const QString &label) { customLabel = label; } + +void ScraperResultsPaginator::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + numElements->setStyleSheet(comicVineTheme.defaultLabelQSS); + numPages->setStyleSheet(comicVineTheme.defaultLabelQSS); + + nextPage->setStyleSheet(comicVineTheme.noBorderToolButtonQSS); + nextPage->setIconSize(comicVineTheme.nextPageIcon.size); + nextPage->setIcon(comicVineTheme.nextPageIcon.icon); + + previousPage->setStyleSheet(comicVineTheme.noBorderToolButtonQSS); + previousPage->setIconSize(comicVineTheme.previousPageIcon.size); + previousPage->setIcon(comicVineTheme.previousPageIcon.icon); +} diff --git a/YACReaderLibrary/comic_vine/scraper_results_paginator.h b/YACReaderLibrary/comic_vine/scraper_results_paginator.h index 4395df4cd..d099e1af0 100644 --- a/YACReaderLibrary/comic_vine/scraper_results_paginator.h +++ b/YACReaderLibrary/comic_vine/scraper_results_paginator.h @@ -1,12 +1,14 @@ #ifndef SCRAPER_RESULTS_PAGINATOR_H #define SCRAPER_RESULTS_PAGINATOR_H +#include "themable.h" + #include class QToolButton; class QLabel; -class ScraperResultsPaginator : public QWidget +class ScraperResultsPaginator : public QWidget, protected Themable { Q_OBJECT public: @@ -18,8 +20,6 @@ class ScraperResultsPaginator : public QWidget void loadNextPage(); void loadPreviousPage(); -public slots: - private: QToolButton *nextPage; QToolButton *previousPage; @@ -29,6 +29,9 @@ public slots: int currentPage; QString customLabel; + +protected: + void applyTheme() override; }; #endif // SCRAPER_RESULTS_PAGINATOR_H diff --git a/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp b/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp index f067a4e08..1fd4cdd3b 100644 --- a/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp +++ b/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp @@ -1,5 +1,7 @@ #include "scraper_scroll_label.h" +#include "theme_manager.h" + #include #include #include @@ -8,28 +10,16 @@ ScraperScrollLabel::ScraperScrollLabel(QWidget *parent) : QScrollArea(parent) { textLabel = new QLabel(this); - textLabel->setStyleSheet("QLabel {background-color: #2B2B2B; color:white; font-size:12px; font-family:Arial; }"); textLabel->setWordWrap(true); textLabel->setMinimumSize(168, 12); setWidget(textLabel); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setStyleSheet( - "QScrollArea {background-color:#2B2B2B; border:none;}" - "QScrollBar:vertical { border: none; background: #2B2B2B; width: 3px; margin: 0; }" - "QScrollBar:horizontal { border: none; background: #2B2B2B; height: 3px; margin: 0; }" - "QScrollBar::handle:vertical { background: #DDDDDD; width: 7px; min-height: 20px; }" - "QScrollBar::handle:horizontal { background: #DDDDDD; width: 7px; min-height: 20px; }" - "QScrollBar::add-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::sub-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::add-line:horizontal { border: none; background: #404040; width: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 0 3px 0;}" - "QScrollBar::sub-line:horizontal { border: none; background: #404040; width: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 0 3px 0;}" - "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" - "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" - "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {background: none; }"); connect(textLabel, &QLabel::linkActivated, this, &ScraperScrollLabel::openLink); + + initTheme(this); } void ScraperScrollLabel::setAltText(const QString &text) @@ -50,3 +40,11 @@ void ScraperScrollLabel::openLink(const QString &link) { QDesktopServices::openUrl(QUrl("http://www.comicvine.com" + link)); } + +void ScraperScrollLabel::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + textLabel->setStyleSheet(comicVineTheme.scraperScrollLabelTextQSS); + setStyleSheet(comicVineTheme.scraperScrollLabelScrollAreaQSS); +} diff --git a/YACReaderLibrary/comic_vine/scraper_scroll_label.h b/YACReaderLibrary/comic_vine/scraper_scroll_label.h index 6dc428dd4..7c555d5c0 100644 --- a/YACReaderLibrary/comic_vine/scraper_scroll_label.h +++ b/YACReaderLibrary/comic_vine/scraper_scroll_label.h @@ -3,16 +3,16 @@ #include +#include "themable.h" + class QLabel; -class ScraperScrollLabel : public QScrollArea +class ScraperScrollLabel : public QScrollArea, protected Themable { Q_OBJECT public: explicit ScraperScrollLabel(QWidget *parent = nullptr); -signals: - public slots: void setText(const QString &text); void setAltText(const QString &text); @@ -21,6 +21,9 @@ public slots: private: QLabel *textLabel; + +protected: + void applyTheme() override; }; #endif // SCRAPER_SCROLL_LABEL_H diff --git a/YACReaderLibrary/comic_vine/scraper_tableview.cpp b/YACReaderLibrary/comic_vine/scraper_tableview.cpp index eec6da838..a9c509786 100644 --- a/YACReaderLibrary/comic_vine/scraper_tableview.cpp +++ b/YACReaderLibrary/comic_vine/scraper_tableview.cpp @@ -1,31 +1,12 @@ #include "scraper_tableview.h" +#include "theme_manager.h" + #include ScraperTableView::ScraperTableView(QWidget *parent) : QTableView(parent) { - QString tableStylesheet = "QTableView {color:white; border:0px;alternate-background-color: #2E2E2E;background-color: #2B2B2B; outline: 0px;}" - "QTableView::item {outline: 0px; border: 0px; color:#FFFFFF;}" - "QTableView::item:selected {outline: 0px; background-color: #555555; }" - "QHeaderView::section:horizontal {background-color:#292929; border-bottom:1px solid #1F1F1F; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #292929, stop: 1 #1F1F1F); border-left:none; border-top:none; padding:4px; color:#ebebeb;}" - "QHeaderView::section:vertical {border-bottom: 1px solid #DFDFDF;border-top: 1px solid #FEFEFE;}" - "QHeaderView::down-arrow {image: url(':/images/comic_vine/downArrow.png');}" - "QHeaderView::up-arrow {image: url(':/images/comic_vine/upArrow.png');}" - "QScrollBar:vertical { border: none; background: #2B2B2B; width: 3px; margin: 0; }" - "QScrollBar:horizontal { border: none; background: #2B2B2B; height: 3px; margin: 0; }" - "QScrollBar::handle:vertical { background: #DDDDDD; width: 7px; min-height: 20px; }" - "QScrollBar::handle:horizontal { background: #DDDDDD; width: 7px; min-height: 20px; }" - "QScrollBar::add-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::sub-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::add-line:horizontal { border: none; background: #404040; width: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 0 3px 0;}" - "QScrollBar::sub-line:horizontal { border: none; background: #404040; width: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 0 3px 0;}" - "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" - "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" - "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {background: none; }"; - - setStyleSheet(tableStylesheet); - setShowGrid(false); #if QT_VERSION >= 0x050000 verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); @@ -59,4 +40,13 @@ ScraperTableView::ScraperTableView(QWidget *parent) verticalHeader()->hide(); setSelectionMode(QAbstractItemView::SingleSelection); + + initTheme(this); +} + +void ScraperTableView::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + setStyleSheet(comicVineTheme.scraperTableViewQSS); } diff --git a/YACReaderLibrary/comic_vine/scraper_tableview.h b/YACReaderLibrary/comic_vine/scraper_tableview.h index 03eb0322e..8061b8b87 100644 --- a/YACReaderLibrary/comic_vine/scraper_tableview.h +++ b/YACReaderLibrary/comic_vine/scraper_tableview.h @@ -3,15 +3,16 @@ #include -class ScraperTableView : public QTableView +#include "themable.h" + +class ScraperTableView : public QTableView, protected Themable { Q_OBJECT public: explicit ScraperTableView(QWidget *parent = nullptr); -signals: - -public slots: +protected: + void applyTheme() override; }; #endif // SCRAPPER_TABLEVIEW_H diff --git a/YACReaderLibrary/comic_vine/search_single_comic.cpp b/YACReaderLibrary/comic_vine/search_single_comic.cpp index 1d637990d..f9e446886 100644 --- a/YACReaderLibrary/comic_vine/search_single_comic.cpp +++ b/YACReaderLibrary/comic_vine/search_single_comic.cpp @@ -1,6 +1,7 @@ #include "search_single_comic.h" #include "scraper_lineedit.h" +#include "theme_manager.h" #include #include @@ -11,8 +12,7 @@ SearchSingleComic::SearchSingleComic(QWidget *parent) { // QLabel * label = new QLabel(tr("Please provide some additional information. At least one field is needed.")); - QLabel *label = new QLabel(tr("Please provide some additional information for this comic.")); - label->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}"); + label = new QLabel(tr("Please provide some additional information for this comic.")); // titleEdit = new ScraperLineEdit(tr("Title:")); // numberEdit = new ScraperLineEdit(tr("Number:")); @@ -39,6 +39,8 @@ SearchSingleComic::SearchSingleComic(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); setLayout(l); setContentsMargins(0, 0, 0, 0); + + initTheme(this); } QString SearchSingleComic::getVolumeInfo() const @@ -70,3 +72,10 @@ void SearchSingleComic::clean() { volumeEdit->clear(); } + +void SearchSingleComic::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + label->setStyleSheet(comicVineTheme.defaultLabelQSS); +} diff --git a/YACReaderLibrary/comic_vine/search_single_comic.h b/YACReaderLibrary/comic_vine/search_single_comic.h index 7a8d7c107..12195f772 100644 --- a/YACReaderLibrary/comic_vine/search_single_comic.h +++ b/YACReaderLibrary/comic_vine/search_single_comic.h @@ -4,10 +4,12 @@ #include #include "scraper_checkbox.h" +#include "themable.h" class ScraperLineEdit; +class QLabel; -class SearchSingleComic : public QWidget +class SearchSingleComic : public QWidget, protected Themable { Q_OBJECT public: @@ -24,5 +26,9 @@ class SearchSingleComic : public QWidget // ScraperLineEdit *numberEdit; ScraperLineEdit *volumeEdit; ScraperCheckBox *exactMatchCheckBox; + QLabel *label; + +protected: + void applyTheme() override; }; #endif // SEARCH_SINGLE_COMIC_H diff --git a/YACReaderLibrary/comic_vine/search_volume.cpp b/YACReaderLibrary/comic_vine/search_volume.cpp index bace44252..29790686e 100644 --- a/YACReaderLibrary/comic_vine/search_volume.cpp +++ b/YACReaderLibrary/comic_vine/search_volume.cpp @@ -2,6 +2,7 @@ #include "scraper_lineedit.h" #include "scraper_checkbox.h" +#include "theme_manager.h" #include #include @@ -9,8 +10,7 @@ SearchVolume::SearchVolume(QWidget *parent) : QWidget(parent) { - QLabel *label = new QLabel(tr("Please provide some additional information.")); - label->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}"); + label = new QLabel(tr("Please provide some additional information.")); volumeEdit = new ScraperLineEdit(tr("Series:")); volumeEdit->setClearButtonEnabled(true); @@ -29,6 +29,8 @@ SearchVolume::SearchVolume(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); setLayout(l); setContentsMargins(0, 0, 0, 0); + + initTheme(this); } void SearchVolume::clean() @@ -45,3 +47,10 @@ QString SearchVolume::getVolumeInfo() const { return volumeEdit->text(); } + +void SearchVolume::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + label->setStyleSheet(comicVineTheme.defaultLabelQSS); +} diff --git a/YACReaderLibrary/comic_vine/search_volume.h b/YACReaderLibrary/comic_vine/search_volume.h index 4ad8db80d..09ca64377 100644 --- a/YACReaderLibrary/comic_vine/search_volume.h +++ b/YACReaderLibrary/comic_vine/search_volume.h @@ -3,11 +3,12 @@ #include #include "scraper_checkbox.h" +#include "themable.h" class ScraperLineEdit; class ScraperCheckBox; -class SearchVolume : public QWidget +class SearchVolume : public QWidget, protected Themable { Q_OBJECT public: @@ -20,6 +21,10 @@ class SearchVolume : public QWidget private: ScraperLineEdit *volumeEdit; ScraperCheckBox *exactMatchCheckBox; + QLabel *label; + +protected: + void applyTheme() override; }; #endif // SEARCH_VOLUME_H diff --git a/YACReaderLibrary/comic_vine/select_comic.cpp b/YACReaderLibrary/comic_vine/select_comic.cpp index 70b64359c..8c5a06a22 100644 --- a/YACReaderLibrary/comic_vine/select_comic.cpp +++ b/YACReaderLibrary/comic_vine/select_comic.cpp @@ -4,6 +4,7 @@ #include "scraper_scroll_label.h" #include "scraper_tableview.h" #include "volume_comics_model.h" +#include "theme_manager.h" #include #include @@ -13,10 +14,7 @@ SelectComic::SelectComic(QWidget *parent) : QWidget(parent), model(0) { - QString labelStylesheet = "QLabel {color:white; font-size:12px;font-family:Arial;}"; - - QLabel *label = new QLabel(tr("Please, select the right comic info.")); - label->setStyleSheet(labelStylesheet); + label = new QLabel(tr("Please, select the right comic info.")); auto l = new QVBoxLayout; QWidget *leftWidget = new QWidget; @@ -28,7 +26,6 @@ SelectComic::SelectComic(QWidget *parent) cover->setScaledContents(true); cover->setAlignment(Qt::AlignTop | Qt::AlignHCenter); cover->setMinimumSize(168, 168 * 5.0 / 3); - cover->setStyleSheet("QLabel {background-color: #2B2B2B; color:white; font-size:12px; font-family:Arial; }"); detailLabel = new ScraperScrollLabel(this); tableComics = new ScraperTableView(this); @@ -63,6 +60,8 @@ SelectComic::SelectComic(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); setLayout(l); setContentsMargins(0, 0, 0, 0); + + initTheme(this); } void SelectComic::load(const QString &json, const QString &volumeId) @@ -164,3 +163,11 @@ QString SelectComic::getSelectedComicId() { return model->getComicId(tableComics->currentIndex()); } + +void SelectComic::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + label->setStyleSheet(comicVineTheme.defaultLabelQSS); + cover->setStyleSheet(comicVineTheme.coverLabelQSS); +} diff --git a/YACReaderLibrary/comic_vine/select_comic.h b/YACReaderLibrary/comic_vine/select_comic.h index 427c3e290..4b1120c6c 100644 --- a/YACReaderLibrary/comic_vine/select_comic.h +++ b/YACReaderLibrary/comic_vine/select_comic.h @@ -4,6 +4,7 @@ #include #include "scraper_results_paginator.h" +#include "themable.h" class QLabel; class VolumeComicsModel; @@ -12,7 +13,7 @@ class QModelIndex; class ScraperScrollLabel; class ScraperTableView; -class SelectComic : public QWidget +class SelectComic : public QWidget, protected Themable { Q_OBJECT public: @@ -34,12 +35,16 @@ private slots: void loadPreviousPage(); private: + QLabel *label; QLabel *cover; ScraperScrollLabel *detailLabel; ScraperTableView *tableComics; VolumeComicsModel *model; QString currentVolumeId; ScraperResultsPaginator *paginator; + +protected: + void applyTheme() override; }; #endif // SELECT_COMIC_H diff --git a/YACReaderLibrary/comic_vine/select_volume.cpp b/YACReaderLibrary/comic_vine/select_volume.cpp index 86bd49ac6..9a190d659 100644 --- a/YACReaderLibrary/comic_vine/select_volume.cpp +++ b/YACReaderLibrary/comic_vine/select_volume.cpp @@ -25,6 +25,7 @@ #include "scraper_results_paginator.h" #include "selected_volume_info.h" +#include "theme_manager.h" SelectVolume::SelectVolume(QWidget *parent) : QWidget(parent), model(0) @@ -32,10 +33,7 @@ SelectVolume::SelectVolume(QWidget *parent) proxyModel = new QSortFilterProxyModel; proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); - QString labelStylesheet = "QLabel {color:white; font-size:12px;font-family:Arial;}"; - - QLabel *label = new QLabel(tr("Please, select the right series for your comic.")); - label->setStyleSheet(labelStylesheet); + label = new QLabel(tr("Please, select the right series for your comic.")); auto l = new QVBoxLayout; QWidget *leftWidget = new QWidget; @@ -48,7 +46,6 @@ SelectVolume::SelectVolume(QWidget *parent) cover->setScaledContents(true); cover->setAlignment(Qt::AlignTop | Qt::AlignHCenter); cover->setMinimumSize(168, 168 * 5.0 / 3); - cover->setStyleSheet("QLabel {background-color: #2B2B2B; color:white; font-size:12px; font-family:Arial; }"); detailLabel = new ScraperScrollLabel(); tableVolumes = new ScraperTableView(); @@ -94,6 +91,8 @@ SelectVolume::SelectVolume(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); setLayout(l); setContentsMargins(0, 0, 0, 0); + + initTheme(this); } void SelectVolume::load(const QString &json, const VolumeSearchQuery &searchQuery) @@ -218,3 +217,11 @@ SelectedVolumeInfo SelectVolume::getSelectedVolumeInfo() return { volumeId, numIssues, publisher, selectedVolumeDescription }; } + +void SelectVolume::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + label->setStyleSheet(comicVineTheme.defaultLabelQSS); + cover->setStyleSheet(comicVineTheme.coverLabelQSS); +} diff --git a/YACReaderLibrary/comic_vine/select_volume.h b/YACReaderLibrary/comic_vine/select_volume.h index 944c833be..f4e06d1bc 100644 --- a/YACReaderLibrary/comic_vine/select_volume.h +++ b/YACReaderLibrary/comic_vine/select_volume.h @@ -6,6 +6,7 @@ #include "scraper_results_paginator.h" #include "selected_volume_info.h" #include "volume_search_query.h" +#include "themable.h" class QLabel; class VolumesModel; @@ -17,7 +18,7 @@ class ScraperScrollLabel; class ScraperTableView; class ScraperLineEdit; -class SelectVolume : public QWidget +class SelectVolume : public QWidget, protected Themable { Q_OBJECT public: @@ -40,6 +41,7 @@ private slots: void loadPreviousPage(); private: + QLabel *label; QLabel *cover; ScraperScrollLabel *detailLabel; ScraperTableView *tableVolumes; @@ -49,6 +51,9 @@ private slots: QString selectedVolumeDescription; VolumeSearchQuery currentSearchQuery; ScraperResultsPaginator *paginator; + +protected: + void applyTheme() override; }; #endif // SELECT_VOLUME_H diff --git a/YACReaderLibrary/comic_vine/series_question.cpp b/YACReaderLibrary/comic_vine/series_question.cpp index d04fba677..80b43bf3c 100644 --- a/YACReaderLibrary/comic_vine/series_question.cpp +++ b/YACReaderLibrary/comic_vine/series_question.cpp @@ -1,5 +1,7 @@ #include "series_question.h" +#include "theme_manager.h" + #include #include #include @@ -9,18 +11,10 @@ SeriesQuestion::SeriesQuestion(QWidget *parent) { auto l = new QVBoxLayout; - QLabel *questionLabel = new QLabel(tr("You are trying to get information for various comics at once, are they part of the same series?")); - questionLabel->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}"); + questionLabel = new QLabel(tr("You are trying to get information for various comics at once, are they part of the same series?")); yes = new QRadioButton(tr("yes")); no = new QRadioButton(tr("no")); - QString rbStyle = "QRadioButton {margin-left:27px; margin-top:5px; color:white;font-size:12px;font-family:Arial;}" - "QRadioButton::indicator {width:11px;height:11px;}" - "QRadioButton::indicator::unchecked {image : url(:/images/comic_vine/radioUnchecked.png);}" - "QRadioButton::indicator::checked {image : url(:/images/comic_vine/radioChecked.png);}"; - yes->setStyleSheet(rbStyle); - no->setStyleSheet(rbStyle); - yes->setChecked(true); l->addSpacing(35); @@ -32,6 +26,8 @@ SeriesQuestion::SeriesQuestion(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); setLayout(l); setContentsMargins(0, 0, 0, 0); + + initTheme(this); } bool SeriesQuestion::getYes() @@ -43,3 +39,12 @@ void SeriesQuestion::setYes(bool y) { yes->setChecked(y); } + +void SeriesQuestion::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + questionLabel->setStyleSheet(comicVineTheme.defaultLabelQSS); + yes->setStyleSheet(comicVineTheme.radioButtonQSS); + no->setStyleSheet(comicVineTheme.radioButtonQSS); +} diff --git a/YACReaderLibrary/comic_vine/series_question.h b/YACReaderLibrary/comic_vine/series_question.h index a02654f84..b354fb5cc 100644 --- a/YACReaderLibrary/comic_vine/series_question.h +++ b/YACReaderLibrary/comic_vine/series_question.h @@ -3,9 +3,12 @@ #include +#include "themable.h" + class QRadioButton; +class QLabel; -class SeriesQuestion : public QWidget +class SeriesQuestion : public QWidget, protected Themable { Q_OBJECT @@ -15,8 +18,12 @@ class SeriesQuestion : public QWidget void setYes(bool yes = true); private: + QLabel *questionLabel; QRadioButton *yes; QRadioButton *no; + +protected: + void applyTheme() override; }; #endif // SERIES_QUESTION_H diff --git a/YACReaderLibrary/comic_vine/sort_volume_comics.cpp b/YACReaderLibrary/comic_vine/sort_volume_comics.cpp index fedd54a93..40f6d0972 100644 --- a/YACReaderLibrary/comic_vine/sort_volume_comics.cpp +++ b/YACReaderLibrary/comic_vine/sort_volume_comics.cpp @@ -9,23 +9,60 @@ #include "scraper_tableview.h" #include "local_comic_list_model.h" #include "volume_comics_model.h" +#include "theme_manager.h" + +ScrapperToolButton::ScrapperToolButton(ScrapperToolButton::Appearance appearance, QWidget *parent) + : QPushButton(parent), appearance(appearance) +{ + setFixedSize(18, 17); + initTheme(this); +} + +QWidget *ScrapperToolButton::getSeparator() +{ + QWidget *w = new QWidget; + w->setFixedWidth(1); + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + w->setStyleSheet(comicVineTheme.scraperToolButtonSeparatorQSS); + return w; +} + +void ScrapperToolButton::paintEvent(QPaintEvent *e) +{ + QPainter p(this); + + switch (appearance) { + case LEFT: + p.fillRect(16, 0, 2, 18, fillColor); + break; + case RIGHT: + p.fillRect(0, 0, 2, 18, fillColor); + break; + default: + break; + } + + QPushButton::paintEvent(e); +} + +void ScrapperToolButton::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + setStyleSheet(comicVineTheme.scraperToolButtonQSS); + fillColor = comicVineTheme.scraperToolButtonFillColor; + update(); +} SortVolumeComics::SortVolumeComics(QWidget *parent) : QWidget(parent) { - QString labelStylesheet = "QLabel {color:white; font-size:12px;font-family:Arial;}"; + label = new QLabel(tr("Please, sort the list of comics on the left until it matches the comics' information.")); - QLabel *label = new QLabel(tr("Please, sort the list of comics on the left until it matches the comics' information.")); - label->setStyleSheet(labelStylesheet); - - QLabel *sortLabel = new QLabel(tr("sort comics to match comic information")); - sortLabel->setStyleSheet(labelStylesheet); + sortLabel = new QLabel(tr("sort comics to match comic information")); moveUpButtonCL = new ScrapperToolButton(ScrapperToolButton::LEFT); - moveUpButtonCL->setIcon(QIcon(":/images/comic_vine/rowUp.png")); moveUpButtonCL->setAutoRepeat(true); moveDownButtonCL = new ScrapperToolButton(ScrapperToolButton::RIGHT); - moveDownButtonCL->setIcon(QIcon(":/images/comic_vine/rowDown.png")); moveDownButtonCL->setAutoRepeat(true); // moveUpButtonIL = new ScrapperToolButton(ScrapperToolButton::LEFT); // moveUpButtonIL->setIcon(QIcon(":/images/comic_vine/rowUp.png")); @@ -98,6 +135,8 @@ SortVolumeComics::SortVolumeComics(QWidget *parent) connect(removeItemFromList, &QAction::triggered, this, &SortVolumeComics::removeSelectedComics); connect(restoreAllItems, &QAction::triggered, this, &SortVolumeComics::restoreAllComics); // connect(restoreItems,SIGNAL(triggered()),this,SLOT(showRemovedComicsSelector())); + + initTheme(this); } void SortVolumeComics::setData(QList &comics, const QString &json, const QString &vID) @@ -225,3 +264,16 @@ QList> SortVolumeComics::getMatchingInfo() return l; } + +void SortVolumeComics::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + label->setStyleSheet(comicVineTheme.defaultLabelQSS); + sortLabel->setStyleSheet(comicVineTheme.defaultLabelQSS); + + moveUpButtonCL->setIconSize(comicVineTheme.rowUpIcon.size); + moveUpButtonCL->setIcon(comicVineTheme.rowUpIcon.icon); + moveDownButtonCL->setIconSize(comicVineTheme.rowDownIcon.size); + moveDownButtonCL->setIcon(comicVineTheme.rowDownIcon.icon); +} diff --git a/YACReaderLibrary/comic_vine/sort_volume_comics.h b/YACReaderLibrary/comic_vine/sort_volume_comics.h index 2a6003415..5e891337d 100644 --- a/YACReaderLibrary/comic_vine/sort_volume_comics.h +++ b/YACReaderLibrary/comic_vine/sort_volume_comics.h @@ -8,12 +8,14 @@ #include "comic_db.h" #include "scraper_results_paginator.h" +#include "themable.h" class ScraperTableView; class LocalComicListModel; class VolumeComicsModel; +class QLabel; -class ScrapperToolButton : public QPushButton +class ScrapperToolButton : public QPushButton, protected Themable { Q_OBJECT public: @@ -23,47 +25,21 @@ class ScrapperToolButton : public QPushButton RIGHT }; - ScrapperToolButton(ScrapperToolButton::Appearance appearance = DEFAULT, QWidget *parent = nullptr) - : QPushButton(parent), appearance(appearance) - { - setStyleSheet("QPushButton {border: none; background: #2e2e2e; color:white; border-radius:2px;}" - "QPushButton::pressed {border: none; background: #282828; color:white; border-radius:2px;}"); - setFixedSize(18, 17); - } - static QWidget *getSeparator() - { - QWidget *w = new QWidget; - w->setFixedWidth(1); - w->setStyleSheet("QWidget {background:#282828;}"); - return w; - } + ScrapperToolButton(ScrapperToolButton::Appearance appearance = DEFAULT, QWidget *parent = nullptr); + static QWidget *getSeparator(); void setAppearance(ScrapperToolButton::Appearance appearance) { this->appearance = appearance; } virtual ~ScrapperToolButton() { } protected: - void paintEvent(QPaintEvent *e) override - { - QPainter p(this); - - switch (appearance) { - case LEFT: - p.fillRect(16, 0, 2, 18, QColor("#2E2E2E")); - break; - case RIGHT: - p.fillRect(0, 0, 2, 18, QColor("#2E2E2E")); - break; - default: - break; - } - - QPushButton::paintEvent(e); - } + void paintEvent(QPaintEvent *e) override; + void applyTheme() override; private: Appearance appearance; + QColor fillColor; }; -class SortVolumeComics : public QWidget +class SortVolumeComics : public QWidget, protected Themable { Q_OBJECT public: @@ -92,6 +68,8 @@ private slots: void loadPreviousPage(); private: + QLabel *label; + QLabel *sortLabel; ScraperTableView *tableFiles; ScraperTableView *tableVolumeComics; @@ -105,6 +83,9 @@ private slots: QString currentVolumeId; ScraperResultsPaginator *paginator; + +protected: + void applyTheme() override; }; #endif // SORT_VOLUME_COMICS_H diff --git a/YACReaderLibrary/comic_vine/title_header.cpp b/YACReaderLibrary/comic_vine/title_header.cpp index 4dd4a2aa0..77931b579 100644 --- a/YACReaderLibrary/comic_vine/title_header.cpp +++ b/YACReaderLibrary/comic_vine/title_header.cpp @@ -1,5 +1,7 @@ #include "title_header.h" +#include "theme_manager.h" + #include #include #include @@ -10,9 +12,6 @@ TitleHeader::TitleHeader(QWidget *parent) mainTitleLabel = new QLabel(); subTitleLabel = new QLabel(); - mainTitleLabel->setStyleSheet("QLabel {color:white; font-size:18px;font-family:Arial;}"); - subTitleLabel->setStyleSheet("QLabel {color:white; font-size:12px;font-family:Arial;}"); - auto titleLayout = new QHBoxLayout; auto titleLabelsLayout = new QVBoxLayout; @@ -28,6 +27,8 @@ TitleHeader::TitleHeader(QWidget *parent) setContentsMargins(0, 0, 0, 0); setTitle(tr("SEARCH")); + + initTheme(this); } void TitleHeader::setTitle(const QString &title) @@ -47,3 +48,11 @@ void TitleHeader::showButtons(bool show) } else { } } + +void TitleHeader::applyTheme() +{ + auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + + mainTitleLabel->setStyleSheet(comicVineTheme.titleLabelQSS); + subTitleLabel->setStyleSheet(comicVineTheme.defaultLabelQSS); +} diff --git a/YACReaderLibrary/comic_vine/title_header.h b/YACReaderLibrary/comic_vine/title_header.h index 4a359ede3..01956e40a 100644 --- a/YACReaderLibrary/comic_vine/title_header.h +++ b/YACReaderLibrary/comic_vine/title_header.h @@ -3,9 +3,11 @@ #include +#include "themable.h" + class QLabel; -class TitleHeader : public QWidget +class TitleHeader : public QWidget, protected Themable { Q_OBJECT public: @@ -18,6 +20,9 @@ public slots: private: QLabel *mainTitleLabel; QLabel *subTitleLabel; + +protected: + void applyTheme() override; }; #endif // TITLE_HEADER_H diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index c770f3e2a..884c48f0b 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -1,7 +1,129 @@ #ifndef THEME_H #define THEME_H +#include + +#include "yacreader_icon.h" + +struct ComicVineThemeTemplates { + QString defaultLabelQSS = "QLabel {color:%1; font-size:12px;font-family:Arial;}"; + QString titleLabelQSS = "QLabel {color:%1; font-size:18px;font-family:Arial;}"; + QString coverLabelQSS = "QLabel {background-color: %1; color:%2; font-size:12px; font-family:Arial; }"; + + QString radioButtonQSS = "QRadioButton {margin-left:27px; margin-top:5px; color:%1;font-size:12px;font-family:Arial;}" + "QRadioButton::indicator {width:11px;height:11px;}" + "QRadioButton::indicator::unchecked {image : url(%2);}" + "QRadioButton::indicator::checked {image : url(%3);}"; + + QString checkBoxQSS = "QCheckBox {" + " color: %1;" + " font-size: 12px;" + " font-family: Arial;" + " spacing: 10px;" + "}" + "QCheckBox::indicator {" + " width: 13px;" + " height: 13px;" + " border: 1px solid %2;" + " background: %3;" + "}" + "QCheckBox::indicator:checked {" + " image: url(%4);" + " background: %3;" + "}" + "QCheckBox::indicator:unchecked {" + " background: %3;" + "}"; + + QString scraperLineEditTitleLabelQSS = "QLabel {color:%1;}"; + QString scraperLineEditQSS = "QLineEdit {" + "border:none; background-color: %1; color : %2; padding-left: %3; padding-bottom: 1px; margin-bottom: 0px;" + "}"; + + QString scraperToolButtonQSS = "QPushButton {border: none; background: %1; color:%2; border-radius:2px;}" + "QPushButton::pressed {border: none; background: %3; color:%2; border-radius:2px;}"; + QString scraperToolButtonSeparatorQSS = "QWidget {background:%1;}"; + + QString scraperScrollLabelTextQSS = "QLabel {background-color: %1; color:%2; font-size:12px; font-family:Arial; } QLabel::link { color: %3; font-size:12px; font-family:Arial; }"; + QString scraperScrollLabelScrollAreaQSS = "QScrollArea {background-color:%1; border:none;}" + "QScrollBar:vertical { border: none; background: %1; width: 3px; margin: 0; }" + "QScrollBar:horizontal { border: none; background: %1; height: 3px; margin: 0; }" + "QScrollBar::handle:vertical { background: %2; width: 7px; min-height: 20px; }" + "QScrollBar::handle:horizontal { background: %2; width: 7px; min-height: 20px; }" + "QScrollBar::add-line:vertical { border: none; background: %3; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::sub-line:vertical { border: none; background: %3; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::add-line:horizontal { border: none; background: %3; width: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 0 3px 0;}" + "QScrollBar::sub-line:horizontal { border: none; background: %3; width: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 0 3px 0;}" + "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" + "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" + "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {background: none; }"; + + QString scraperTableViewQSS = "QTableView {color:%1; border:0px;alternate-background-color: %2;background-color: %3; outline: 0px;}" + "QTableView::item {outline: 0px; border: 0px; color:%1;}" + "QTableView::item:selected {outline: 0px; background-color: %4; }" + "QHeaderView::section:horizontal {background-color:%5; border-bottom:1px solid %6; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %5, stop: 1 %6); border-left:none; border-top:none; padding:4px; color:%7;}" + "QHeaderView::section:vertical {border-bottom: 1px solid %8;border-top: 1px solid %9;}" + "QHeaderView::down-arrow {image: url('%12');width: 8px;height: 7px;padding-right: 10px;}" + "QHeaderView::up-arrow {image: url('%13');width: 8px;height: 7px; padding-right: 10px;}" + "QScrollBar:vertical { border: none; background: %3; width: 3px; margin: 0; }" + "QScrollBar:horizontal { border: none; background: %3; height: 3px; margin: 0; }" + "QScrollBar::handle:vertical { background: %10; width: 7px; min-height: 20px; }" + "QScrollBar::handle:horizontal { background: %10; width: 7px; min-height: 20px; }" + "QScrollBar::add-line:vertical { border: none; background: %11; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::sub-line:vertical { border: none; background: %11; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::add-line:horizontal { border: none; background: %11; width: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 0 3px 0;}" + "QScrollBar::sub-line:horizontal { border: none; background: %11; width: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 0 3px 0;}" + "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" + "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" + "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {background: none; }"; + + QString dialogQSS = "QDialog {background-color: %1; }"; + QString dialogButtonsQSS = "QPushButton {border: 1px solid %1; background: %2; color:%3; padding: 5px 26px 5px 26px; font-size:12px;font-family:Arial; font-weight:bold;}"; + + QString nextPageIcon = ":/images/comic_vine/nextPage.svg"; + QString previousPageIcon = ":/images/comic_vine/previousPage.svg"; + QSize pageIconSize = QSize(7, 8); + + QString rowUpIcon = ":/images/comic_vine/rowUp.svg"; + QString rowDownIcon = ":/images/comic_vine/rowDown.svg"; + QSize rowIconSize = QSize(8, 7); +}; + +struct ComicVineTheme { + QString defaultLabelQSS; + QString titleLabelQSS; + QString coverLabelQSS; + QString radioButtonQSS; + QString checkBoxQSS; + + QString scraperLineEditTitleLabelQSS; + QString scraperLineEditQSS; + + QString scraperToolButtonQSS; + QString scraperToolButtonSeparatorQSS; + QColor scraperToolButtonFillColor; + + QString scraperScrollLabelTextQSS; + QString scraperScrollLabelScrollAreaQSS; + + QString scraperTableViewQSS; + + QString dialogQSS; + QString dialogButtonsQSS; + + QString noBorderToolButtonQSS = "QToolButton { border: none; }"; + + QColor busyIndicatorColor; + + YACReaderIcon nextPageIcon; + YACReaderIcon previousPageIcon; + + YACReaderIcon rowUpIcon; + YACReaderIcon rowDownIcon; +}; + struct Theme { + ComicVineTheme comicVine; }; #endif // THEME_H diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp new file mode 100644 index 000000000..93c5fa0ed --- /dev/null +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -0,0 +1,299 @@ +#include "theme_factory.h" + +#include "icon_utils.h" + +struct ComicVineParams { + + ComicVineThemeTemplates t; + + QColor contentTextColor; + QColor contentBackgroundColor; + QColor contentAltBackgroundColor; + QColor dialogBackgroundColor; + + QColor tableBackgroundColor; + QColor tableAltBackgroundColor; + QColor tableBorderColor; + QColor tableSelectedColor; + QColor tableHeaderBackgroundColor; + QColor tableHeaderBorderColor; + QColor tableHeaderTextColor; + QColor tableScrollHandleColor; + QColor tableScrollBackgroundColor; + QColor tableSectionBorderLight; + QColor tableSectionBorderDark; + + QColor labelTextColor; + QColor labelBackgroundColor; + QColor hyperlinkColor; // TODO: it doesn't work + + QColor buttonBackgroundColor; + QColor buttonTextColor; + QColor buttonBorderColor; + + QString radioUncheckedPath; + QColor radioUncheckedColor; + + QString radioCheckedPath; + QColor radioCheckedBackgroundColor; + QColor radioCheckedIndicatorColor; + + QColor checkBoxTickColor; + + QColor toolButtonAccentColor; + + QColor downArrowColor; + QColor upArrowColor; + + QColor busyIndicatorColor; + QColor navIconColor; + QColor rowIconColor; +}; + +struct ThemeParams { + QString themeName; + + ComicVineParams comicVineParams; +}; + +Theme makeTheme(const ThemeParams ¶ms) +{ + Theme theme; + + const auto &cv = params.comicVineParams; + const auto &t = cv.t; + + auto recolor = [&](const QString &path, const QColor &color) { + return recoloredSvgToThemeFile(path, color, params.themeName); + }; + + theme.comicVine.defaultLabelQSS = t.defaultLabelQSS.arg(cv.labelTextColor.name()); + theme.comicVine.titleLabelQSS = t.titleLabelQSS.arg(cv.labelTextColor.name()); + theme.comicVine.coverLabelQSS = t.coverLabelQSS.arg(cv.labelBackgroundColor.name(), cv.labelTextColor.name()); + theme.comicVine.radioButtonQSS = t.radioButtonQSS.arg(cv.buttonTextColor.name(), recolor(cv.radioUncheckedPath, cv.radioUncheckedColor), recoloredSvgToThemeFile(cv.radioCheckedPath, cv.radioCheckedBackgroundColor, cv.radioCheckedIndicatorColor, params.themeName)); + theme.comicVine.checkBoxQSS = t.checkBoxQSS.arg(cv.buttonTextColor.name(), cv.buttonBorderColor.name(), cv.buttonBackgroundColor.name(), recolor(":/images/comic_vine/checkBoxTick.svg", cv.checkBoxTickColor)); + + theme.comicVine.scraperLineEditTitleLabelQSS = t.scraperLineEditTitleLabelQSS.arg(cv.contentTextColor.name()); + theme.comicVine.scraperLineEditQSS = t.scraperLineEditQSS.arg(cv.contentAltBackgroundColor.name(), cv.contentTextColor.name(), "%1"); + + theme.comicVine.scraperToolButtonQSS = t.scraperToolButtonQSS.arg(cv.buttonBackgroundColor.name(), cv.buttonTextColor.name(), cv.toolButtonAccentColor.name()); + theme.comicVine.scraperToolButtonSeparatorQSS = t.scraperToolButtonSeparatorQSS.arg(cv.toolButtonAccentColor.name()); + theme.comicVine.scraperToolButtonFillColor = cv.buttonBackgroundColor; + + theme.comicVine.scraperScrollLabelTextQSS = t.scraperScrollLabelTextQSS.arg(cv.contentBackgroundColor.name(), cv.contentTextColor.name(), cv.hyperlinkColor.name()); + theme.comicVine.scraperScrollLabelScrollAreaQSS = t.scraperScrollLabelScrollAreaQSS.arg(cv.contentBackgroundColor.name(), cv.tableScrollHandleColor.name(), cv.tableScrollBackgroundColor.name()); + + theme.comicVine.scraperTableViewQSS = t.scraperTableViewQSS + .arg(cv.tableHeaderTextColor.name()) + .arg(cv.tableAltBackgroundColor.name()) + .arg(cv.tableBackgroundColor.name()) + .arg(cv.tableSelectedColor.name()) + .arg(cv.tableHeaderBackgroundColor.name()) + .arg(cv.tableHeaderBorderColor.name()) + .arg(cv.tableHeaderTextColor.name()) + .arg(cv.tableSectionBorderDark.name()) + .arg(cv.tableSectionBorderLight.name()) + .arg(cv.tableScrollHandleColor.name()) + .arg(cv.tableScrollBackgroundColor.name()) + .arg(recolor(":/images/comic_vine/downArrow.svg", cv.downArrowColor)) + .arg(recolor(":/images/comic_vine/upArrow.svg", cv.upArrowColor)); + + theme.comicVine.dialogQSS = t.dialogQSS.arg(cv.dialogBackgroundColor.name()); + theme.comicVine.dialogButtonsQSS = t.dialogButtonsQSS.arg(cv.buttonBorderColor.name(), cv.buttonBackgroundColor.name(), cv.buttonTextColor.name()); + + theme.comicVine.busyIndicatorColor = cv.busyIndicatorColor; + + theme.comicVine.nextPageIcon = { QIcon(recolor(t.nextPageIcon, cv.navIconColor)), t.pageIconSize }; + theme.comicVine.previousPageIcon = { QIcon(recolor(t.previousPageIcon, cv.navIconColor)), t.pageIconSize }; + + theme.comicVine.rowUpIcon = { QIcon(recolor(t.rowUpIcon, cv.rowIconColor)), t.rowIconSize }; + theme.comicVine.rowDownIcon = { QIcon(recolor(t.rowDownIcon, cv.rowIconColor)), t.rowIconSize }; + + return theme; +} + +ThemeParams classicThemeParams(); +ThemeParams lightThemeParams(); +ThemeParams darkThemeParams(); + +Theme makeTheme(ThemeId themeId) +{ + switch (themeId) { + case ThemeId::Classic: + return makeTheme(classicThemeParams()); + case ThemeId::Light: + return makeTheme(lightThemeParams()); + case ThemeId::Dark: + return makeTheme(darkThemeParams()); + } + + return makeTheme(classicThemeParams()); +} + +ThemeParams classicThemeParams() +{ + ThemeParams params; + params.themeName = "classic"; + + ComicVineParams cv; + cv.contentTextColor = Qt::white; + cv.contentBackgroundColor = QColor(0x2B2B2B); + cv.contentAltBackgroundColor = QColor(0x2B2B2B); + cv.dialogBackgroundColor = QColor(0x404040); + + cv.tableBackgroundColor = QColor(0x2B2B2B); + cv.tableAltBackgroundColor = QColor(0x2E2E2E); + cv.tableBorderColor = QColor(0x242424); + cv.tableSelectedColor = QColor(0x555555); + cv.tableHeaderBackgroundColor = QColor(0x292929); + cv.tableHeaderBorderColor = QColor(0x1F1F1F); + cv.tableHeaderTextColor = QColor(0xEBEBEB); + cv.tableScrollHandleColor = QColor(0xDDDDDD); + cv.tableScrollBackgroundColor = QColor(0x404040); + cv.tableSectionBorderLight = QColor(0xFEFEFE); + cv.tableSectionBorderDark = QColor(0xDFDFDF); + + cv.labelTextColor = Qt::white; + cv.labelBackgroundColor = QColor(0x2B2B2B); + cv.hyperlinkColor = QColor(0xFFCC00); + + cv.buttonBackgroundColor = QColor(0x2E2E2E); + cv.buttonTextColor = Qt::white; + cv.buttonBorderColor = QColor(0x242424); + + cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.png"; + cv.radioUncheckedColor = QColor(0xE5E5E5); + + cv.radioCheckedPath = ":/images/comic_vine/radioChecked.svg"; + cv.radioCheckedBackgroundColor = QColor(0xE5E5E5); + cv.radioCheckedIndicatorColor = QColor(0x5F5F5F); + + cv.checkBoxTickColor = Qt::white; + + cv.toolButtonAccentColor = QColor(0x282828); + + cv.downArrowColor = QColor(0x9F9F9F); + cv.upArrowColor = QColor(0x9F9F9F); + + cv.busyIndicatorColor = Qt::white; + cv.navIconColor = Qt::white; + cv.rowIconColor = QColor(0xE5E5E5); + + cv.t = ComicVineThemeTemplates(); + + params.comicVineParams = cv; + + return params; +} + +ThemeParams lightThemeParams() +{ + ThemeParams params; + params.themeName = "light"; + + ComicVineParams cv; + cv.contentTextColor = Qt::black; + cv.contentBackgroundColor = QColor(0xECECEC); + cv.contentAltBackgroundColor = QColor(0xE0E0E0); + cv.dialogBackgroundColor = QColor(0xFBFBFB); + + cv.tableBackgroundColor = QColor(0xF4F4F4); + cv.tableAltBackgroundColor = QColor(0xFAFAFA); + cv.tableBorderColor = QColor(0xCCCCCC); + cv.tableSelectedColor = QColor(0xDDDDDD); + cv.tableHeaderBackgroundColor = QColor(0xE0E0E0); + cv.tableHeaderBorderColor = QColor(0xC0C0C0); + cv.tableHeaderTextColor = QColor(0x333333); + cv.tableScrollHandleColor = QColor(0x888888); + cv.tableScrollBackgroundColor = QColor(0xD0D0D0); + cv.tableSectionBorderLight = QColor(0xFFFFFF); + cv.tableSectionBorderDark = QColor(0xCCCCCC); + + cv.labelTextColor = Qt::black; + cv.labelBackgroundColor = QColor(0xECECEC); + cv.hyperlinkColor = QColor(0xFFCC00); + + cv.buttonBackgroundColor = QColor(0xE0E0E0); + cv.buttonTextColor = Qt::black; + cv.buttonBorderColor = QColor(0xCCCCCC); + + cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.svg"; + cv.radioUncheckedColor = QColor(0xE0E0E0); + + cv.radioCheckedPath = ":/images/comic_vine/radioChecked.svg"; + cv.radioCheckedBackgroundColor = QColor(0xE0E0E0); + cv.radioCheckedIndicatorColor = QColor(0x222222); + + cv.checkBoxTickColor = Qt::black; + + cv.toolButtonAccentColor = QColor(0xA0A0A0); + + cv.downArrowColor = QColor(0x222222); + cv.upArrowColor = QColor(0x222222); + + cv.busyIndicatorColor = Qt::black; + cv.navIconColor = QColor(0x222222); + cv.rowIconColor = QColor(0x222222); + + cv.t = ComicVineThemeTemplates(); + + params.comicVineParams = cv; + + return params; +} + +ThemeParams darkThemeParams() +{ + ThemeParams params; + params.themeName = "dark"; + + ComicVineParams cv; + cv.contentTextColor = Qt::white; + cv.contentBackgroundColor = QColor(0x2B2B2B); + cv.contentAltBackgroundColor = QColor(0x2E2E2E); + cv.dialogBackgroundColor = QColor(0x404040); + + cv.tableBackgroundColor = QColor(0x2B2B2B); + cv.tableAltBackgroundColor = QColor(0x2E2E2E); + cv.tableBorderColor = QColor(0x242424); + cv.tableSelectedColor = QColor(0x555555); + cv.tableHeaderBackgroundColor = QColor(0x292929); + cv.tableHeaderBorderColor = QColor(0x1F1F1F); + cv.tableHeaderTextColor = QColor(0xEBEBEB); + cv.tableScrollHandleColor = QColor(0xDDDDDD); + cv.tableScrollBackgroundColor = QColor(0x404040); + cv.tableSectionBorderLight = QColor(0xFEFEFE); + cv.tableSectionBorderDark = QColor(0xDFDFDF); + + cv.labelTextColor = Qt::white; + cv.labelBackgroundColor = QColor(0x2B2B2B); + cv.hyperlinkColor = QColor(0xFFCC00); + + cv.buttonBackgroundColor = QColor(0x2E2E2E); + cv.buttonTextColor = Qt::white; + cv.buttonBorderColor = QColor(0x242424); + + cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.png"; + cv.radioUncheckedColor = QColor(0xE5E5E5); + + cv.radioCheckedPath = ":/images/comic_vine/radioChecked.svg"; + cv.radioCheckedBackgroundColor = QColor(0xE5E5E5); + cv.radioCheckedIndicatorColor = QColor(0x5F5F5F); + + cv.checkBoxTickColor = Qt::white; + + cv.toolButtonAccentColor = QColor(0x282828); + + cv.downArrowColor = QColor(0x9F9F9F); + cv.upArrowColor = QColor(0x9F9F9F); + + cv.busyIndicatorColor = Qt::white; + cv.navIconColor = Qt::white; + cv.rowIconColor = QColor(0xE5E5E5); + + cv.t = ComicVineThemeTemplates(); + + params.comicVineParams = cv; + + return params; +} diff --git a/YACReaderLibrary/themes/theme_factory.h b/YACReaderLibrary/themes/theme_factory.h new file mode 100644 index 000000000..72cb4ca28 --- /dev/null +++ b/YACReaderLibrary/themes/theme_factory.h @@ -0,0 +1,9 @@ +#ifndef THEME_FACTORY_H +#define THEME_FACTORY_H + +#include "theme.h" +#include "theme_id.h" + +Theme makeTheme(ThemeId themeId); + +#endif // THEME_FACTORY_H diff --git a/YACReaderLibrary/themes/themes.pri b/YACReaderLibrary/themes/themes.pri index 9e42ad159..eee35324e 100644 --- a/YACReaderLibrary/themes/themes.pri +++ b/YACReaderLibrary/themes/themes.pri @@ -2,3 +2,6 @@ INCLUDEPATH += $$PWD HEADERS += \ $$PWD/theme.h \ + $$PWD/theme_factory.h +SOURCES += \ + $$PWD/theme_factory.cpp From b662e4975bb3839e9542663a20669e70bf84eea4 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Tue, 20 Jan 2026 11:23:42 +0100 Subject: [PATCH 041/187] Make comic flow themable --- YACReaderLibrary/themes/theme.h | 6 ++++++ YACReaderLibrary/themes/theme_factory.cpp | 23 ++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index 884c48f0b..0eabd4663 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -89,6 +89,11 @@ struct ComicVineThemeTemplates { QSize rowIconSize = QSize(8, 7); }; +struct ComicFlowColors { + QColor backgroundColor; + QColor textColor; +}; + struct ComicVineTheme { QString defaultLabelQSS; QString titleLabelQSS; @@ -123,6 +128,7 @@ struct ComicVineTheme { }; struct Theme { + ComicFlowColors comicFlow; ComicVineTheme comicVine; }; diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 93c5fa0ed..6d11c65dd 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -3,7 +3,6 @@ #include "icon_utils.h" struct ComicVineParams { - ComicVineThemeTemplates t; QColor contentTextColor; @@ -53,6 +52,7 @@ struct ComicVineParams { struct ThemeParams { QString themeName; + ComicFlowColors comicFlowColors; ComicVineParams comicVineParams; }; @@ -60,6 +60,12 @@ Theme makeTheme(const ThemeParams ¶ms) { Theme theme; + // Comic Flow + const auto &cf = params.comicFlowColors; + theme.comicFlow.backgroundColor = cf.backgroundColor; + theme.comicFlow.textColor = cf.textColor; + + // Comic Vine const auto &cv = params.comicVineParams; const auto &t = cv.t; @@ -135,6 +141,10 @@ ThemeParams classicThemeParams() ThemeParams params; params.themeName = "classic"; + ComicFlowColors cf; + cf.backgroundColor = Qt::black; + cf.textColor = QColor(0x4C4C4C); + ComicVineParams cv; cv.contentTextColor = Qt::white; cv.contentBackgroundColor = QColor(0x2B2B2B); @@ -181,6 +191,7 @@ ThemeParams classicThemeParams() cv.t = ComicVineThemeTemplates(); + params.comicFlowColors = cf; params.comicVineParams = cv; return params; @@ -191,6 +202,10 @@ ThemeParams lightThemeParams() ThemeParams params; params.themeName = "light"; + ComicFlowColors cf; + cf.backgroundColor = Qt::white; + cf.textColor = Qt::black; + ComicVineParams cv; cv.contentTextColor = Qt::black; cv.contentBackgroundColor = QColor(0xECECEC); @@ -237,6 +252,7 @@ ThemeParams lightThemeParams() cv.t = ComicVineThemeTemplates(); + params.comicFlowColors = cf; params.comicVineParams = cv; return params; @@ -247,6 +263,10 @@ ThemeParams darkThemeParams() ThemeParams params; params.themeName = "dark"; + ComicFlowColors cf; + cf.backgroundColor = QColor(0x111111); + cf.textColor = QColor(0x888888); + ComicVineParams cv; cv.contentTextColor = Qt::white; cv.contentBackgroundColor = QColor(0x2B2B2B); @@ -293,6 +313,7 @@ ThemeParams darkThemeParams() cv.t = ComicVineThemeTemplates(); + params.comicFlowColors = cf; params.comicVineParams = cv; return params; From edd5bbc69ca143abe4458501de4ad2002e5c925b Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Tue, 20 Jan 2026 15:57:22 +0100 Subject: [PATCH 042/187] Make Themable pass the current Theme through applyTheme This reduces boilerplate code and remove the ThemeManager dependency at Thamable subclasses level. --- YACReader/main_window_viewer.cpp | 5 ++--- YACReader/main_window_viewer.h | 2 +- YACReader/page_label_widget.cpp | 6 ++---- YACReader/page_label_widget.h | 2 +- YACReader/viewer.cpp | 6 +++--- YACReader/viewer.h | 2 +- YACReaderLibrary/comic_vine/comic_vine_dialog.cpp | 6 ++---- YACReaderLibrary/comic_vine/comic_vine_dialog.h | 2 +- YACReaderLibrary/comic_vine/scraper_checkbox.cpp | 6 ++---- YACReaderLibrary/comic_vine/scraper_checkbox.h | 2 +- YACReaderLibrary/comic_vine/scraper_lineedit.cpp | 6 ++---- YACReaderLibrary/comic_vine/scraper_lineedit.h | 2 +- YACReaderLibrary/comic_vine/scraper_results_paginator.cpp | 5 ++--- YACReaderLibrary/comic_vine/scraper_results_paginator.h | 2 +- YACReaderLibrary/comic_vine/scraper_scroll_label.cpp | 6 ++---- YACReaderLibrary/comic_vine/scraper_scroll_label.h | 2 +- YACReaderLibrary/comic_vine/scraper_tableview.cpp | 6 ++---- YACReaderLibrary/comic_vine/scraper_tableview.h | 2 +- YACReaderLibrary/comic_vine/search_single_comic.cpp | 5 ++--- YACReaderLibrary/comic_vine/search_single_comic.h | 2 +- YACReaderLibrary/comic_vine/search_volume.cpp | 5 ++--- YACReaderLibrary/comic_vine/search_volume.h | 2 +- YACReaderLibrary/comic_vine/select_comic.cpp | 5 ++--- YACReaderLibrary/comic_vine/select_comic.h | 2 +- YACReaderLibrary/comic_vine/select_volume.cpp | 5 ++--- YACReaderLibrary/comic_vine/select_volume.h | 2 +- YACReaderLibrary/comic_vine/series_question.cpp | 6 ++---- YACReaderLibrary/comic_vine/series_question.h | 2 +- YACReaderLibrary/comic_vine/sort_volume_comics.cpp | 8 ++++---- YACReaderLibrary/comic_vine/sort_volume_comics.h | 4 ++-- YACReaderLibrary/comic_vine/title_header.cpp | 6 ++---- YACReaderLibrary/comic_vine/title_header.h | 2 +- common/themes/themable.h | 6 +++--- 33 files changed, 55 insertions(+), 77 deletions(-) diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 1c3e1981d..a35b52465 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -18,7 +18,6 @@ #include "yacreader_global.h" #include "edit_shortcuts_dialog.h" #include "shortcuts_manager.h" -#include "theme_manager.h" #include "whats_new_controller.h" @@ -1556,9 +1555,9 @@ void MainWindowViewer::setLoadedComicActionsEnabled(bool enabled) a->setEnabled(enabled); } -void MainWindowViewer::applyTheme() +void MainWindowViewer::applyTheme(const Theme &theme) { - const auto toolbarTheme = ThemeManager::instance().getCurrentTheme().toolbar; + const auto toolbarTheme = theme.toolbar; if (comicToolBar) { comicToolBar->setStyleSheet(toolbarTheme.toolbarQSS); diff --git a/YACReader/main_window_viewer.h b/YACReader/main_window_viewer.h index ec6033b8a..db24d2f54 100644 --- a/YACReader/main_window_viewer.h +++ b/YACReader/main_window_viewer.h @@ -174,7 +174,7 @@ public slots: void setMglassActionsEnabled(bool enabled); void setLoadedComicActionsEnabled(bool enabled); - void applyTheme() override; + void applyTheme(const Theme &theme) override; //! Manejadores de evento: // void resizeEvent(QResizeEvent * event); diff --git a/YACReader/page_label_widget.cpp b/YACReader/page_label_widget.cpp index afd60e9dc..4a1e7cad2 100644 --- a/YACReader/page_label_widget.cpp +++ b/YACReader/page_label_widget.cpp @@ -2,8 +2,6 @@ #include -#include "theme_manager.h" - PageLabelWidget::PageLabelWidget(QWidget *parent) : QWidget(parent) { @@ -111,9 +109,9 @@ void PageLabelWidget::updatePosition() move(QPoint((parent->geometry().size().width() - this->width()), -this->height())); } -void PageLabelWidget::applyTheme() +void PageLabelWidget::applyTheme(const Theme &theme) { - const auto viewerTheme = ThemeManager::instance().getCurrentTheme().viewer; + const auto viewerTheme = theme.viewer; infoBackgroundColor = viewerTheme.infoBackgroundColor; diff --git a/YACReader/page_label_widget.h b/YACReader/page_label_widget.h index f65cfd9c1..1bec7c4e6 100644 --- a/YACReader/page_label_widget.h +++ b/YACReader/page_label_widget.h @@ -19,7 +19,7 @@ class PageLabelWidget : public QWidget, protected Themable protected: void paintEvent(QPaintEvent *) override; - void applyTheme() override; + void applyTheme(const Theme &theme) override; public: PageLabelWidget(QWidget *parent); diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index c42458278..fa7e15030 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -1019,11 +1019,11 @@ void Viewer::updateBackgroundColor(const QColor &color) setPalette(palette); } -void Viewer::applyTheme() +void Viewer::applyTheme(const Theme &theme) { - const auto viewerTheme = ThemeManager::instance().getCurrentTheme().viewer; + const auto viewerTheme = theme.viewer; - updateBackgroundColor(Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor)); + updateBackgroundColor(Configuration::getConfiguration().getBackgroundColor(theme.viewer.defaultBackgroundColor)); const QString textColor = viewerTheme.defaultTextColor.name(QColor::HexArgb); content->setStyleSheet(QStringLiteral("QLabel { color : %1; background: transparent; }").arg(textColor)); diff --git a/YACReader/viewer.h b/YACReader/viewer.h index e7dbaa5a6..0684e501e 100644 --- a/YACReader/viewer.h +++ b/YACReader/viewer.h @@ -188,7 +188,7 @@ public slots: std::unique_ptr mouseHandler; protected: - void applyTheme() override; + void applyTheme(const Theme &theme) override; public: Viewer(QWidget *parent = nullptr); diff --git a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp index d53b1e4c4..2c172d1d4 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp +++ b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp @@ -27,8 +27,6 @@ #include "db_helper.h" #include "response_parser.h" -#include "theme_manager.h" - #include "QsLog.h" ComicVineDialog::ComicVineDialog(QWidget *parent) @@ -657,9 +655,9 @@ void ComicVineDialog::launchSearchComic() searchVolume({ volumeInfo, 1, exactMatch }); } -void ComicVineDialog::applyTheme() +void ComicVineDialog::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; setStyleSheet(comicVineTheme.dialogQSS); diff --git a/YACReaderLibrary/comic_vine/comic_vine_dialog.h b/YACReaderLibrary/comic_vine/comic_vine_dialog.h index b9626cd81..364680233 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_dialog.h +++ b/YACReaderLibrary/comic_vine/comic_vine_dialog.h @@ -129,7 +129,7 @@ protected slots: QString currentVolumeId; protected: - void applyTheme() override; + void applyTheme(const Theme &theme) override; }; #endif // COMIC_VINE_DIALOG_H diff --git a/YACReaderLibrary/comic_vine/scraper_checkbox.cpp b/YACReaderLibrary/comic_vine/scraper_checkbox.cpp index f7131d777..2aa78b9b2 100644 --- a/YACReaderLibrary/comic_vine/scraper_checkbox.cpp +++ b/YACReaderLibrary/comic_vine/scraper_checkbox.cpp @@ -1,16 +1,14 @@ #include "scraper_checkbox.h" -#include "theme_manager.h" - ScraperCheckBox::ScraperCheckBox(const QString &text, QWidget *parent) : QCheckBox(text, parent) { initTheme(this); } -void ScraperCheckBox::applyTheme() +void ScraperCheckBox::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; setStyleSheet(comicVineTheme.checkBoxQSS); } diff --git a/YACReaderLibrary/comic_vine/scraper_checkbox.h b/YACReaderLibrary/comic_vine/scraper_checkbox.h index ce2200c27..d2362650e 100644 --- a/YACReaderLibrary/comic_vine/scraper_checkbox.h +++ b/YACReaderLibrary/comic_vine/scraper_checkbox.h @@ -11,7 +11,7 @@ class ScraperCheckBox : public QCheckBox, protected Themable ScraperCheckBox(const QString &text, QWidget *parent = nullptr); protected: - void applyTheme() override; + void applyTheme(const Theme &theme) override; }; #endif // SCRAPER_CHECKBOX_H diff --git a/YACReaderLibrary/comic_vine/scraper_lineedit.cpp b/YACReaderLibrary/comic_vine/scraper_lineedit.cpp index a5b2fc34f..fb305c05f 100644 --- a/YACReaderLibrary/comic_vine/scraper_lineedit.cpp +++ b/YACReaderLibrary/comic_vine/scraper_lineedit.cpp @@ -1,7 +1,5 @@ #include "scraper_lineedit.h" -#include "theme_manager.h" - #include ScraperLineEdit::ScraperLineEdit(const QString &title, QWidget *widget) @@ -20,9 +18,9 @@ void ScraperLineEdit::resizeEvent(QResizeEvent *) titleLabel->move(6, (rect().bottom() + 1 - szl.height()) / 2); } -void ScraperLineEdit::applyTheme() +void ScraperLineEdit::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; titleLabel->setStyleSheet(comicVineTheme.scraperLineEditTitleLabelQSS); setStyleSheet(comicVineTheme.scraperLineEditQSS.arg(titleLabel->sizeHint().width() + 6)); diff --git a/YACReaderLibrary/comic_vine/scraper_lineedit.h b/YACReaderLibrary/comic_vine/scraper_lineedit.h index e7d41d436..977e4d0f0 100644 --- a/YACReaderLibrary/comic_vine/scraper_lineedit.h +++ b/YACReaderLibrary/comic_vine/scraper_lineedit.h @@ -15,7 +15,7 @@ class ScraperLineEdit : public QLineEdit, protected Themable protected: void resizeEvent(QResizeEvent *) override; - void applyTheme() override; + void applyTheme(const Theme &theme) override; private: QLabel *titleLabel; diff --git a/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp b/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp index e2f562051..637b7fb90 100644 --- a/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp +++ b/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp @@ -1,6 +1,5 @@ #include "scraper_results_paginator.h" #include "response_parser.h" -#include "theme_manager.h" #include #include @@ -62,9 +61,9 @@ void ScraperResultsPaginator::setCustomLabel(const QString &label) customLabel = label; } -void ScraperResultsPaginator::applyTheme() +void ScraperResultsPaginator::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; numElements->setStyleSheet(comicVineTheme.defaultLabelQSS); numPages->setStyleSheet(comicVineTheme.defaultLabelQSS); diff --git a/YACReaderLibrary/comic_vine/scraper_results_paginator.h b/YACReaderLibrary/comic_vine/scraper_results_paginator.h index d099e1af0..873ece507 100644 --- a/YACReaderLibrary/comic_vine/scraper_results_paginator.h +++ b/YACReaderLibrary/comic_vine/scraper_results_paginator.h @@ -31,7 +31,7 @@ class ScraperResultsPaginator : public QWidget, protected Themable QString customLabel; protected: - void applyTheme() override; + void applyTheme(const Theme &theme) override; }; #endif // SCRAPER_RESULTS_PAGINATOR_H diff --git a/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp b/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp index 1fd4cdd3b..314a7ac3c 100644 --- a/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp +++ b/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp @@ -1,7 +1,5 @@ #include "scraper_scroll_label.h" -#include "theme_manager.h" - #include #include #include @@ -41,9 +39,9 @@ void ScraperScrollLabel::openLink(const QString &link) QDesktopServices::openUrl(QUrl("http://www.comicvine.com" + link)); } -void ScraperScrollLabel::applyTheme() +void ScraperScrollLabel::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; textLabel->setStyleSheet(comicVineTheme.scraperScrollLabelTextQSS); setStyleSheet(comicVineTheme.scraperScrollLabelScrollAreaQSS); diff --git a/YACReaderLibrary/comic_vine/scraper_scroll_label.h b/YACReaderLibrary/comic_vine/scraper_scroll_label.h index 7c555d5c0..f78da91ac 100644 --- a/YACReaderLibrary/comic_vine/scraper_scroll_label.h +++ b/YACReaderLibrary/comic_vine/scraper_scroll_label.h @@ -23,7 +23,7 @@ public slots: QLabel *textLabel; protected: - void applyTheme() override; + void applyTheme(const Theme &theme) override; }; #endif // SCRAPER_SCROLL_LABEL_H diff --git a/YACReaderLibrary/comic_vine/scraper_tableview.cpp b/YACReaderLibrary/comic_vine/scraper_tableview.cpp index a9c509786..0fa134a87 100644 --- a/YACReaderLibrary/comic_vine/scraper_tableview.cpp +++ b/YACReaderLibrary/comic_vine/scraper_tableview.cpp @@ -1,7 +1,5 @@ #include "scraper_tableview.h" -#include "theme_manager.h" - #include ScraperTableView::ScraperTableView(QWidget *parent) @@ -44,9 +42,9 @@ ScraperTableView::ScraperTableView(QWidget *parent) initTheme(this); } -void ScraperTableView::applyTheme() +void ScraperTableView::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; setStyleSheet(comicVineTheme.scraperTableViewQSS); } diff --git a/YACReaderLibrary/comic_vine/scraper_tableview.h b/YACReaderLibrary/comic_vine/scraper_tableview.h index 8061b8b87..98159dce8 100644 --- a/YACReaderLibrary/comic_vine/scraper_tableview.h +++ b/YACReaderLibrary/comic_vine/scraper_tableview.h @@ -12,7 +12,7 @@ class ScraperTableView : public QTableView, protected Themable explicit ScraperTableView(QWidget *parent = nullptr); protected: - void applyTheme() override; + void applyTheme(const Theme &theme) override; }; #endif // SCRAPPER_TABLEVIEW_H diff --git a/YACReaderLibrary/comic_vine/search_single_comic.cpp b/YACReaderLibrary/comic_vine/search_single_comic.cpp index f9e446886..edf187828 100644 --- a/YACReaderLibrary/comic_vine/search_single_comic.cpp +++ b/YACReaderLibrary/comic_vine/search_single_comic.cpp @@ -1,7 +1,6 @@ #include "search_single_comic.h" #include "scraper_lineedit.h" -#include "theme_manager.h" #include #include @@ -73,9 +72,9 @@ void SearchSingleComic::clean() volumeEdit->clear(); } -void SearchSingleComic::applyTheme() +void SearchSingleComic::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; label->setStyleSheet(comicVineTheme.defaultLabelQSS); } diff --git a/YACReaderLibrary/comic_vine/search_single_comic.h b/YACReaderLibrary/comic_vine/search_single_comic.h index 12195f772..e3a1bd165 100644 --- a/YACReaderLibrary/comic_vine/search_single_comic.h +++ b/YACReaderLibrary/comic_vine/search_single_comic.h @@ -29,6 +29,6 @@ class SearchSingleComic : public QWidget, protected Themable QLabel *label; protected: - void applyTheme() override; + void applyTheme(const Theme &theme) override; }; #endif // SEARCH_SINGLE_COMIC_H diff --git a/YACReaderLibrary/comic_vine/search_volume.cpp b/YACReaderLibrary/comic_vine/search_volume.cpp index 29790686e..e520f02c1 100644 --- a/YACReaderLibrary/comic_vine/search_volume.cpp +++ b/YACReaderLibrary/comic_vine/search_volume.cpp @@ -2,7 +2,6 @@ #include "scraper_lineedit.h" #include "scraper_checkbox.h" -#include "theme_manager.h" #include #include @@ -48,9 +47,9 @@ QString SearchVolume::getVolumeInfo() const return volumeEdit->text(); } -void SearchVolume::applyTheme() +void SearchVolume::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; label->setStyleSheet(comicVineTheme.defaultLabelQSS); } diff --git a/YACReaderLibrary/comic_vine/search_volume.h b/YACReaderLibrary/comic_vine/search_volume.h index 09ca64377..9d874273e 100644 --- a/YACReaderLibrary/comic_vine/search_volume.h +++ b/YACReaderLibrary/comic_vine/search_volume.h @@ -24,7 +24,7 @@ class SearchVolume : public QWidget, protected Themable QLabel *label; protected: - void applyTheme() override; + void applyTheme(const Theme &theme) override; }; #endif // SEARCH_VOLUME_H diff --git a/YACReaderLibrary/comic_vine/select_comic.cpp b/YACReaderLibrary/comic_vine/select_comic.cpp index 8c5a06a22..aa5eb668d 100644 --- a/YACReaderLibrary/comic_vine/select_comic.cpp +++ b/YACReaderLibrary/comic_vine/select_comic.cpp @@ -4,7 +4,6 @@ #include "scraper_scroll_label.h" #include "scraper_tableview.h" #include "volume_comics_model.h" -#include "theme_manager.h" #include #include @@ -164,9 +163,9 @@ QString SelectComic::getSelectedComicId() return model->getComicId(tableComics->currentIndex()); } -void SelectComic::applyTheme() +void SelectComic::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; label->setStyleSheet(comicVineTheme.defaultLabelQSS); cover->setStyleSheet(comicVineTheme.coverLabelQSS); diff --git a/YACReaderLibrary/comic_vine/select_comic.h b/YACReaderLibrary/comic_vine/select_comic.h index 4b1120c6c..e6c7f3c8a 100644 --- a/YACReaderLibrary/comic_vine/select_comic.h +++ b/YACReaderLibrary/comic_vine/select_comic.h @@ -44,7 +44,7 @@ private slots: ScraperResultsPaginator *paginator; protected: - void applyTheme() override; + void applyTheme(const Theme &theme) override; }; #endif // SELECT_COMIC_H diff --git a/YACReaderLibrary/comic_vine/select_volume.cpp b/YACReaderLibrary/comic_vine/select_volume.cpp index 9a190d659..2ed1656df 100644 --- a/YACReaderLibrary/comic_vine/select_volume.cpp +++ b/YACReaderLibrary/comic_vine/select_volume.cpp @@ -25,7 +25,6 @@ #include "scraper_results_paginator.h" #include "selected_volume_info.h" -#include "theme_manager.h" SelectVolume::SelectVolume(QWidget *parent) : QWidget(parent), model(0) @@ -218,9 +217,9 @@ SelectedVolumeInfo SelectVolume::getSelectedVolumeInfo() return { volumeId, numIssues, publisher, selectedVolumeDescription }; } -void SelectVolume::applyTheme() +void SelectVolume::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; label->setStyleSheet(comicVineTheme.defaultLabelQSS); cover->setStyleSheet(comicVineTheme.coverLabelQSS); diff --git a/YACReaderLibrary/comic_vine/select_volume.h b/YACReaderLibrary/comic_vine/select_volume.h index f4e06d1bc..be50d2bbd 100644 --- a/YACReaderLibrary/comic_vine/select_volume.h +++ b/YACReaderLibrary/comic_vine/select_volume.h @@ -53,7 +53,7 @@ private slots: ScraperResultsPaginator *paginator; protected: - void applyTheme() override; + void applyTheme(const Theme &theme) override; }; #endif // SELECT_VOLUME_H diff --git a/YACReaderLibrary/comic_vine/series_question.cpp b/YACReaderLibrary/comic_vine/series_question.cpp index 80b43bf3c..caab57fe1 100644 --- a/YACReaderLibrary/comic_vine/series_question.cpp +++ b/YACReaderLibrary/comic_vine/series_question.cpp @@ -1,7 +1,5 @@ #include "series_question.h" -#include "theme_manager.h" - #include #include #include @@ -40,9 +38,9 @@ void SeriesQuestion::setYes(bool y) yes->setChecked(y); } -void SeriesQuestion::applyTheme() +void SeriesQuestion::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; questionLabel->setStyleSheet(comicVineTheme.defaultLabelQSS); yes->setStyleSheet(comicVineTheme.radioButtonQSS); diff --git a/YACReaderLibrary/comic_vine/series_question.h b/YACReaderLibrary/comic_vine/series_question.h index b354fb5cc..26b850c09 100644 --- a/YACReaderLibrary/comic_vine/series_question.h +++ b/YACReaderLibrary/comic_vine/series_question.h @@ -23,7 +23,7 @@ class SeriesQuestion : public QWidget, protected Themable QRadioButton *no; protected: - void applyTheme() override; + void applyTheme(const Theme &theme) override; }; #endif // SERIES_QUESTION_H diff --git a/YACReaderLibrary/comic_vine/sort_volume_comics.cpp b/YACReaderLibrary/comic_vine/sort_volume_comics.cpp index 40f6d0972..d44774d4f 100644 --- a/YACReaderLibrary/comic_vine/sort_volume_comics.cpp +++ b/YACReaderLibrary/comic_vine/sort_volume_comics.cpp @@ -45,9 +45,9 @@ void ScrapperToolButton::paintEvent(QPaintEvent *e) QPushButton::paintEvent(e); } -void ScrapperToolButton::applyTheme() +void ScrapperToolButton::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; setStyleSheet(comicVineTheme.scraperToolButtonQSS); fillColor = comicVineTheme.scraperToolButtonFillColor; update(); @@ -265,9 +265,9 @@ QList> SortVolumeComics::getMatchingInfo() return l; } -void SortVolumeComics::applyTheme() +void SortVolumeComics::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; label->setStyleSheet(comicVineTheme.defaultLabelQSS); sortLabel->setStyleSheet(comicVineTheme.defaultLabelQSS); diff --git a/YACReaderLibrary/comic_vine/sort_volume_comics.h b/YACReaderLibrary/comic_vine/sort_volume_comics.h index 5e891337d..c3a1a160f 100644 --- a/YACReaderLibrary/comic_vine/sort_volume_comics.h +++ b/YACReaderLibrary/comic_vine/sort_volume_comics.h @@ -32,7 +32,7 @@ class ScrapperToolButton : public QPushButton, protected Themable protected: void paintEvent(QPaintEvent *e) override; - void applyTheme() override; + void applyTheme(const Theme &theme) override; private: Appearance appearance; @@ -85,7 +85,7 @@ private slots: ScraperResultsPaginator *paginator; protected: - void applyTheme() override; + void applyTheme(const Theme &theme) override; }; #endif // SORT_VOLUME_COMICS_H diff --git a/YACReaderLibrary/comic_vine/title_header.cpp b/YACReaderLibrary/comic_vine/title_header.cpp index 77931b579..06585908f 100644 --- a/YACReaderLibrary/comic_vine/title_header.cpp +++ b/YACReaderLibrary/comic_vine/title_header.cpp @@ -1,7 +1,5 @@ #include "title_header.h" -#include "theme_manager.h" - #include #include #include @@ -49,9 +47,9 @@ void TitleHeader::showButtons(bool show) } } -void TitleHeader::applyTheme() +void TitleHeader::applyTheme(const Theme &theme) { - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; + auto comicVineTheme = theme.comicVine; mainTitleLabel->setStyleSheet(comicVineTheme.titleLabelQSS); subTitleLabel->setStyleSheet(comicVineTheme.defaultLabelQSS); diff --git a/YACReaderLibrary/comic_vine/title_header.h b/YACReaderLibrary/comic_vine/title_header.h index 01956e40a..7ce33d6c8 100644 --- a/YACReaderLibrary/comic_vine/title_header.h +++ b/YACReaderLibrary/comic_vine/title_header.h @@ -22,7 +22,7 @@ public slots: QLabel *subTitleLabel; protected: - void applyTheme() override; + void applyTheme(const Theme &theme) override; }; #endif // TITLE_HEADER_H diff --git a/common/themes/themable.h b/common/themes/themable.h index fd5f39120..1915bee81 100644 --- a/common/themes/themable.h +++ b/common/themes/themable.h @@ -12,13 +12,13 @@ class Themable &ThemeManager::themeChanged, owner, [this]() { - applyTheme(); + applyTheme(ThemeManager::instance().getCurrentTheme()); }); - applyTheme(); + applyTheme(ThemeManager::instance().getCurrentTheme()); } - virtual void applyTheme() = 0; + virtual void applyTheme(const Theme &theme) = 0; }; #endif // THEMABLE_H From bd4c5eace081393cc92ad610612d7536eb20f537 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Tue, 20 Jan 2026 20:41:04 +0100 Subject: [PATCH 043/187] Make Themable keep the current theme for convenience --- YACReader/viewer.cpp | 4 ++-- common/themes/themable.h | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index fa7e15030..15d12ace5 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -1007,7 +1007,7 @@ void Viewer::showCursor() void Viewer::updateOptions() { goToFlow->setFlowType(Configuration::getConfiguration().getFlowType()); - updateBackgroundColor(Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor)); + updateBackgroundColor(Configuration::getConfiguration().getBackgroundColor(theme.viewer.defaultBackgroundColor)); updateContentSize(); updateInformation(); } @@ -1092,7 +1092,7 @@ void Viewer::updateConfig(QSettings *settings) goToFlow->updateConfig(settings); QPalette palette; - palette.setColor(backgroundRole(), Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor)); + palette.setColor(backgroundRole(), Configuration::getConfiguration().getBackgroundColor(theme.viewer.defaultBackgroundColor)); setPalette(palette); } diff --git a/common/themes/themable.h b/common/themes/themable.h index 1915bee81..455162705 100644 --- a/common/themes/themable.h +++ b/common/themes/themable.h @@ -12,13 +12,16 @@ class Themable &ThemeManager::themeChanged, owner, [this]() { - applyTheme(ThemeManager::instance().getCurrentTheme()); + theme = ThemeManager::instance().getCurrentTheme(); + applyTheme(theme); }); applyTheme(ThemeManager::instance().getCurrentTheme()); } virtual void applyTheme(const Theme &theme) = 0; + + Theme theme; }; #endif // THEMABLE_H From be7b41ab9d81eb079b0937f048507955c5ee24a0 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 23 Jan 2026 21:19:22 +0100 Subject: [PATCH 044/187] Remove unused include --- YACReader/goto_flow_widget.h | 1 - 1 file changed, 1 deletion(-) diff --git a/YACReader/goto_flow_widget.h b/YACReader/goto_flow_widget.h index f8f93fc7a..df294dfb0 100644 --- a/YACReader/goto_flow_widget.h +++ b/YACReader/goto_flow_widget.h @@ -3,7 +3,6 @@ #include #include -#include "yacreader_global.h" #include "yacreader_global_gui.h" #include "yacreader_page_flow_rhi.h" From 599ad678779e8a4e5893bd1957706e94e371314a Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 23 Jan 2026 21:19:45 +0100 Subject: [PATCH 045/187] Fix go to toolbar go to button --- YACReader/goto_flow_toolbar.cpp | 22 ++++++++++++++-------- YACReader/goto_flow_toolbar.h | 1 + 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/YACReader/goto_flow_toolbar.cpp b/YACReader/goto_flow_toolbar.cpp index bf2b1e9f8..c0c35de2a 100644 --- a/YACReader/goto_flow_toolbar.cpp +++ b/YACReader/goto_flow_toolbar.cpp @@ -36,9 +36,9 @@ GoToFlowToolBar::GoToFlowToolBar(QWidget *parent) connect(slider, &QSlider::valueChanged, this, &GoToFlowToolBar::setPage); pageHint = new QLabel("" + tr("Page : ") + "", this); - v = new QIntValidator(this); + v = new QIntValidator(); v->setBottom(1); - edit = new QLineEdit(this); + edit = new QLineEdit(); edit->setValidator(v); edit->setAlignment(Qt::AlignRight | Qt::AlignVCenter); edit->setStyleSheet("QLineEdit {border: 1px solid #77000000; background: #55000000; color: white; padding: 3px 5px 5px 5px; margin: 13px 5px 12px 5px; font-weight:bold}"); @@ -53,8 +53,7 @@ GoToFlowToolBar::GoToFlowToolBar(QWidget *parent) QString centerButtonCSS = "QPushButton {background-image: url(:/images/imgCenterSlide.png); width: 100%; height:100%; background-repeat: none; border: none;} " "QPushButton:focus { border: none; outline: none;}" "QPushButton:pressed {background-image: url(:/images/imgCenterSlidePressed.png); width: 100%; height:100%; background-repeat: none; border: none;} "; - centerButton = new QPushButton(this); - // centerButton->setIcon(QIcon(":/images/center.png")); + centerButton = new QPushButton(); centerButton->setStyleSheet(centerButtonCSS); centerButton->setFixedSize(26, 50); centerButton->setAttribute(Qt::WA_LayoutUsesWidgetRect, true); @@ -63,14 +62,18 @@ GoToFlowToolBar::GoToFlowToolBar(QWidget *parent) QString goToButtonCSS = "QPushButton {background-image: url(:/images/imgGoToSlide.png); width: 100%; height:100%; background-repeat: none; border: none;} " "QPushButton:focus { border: none; outline: none;}" "QPushButton:pressed {background-image: url(:/images/imgGoToSlidePressed.png); width: 100%; height:100%; background-repeat: none; border: none;} "; - goToButton = new QPushButton(this); - // goToButton->setIcon(QIcon(":/images/goto.png")); + goToButton = new QPushButton(); goToButton->setStyleSheet(goToButtonCSS); goToButton->setFixedSize(32, 50); goToButton->setAttribute(Qt::WA_LayoutUsesWidgetRect, true); - connect(goToButton, &QPushButton::clicked, this, &GoToFlowToolBar::goTo); + goToButton2 = new QPushButton(); + goToButton2->setStyleSheet(goToButtonCSS); + goToButton2->setFixedSize(32, 50); + goToButton2->setAttribute(Qt::WA_LayoutUsesWidgetRect, true); + connect(goToButton2, &QPushButton::clicked, this, &GoToFlowToolBar::goTo); + normalLayout->setContentsMargins(0, 0, 0, 0); normalLayout->setSpacing(0); normalLayout->addStretch(); @@ -83,7 +86,10 @@ GoToFlowToolBar::GoToFlowToolBar(QWidget *parent) naviLayout->setContentsMargins(5, 0, 0, 0); naviLayout->setSpacing(2); naviLayout->addWidget(slider); - naviLayout->addWidget(goToButton); + naviLayout->addWidget(goToButton2); + + this->addWidget(normal); + this->addWidget(quickNavi); updateOptions(); diff --git a/YACReader/goto_flow_toolbar.h b/YACReader/goto_flow_toolbar.h index 9368d1cb1..ba5b0d261 100644 --- a/YACReader/goto_flow_toolbar.h +++ b/YACReader/goto_flow_toolbar.h @@ -19,6 +19,7 @@ class GoToFlowToolBar : public QStackedWidget QIntValidator *v; QPushButton *centerButton; QPushButton *goToButton; + QPushButton *goToButton2; QLabel *pageHint; QWidget *bar; void paintEvent(QPaintEvent *) override; From 561c2ae568d65247871c284b4ea8246051af32f2 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 23 Jan 2026 21:44:55 +0100 Subject: [PATCH 046/187] Fix theme initialization in Themable --- common/themes/themable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/themes/themable.h b/common/themes/themable.h index 455162705..43694f779 100644 --- a/common/themes/themable.h +++ b/common/themes/themable.h @@ -16,7 +16,8 @@ class Themable applyTheme(theme); }); - applyTheme(ThemeManager::instance().getCurrentTheme()); + theme = ThemeManager::instance().getCurrentTheme(); + applyTheme(theme); } virtual void applyTheme(const Theme &theme) = 0; From 3bdbf4424b1618730bdc0e47b8aad82486a08eeb Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 23 Jan 2026 21:45:13 +0100 Subject: [PATCH 047/187] Use local var --- YACReader/viewer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index 15d12ace5..80ea83388 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -1023,7 +1023,7 @@ void Viewer::applyTheme(const Theme &theme) { const auto viewerTheme = theme.viewer; - updateBackgroundColor(Configuration::getConfiguration().getBackgroundColor(theme.viewer.defaultBackgroundColor)); + updateBackgroundColor(Configuration::getConfiguration().getBackgroundColor(viewerTheme.defaultBackgroundColor)); const QString textColor = viewerTheme.defaultTextColor.name(QColor::HexArgb); content->setStyleSheet(QStringLiteral("QLabel { color : %1; background: transparent; }").arg(textColor)); From 7b6055e76d809d2b72dd1a793244d858f4a62e0e Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 24 Jan 2026 18:43:25 +0100 Subject: [PATCH 048/187] Make go to flow widget themable --- YACReader/goto_flow_toolbar.cpp | 53 +++++++++-------- YACReader/goto_flow_toolbar.h | 7 ++- YACReader/goto_flow_widget.cpp | 10 ++++ YACReader/goto_flow_widget.h | 6 +- YACReader/themes/theme.h | 33 +++++++++++ YACReader/themes/theme_factory.cpp | 87 ++++++++++++++++++++++++++++ YACReader/yacreader_images.qrc | 6 +- images/centerFlow.svg | 11 ++++ images/gotoFlow.svg | 11 ++++ images/imgCenterSlide.png | Bin 298 -> 0 bytes images/imgCenterSlide@2x.png | Bin 465 -> 0 bytes images/imgCenterSlidePressed.png | Bin 339 -> 0 bytes images/imgCenterSlidePressed@2x.png | Bin 563 -> 0 bytes images/imgGoToSlide.png | Bin 204 -> 0 bytes images/imgGoToSlide@2x.png | Bin 291 -> 0 bytes images/imgGoToSlidePressed.png | Bin 241 -> 0 bytes images/imgGoToSlidePressed@2x.png | Bin 374 -> 0 bytes 17 files changed, 191 insertions(+), 33 deletions(-) create mode 100644 images/centerFlow.svg create mode 100644 images/gotoFlow.svg delete mode 100644 images/imgCenterSlide.png delete mode 100644 images/imgCenterSlide@2x.png delete mode 100644 images/imgCenterSlidePressed.png delete mode 100644 images/imgCenterSlidePressed@2x.png delete mode 100644 images/imgGoToSlide.png delete mode 100644 images/imgGoToSlide@2x.png delete mode 100644 images/imgGoToSlidePressed.png delete mode 100644 images/imgGoToSlidePressed@2x.png diff --git a/YACReader/goto_flow_toolbar.cpp b/YACReader/goto_flow_toolbar.cpp index c0c35de2a..2f45af1de 100644 --- a/YACReader/goto_flow_toolbar.cpp +++ b/YACReader/goto_flow_toolbar.cpp @@ -18,19 +18,6 @@ GoToFlowToolBar::GoToFlowToolBar(QWidget *parent) quickNavi->setLayout(naviLayout); slider = new QSlider(Qt::Horizontal, this); - slider->setStyleSheet( - "QSlider::groove:horizontal {" - " border: 1px solid #22FFFFFF;" - " border-radius: 1px;" - " background: #77000000;" - " margin: 2px 0;" - " padding: 1px;" - "}" - "QSlider::handle:horizontal {" - " background: #55FFFFFF;" - " width: 48px;" - " border-radius: 1px;" - "}"); connect(slider, &QSlider::valueChanged, this, &GoToFlowToolBar::setCenter); connect(slider, &QSlider::valueChanged, this, &GoToFlowToolBar::setPage); @@ -41,35 +28,25 @@ GoToFlowToolBar::GoToFlowToolBar(QWidget *parent) edit = new QLineEdit(); edit->setValidator(v); edit->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - edit->setStyleSheet("QLineEdit {border: 1px solid #77000000; background: #55000000; color: white; padding: 3px 5px 5px 5px; margin: 13px 5px 12px 5px; font-weight:bold}"); edit->setFixedSize(54, 50); edit->setAttribute(Qt::WA_MacShowFocusRect, false); - // edit->setAttribute(Qt::WA_LayoutUsesWidgetRect,true); - // edit->resize(QSize(54,50)); edit->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); - // edit->setAutoFillBackground(false); connect(edit, &QLineEdit::returnPressed, this, &GoToFlowToolBar::goTo); - QString centerButtonCSS = "QPushButton {background-image: url(:/images/imgCenterSlide.png); width: 100%; height:100%; background-repeat: none; border: none;} " - "QPushButton:focus { border: none; outline: none;}" - "QPushButton:pressed {background-image: url(:/images/imgCenterSlidePressed.png); width: 100%; height:100%; background-repeat: none; border: none;} "; centerButton = new QPushButton(); - centerButton->setStyleSheet(centerButtonCSS); + centerButton->setIconSize(QSize(12, 12)); centerButton->setFixedSize(26, 50); centerButton->setAttribute(Qt::WA_LayoutUsesWidgetRect, true); connect(centerButton, &QAbstractButton::clicked, this, &GoToFlowToolBar::centerSlide); - QString goToButtonCSS = "QPushButton {background-image: url(:/images/imgGoToSlide.png); width: 100%; height:100%; background-repeat: none; border: none;} " - "QPushButton:focus { border: none; outline: none;}" - "QPushButton:pressed {background-image: url(:/images/imgGoToSlidePressed.png); width: 100%; height:100%; background-repeat: none; border: none;} "; goToButton = new QPushButton(); - goToButton->setStyleSheet(goToButtonCSS); + goToButton->setIconSize(QSize(12, 12)); goToButton->setFixedSize(32, 50); goToButton->setAttribute(Qt::WA_LayoutUsesWidgetRect, true); connect(goToButton, &QPushButton::clicked, this, &GoToFlowToolBar::goTo); goToButton2 = new QPushButton(); - goToButton2->setStyleSheet(goToButtonCSS); + goToButton2->setIconSize(QSize(12, 12)); goToButton2->setFixedSize(32, 50); goToButton2->setAttribute(Qt::WA_LayoutUsesWidgetRect, true); connect(goToButton2, &QPushButton::clicked, this, &GoToFlowToolBar::goTo); @@ -94,12 +71,34 @@ GoToFlowToolBar::GoToFlowToolBar(QWidget *parent) updateOptions(); setFixedHeight(50); + + initTheme(this); +} + +void GoToFlowToolBar::applyTheme(const Theme &theme) +{ + auto goToFlowTheme = theme.goToFlowWidget; + + slider->setStyleSheet(goToFlowTheme.sliderQSS); + edit->setStyleSheet(goToFlowTheme.editQSS); + pageHint->setStyleSheet(goToFlowTheme.labelQSS); + + centerButton->setStyleSheet(goToFlowTheme.buttonQSS); + centerButton->setIcon(goToFlowTheme.centerIcon); + + goToButton->setStyleSheet(goToFlowTheme.buttonQSS); + goToButton->setIcon(goToFlowTheme.goToIcon); + + goToButton2->setStyleSheet(goToFlowTheme.buttonQSS); + goToButton2->setIcon(goToFlowTheme.goToIcon); + + update(); } void GoToFlowToolBar::paintEvent(QPaintEvent *) { QPainter painter(this); - painter.fillRect(0, 0, width(), height(), QColor(0x99000000)); + painter.fillRect(0, 0, width(), height(), theme.goToFlowWidget.toolbarBackgroundColor); } void GoToFlowToolBar::setPage(int pageNumber) diff --git a/YACReader/goto_flow_toolbar.h b/YACReader/goto_flow_toolbar.h index ba5b0d261..615a3511d 100644 --- a/YACReader/goto_flow_toolbar.h +++ b/YACReader/goto_flow_toolbar.h @@ -4,15 +4,20 @@ #include #include +#include "themable.h" + class QLineEdit; class QIntValidator; class QPushButton; class QSlider; class QLabel; -class GoToFlowToolBar : public QStackedWidget +class GoToFlowToolBar : public QStackedWidget, protected Themable { Q_OBJECT +protected: + void applyTheme(const Theme &theme) override; + private: QLineEdit *edit; QSlider *slider; diff --git a/YACReader/goto_flow_widget.cpp b/YACReader/goto_flow_widget.cpp index 1fc339d35..782b9b87e 100644 --- a/YACReader/goto_flow_widget.cpp +++ b/YACReader/goto_flow_widget.cpp @@ -40,6 +40,16 @@ GoToFlowWidget::GoToFlowWidget(QWidget *parent, FlowType flowType) resize(static_cast(5 * imageSize.width()), toolBar->height() + static_cast(imageSize.height() * 1.7)); this->setCursor(QCursor(Qt::ArrowCursor)); + + initTheme(this); +} + +void GoToFlowWidget::applyTheme(const Theme &theme) +{ + auto goToFlowTheme = theme.goToFlowWidget; + + flow->setBackgroundColor(goToFlowTheme.flowBackgroundColor); + flow->setTextColor(goToFlowTheme.flowTextColor); } GoToFlowWidget::~GoToFlowWidget() diff --git a/YACReader/goto_flow_widget.h b/YACReader/goto_flow_widget.h index df294dfb0..6456463a9 100644 --- a/YACReader/goto_flow_widget.h +++ b/YACReader/goto_flow_widget.h @@ -6,6 +6,7 @@ #include "yacreader_global_gui.h" #include "yacreader_page_flow_rhi.h" +#include "themable.h" using namespace YACReader; @@ -14,9 +15,12 @@ class GoToFlowToolBar; class QVBoxLayout; class QKeyEvent; -class GoToFlowWidget : public QWidget +class GoToFlowWidget : public QWidget, protected Themable { Q_OBJECT +protected: + void applyTheme(const Theme &theme) override; + public: GoToFlowWidget(QWidget *parent = nullptr, FlowType flowType = CoverFlowLike); ~GoToFlowWidget() override; diff --git a/YACReader/themes/theme.h b/YACReader/themes/theme.h index 719ba61b5..0ccec5a02 100644 --- a/YACReader/themes/theme.h +++ b/YACReader/themes/theme.h @@ -16,6 +16,26 @@ struct ViewerThemeTemplates { QString infoLabelQSS = "QLabel { color : %1; font-size:%2px; }"; }; +struct GoToFlowWidgetThemeTemplates { + QString sliderQSS = "QSlider::groove:horizontal {" + " border: 1px solid %1;" + " border-radius: 1px;" + " background: %2;" + " margin: 2px 0;" + " padding: 1px;" + "}" + "QSlider::handle:horizontal {" + " background: %3;" + " width: 48px;" + " border-radius: 1px;" + "}"; + QString editQSS = "QLineEdit {border: 1px solid %1; background: %2; color: %3; padding: 3px 5px 5px 5px; margin: 13px 5px 12px 5px; font-weight:bold}"; + QString buttonQSS = "QPushButton { border: none; padding: 0px; } " + "QPushButton:focus { border: none; outline: none; } " + "QPushButton:pressed { padding-top: 1px; padding-left: 1px; padding-bottom: -1px; padding-right: -1px; }"; + QString labelQSS = "QLabel { color: %1; }"; +}; + struct ToolbarTheme { QString toolbarQSS; @@ -92,9 +112,22 @@ struct ViewerTheme { QString infoLabelQSS; }; +struct GoToFlowWidgetTheme { + QColor flowBackgroundColor; + QColor flowTextColor; + QColor toolbarBackgroundColor; + QString sliderQSS; + QString editQSS; + QString buttonQSS; + QString labelQSS; + QIcon centerIcon; + QIcon goToIcon; +}; + struct Theme { ToolbarTheme toolbar; ViewerTheme viewer; + GoToFlowWidgetTheme goToFlowWidget; }; #endif // THEME_H diff --git a/YACReader/themes/theme_factory.cpp b/YACReader/themes/theme_factory.cpp index 04002b472..603572fbc 100644 --- a/YACReader/themes/theme_factory.cpp +++ b/YACReader/themes/theme_factory.cpp @@ -23,11 +23,28 @@ struct ViewerParams { QColor infoTextColor; }; +struct GoToFlowWidgetParams { + GoToFlowWidgetThemeTemplates t; + + QColor flowBackgroundColor; + QColor flowTextColor; + QColor toolbarBackgroundColor; + QColor sliderBorderColor; + QColor sliderGrooveColor; + QColor sliderHandleColor; + QColor editBorderColor; + QColor editBackgroundColor; + QColor editTextColor; + QColor labelTextColor; + QColor iconColor; +}; + struct ThemeParams { QString themeName; ToolbarParams toolbarParams; ViewerParams viewerParams; + GoToFlowWidgetParams goToFlowWidgetParams; }; void setToolbarIconPair(QIcon &icon, @@ -113,6 +130,28 @@ Theme makeTheme(const ThemeParams ¶ms) theme.viewer.infoLabelQSS = params.viewerParams.t.infoLabelQSS.arg(params.viewerParams.infoTextColor.name()); // end Viewer + // GoToFlowWidget + auto &gotoParams = params.goToFlowWidgetParams; + theme.goToFlowWidget.flowBackgroundColor = gotoParams.flowBackgroundColor; + theme.goToFlowWidget.flowTextColor = gotoParams.flowTextColor; + theme.goToFlowWidget.toolbarBackgroundColor = gotoParams.toolbarBackgroundColor; + theme.goToFlowWidget.sliderQSS = gotoParams.t.sliderQSS.arg( + gotoParams.sliderBorderColor.name(QColor::HexArgb), + gotoParams.sliderGrooveColor.name(QColor::HexArgb), + gotoParams.sliderHandleColor.name(QColor::HexArgb)); + theme.goToFlowWidget.editQSS = gotoParams.t.editQSS.arg( + gotoParams.editBorderColor.name(QColor::HexArgb), + gotoParams.editBackgroundColor.name(QColor::HexArgb), + gotoParams.editTextColor.name()); + theme.goToFlowWidget.buttonQSS = gotoParams.t.buttonQSS; + theme.goToFlowWidget.labelQSS = gotoParams.t.labelQSS.arg(gotoParams.labelTextColor.name()); + + const QString centerIconPath = recoloredSvgToThemeFile(":/images/centerFlow.svg", gotoParams.iconColor, params.themeName); + const QString goToIconPath = recoloredSvgToThemeFile(":/images/gotoFlow.svg", gotoParams.iconColor, params.themeName); + theme.goToFlowWidget.centerIcon = QIcon(centerIconPath); + theme.goToFlowWidget.goToIcon = QIcon(goToIconPath); + // end GoToFlowWidget + return theme; } @@ -157,6 +196,22 @@ ThemeParams classicThemeParams() params.viewerParams = viewerParams; + GoToFlowWidgetParams goToFlowWidgetParams; + goToFlowWidgetParams.flowBackgroundColor = QColor(0x282828); + goToFlowWidgetParams.flowTextColor = Qt::white; + goToFlowWidgetParams.toolbarBackgroundColor = QColor::fromRgba(0x99000000); + goToFlowWidgetParams.sliderBorderColor = QColor::fromRgba(0x22FFFFFF); + goToFlowWidgetParams.sliderGrooveColor = QColor::fromRgba(0x77000000); + goToFlowWidgetParams.sliderHandleColor = QColor::fromRgba(0x55FFFFFF); + goToFlowWidgetParams.editBorderColor = QColor::fromRgba(0x77000000); + goToFlowWidgetParams.editBackgroundColor = QColor::fromRgba(0x55000000); + goToFlowWidgetParams.editTextColor = Qt::white; + goToFlowWidgetParams.labelTextColor = Qt::white; + goToFlowWidgetParams.iconColor = Qt::white; + goToFlowWidgetParams.t = GoToFlowWidgetThemeTemplates(); + + params.goToFlowWidgetParams = goToFlowWidgetParams; + return params; } @@ -185,6 +240,22 @@ ThemeParams lightThemeParams() params.viewerParams = viewerParams; + GoToFlowWidgetParams goToFlowWidgetParams; + goToFlowWidgetParams.flowBackgroundColor = QColor(0xF6F6F6); + goToFlowWidgetParams.flowTextColor = QColor(0x202020); + goToFlowWidgetParams.toolbarBackgroundColor = QColor::fromRgba(0xBBFFFFFF); + goToFlowWidgetParams.sliderBorderColor = QColor::fromRgba(0x22000000); + goToFlowWidgetParams.sliderGrooveColor = QColor::fromRgba(0x33000000); + goToFlowWidgetParams.sliderHandleColor = QColor::fromRgba(0x55000000); + goToFlowWidgetParams.editBorderColor = QColor::fromRgba(0x33000000); + goToFlowWidgetParams.editBackgroundColor = QColor::fromRgba(0x22000000); + goToFlowWidgetParams.editTextColor = QColor(0x202020); + goToFlowWidgetParams.labelTextColor = QColor(0x202020); + goToFlowWidgetParams.iconColor = QColor(0x404040); + goToFlowWidgetParams.t = GoToFlowWidgetThemeTemplates(); + + params.goToFlowWidgetParams = goToFlowWidgetParams; + return params; } @@ -213,6 +284,22 @@ ThemeParams darkThemeParams() params.viewerParams = viewerParams; + GoToFlowWidgetParams goToFlowWidgetParams; + goToFlowWidgetParams.flowBackgroundColor = QColor(40, 40, 40); + goToFlowWidgetParams.flowTextColor = Qt::white; + goToFlowWidgetParams.toolbarBackgroundColor = QColor::fromRgba(0x99000000); + goToFlowWidgetParams.sliderBorderColor = QColor::fromRgba(0x22FFFFFF); + goToFlowWidgetParams.sliderGrooveColor = QColor::fromRgba(0x77000000); + goToFlowWidgetParams.sliderHandleColor = QColor::fromRgba(0x55FFFFFF); + goToFlowWidgetParams.editBorderColor = QColor::fromRgba(0x77000000); + goToFlowWidgetParams.editBackgroundColor = QColor::fromRgba(0x55000000); + goToFlowWidgetParams.editTextColor = Qt::white; + goToFlowWidgetParams.labelTextColor = Qt::white; + goToFlowWidgetParams.iconColor = QColor(0xCCCCCC); + goToFlowWidgetParams.t = GoToFlowWidgetThemeTemplates(); + + params.goToFlowWidgetParams = goToFlowWidgetParams; + return params; } diff --git a/YACReader/yacreader_images.qrc b/YACReader/yacreader_images.qrc index ef71304de..ac17f2956 100644 --- a/YACReader/yacreader_images.qrc +++ b/YACReader/yacreader_images.qrc @@ -12,10 +12,8 @@ ../images/close.svg ../images/up.png ../images/down.png - ../images/imgCenterSlide.png - ../images/imgGoToSlide.png - ../images/imgCenterSlidePressed.png - ../images/imgGoToSlidePressed.png + ../images/centerFlow.svg + ../images/gotoFlow.svg ../images/defaultCover.png ../images/fromTo.png ../images/dropDownArrow.png diff --git a/images/centerFlow.svg b/images/centerFlow.svg new file mode 100644 index 000000000..ccfb1c172 --- /dev/null +++ b/images/centerFlow.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/gotoFlow.svg b/images/gotoFlow.svg new file mode 100644 index 000000000..8c0a7158b --- /dev/null +++ b/images/gotoFlow.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/imgCenterSlide.png b/images/imgCenterSlide.png deleted file mode 100644 index 0c50ca860aaba6c6204e9b4852331406fe02f3d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^Qb26P!3HFqww|5}q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6`k>PaSW-r^=8UN-X;TqwrKSi96c8V3z%dY1!WHUN;C?t z5N@edIt@m21m#_UTTla-)-S*adQ&&&rc(o&pdvDga-Wxr$ zGUYPkZnka+a%@}wRVp!i#yugorSoLNXGJ?NyEoe=Ywhm6az+1+HQg{=*V_A7;)KVx t-TxNJ`RDJIpCcdV#t3x6gYz{k5)3{&Z|i)nZ_Wof%G1@)Wt~$(696YxcpLx# diff --git a/images/imgCenterSlide@2x.png b/images/imgCenterSlide@2x.png deleted file mode 100644 index eb1108eda934a236f850ea23fbed3191994c3035..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 465 zcmeAS@N?(olHy`uVBq!ia0vp^CP19R!3HExeiN1fQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07#NE^T^vIyZoRqjF}KM< z>P;}uux7mL5S_cEKIHcQfd4z}gneJIvS#MqH@)xwsp(?#hvvr>g$6(i;oyhtL4Ub3 zQPQW?rtX^3wM1@-TF`b!fj!m5p(-9qrrX+emlmzO&~C8v?K+F{6%S@78r_t5{@Q(I z^-BJg5A(Qo?T=qMyGckbYerb+;T-{4PkQ!Vw7A+Mtd=MFzO8EuYt%JAz4r!oCEs>l z6HzN$S9as^x>?0@Zo8iUyN|`$!w0k9T@+ zE$4_l%@uxSdS&nXg&P*u8^8OVDt#q#U9|pzc>Vjn>brTXt}omkES;6}`}7vS{eKSJ z-L!j~dSTp}UCx%}Ix9mfmPCJ0zS5~Hu&{<_YL#@>-kUR4t$MRBY<20wqxJm9ebV)x zRa$KhI=ZLktM!?Cx05EGKmDn`g%KVw4E{A-1`HeTzUltI2>$W?6Q$CIk_^cq0Ox42P085If8j@(lHzh-|UwN(a6ZM6YXTM13tJmc@u8 z1op$YSXN2{v5h|(EILiphW&|b2(^;aiCQ|Evs?%k_0o9+8>?YIkaMJ5rggSXosv`c z$s*lMf~Hy<_ehJaM|SCbtK>k;5_6Z{^wAwNig`_;1^~_JN>OG2Uq}D|002ovPDHLkV1njHhJfb?)d)#PRVTYf81>YnE$t`PXkAJBdDel>Qrv5HZnQ0o*3-e0?k_fwUYvhkGt5&PU|9DStgkmqRZ$YI}>25ZgXuV#y z{hRBRbLzg9%faVj;W+>R0000000000fTQ^lU;zJ2q03o7pGE)x002ovPDHLkV1l;Y B`4RvC diff --git a/images/imgGoToSlide.png b/images/imgGoToSlide.png deleted file mode 100644 index 3187cfc5ff42a006f6d266d05401c452ee11e508..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 204 zcmeAS@N?(olHy`uVBq!ia0vp^Qb26P!3HFqww|5}q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c73F!lIEGZ*dUM5*t3g4)A+VFrzbaMp&=zrtu*KPgqsu9?8RI@CC4tY5A@UN=-~E@TH|-EZebXw*&=`crFGlw zo+Md4{ub-Bc-r=R5B@v7?zOa@Z^*z9U&vv=P%d8U}fi7AzZCsS>JijI1^IEGZ*dUK;bKmcTTzSKj zd!>$lB|qO0`FD1Lj^)-sEg;a)D{xr;v)rh3$Hsx%)Rl g+`%y8dT0Y9gR8@4UX8O0FMtF+UHx3vIVCg!0L*!BN&o-= diff --git a/images/imgGoToSlidePressed.png b/images/imgGoToSlidePressed.png deleted file mode 100644 index 76f5b0b15fa974f5089c21a0eb285fac39ee2c40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 241 zcmeAS@N?(olHy`uVBq!ia0vp^Qb26P!3HFqww|5}q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6;1YZaSW-r^=8Uj&ISd6HdCnufl&uNV-5-yiKrK{x@R_9 zJ*<-nJkjZLS`NH3fTdhtAx6u6jSeIOoYz&aTRv=L#*J>g(mX z)8kddvl(?4dyjNxE}yuyOk|0RoZ$AQIwjp18+%v%DB*V!vn-P-adFqZwddtp_TTmw k?@SE-Pz*9S{-H<$!*xG%50;pBOdyLqUHx3vIVCg!01B{Jn*aa+ diff --git a/images/imgGoToSlidePressed@2x.png b/images/imgGoToSlidePressed@2x.png deleted file mode 100644 index 354993d75c37d7cc6c9649334becc845c5432cad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 374 zcmeAS@N?(olHy`uVBq!ia0vp^CP19R!3HExeiN1fQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07#JlyT^vIyZoRqwF!Qj10NaIcFBoJsB^L_skW-vo(sE>W zNlV`&-YC{Dhi6P%R_NDv`nQ9Joxvq%j?*7MoELJy55CV@{)V$Hu|oH5bgfNEZ27G> ze4%GHZh3yIZ|gSO3oOR|T3S-cmjX93sfmheCteEJsHDa!dUD3UL$}TbOziymZgy~X z=8BBY%*HO(8Fx)*a0l)-Eqk$en|*Sf<6N)5do5S^SWU~bcl>(&&gHZf#>?X0^7sbm zd+W{pdiQV88Owg&yxa3PA6 Date: Sat, 24 Jan 2026 18:44:29 +0100 Subject: [PATCH 049/187] Don't save the default theme color --- YACReader/options_dialog.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/YACReader/options_dialog.cpp b/YACReader/options_dialog.cpp index 6a987c069..03ee97650 100644 --- a/YACReader/options_dialog.cpp +++ b/YACReader/options_dialog.cpp @@ -247,7 +247,11 @@ void OptionsDialog::saveOptions() Configuration::getConfiguration().setShowTimeInInformation(showTimeInInformationLabel->isChecked()); - settings->setValue(BACKGROUND_COLOR, currentColor); + if (currentColor != ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor) { + settings->setValue(BACKGROUND_COLOR, currentColor); + } else { + settings->remove(BACKGROUND_COLOR); + } // settings->setValue(FIT_TO_WIDTH_RATIO,fitToWidthRatioS->sliderPosition()/100.0); settings->setValue(QUICK_NAVI_MODE, quickNavi->isChecked()); settings->setValue(DISABLE_MOUSE_OVER_GOTO_FLOW, disableShowOnMouseOver->isChecked()); From 6b3fcc63d36bf2648000f5853cdb67872bdd1061 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 25 Jan 2026 10:25:00 +0100 Subject: [PATCH 050/187] Make help/about dialog themable Just the hardcoded colors used, the rest of the dialog will be themed by Qt. --- YACReader/themes/theme.h | 3 ++ YACReader/themes/theme_factory.cpp | 14 +++++++ YACReaderLibrary/themes/theme.h | 2 + YACReaderLibrary/themes/theme_factory.cpp | 14 +++++++ .../themes/shared/help_about_dialog_theme.h | 11 +++++ common/themes/themes_common.pri | 4 +- custom_widgets/help_about_dialog.cpp | 41 +++++++++++++++++-- custom_widgets/help_about_dialog.h | 11 ++++- 8 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 common/themes/shared/help_about_dialog_theme.h diff --git a/YACReader/themes/theme.h b/YACReader/themes/theme.h index 0ccec5a02..9754f30c7 100644 --- a/YACReader/themes/theme.h +++ b/YACReader/themes/theme.h @@ -3,6 +3,8 @@ #include +#include "help_about_dialog_theme.h" + struct ToolbarThemeTemplates { QString toolbarQSS = "QToolBar { border: none; background: %1; }\n" "QToolBar::separator { background: %2; width: 1px; margin: 5px 4px; }\n" @@ -128,6 +130,7 @@ struct Theme { ToolbarTheme toolbar; ViewerTheme viewer; GoToFlowWidgetTheme goToFlowWidget; + HelpAboutDialogTheme helpAboutDialog; }; #endif // THEME_H diff --git a/YACReader/themes/theme_factory.cpp b/YACReader/themes/theme_factory.cpp index 603572fbc..d0ecc7d9e 100644 --- a/YACReader/themes/theme_factory.cpp +++ b/YACReader/themes/theme_factory.cpp @@ -45,6 +45,7 @@ struct ThemeParams { ToolbarParams toolbarParams; ViewerParams viewerParams; GoToFlowWidgetParams goToFlowWidgetParams; + HelpAboutDialogTheme helpAboutDialogParams; }; void setToolbarIconPair(QIcon &icon, @@ -152,6 +153,10 @@ Theme makeTheme(const ThemeParams ¶ms) theme.goToFlowWidget.goToIcon = QIcon(goToIconPath); // end GoToFlowWidget + // HelpAboutDialog + theme.helpAboutDialog = params.helpAboutDialogParams; + // end HelpAboutDialog + return theme; } @@ -212,6 +217,9 @@ ThemeParams classicThemeParams() params.goToFlowWidgetParams = goToFlowWidgetParams; + params.helpAboutDialogParams.headingColor = QColor(0x302f2d); + params.helpAboutDialogParams.linkColor = QColor(0xC19441); + return params; } @@ -256,6 +264,9 @@ ThemeParams lightThemeParams() params.goToFlowWidgetParams = goToFlowWidgetParams; + params.helpAboutDialogParams.headingColor = QColor(0x302f2d); + params.helpAboutDialogParams.linkColor = QColor(0xC19441); + return params; } @@ -300,6 +311,9 @@ ThemeParams darkThemeParams() params.goToFlowWidgetParams = goToFlowWidgetParams; + params.helpAboutDialogParams.headingColor = QColor(0xE0E0E0); + params.helpAboutDialogParams.linkColor = QColor(0xD4A84B); + return params; } diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index 0eabd4663..ed8b7a1c0 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -4,6 +4,7 @@ #include #include "yacreader_icon.h" +#include "help_about_dialog_theme.h" struct ComicVineThemeTemplates { QString defaultLabelQSS = "QLabel {color:%1; font-size:12px;font-family:Arial;}"; @@ -130,6 +131,7 @@ struct ComicVineTheme { struct Theme { ComicFlowColors comicFlow; ComicVineTheme comicVine; + HelpAboutDialogTheme helpAboutDialog; }; #endif // THEME_H diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 6d11c65dd..bdd589f4a 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -54,6 +54,7 @@ struct ThemeParams { ComicFlowColors comicFlowColors; ComicVineParams comicVineParams; + HelpAboutDialogTheme helpAboutDialogParams; }; Theme makeTheme(const ThemeParams ¶ms) @@ -115,6 +116,10 @@ Theme makeTheme(const ThemeParams ¶ms) theme.comicVine.rowUpIcon = { QIcon(recolor(t.rowUpIcon, cv.rowIconColor)), t.rowIconSize }; theme.comicVine.rowDownIcon = { QIcon(recolor(t.rowDownIcon, cv.rowIconColor)), t.rowIconSize }; + // HelpAboutDialog + theme.helpAboutDialog = params.helpAboutDialogParams; + // end HelpAboutDialog + return theme; } @@ -194,6 +199,9 @@ ThemeParams classicThemeParams() params.comicFlowColors = cf; params.comicVineParams = cv; + params.helpAboutDialogParams.headingColor = QColor(0x302f2d); + params.helpAboutDialogParams.linkColor = QColor(0xC19441); + return params; } @@ -255,6 +263,9 @@ ThemeParams lightThemeParams() params.comicFlowColors = cf; params.comicVineParams = cv; + params.helpAboutDialogParams.headingColor = QColor(0x302f2d); + params.helpAboutDialogParams.linkColor = QColor(0xC19441); + return params; } @@ -316,5 +327,8 @@ ThemeParams darkThemeParams() params.comicFlowColors = cf; params.comicVineParams = cv; + params.helpAboutDialogParams.headingColor = QColor(0xE0E0E0); + params.helpAboutDialogParams.linkColor = QColor(0xD4A84B); + return params; } diff --git a/common/themes/shared/help_about_dialog_theme.h b/common/themes/shared/help_about_dialog_theme.h new file mode 100644 index 000000000..52f98d35b --- /dev/null +++ b/common/themes/shared/help_about_dialog_theme.h @@ -0,0 +1,11 @@ +#ifndef HELP_ABOUT_DIALOG_THEME_H +#define HELP_ABOUT_DIALOG_THEME_H + +#include + +struct HelpAboutDialogTheme { + QColor headingColor; + QColor linkColor; +}; + +#endif // HELP_ABOUT_DIALOG_THEME_H diff --git a/common/themes/themes_common.pri b/common/themes/themes_common.pri index 67b11da3f..bed4ed5cd 100644 --- a/common/themes/themes_common.pri +++ b/common/themes/themes_common.pri @@ -1,4 +1,5 @@ -INCLUDEPATH += $$PWD +INCLUDEPATH += $$PWD \ + $$PWD/shared HEADERS += \ $$PWD/icon_utils.h \ @@ -6,6 +7,7 @@ HEADERS += \ $$PWD/theme_manager.h \ $$PWD/themable.h \ $$PWD/yacreader_icon.h \ + $$PWD/shared/help_about_dialog_theme.h \ SOURCES += \ diff --git a/custom_widgets/help_about_dialog.cpp b/custom_widgets/help_about_dialog.cpp index 25538c805..17c4a82d7 100644 --- a/custom_widgets/help_about_dialog.cpp +++ b/custom_widgets/help_about_dialog.cpp @@ -50,6 +50,8 @@ HelpAboutDialog::HelpAboutDialog(QWidget *parent) resize(500, heightDesktopResolution * 0.83); loadSystemInfo(); + + initTheme(this); } HelpAboutDialog::HelpAboutDialog(const QString &pathAbout, const QString &pathHelp, QWidget *parent) @@ -67,14 +69,14 @@ void HelpAboutDialog::loadAboutInformation(const QString &path) buildNumber = BUILD_NUMBER; #endif - aboutText->setHtml(fileToString(path).arg(VERSION, buildNumber)); - aboutText->moveCursor(QTextCursor::Start); + aboutHtmlContent = fileToString(path).arg(VERSION, buildNumber); + applyHtmlTheme(); } void HelpAboutDialog::loadHelp(const QString &path) { - helpText->setHtml(fileToString(path)); - helpText->moveCursor(QTextCursor::Start); + helpHtmlContent = fileToString(path); + applyHtmlTheme(); } QString HelpAboutDialog::fileToString(const QString &path) @@ -104,3 +106,34 @@ void HelpAboutDialog::loadSystemInfo() systemInfoText->setText(text); } + +void HelpAboutDialog::applyTheme(const Theme &theme) +{ + Q_UNUSED(theme) + applyHtmlTheme(); +} + +void HelpAboutDialog::applyHtmlTheme() +{ + auto helpTheme = theme.helpAboutDialog; + + // Original colors in the HTML CSS + const QString originalHeadingColor = "#302f2d"; + const QString originalLinkColor = "#C19441"; + + if (!aboutHtmlContent.isEmpty()) { + QString themedAbout = aboutHtmlContent; + themedAbout.replace(originalHeadingColor, helpTheme.headingColor.name(), Qt::CaseInsensitive); + themedAbout.replace(originalLinkColor, helpTheme.linkColor.name(), Qt::CaseInsensitive); + aboutText->setHtml(themedAbout); + aboutText->moveCursor(QTextCursor::Start); + } + + if (!helpHtmlContent.isEmpty()) { + QString themedHelp = helpHtmlContent; + themedHelp.replace(originalHeadingColor, helpTheme.headingColor.name(), Qt::CaseInsensitive); + themedHelp.replace(originalLinkColor, helpTheme.linkColor.name(), Qt::CaseInsensitive); + helpText->setHtml(themedHelp); + helpText->moveCursor(QTextCursor::Start); + } +} diff --git a/custom_widgets/help_about_dialog.h b/custom_widgets/help_about_dialog.h index d7b8289f6..2bf69160b 100644 --- a/custom_widgets/help_about_dialog.h +++ b/custom_widgets/help_about_dialog.h @@ -3,12 +3,17 @@ #include +#include "themable.h" + class QTabWidget; class QTextBrowser; -class HelpAboutDialog : public QDialog +class HelpAboutDialog : public QDialog, protected Themable { Q_OBJECT +protected: + void applyTheme(const Theme &theme) override; + public: HelpAboutDialog(QWidget *parent = 0); HelpAboutDialog(const QString &pathAbout, const QString &pathHelp, QWidget *parent = 0); @@ -23,6 +28,10 @@ public slots: QTextBrowser *systemInfoText; QString fileToString(const QString &path); void loadSystemInfo(); + void applyHtmlTheme(); + + QString aboutHtmlContent; + QString helpHtmlContent; }; #endif // HELP_ABOUT_DIALOG_H From 36899b4e06169b85638777602c6d62c6f160eca1 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 1 Feb 2026 14:26:22 +0100 Subject: [PATCH 051/187] Add new function to recolor svg files supporting 3 placeholders --- common/themes/icon_utils.cpp | 34 +++++++++++++++++++++++++--------- common/themes/icon_utils.h | 12 +++++++++--- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/common/themes/icon_utils.cpp b/common/themes/icon_utils.cpp index 826b31ef5..0de175da7 100644 --- a/common/themes/icon_utils.cpp +++ b/common/themes/icon_utils.cpp @@ -2,13 +2,6 @@ #include "yacreader_global.h" -QString recolorSvgXML(QString &svg, - const QString &placeHolder, - const QColor &color) -{ - return svg.replace(placeHolder, color.name(QColor::HexRgb), Qt::CaseInsensitive); -} - QString readSvg(const QString &resourcePath) { QFile in(resourcePath); @@ -48,6 +41,25 @@ QString writeSvg(const QString &svg, const QString &resourcePath, const QString return outPath; } +QString recolorSvgXML(QString &svg, + const QString &placeHolder, + const QColor &color) +{ + return svg.replace(placeHolder, color.name(QColor::HexRgb), Qt::CaseInsensitive); +} + +QString recoloredSvgToThemeFile(const QString &resourcePath, + const QColor &color, // #f0f (magenta) + const QString &themeName, + const QString &suffix) +{ + auto svg = readSvg(resourcePath); + + recolorSvgXML(svg, "#f0f", color); + + return writeSvg(svg, resourcePath, themeName, suffix); +} + QString recoloredSvgToThemeFile(const QString &resourcePath, const QColor &color1, // #f0f (magenta) const QColor &color2, // #0ff (cyan) @@ -63,13 +75,17 @@ QString recoloredSvgToThemeFile(const QString &resourcePath, } QString recoloredSvgToThemeFile(const QString &resourcePath, - const QColor &color, // #f0f (magenta) + const QColor &color1, // #f0f (magenta) + const QColor &color2, // #0ff (cyan) + const QColor &color3, // #ff0 (yellow) const QString &themeName, const QString &suffix) { auto svg = readSvg(resourcePath); - recolorSvgXML(svg, "#f0f", color); + recolorSvgXML(svg, "#f0f", color1); + recolorSvgXML(svg, "#0ff", color2); + recolorSvgXML(svg, "#ff0", color3); return writeSvg(svg, resourcePath, themeName, suffix); } diff --git a/common/themes/icon_utils.h b/common/themes/icon_utils.h index 014a1b694..132c48452 100644 --- a/common/themes/icon_utils.h +++ b/common/themes/icon_utils.h @@ -3,18 +3,24 @@ #include -QString recolorSvgXML(QString &svg, const QString &placeHolder, const QColor &color); QString readSvg(const QString &resourcePath); QString writeSvg(const QString &svg, const QString &resourcePath, const QString &themeName); + +QString recolorSvgXML(QString &svg, const QString &placeHolder, const QColor &color); +QString recoloredSvgToThemeFile(const QString &resourcePath, + const QColor &color, // #f0f (magenta) + const QString &themeName, + const QString &suffix = QString()); QString recoloredSvgToThemeFile(const QString &resourcePath, const QColor &color1, // #f0f (magenta) const QColor &color2, // #0ff (cyan) const QString &themeName, const QString &suffix = QString()); QString recoloredSvgToThemeFile(const QString &resourcePath, - const QColor &color, // #f0f (magenta) + const QColor &color1, // #f0f (magenta) + const QColor &color2, // #0ff (cyan) + const QColor &color3, // #ff0 (yellow) const QString &themeName, const QString &suffix = QString()); -QString createMenuArrowSvg(const QColor &color, const QString &themeName); #endif // ICON_UTILS_H From 9d6a1abd3954eea717ad2e17c8f6a4cdcca750f1 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Wed, 4 Feb 2026 18:51:28 +0100 Subject: [PATCH 052/187] Improve icon utils by supporting explicit file name destination Useful for using svg templates that can generate multiple icons, e.g. labels --- YACReader/themes/theme_factory.cpp | 8 ++++---- common/themes/icon_utils.cpp | 24 ++++++++++++------------ common/themes/icon_utils.h | 13 +++++++++---- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/YACReader/themes/theme_factory.cpp b/YACReader/themes/theme_factory.cpp index d0ecc7d9e..3f48955a7 100644 --- a/YACReader/themes/theme_factory.cpp +++ b/YACReader/themes/theme_factory.cpp @@ -66,11 +66,11 @@ void setToolbarIconPair(QIcon &icon, const QString normalPath = recoloredSvgToThemeFile(basePath, iconColor, themeName); const QString normalPath18 = recoloredSvgToThemeFile(path18, iconColor, themeName); // Disabled - const QString disabledPath = recoloredSvgToThemeFile(basePath, disabledColor, themeName, "_disabled"); - const QString disabledPath18 = recoloredSvgToThemeFile(path18, disabledColor, themeName, "_disabled"); + const QString disabledPath = recoloredSvgToThemeFile(basePath, disabledColor, themeName, { .suffix = "_disabled" }); + const QString disabledPath18 = recoloredSvgToThemeFile(path18, disabledColor, themeName, { .suffix = "_disabled" }); // Checked (On state) - const QString checkedPath = recoloredSvgToThemeFile(basePath, checkedColor, themeName, "_checked"); - const QString checkedPath18 = recoloredSvgToThemeFile(path18, checkedColor, themeName, "_checked"); + const QString checkedPath = recoloredSvgToThemeFile(basePath, checkedColor, themeName, { .suffix = "_checked" }); + const QString checkedPath18 = recoloredSvgToThemeFile(path18, checkedColor, themeName, { .suffix = "_checked" }); icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); icon.addFile(disabledPath, QSize(), QIcon::Disabled, QIcon::Off); diff --git a/common/themes/icon_utils.cpp b/common/themes/icon_utils.cpp index 0de175da7..bfa0fead9 100644 --- a/common/themes/icon_utils.cpp +++ b/common/themes/icon_utils.cpp @@ -16,18 +16,18 @@ QString readSvg(const QString &resourcePath) return svg; } -QString writeSvg(const QString &svg, const QString &resourcePath, const QString &themeName, const QString &suffix = QString()) +QString writeSvg(const QString &svg, const QString &resourcePath, const QString &themeName, const RecolorOptions &options) { const QString basePath = YACReader::getSettingsPath() + "/themes/" + themeName; QDir().mkpath(basePath); - QString fileName = QFileInfo(resourcePath).completeBaseName(); - if (!suffix.isEmpty()) { - fileName += suffix; + QString outFileName = options.fileName.isEmpty() ? QFileInfo(resourcePath).completeBaseName() : options.fileName; + if (!options.suffix.isEmpty()) { + outFileName += options.suffix; } - fileName += "." + QFileInfo(resourcePath).suffix(); - const QString outPath = basePath + "/" + fileName; + outFileName += "." + QFileInfo(resourcePath).suffix(); + const QString outPath = basePath + "/" + outFileName; QFile out(outPath); if (!out.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { @@ -51,27 +51,27 @@ QString recolorSvgXML(QString &svg, QString recoloredSvgToThemeFile(const QString &resourcePath, const QColor &color, // #f0f (magenta) const QString &themeName, - const QString &suffix) + const RecolorOptions &options) { auto svg = readSvg(resourcePath); recolorSvgXML(svg, "#f0f", color); - return writeSvg(svg, resourcePath, themeName, suffix); + return writeSvg(svg, resourcePath, themeName, options); } QString recoloredSvgToThemeFile(const QString &resourcePath, const QColor &color1, // #f0f (magenta) const QColor &color2, // #0ff (cyan) const QString &themeName, - const QString &suffix) + const RecolorOptions &options) { auto svg = readSvg(resourcePath); recolorSvgXML(svg, "#f0f", color1); recolorSvgXML(svg, "#0ff", color2); - return writeSvg(svg, resourcePath, themeName, suffix); + return writeSvg(svg, resourcePath, themeName, options); } QString recoloredSvgToThemeFile(const QString &resourcePath, @@ -79,7 +79,7 @@ QString recoloredSvgToThemeFile(const QString &resourcePath, const QColor &color2, // #0ff (cyan) const QColor &color3, // #ff0 (yellow) const QString &themeName, - const QString &suffix) + const RecolorOptions &options) { auto svg = readSvg(resourcePath); @@ -87,5 +87,5 @@ QString recoloredSvgToThemeFile(const QString &resourcePath, recolorSvgXML(svg, "#0ff", color2); recolorSvgXML(svg, "#ff0", color3); - return writeSvg(svg, resourcePath, themeName, suffix); + return writeSvg(svg, resourcePath, themeName, options); } diff --git a/common/themes/icon_utils.h b/common/themes/icon_utils.h index 132c48452..8575590dd 100644 --- a/common/themes/icon_utils.h +++ b/common/themes/icon_utils.h @@ -3,24 +3,29 @@ #include +struct RecolorOptions { + QString suffix; + QString fileName; +}; + QString readSvg(const QString &resourcePath); -QString writeSvg(const QString &svg, const QString &resourcePath, const QString &themeName); +QString writeSvg(const QString &svg, const QString &resourcePath, const QString &themeName, const RecolorOptions &options = {}); QString recolorSvgXML(QString &svg, const QString &placeHolder, const QColor &color); QString recoloredSvgToThemeFile(const QString &resourcePath, const QColor &color, // #f0f (magenta) const QString &themeName, - const QString &suffix = QString()); + const RecolorOptions &options = {}); QString recoloredSvgToThemeFile(const QString &resourcePath, const QColor &color1, // #f0f (magenta) const QColor &color2, // #0ff (cyan) const QString &themeName, - const QString &suffix = QString()); + const RecolorOptions &options = {}); QString recoloredSvgToThemeFile(const QString &resourcePath, const QColor &color1, // #f0f (magenta) const QColor &color2, // #0ff (cyan) const QColor &color3, // #ff0 (yellow) const QString &themeName, - const QString &suffix = QString()); + const RecolorOptions &options = {}); #endif // ICON_UTILS_H From 4e79cd9a364bfc64d74b173a1fe53b7f80d4f16e Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Wed, 4 Feb 2026 19:10:00 +0100 Subject: [PATCH 053/187] Enable c++20 --- config.pri | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config.pri b/config.pri index d76a258d6..2ca74575c 100644 --- a/config.pri +++ b/config.pri @@ -2,11 +2,11 @@ # default values if they're not set on build time # for a more detailed description, see INSTALL.TXT -CONFIG += c++17 +CONFIG += c++20 win32 { - #enable c++17 explicitly in msvc - QMAKE_CXXFLAGS += /std:c++17 /Zc:__cplusplus /permissive- + #enable c++20 explicitly in msvc + QMAKE_CXXFLAGS += /std:c++20 /Zc:__cplusplus /permissive- } DEFINES += NOMINMAX From 31b15a6b2273c8788eb309cc43fa6ed4f166b472 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 5 Feb 2026 19:12:55 +0100 Subject: [PATCH 054/187] Move shorcuts icons to a subfolder in images --- YACReader/main_window_viewer.cpp | 10 +++++----- YACReader/yacreader_images.qrc | 16 ++++++++-------- YACReaderLibrary/images.qrc | 16 ++++++++-------- YACReaderLibrary/library_window_actions.cpp | 12 ++++++------ .../{ => shortcuts}/shortcuts_group_comics.svg | 0 .../{ => shortcuts}/shortcuts_group_folders.svg | 0 .../{ => shortcuts}/shortcuts_group_general.svg | 0 .../shortcuts_group_libraries.svg | 0 .../{ => shortcuts}/shortcuts_group_mglass.svg | 0 images/{ => shortcuts}/shortcuts_group_page.svg | 0 .../{ => shortcuts}/shortcuts_group_reading.svg | 0 .../shortcuts_group_visualization.svg | 0 12 files changed, 27 insertions(+), 27 deletions(-) rename images/{ => shortcuts}/shortcuts_group_comics.svg (100%) rename images/{ => shortcuts}/shortcuts_group_folders.svg (100%) rename images/{ => shortcuts}/shortcuts_group_general.svg (100%) rename images/{ => shortcuts}/shortcuts_group_libraries.svg (100%) rename images/{ => shortcuts}/shortcuts_group_mglass.svg (100%) rename images/{ => shortcuts}/shortcuts_group_page.svg (100%) rename images/{ => shortcuts}/shortcuts_group_reading.svg (100%) rename images/{ => shortcuts}/shortcuts_group_visualization.svg (100%) diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index a35b52465..67f545e51 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -1162,7 +1162,7 @@ void MainWindowViewer::setUpShortcutsManagement() QList allActions; QList tmpList; - editShortcutsDialog->addActionsGroup(tr("Comics"), QIcon(":/images/shortcuts_group_comics.svg"), + editShortcutsDialog->addActionsGroup(tr("Comics"), QIcon(":/images/shortcuts/shortcuts_group_comics.svg"), tmpList = { openAction, openLatestComicAction, openFolderAction, @@ -1178,7 +1178,7 @@ void MainWindowViewer::setUpShortcutsManagement() auto *const toggleToolbarsAction = addActionWithShortcut(tr("Hide/show toolbar"), TOGGLE_TOOL_BARS_ACTION_Y); connect(toggleToolbarsAction, &QAction::triggered, this, &MainWindowViewer::toggleToolBars); - editShortcutsDialog->addActionsGroup(tr("General"), QIcon(":/images/shortcuts_group_general.svg"), + editShortcutsDialog->addActionsGroup(tr("General"), QIcon(":/images/shortcuts/shortcuts_group_general.svg"), tmpList = QList() << optionsAction << helpAboutAction @@ -1216,7 +1216,7 @@ void MainWindowViewer::setUpShortcutsManagement() zoomInMglassAction, zoomOutMglassAction, resetMglassAction }; - editShortcutsDialog->addActionsGroup(tr("Magnifiying glass"), QIcon(":/images/shortcuts_group_mglass.svg"), + editShortcutsDialog->addActionsGroup(tr("Magnifiying glass"), QIcon(":/images/shortcuts/shortcuts_group_mglass.svg"), tmpList = QList() << showMagnifyingGlassAction << mglassActions); @@ -1227,7 +1227,7 @@ void MainWindowViewer::setUpShortcutsManagement() CHANGE_FIT_ACTION_Y); connect(toggleFitToScreenAction, &QAction::triggered, this, &MainWindowViewer::toggleWidthHeight); - editShortcutsDialog->addActionsGroup(tr("Page adjustement"), QIcon(":/images/shortcuts_group_page.svg"), + editShortcutsDialog->addActionsGroup(tr("Page adjustement"), QIcon(":/images/shortcuts/shortcuts_group_page.svg"), tmpList = QList() << adjustHeightAction << adjustWidthAction @@ -1304,7 +1304,7 @@ void MainWindowViewer::setUpShortcutsManagement() offsetDoublePageToTheLeft, offsetDoublePageToTheRight }; - editShortcutsDialog->addActionsGroup(tr("Reading"), QIcon(":/images/shortcuts_group_reading.svg"), + editShortcutsDialog->addActionsGroup(tr("Reading"), QIcon(":/images/shortcuts/shortcuts_group_reading.svg"), tmpList = QList() << goToPageOnTheRightAction << goToPageOnTheLeftAction diff --git a/YACReader/yacreader_images.qrc b/YACReader/yacreader_images.qrc index ac17f2956..3a145e43e 100644 --- a/YACReader/yacreader_images.qrc +++ b/YACReader/yacreader_images.qrc @@ -21,14 +21,14 @@ ../images/speaker.png ../images/clear_shortcut.svg ../images/accept_shortcut.svg - ../images/shortcuts_group_comics.svg - ../images/shortcuts_group_folders.svg - ../images/shortcuts_group_general.svg - ../images/shortcuts_group_libraries.svg - ../images/shortcuts_group_mglass.svg - ../images/shortcuts_group_page.svg - ../images/shortcuts_group_reading.svg - ../images/shortcuts_group_visualization.svg + ../images/shortcuts/shortcuts_group_comics.svg + ../images/shortcuts/shortcuts_group_folders.svg + ../images/shortcuts/shortcuts_group_general.svg + ../images/shortcuts/shortcuts_group_libraries.svg + ../images/shortcuts/shortcuts_group_mglass.svg + ../images/shortcuts/shortcuts_group_page.svg + ../images/shortcuts/shortcuts_group_reading.svg + ../images/shortcuts/shortcuts_group_visualization.svg ../images/custom_dialog/custom_close_button.svg ../images/whats_new/whatsnew_header.svg ../images/viewer_toolbar/bookmark.svg diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index ae8add4a1..175162087 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -74,14 +74,14 @@ ../images/resetCover.svg ../images/searching_icon.png ../images/serverConfigBackground.png - ../images/shortcuts_group_comics.svg - ../images/shortcuts_group_folders.svg - ../images/shortcuts_group_general.svg - ../images/shortcuts_group_libraries.svg - ../images/shortcuts_group_mglass.svg - ../images/shortcuts_group_page.svg - ../images/shortcuts_group_reading.svg - ../images/shortcuts_group_visualization.svg + ../images/shortcuts/shortcuts_group_comics.svg + ../images/shortcuts/shortcuts_group_folders.svg + ../images/shortcuts/shortcuts_group_general.svg + ../images/shortcuts/shortcuts_group_libraries.svg + ../images/shortcuts/shortcuts_group_mglass.svg + ../images/shortcuts/shortcuts_group_page.svg + ../images/shortcuts/shortcuts_group_reading.svg + ../images/shortcuts/shortcuts_group_visualization.svg ../images/shownCovers.png ../images/sidebar/branch-closed.svg ../images/sidebar/branch-open.svg diff --git a/YACReaderLibrary/library_window_actions.cpp b/YACReaderLibrary/library_window_actions.cpp index ad49d1e7b..011321e64 100644 --- a/YACReaderLibrary/library_window_actions.cpp +++ b/YACReaderLibrary/library_window_actions.cpp @@ -613,7 +613,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho QList allActions; QList tmpList; - editShortcutsDialog->addActionsGroup("Comics", QIcon(":/images/shortcuts_group_comics.svg"), + editShortcutsDialog->addActionsGroup("Comics", QIcon(":/images/shortcuts/shortcuts_group_comics.svg"), tmpList = QList() << openComicAction << saveCoversToAction @@ -632,7 +632,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho allActions << tmpList; - editShortcutsDialog->addActionsGroup("Folders", QIcon(":/images/shortcuts_group_folders.svg"), + editShortcutsDialog->addActionsGroup("Folders", QIcon(":/images/shortcuts/shortcuts_group_folders.svg"), tmpList = QList() << addFolderAction << deleteFolderAction @@ -652,7 +652,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho << deleteCustomFolderCoverAction); allActions << tmpList; - editShortcutsDialog->addActionsGroup("Lists", QIcon(":/images/shortcuts_group_folders.svg"), // TODO change icon + editShortcutsDialog->addActionsGroup("Lists", QIcon(":/images/shortcuts/shortcuts_group_folders.svg"), // TODO change icon tmpList = QList() << addReadingListAction << deleteReadingListAction @@ -660,7 +660,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho << renameListAction); allActions << tmpList; - editShortcutsDialog->addActionsGroup("General", QIcon(":/images/shortcuts_group_general.svg"), + editShortcutsDialog->addActionsGroup("General", QIcon(":/images/shortcuts/shortcuts_group_general.svg"), tmpList = QList() << backAction << forwardAction @@ -674,7 +674,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho allActions << tmpList; - editShortcutsDialog->addActionsGroup("Libraries", QIcon(":/images/shortcuts_group_libraries.svg"), + editShortcutsDialog->addActionsGroup("Libraries", QIcon(":/images/shortcuts/shortcuts_group_libraries.svg"), tmpList = QList() << createLibraryAction << openLibraryAction @@ -690,7 +690,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho allActions << tmpList; - editShortcutsDialog->addActionsGroup("Visualization", QIcon(":/images/shortcuts_group_visualization.svg"), + editShortcutsDialog->addActionsGroup("Visualization", QIcon(":/images/shortcuts/shortcuts_group_visualization.svg"), tmpList = QList() << showHideMarksAction << toogleShowRecentIndicatorAction diff --git a/images/shortcuts_group_comics.svg b/images/shortcuts/shortcuts_group_comics.svg similarity index 100% rename from images/shortcuts_group_comics.svg rename to images/shortcuts/shortcuts_group_comics.svg diff --git a/images/shortcuts_group_folders.svg b/images/shortcuts/shortcuts_group_folders.svg similarity index 100% rename from images/shortcuts_group_folders.svg rename to images/shortcuts/shortcuts_group_folders.svg diff --git a/images/shortcuts_group_general.svg b/images/shortcuts/shortcuts_group_general.svg similarity index 100% rename from images/shortcuts_group_general.svg rename to images/shortcuts/shortcuts_group_general.svg diff --git a/images/shortcuts_group_libraries.svg b/images/shortcuts/shortcuts_group_libraries.svg similarity index 100% rename from images/shortcuts_group_libraries.svg rename to images/shortcuts/shortcuts_group_libraries.svg diff --git a/images/shortcuts_group_mglass.svg b/images/shortcuts/shortcuts_group_mglass.svg similarity index 100% rename from images/shortcuts_group_mglass.svg rename to images/shortcuts/shortcuts_group_mglass.svg diff --git a/images/shortcuts_group_page.svg b/images/shortcuts/shortcuts_group_page.svg similarity index 100% rename from images/shortcuts_group_page.svg rename to images/shortcuts/shortcuts_group_page.svg diff --git a/images/shortcuts_group_reading.svg b/images/shortcuts/shortcuts_group_reading.svg similarity index 100% rename from images/shortcuts_group_reading.svg rename to images/shortcuts/shortcuts_group_reading.svg diff --git a/images/shortcuts_group_visualization.svg b/images/shortcuts/shortcuts_group_visualization.svg similarity index 100% rename from images/shortcuts_group_visualization.svg rename to images/shortcuts/shortcuts_group_visualization.svg From ee151fc077697c925c0cec689d0a217f7a667116 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 5 Feb 2026 19:19:31 +0100 Subject: [PATCH 055/187] Remove unused widget --- YACReaderLibrary/YACReaderLibrary.pro | 2 - YACReaderLibrary/empty_folder_widget.cpp | 190 ----------------------- YACReaderLibrary/empty_folder_widget.h | 34 ---- YACReaderLibrary/library_window.h | 1 - 4 files changed, 227 deletions(-) delete mode 100644 YACReaderLibrary/empty_folder_widget.cpp delete mode 100644 YACReaderLibrary/empty_folder_widget.h diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index eebe8a031..c1a88482c 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -115,7 +115,6 @@ HEADERS += \ ../common/exit_check.h \ comics_view.h \ classic_comics_view.h \ - empty_folder_widget.h \ no_search_results_widget.h \ comic_files_manager.h \ db/reading_list_model.h \ @@ -201,7 +200,6 @@ SOURCES += \ ../common/exit_check.cpp \ comics_view.cpp \ classic_comics_view.cpp \ - empty_folder_widget.cpp \ no_search_results_widget.cpp \ comic_files_manager.cpp \ db/reading_list_model.cpp \ diff --git a/YACReaderLibrary/empty_folder_widget.cpp b/YACReaderLibrary/empty_folder_widget.cpp deleted file mode 100644 index a2bb1d137..000000000 --- a/YACReaderLibrary/empty_folder_widget.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include "empty_folder_widget.h" - -#include "yacreader_global.h" - -#include -#include -#include -#include -#include - -#include "comic.h" -#include "comic_files_manager.h" -#include "QsLog.h" - -void testListView(QListView *l) -{ - QStringListModel *slm = new QStringListModel(QStringList() << "Lorem ipsum" - << "Hailer skualer" - << "Mumbaluba X" - << "Finger layden" - << "Pacum tactus filer" - << "Aposum" - << "En" - << "Lorem ipsum" - << "Hailer skualer" - << "Mumbaluba X" - << "Finger layden" - << "Pacum tactus filer" - << "Aposum" - << "En"); - l->setModel(slm); -} - -class ListviewDelegate : public QStyledItemDelegate -{ -public: - ListviewDelegate() - : QStyledItemDelegate() { } - - virtual ~ListviewDelegate() { } - - void paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const override - { - painter->save(); - - QFontMetrics fm(option.font); - QString text = qvariant_cast(index.data(Qt::DisplayRole)); - - QRect textRect = option.rect; - - textRect.setLeft(std::max(0, (option.rect.size().width() - fm.horizontalAdvance(text)) / 2)); - - painter->drawText(textRect, text); - - painter->restore(); - - // TODO add mouse hover style ?? - } - - QSize sizeHint(const QStyleOptionViewItem &option, - const QModelIndex &index) const override - { - QFontMetrics fm(option.font); - QString text = qvariant_cast(index.data(Qt::DisplayRole)); - - return QSize(fm.horizontalAdvance(text), fm.height()); - } -}; - -EmptyFolderWidget::EmptyFolderWidget(QWidget *parent) - : EmptyContainerInfo(parent), subfoldersModel(new QStringListModel()) -{ - QVBoxLayout *layout = setUpDefaultLayout(false); - - iconLabel->setPixmap(QPixmap(":/images/empty_folder.png")); - titleLabel->setText(tr("Subfolders in this folder")); - - foldersView = new QListView(); - foldersView->setAttribute(Qt::WA_MacShowFocusRect, false); - foldersView->setItemDelegate(new ListviewDelegate); -#ifdef Y_MAC_UI - foldersView->setStyleSheet("QListView {background-color:transparent; border: none; color:#959595; outline:0; font-size: 18px; show-decoration-selected: 0; margin:0}" - "QListView::item:selected {background-color: #EFEFEF; color:#CCCCCC;}" - "QListView::item:hover {background-color:#F4F4F8; color:#757575; }" - - "QScrollBar:vertical { border-radius:3px; background: #FFFFFF; width: 14px; margin: 0 10px 0 0; }" - "QScrollBar::handle:vertical { border: 1px solid #999999; background: #999999; width: 14px; min-height: 20px; border-radius: 2px; }" - "QScrollBar::add-line:vertical { border: none; background: #999999; height: 0px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" - - "QScrollBar::sub-line:vertical { border: none; background: #999999; height: 0px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" - "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" - - "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none; }" - "QScrollBar:horizontal{height:0px;}"); -#else - foldersView->setStyleSheet("QListView {background-color:transparent; border: none; color:#858585; outline:0; font-size: 18px; font:bold; show-decoration-selected: 0; margin:0}" - "QListView::item:selected {background-color: #212121; color:#CCCCCC;}" - "QListView::item:hover {background-color:#212121; color:#CCCCCC; }" - - "QScrollBar:vertical { border: none; background: #212121; width: 14px; margin: 0 10px 0 0; }" - "QScrollBar::handle:vertical { background: #858585; width: 14px; min-height: 20px; }" - "QScrollBar::add-line:vertical { border: none; background: #212121; height: 0px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" - - "QScrollBar::sub-line:vertical { border: none; background: #212121; height: 0px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" - "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" - - "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none; }" - "QScrollBar:horizontal{height:0px;}"); - -#endif - foldersView->setSizePolicy(QSizePolicy ::Expanding, QSizePolicy ::Expanding); - - layout->addSpacing(12); - layout->addWidget(foldersView, 1); - layout->addStretch(); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - - setContentsMargins(0, 0, 0, 0); - - setStyleSheet(QString("QWidget {background:%1}").arg(backgroundColor)); - - setSizePolicy(QSizePolicy ::Expanding, QSizePolicy ::Expanding); - - setAcceptDrops(true); - - connect(foldersView, &QAbstractItemView::clicked, this, &EmptyFolderWidget::onItemClicked); -} - -void EmptyFolderWidget::setSubfolders(const QModelIndex &mi, const QStringList &foldersNames) -{ - parent = mi; - subfoldersModel->setStringList(foldersNames); - foldersView->setModel(subfoldersModel); - - if (foldersNames.isEmpty()) { - titleLabel->setText(tr("Empty folder") + QString("

%1

").arg(tr("Drag and drop folders and comics here"))); - } else { - titleLabel->setText(tr("Subfolders in this folder")); - } -} - -void EmptyFolderWidget::onItemClicked(const QModelIndex &mi) -{ - emit subfolderSelected(parent, mi.row()); -} - -// TODO remove repeated code in drag & drop support.... -void EmptyFolderWidget::dragEnterEvent(QDragEnterEvent *event) -{ - QList urlList; - - if (event->mimeData()->hasUrls() && event->dropAction() == Qt::CopyAction) { - urlList = event->mimeData()->urls(); - QString currentPath; - foreach (QUrl url, urlList) { - // comics or folders are accepted, folders' content is validate in dropEvent (avoid any lag before droping) - currentPath = url.toLocalFile(); - if (Comic::fileIsComic(currentPath) || QFileInfo(currentPath).isDir()) { - event->acceptProposedAction(); - return; - } - } - } -} - -void EmptyFolderWidget::dropEvent(QDropEvent *event) -{ - QLOG_DEBUG() << "drop in emptyfolder" << event->dropAction(); - - bool validAction = event->dropAction() == Qt::CopyAction; // || event->dropAction() & Qt::MoveAction; TODO move - - if (validAction) { - - QList> droppedFiles = ComicFilesManager::getDroppedFiles(event->mimeData()->urls()); - - if (event->dropAction() == Qt::CopyAction) { - QLOG_DEBUG() << "copy in emptyfolder:" << droppedFiles; - emit copyComicsToCurrentFolder(droppedFiles); - } else if (event->dropAction() & Qt::MoveAction) { - QLOG_DEBUG() << "move in emptyfolder:" << droppedFiles; - emit moveComicsToCurrentFolder(droppedFiles); - } - - event->acceptProposedAction(); - } -} diff --git a/YACReaderLibrary/empty_folder_widget.h b/YACReaderLibrary/empty_folder_widget.h deleted file mode 100644 index 948f354bc..000000000 --- a/YACReaderLibrary/empty_folder_widget.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef EMPTY_FOLDER_WIDGET_H -#define EMPTY_FOLDER_WIDGET_H - -#include "empty_container_info.h" -#include - -class EmptyFolderWidget : public EmptyContainerInfo -{ - Q_OBJECT -public: - explicit EmptyFolderWidget(QWidget *parent = nullptr); - void setSubfolders(const QModelIndex &mi, const QStringList &foldersNames); -signals: - void subfolderSelected(QModelIndex, int); - - // Drops - void copyComicsToCurrentFolder(QList>); - void moveComicsToCurrentFolder(QList>); - -public slots: - void onItemClicked(const QModelIndex &mi); - -protected: - QListView *foldersView; - QModelIndex parent; - QStringListModel *subfoldersModel; - QString backgroundColor; - - // Drop to import - void dragEnterEvent(QDragEnterEvent *event) override; - void dropEvent(QDropEvent *event) override; -}; - -#endif // EMPTY_FOLDER_WIDGET_H diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index 4f153a542..c200a8b85 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -72,7 +72,6 @@ class ComicsView; class ClassicComicsView; class GridComicsView; class ComicsViewTransition; -class EmptyFolderWidget; class NoSearchResultsWidget; class EditShortcutsDialog; class ComicFilesManager; From 94fa95924c6a80ed7a2684f47f5dcb2cca8074bd Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Feb 2026 14:39:49 +0100 Subject: [PATCH 056/187] Remove unused images --- YACReaderLibrary/images_osx.qrc | 20 ------------------ images/accept_shortcut.png | Bin 204 -> 0 bytes images/clear_shortcut.png | Bin 200 -> 0 bytes images/f_retina.png | Bin 1371 -> 0 bytes images/main_toolbar/back_disabled_osx.png | Bin 350 -> 0 bytes images/main_toolbar/back_osx.png | Bin 349 -> 0 bytes images/main_toolbar/back_osx@2x.png | Bin 1578 -> 0 bytes images/main_toolbar/flow_osx.png | Bin 1116 -> 0 bytes images/main_toolbar/flow_osx@2x.png | Bin 1537 -> 0 bytes images/main_toolbar/forward_disabled_osx.png | Bin 380 -> 0 bytes images/main_toolbar/forward_osx.png | Bin 345 -> 0 bytes images/main_toolbar/forward_osx@2x.png | Bin 1610 -> 0 bytes images/main_toolbar/fullscreen_osx.png | Bin 563 -> 0 bytes images/main_toolbar/grid_osx.png | Bin 1050 -> 0 bytes images/main_toolbar/grid_osx@2x.png | Bin 1480 -> 0 bytes images/main_toolbar/help_osx.png | Bin 536 -> 0 bytes images/main_toolbar/help_osx@2x.png | Bin 1972 -> 0 bytes images/main_toolbar/info_osx.png | Bin 1172 -> 0 bytes images/main_toolbar/info_osx@2x.png | Bin 1496 -> 0 bytes images/main_toolbar/server_osx.png | Bin 376 -> 0 bytes images/main_toolbar/server_osx@2x.png | Bin 1687 -> 0 bytes images/main_toolbar/settings_osx.png | Bin 781 -> 0 bytes images/main_toolbar/settings_osx@2x.png | Bin 2519 -> 0 bytes images/rating0.png | Bin 402 -> 0 bytes images/rating1.png | Bin 479 -> 0 bytes images/rating2.png | Bin 514 -> 0 bytes images/rating3.png | Bin 514 -> 0 bytes images/rating4.png | Bin 498 -> 0 bytes images/rating5.png | Bin 404 -> 0 bytes images/viewer_toolbar/bookmark_osx.png | Bin 348 -> 0 bytes images/viewer_toolbar/bookmark_osx@2x.png | Bin 1710 -> 0 bytes images/viewer_toolbar/close_osx.png | Bin 685 -> 0 bytes images/viewer_toolbar/close_osx@2x.png | Bin 2272 -> 0 bytes images/viewer_toolbar/doubleMangaPage_osx.png | Bin 1407 -> 0 bytes .../viewer_toolbar/doubleMangaPage_osx@2x.png | Bin 1954 -> 0 bytes images/viewer_toolbar/doublePage_osx.png | Bin 290 -> 0 bytes images/viewer_toolbar/doublePage_osx@2x.png | Bin 1536 -> 0 bytes images/viewer_toolbar/fitToPage_osx.png | Bin 1528 -> 0 bytes images/viewer_toolbar/fitToPage_osx@2x.png | Bin 2162 -> 0 bytes images/viewer_toolbar/flow_osx.png | Bin 239 -> 0 bytes images/viewer_toolbar/flow_osx@2x.png | Bin 1411 -> 0 bytes images/viewer_toolbar/full_osx.png | Bin 646 -> 0 bytes images/viewer_toolbar/full_osx@2x.png | Bin 2128 -> 0 bytes images/viewer_toolbar/goto_osx.png | Bin 597 -> 0 bytes images/viewer_toolbar/goto_osx@2x.png | Bin 2025 -> 0 bytes images/viewer_toolbar/help_osx.png | Bin 560 -> 0 bytes images/viewer_toolbar/help_osx@2x.png | Bin 2036 -> 0 bytes images/viewer_toolbar/info_osx.png | Bin 422 -> 0 bytes images/viewer_toolbar/info_osx@2x.png | Bin 1712 -> 0 bytes images/viewer_toolbar/magnifyingGlass_osx.png | Bin 705 -> 0 bytes .../viewer_toolbar/magnifyingGlass_osx@2x.png | Bin 2391 -> 0 bytes images/viewer_toolbar/next_osx.png | Bin 358 -> 0 bytes images/viewer_toolbar/next_osx@2x.png | Bin 1614 -> 0 bytes images/viewer_toolbar/openFolder_osx.png | Bin 280 -> 0 bytes images/viewer_toolbar/openFolder_osx@2x.png | Bin 1464 -> 0 bytes images/viewer_toolbar/openNext_osx.png | Bin 608 -> 0 bytes images/viewer_toolbar/openNext_osx@2x.png | Bin 2098 -> 0 bytes images/viewer_toolbar/openPrevious_osx.png | Bin 614 -> 0 bytes images/viewer_toolbar/openPrevious_osx@2x.png | Bin 2065 -> 0 bytes images/viewer_toolbar/open_osx.png | Bin 661 -> 0 bytes images/viewer_toolbar/open_osx@2x.png | Bin 2162 -> 0 bytes images/viewer_toolbar/options_osx.png | Bin 864 -> 0 bytes images/viewer_toolbar/options_osx@2x.png | Bin 2688 -> 0 bytes images/viewer_toolbar/previous_osx.png | Bin 352 -> 0 bytes images/viewer_toolbar/previous_osx@2x.png | Bin 1582 -> 0 bytes images/viewer_toolbar/rotateL_osx.png | Bin 797 -> 0 bytes images/viewer_toolbar/rotateL_osx@2x.png | Bin 2540 -> 0 bytes images/viewer_toolbar/rotateR_osx.png | Bin 827 -> 0 bytes images/viewer_toolbar/rotateR_osx@2x.png | Bin 2568 -> 0 bytes images/viewer_toolbar/save_osx.png | Bin 468 -> 0 bytes images/viewer_toolbar/save_osx@2x.png | Bin 1849 -> 0 bytes images/viewer_toolbar/shortcuts_osx.png | Bin 531 -> 0 bytes images/viewer_toolbar/shortcuts_osx@2x.png | Bin 2012 -> 0 bytes images/viewer_toolbar/showBookmarks_osx.png | Bin 347 -> 0 bytes .../viewer_toolbar/showBookmarks_osx@2x.png | Bin 1615 -> 0 bytes images/viewer_toolbar/toHeight_osx.png | Bin 401 -> 0 bytes images/viewer_toolbar/toHeight_osx@2x.png | Bin 1712 -> 0 bytes images/viewer_toolbar/toWidthSlider_osx.png | Bin 1321 -> 0 bytes .../viewer_toolbar/toWidthSlider_osx@2x.png | Bin 1793 -> 0 bytes images/viewer_toolbar/toWidth_osx.png | Bin 379 -> 0 bytes images/viewer_toolbar/toWidth_osx@2x.png | Bin 1702 -> 0 bytes images/viewer_toolbar/translator_osx.png | Bin 526 -> 0 bytes images/viewer_toolbar/translator_osx@2x.png | Bin 2024 -> 0 bytes images/viewer_toolbar/zoom_osx.png | Bin 1230 -> 0 bytes images/viewer_toolbar/zoom_osx@2x.png | Bin 1487 -> 0 bytes 85 files changed, 20 deletions(-) delete mode 100644 images/accept_shortcut.png delete mode 100644 images/clear_shortcut.png delete mode 100644 images/f_retina.png delete mode 100644 images/main_toolbar/back_disabled_osx.png delete mode 100644 images/main_toolbar/back_osx.png delete mode 100644 images/main_toolbar/back_osx@2x.png delete mode 100644 images/main_toolbar/flow_osx.png delete mode 100644 images/main_toolbar/flow_osx@2x.png delete mode 100644 images/main_toolbar/forward_disabled_osx.png delete mode 100644 images/main_toolbar/forward_osx.png delete mode 100644 images/main_toolbar/forward_osx@2x.png delete mode 100644 images/main_toolbar/fullscreen_osx.png delete mode 100644 images/main_toolbar/grid_osx.png delete mode 100644 images/main_toolbar/grid_osx@2x.png delete mode 100644 images/main_toolbar/help_osx.png delete mode 100644 images/main_toolbar/help_osx@2x.png delete mode 100644 images/main_toolbar/info_osx.png delete mode 100644 images/main_toolbar/info_osx@2x.png delete mode 100644 images/main_toolbar/server_osx.png delete mode 100644 images/main_toolbar/server_osx@2x.png delete mode 100644 images/main_toolbar/settings_osx.png delete mode 100644 images/main_toolbar/settings_osx@2x.png delete mode 100644 images/rating0.png delete mode 100644 images/rating1.png delete mode 100644 images/rating2.png delete mode 100644 images/rating3.png delete mode 100644 images/rating4.png delete mode 100644 images/rating5.png delete mode 100755 images/viewer_toolbar/bookmark_osx.png delete mode 100644 images/viewer_toolbar/bookmark_osx@2x.png delete mode 100755 images/viewer_toolbar/close_osx.png delete mode 100644 images/viewer_toolbar/close_osx@2x.png delete mode 100644 images/viewer_toolbar/doubleMangaPage_osx.png delete mode 100644 images/viewer_toolbar/doubleMangaPage_osx@2x.png delete mode 100755 images/viewer_toolbar/doublePage_osx.png delete mode 100644 images/viewer_toolbar/doublePage_osx@2x.png delete mode 100644 images/viewer_toolbar/fitToPage_osx.png delete mode 100644 images/viewer_toolbar/fitToPage_osx@2x.png delete mode 100644 images/viewer_toolbar/flow_osx.png delete mode 100644 images/viewer_toolbar/flow_osx@2x.png delete mode 100755 images/viewer_toolbar/full_osx.png delete mode 100644 images/viewer_toolbar/full_osx@2x.png delete mode 100644 images/viewer_toolbar/goto_osx.png delete mode 100644 images/viewer_toolbar/goto_osx@2x.png delete mode 100755 images/viewer_toolbar/help_osx.png delete mode 100644 images/viewer_toolbar/help_osx@2x.png delete mode 100755 images/viewer_toolbar/info_osx.png delete mode 100644 images/viewer_toolbar/info_osx@2x.png delete mode 100755 images/viewer_toolbar/magnifyingGlass_osx.png delete mode 100644 images/viewer_toolbar/magnifyingGlass_osx@2x.png delete mode 100755 images/viewer_toolbar/next_osx.png delete mode 100644 images/viewer_toolbar/next_osx@2x.png delete mode 100644 images/viewer_toolbar/openFolder_osx.png delete mode 100644 images/viewer_toolbar/openFolder_osx@2x.png delete mode 100644 images/viewer_toolbar/openNext_osx.png delete mode 100644 images/viewer_toolbar/openNext_osx@2x.png delete mode 100644 images/viewer_toolbar/openPrevious_osx.png delete mode 100644 images/viewer_toolbar/openPrevious_osx@2x.png delete mode 100644 images/viewer_toolbar/open_osx.png delete mode 100644 images/viewer_toolbar/open_osx@2x.png delete mode 100755 images/viewer_toolbar/options_osx.png delete mode 100644 images/viewer_toolbar/options_osx@2x.png delete mode 100755 images/viewer_toolbar/previous_osx.png delete mode 100644 images/viewer_toolbar/previous_osx@2x.png delete mode 100644 images/viewer_toolbar/rotateL_osx.png delete mode 100644 images/viewer_toolbar/rotateL_osx@2x.png delete mode 100644 images/viewer_toolbar/rotateR_osx.png delete mode 100644 images/viewer_toolbar/rotateR_osx@2x.png delete mode 100644 images/viewer_toolbar/save_osx.png delete mode 100644 images/viewer_toolbar/save_osx@2x.png delete mode 100755 images/viewer_toolbar/shortcuts_osx.png delete mode 100644 images/viewer_toolbar/shortcuts_osx@2x.png delete mode 100755 images/viewer_toolbar/showBookmarks_osx.png delete mode 100644 images/viewer_toolbar/showBookmarks_osx@2x.png delete mode 100755 images/viewer_toolbar/toHeight_osx.png delete mode 100644 images/viewer_toolbar/toHeight_osx@2x.png delete mode 100644 images/viewer_toolbar/toWidthSlider_osx.png delete mode 100644 images/viewer_toolbar/toWidthSlider_osx@2x.png delete mode 100755 images/viewer_toolbar/toWidth_osx.png delete mode 100644 images/viewer_toolbar/toWidth_osx@2x.png delete mode 100755 images/viewer_toolbar/translator_osx.png delete mode 100644 images/viewer_toolbar/translator_osx@2x.png delete mode 100644 images/viewer_toolbar/zoom_osx.png delete mode 100644 images/viewer_toolbar/zoom_osx@2x.png diff --git a/YACReaderLibrary/images_osx.qrc b/YACReaderLibrary/images_osx.qrc index b9f5f34aa..15a289e59 100644 --- a/YACReaderLibrary/images_osx.qrc +++ b/YACReaderLibrary/images_osx.qrc @@ -1,28 +1,8 @@ ../images/folder_finished_macosx.png - ../images/main_toolbar/back_osx.png - ../images/main_toolbar/back_osx@2x.png - ../images/main_toolbar/forward_osx.png - ../images/main_toolbar/forward_osx@2x.png - ../images/main_toolbar/settings_osx.png - ../images/main_toolbar/settings_osx@2x.png - ../images/main_toolbar/server_osx.png - ../images/main_toolbar/server_osx@2x.png - ../images/main_toolbar/help_osx.png - ../images/main_toolbar/help_osx@2x.png - ../images/main_toolbar/flow_osx.png - ../images/main_toolbar/flow_osx@2x.png - ../images/main_toolbar/grid_osx.png - ../images/main_toolbar/grid_osx@2x.png - ../images/main_toolbar/info_osx.png - ../images/main_toolbar/info_osx@2x.png ../images/empty_folder_osx.png ../images/empty_search_osx.png - ../images/iconSearch.png - ../images/iconSearch@2x.png - ../images/clearSearch.png - ../images/clearSearch@2x.png ../images/empty_reading_list_osx.png ../images/sidebar/libraryIcon_osx.png ../images/sidebar/setRoot_osx.png diff --git a/images/accept_shortcut.png b/images/accept_shortcut.png deleted file mode 100644 index dc0017b95566704bdcb79d41406bb660df56f9ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 204 zcmeAS@N?(olHy`uVBq!ia0vp^{2}1{rUgjo_S|OXCsqC{Mo;?wR|a=Y*{`GLBA8( z3?{B9v=dMl6BCtnxY+YXhDl0%fra#{Li-TGK&gkb7M}B9(R4CnnC~W#;NqupqHCd( yg=tcTn{fl}1{rUgjo_S{j>+FR3_;{%avpQ9##6^Uda62oW zNGrK>{q}EpdHFWU#B*%7+_wB~T$jLdu_xrSvDp4a%pv=QADhQ~^09FGZEq$eYhW0_ v(6%D2%SqZcce$`f=F1Z@T|p8K4U7!guUGzRnj~lew3Wfr)z4*}Q$iB}vI|AZ diff --git a/images/f_retina.png b/images/f_retina.png deleted file mode 100644 index b8eeddcf6f76077e6db0ae1487b64051dbe71c98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1371 zcmeAS@N?(olHy`uVBq!ia0vp^3xN0o2OE%Vcg(*9q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~;1FtGgfba4!+xb^0)p?|bH!-0>=NnZ{;yDAvpV5zfC#%l7r zMg!NmD@02Dtld|nt}@y=VQ-=;=c(uuXT%*ozUn<#U8Nqk#H1-??T6jf@Bh|anyfnE z(dPH>tIb-3h=KzP2a`(!$rOhGO9z8v1Ca8tU!(V0e%|@#4}bg!wXpv$ zAlBWQzN?k3+407m8iBGhx%P(zJEr`Oh&<+II(_=|hc`FRZ@s=yfS)g}O<8#-yl>d`6m|J%Ax^1T4|>fp|J{n7{AgBxzkgcR2ip1f?|&OzZMe(cw^Tc+Mks%odF}hVyUkPQHyyoR z_ci9NX<@uCOGM}Tt%6~(93M`UY`YdH&NOG{@oTfT+BwWGi+;O^TU+66t$c;5gOxAP zV~kAKU(T|7%9G3ruoNN`+1_SfpKfj_4AW_9r!yj@pORrNYe z?eTejJ-ZC!`$n00-S(`@*V<11=%u*cWI2!vRJ3fywr?Vd+aGxs@9ME_p1vu*AnEX{ zyq4>ycvt6t>hoJn#HKo~fBl!-G}<3lIUhb%VzT_7ZNAmF#~ZI5X9%vj zfAoXilM8!(vBn=2@PG97cZ}dO8&>(Q^&JBGuQms~h;H!P`E*5<_=4{>t~+1EHi(o; z?GsYitKtAl0??EIq267|ikGjbwd|UI=<8Aqx0!8*+}EdT{j_~v-?@p&O#Xh^o}Uu^ z&m|vof300^ShME1$^p3}-&OAI;gkF?^oA`{XZ>%9hkNH8ogOylK9}61Epm$)th1tS zoGQQUWg(hi9=^Zi@9skGHmi4+Tkrnf!t_pRHAC?&voOYICPqNw&zEk7%{z^*GM!nr ze*ZI}gvhjGS_kI%^@KK9%1Q!N?&J5FuCO}F;L0k0@po@-zi;}^_1~o?wEtrJguZo6 zn-8g1tOr>rlUUXKf5nEW2E9)MZMP{LsB@{Xm)qaA$NtldtI0d=AOA7w-alWDzlUGO zzhc%_U}9lZau6Vea%q^ygf;N+33hQ57~Pbr{&jjnv0l--1|}VMedas;>-X>$&#(RJ zUA$rb>wn?1cP&1c0L+0$r^iQiAOHP>MdsM;S8v|rsUcY~i+>g&CN7P*mdKI;Vst0RKTg#Q*>R diff --git a/images/main_toolbar/back_disabled_osx.png b/images/main_toolbar/back_disabled_osx.png deleted file mode 100644 index 92ef82c9bc1887b66c70d874c981dab9f85ebb25..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 350 zcmV-k0iphhP)J)r19e1f}brwd!Qs0V20I|Sha+}8+dVbELD8;DpgTwN%q zl|eyw)M^ucFpGgX=lc%~2ViC8PvD#jkMH|-6h$}V{X3Moa>kgX>-w4Nx}~bBhobkh z1VIo`jPcfSoDHQEcDtRhW|Dw0CK-lt?s?udA;hq48%)!Lx~_jN7*i8MHk4Ap7=xy1 zAj|TUZ2JXq9AA7*ttbjek~FEgP>^LA>-+uyAv7!XWI<6BcWvAHRaJ#u*B#C74gjJ^ zw+NxrJkPgL6g>jK>%Kp~L;wKL0zi=@$z__R50+&;55w@Qf{~AD!Z3W|oWISe{mg__ wandx+eOZ<-qE)d}0G#t<&iU0M!OH*Q9olTH0jWT~FaQ7m07*qoM6N<$f;lsqA^-pY diff --git a/images/main_toolbar/back_osx.png b/images/main_toolbar/back_osx.png deleted file mode 100644 index e6e7724e9aeaabf18c8e9ee2439a9246f8116d30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 349 zcmV-j0iyniP) zKmQyN5fN8WQBj89zkd_dLzD$_a&nBEoSZ4*;^KXxqM|%PLP8AO+}sTB-@m8a0+_2s zMMYgjMMW9-`S}^x+1VKw85xOj8-5Ga)YMXuUCqP8!@$hUOq9VySr8l?to88WLk=Du z9+F&*44Cjqwzs$M?CtG6sG_3s7GF{%+X4m#h8>cUk`ZNPWpjLdd~Pr?G5w*o1q=)f z3~v}17%DtGJPOOp%MZ%P$h`gc?;lkyfC0E~JUu;cGBY#(B|$GLAfl-7e)8nWzVh<& vcZ7-xaxGx^|Np<(|NsBH$+BP+3@-oxdJ3b+(AR*|00000NkvXXu0mjfDUOx( diff --git a/images/main_toolbar/back_osx@2x.png b/images/main_toolbar/back_osx@2x.png deleted file mode 100644 index c56d5126c366472b81b8b5553e3cde15fb1ecc2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1578 zcmaJ>dr;GM91p0VY*Q^`WXhH@1*a5XL=KqF3U&@OyO~9tm1EeY zOX|4<02s84w`EJ&X|rgD;8rprj56r<%4`5gND6uxM;<4Ec5V^x(Lr~Q9*01l)j?V6 zG&Id?;9Puap~z(xrrR8ac@Bz&k`lp$AT29!a}omv-T59L9n?X+dTIF_5+e}U3z714 zP@hxTX%^5Rh#aU^s$mDJ!ayyh#MEl7RuvDbP>euO48d?1qiBMlQ55WdAlaJ8I%%sh zrQeo((?Kpt^3n(r2n3V?Tq%f)5R9TI1XUp_6)YoQ-%^jn1YwVFa#(|r^EpJ`EAfH{ z3~6NSf?v`>vZs9^xV>p<1ByMq{zS<(ohUZk!lpRL;ZaAg}n9kr!0|U z@P=KX3Cw|$sGWpE;lLQi5ip}sQSySTSq5b^q?UpZ*+nGOGB31HSS0sl=r}MC@?~J8 zIFCF>qC7Cj#ko5HAkt_yPPYY{Zf`%n_@qVglQ64iEZj0UQ^t9ZfilD zVnOnfZPuIfo<=E0#L)iu(;nq=VAqJs)6*42O?TJsPCfA)+hA_ZeT*uvbao%xQfg3) z`FKd@{rgxkGNLYm1fpAkiK_+$CnS$tTT_xcMX`r>uB@MW!@Bp+gAF&1oJ-npy@aEn8o#^DFr!wx%k5ka=jnL~r z5pecdJ$o&8)$9umiSw_PpBxTkC@x7f*ZJh~PT-^VHt*wAF`A8M0#RlAV}JDz>-n3` zNfq8Qe|9ln(-;d5y#Vz5OQ%oz(SP#+)=Y1W>^bkBwu3!X{4VhP`jI)NxlxT{_Oa=4yT0 z^-&uSHFvZ)tM^9gbNsQ5hJ0ee!8Y&NTMv)4+9H1e7w~NLr4_aF?wqn?&5Z}*SO4>H z8!>NN-O9!T)83dnD!U|Q-}$Dm2{d}cVAZ7JmhE-l5@PM;nR{)wT5m3|AY5g*yR2o{ zvYFR6ovW+3>>|4EjkHC7uzG#_!>@uVNmcvQUCpbj%DQv+KeEJ+iFS64o%po4XkyYD zB{;t6QBx@;Rz~bhp8e^SL0_({IXh5MvNmz>IABMXGeh+ty({$hHk;CoRr-Z%{sS0w BO_u-w diff --git a/images/main_toolbar/flow_osx.png b/images/main_toolbar/flow_osx.png deleted file mode 100644 index 261a8ebdfecc8c39a3b8b968a2ca1a1982018da8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1116 zcmaJ=OK8+U7>?9O5fq_XtCx;Zq&{}@aAQqqTy4^|t8QD?g%-g_Hks|FHJLP-nzV|P z6-7a*UesHQ7d?mv5ftjH2c=SrEuQqE;>nZfMa9QDS-aJPYhW@DzVG`V^Uc|gwp~jW zuU<@1)RJVYnkI8yII0(t{~KTaLZ(%?r3>#vIqYjLq;?u83qjJ-x?vh>#z5aw*hEoP z>&;9T?n>>IbYw-f5EBh7hp;KCDIPeQ-U~6v!fw-+=?`NMXWoeXv&-4LZIZGzAh7uprhzU>&hNDUj)su0+=1F++nA1oz7H@1(j?9Y8@Y1VU7Z z=q%5HMls3>LSrMp8SpF@V_1&iwnR8lip3m*hDr66}2qt$1+Va{au3P%*oo` zY@0~Km_TzFF3N@_m4T_$|Dl#OhxTw9{>k^B!d_;;flL~DsNdDe#pTw9p&UtZp@xy0 zLFh=iiye7{k(WmfP?S>FKtrc#8_4%IlsKuBl(app**Z+BGEG#XrfEnD+ni7Zk=wde z6*#UXCMx1KMM(%TKEVrOGhgPaNbk3xjmuo)50|gV4eek#B(e%!^C&bDF0w$WY{{&c z%eF*Cy;-hNITyAfmm$e8;pP5y+2teRpl~^7U9y=oKeUPCU1IIq!=0Esi)Tr7XC`=+ z{a!4_t0MDis?Lv3-x*qPU`I0fzIgxG=Q{0pUteDiJf57GICFLBYJcR=gX3RUUOsrE z_ROBv(T3XP%kNE&kFOb?D%8hMG|lH%9PZHuKkk1tHFZ9Fu}~=78@;fss-~tV|MT1D z;kQ4={7(}lz>s}$bO@Zhd%f;xOY!Hs*p)A>x$L@jJ63;gKie}7ZtWNvDJ~M-`IA@W zF~6Rgd2y}%b@j&QPQ$UYH)=OgE5`Ccyq3#yrw=}v**&t1s%EMFm#04Qm!>y`?>*Vl KrrvBmT=)fV+;s{7 diff --git a/images/main_toolbar/flow_osx@2x.png b/images/main_toolbar/flow_osx@2x.png deleted file mode 100644 index 69081e1e02ae824d32146df2beb1b3dbca2c6510..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1537 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%w?G&5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT-VtFWlg~VrW1CgG|37u|VHY&pf(~1RD?6IsxA(xEJ)Q4 zN-fSWElLK)N18HBGcfG%TLe-Fbd8mNQ6?}_5_4SglS^|`^GZBjY?XjAdMTMHRu;y_ zX{o73DY|BfDTcbK<|c`{mdQ!xx|XI!<|gJA#-_-g{uU;$XqSVBa{GyQj{2W*+ z2*}7U$uG{xFHmrH2FJRBMtEjkN`8512T^vIyZoQd# zFz=CpK-=-Yw<;_3;M_BQ*=HR0|1oa0%4sjPU@s-BTK=SHM|*<^{gK|CvO zxz3uXBa(Ff%=hY?_5-U{HF=xyiRZC6FaXj0>_-vpFH552MP{FE`}^81c}+M|`?-b5 zh0TnQEbL|-Nimwpr;==w z{f}+?-QRwu_xtC>KRenv^_K9f90r|k4WWBHM-pcrF;MFAYkmT=v(D)f1HY+Dz1;We{And~<;pF7^)+$^Wc(ZGO?9@H}k#N2q+UbVus zcJ{`2u7qC3;AwBae(j$vp1fAKi>YXCv)-3>-rouFGR?`-_Af58?K$zw`+&mHoaOI| zcGi4*fA{Xab+NxImo=;vT7C7^&ww*=#tr)Odo=A|eR`r^l=R8JJuk`U|IzD;$&6cf z|N30{_2_G3jdw@iJN5iqsm{Qp(2&11o{5J+JM@v`$#%i3phDTx)z4*}Q$iB}6AUw4 diff --git a/images/main_toolbar/forward_disabled_osx.png b/images/main_toolbar/forward_disabled_osx.png deleted file mode 100644 index b62d0e76233d0a6aec786f2d7d278f7e814f8077..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 380 zcmV-?0fYXDP)D~$iQrj&!B^eEItDZo!Hn2 zICaz>CrlSwK%DHC+~MZr<~#pM?g1(){sbZd5y5rc*KW6KZtg{A8&Z+TvaG94r;~V| zcf&bnhcsIzfDq!`ahxYz*C)MR?{Z(kNl{Tz6c~nqMxy~$RfmhkV&?n)U7DtkNs?@z zOOC<>03gdUTCEmr+lCP0%yFEDebST)06>x?)a!MarU}kDgb+i^vSyy=-Il#A98n&| z*iV{Ttp-(9Ps1?eM-${}x7+JDj;ETYO^zlYA~422UDurlLGS`#1YmU(L6&7`Hk<1x zil&;TjR3su+E}T8h`##${(LYPJY&bMOWAz?@p$~PTrS^<==#uAQ79mydm_5{%`U3= a2YdrY+p0wQ;afHU0000sFlemo!Z;rIgAkVMhg= za|A)agb+8jZSSHel8XvV(}d$VkWwNH!wc7SpR+969Mfi0006qKgE0or^AH5VnGoXo zm^PCF08kX=(8l-uLz^^BHdrT8|96!)Ghmt7~WX-0x!{B4I_iB6XX|c5}Qb!Ax3QX{E?HzDJd-ZzQT1`YV zRJutti@0gTFz0Y_s7whKH#H7}W{!u5Ox(H01$0THCV+R3B401h--G_lWpSmmSD^gGP!)gOYsb#qd7YRnw(StV`V6M z{n|^+0st7dk+tOrIp#Fd!8v7A2qW`3-69(R7A*9+DMt|_fOe*Ub!njcr_VwlOKYHP zg&8rs^-Lj~>gSnEzs2V87dg~4v@jW5;3Gu^PDY?WpR?HIA$=NXST8A_Lt+>Lhap0d z1{!fH$D9G`Ii3L(GKJKEU?@naWvD_y5Lgn3A*dWiP#DFfsG5|^Ndy5$A4s&u)A^*; zkTPmZylJ39L2#2W?DcwOUR=iU1u&{st6>C#F-$5Vq@MLIf$~XRo`kRl1LJY~x0W8b*5rEAzh_FGYK7>)i}& zWjtI7?-1*epAaUCxqG#t5K#1nOy^m#C{(e5bCft4mtZnzAn}WgW@%EPM36-)og6nB z2qT7~I-O2$R1!*+0mBt~BqgllWn6$w@GIA-U#MI(~D`*O#lqy0E!J>$)L0OZv6FWdXZ%5v+XIzGhszs)Vq&zzc6QguvM$vOz%QY&8hrw=Sg8{ElFy;4|eY~-@JU;Gokz3 zW+LF<)cZ5>xZ1uqabO^Jb@JI+rQ>%3G1|yf;Ei8%OZnhNAaPjT9V?Z~oa^?{tExMFhu zGoUH=>xC7~j?D3;wQ+$9_OuRprKKi#rQBejd2D8NZ2(%HS|5BpX?w<;rmQ2oOVW#G z)s0(mb&X<)2I&6SjF5u+Ju^>)%iOWP_`QdN1O}xy{s<Ta^ETi0za zjhbCu_OYws2(i!1Kb`$(M!#^UiL%7r`rEDgwk7|>ro6=uA6uSQHb!@8i1JHocO5+) zsV%#G{mh?(e*clq#YWR>gmy?7v40ZF^&?{A5|*0H1S zKv{HL_u1B|iFX?=(fpP{^yDPQ_$=8}_vG#5trrL1Y>Vhj@PBjjm!^U?nb7;g^RkW4 iyFMSQ_VNC{24Ebp=eQr?AZ=Ud?`|?$3`ZBO-tr$zBwq^v diff --git a/images/main_toolbar/fullscreen_osx.png b/images/main_toolbar/fullscreen_osx.png deleted file mode 100644 index 0b3a1d49c89217d2c775c4fbc61f200f2e76b750..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 563 zcmV-30?hr1P)(IlVg$6 z#i5JPO#+gklsXlI^%+Y{ZkLv7yq5PUk3xAL+~J;c&-c6Bb1rbJ|6U{#c&>K4eNwGfpN_}l zN9A()8Gtu?hM_TK0_ycTm1P;8=j{QO%Ox~TyWi{emH-|Cc=s!p%jKwLS>#IpKoA7P zj%0n8rgy6&u2tHeRW1OcPb=<{GO z*lWI`C@>7eVRj(4^w)pF9fSUjS002ovPDHLkV1i04 B2LS*8 diff --git a/images/main_toolbar/grid_osx.png b/images/main_toolbar/grid_osx.png deleted file mode 100644 index 986b5cba1db991c362789d395ef6433053c24418..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1050 zcmaJ=OH30%7+x$OK{VQM#0_)Y|RxXrQE)CN!Sd?hbSVyR+_2Z9xwN zFH$fXOJ}KOk^|9O&qhA{DNT)SLlLT;XcFT)8UOwS!@i$TGC`OHk{zkpW6&i+c53 zB31RuT&;R8QdKTXl40G;{p+$TN5nzya>u%4vtxc}635%b+S=mJhvZolV{#-__?-E@ zwH5YwYYup>zq?;oTeGh-A_y-ACO0;g!RFJ&FuS@Q3?@3h|>Nvs@dZmC~ddwu!Q zK(Y1w;Tiv2asJkc-rIHi2N&LcP-d56EyoT%=$EAR@8SA}+Gnxm=-!2{V)5m<$F*?H wv#zzgzxI68e|+KV)zvH9g}bYt_RLToYURv)-@WIX-`v+4>lu=tNTaiV0LE)jY5)KL diff --git a/images/main_toolbar/grid_osx@2x.png b/images/main_toolbar/grid_osx@2x.png deleted file mode 100644 index daa81e6cc423f025bbfad5b2989608e8d2701ada..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1480 zcmaJ=d2AGA6rZI?mZO1)Kmnn{v~?7jTc9+wRW!`;Z9CAN8D<7| z%Ml4GwFd-(9D!;Pq<{p7K?N0Qg%&~x7DAN(l5&aB8ld408vVBIB7YFRWWM9g`@Q#j zSIw-#X^Dfz3_=hjF+a~=1Wz*d*$2SAq~DWjc#O7kORYIt$chLCK(b{`1ZaL(C&L&Avpzlo3%uCnyI=gu}78dbCZe2>eguh1zCul@5p^U}}pE z3DzT&5(mTFz1&eu5whWD8VW3mQ0dpC#bKaY`F<}3|2Skt=7F2_IGv&ghc$8IA(5eR zk#$QrEz-0ILKNUaY~0R^@Bu%`1sG4Z%MG(nzoZ0y!Q(7hru%9GkD2mY_-? z?puMr`>@{-srI{6)j{1B(RY%iG6jjzD=A>AedZYFOLwOg- z0YeL;J$dGp7jR%j*)51pCk~vX8)rR?h>H{m;h_*iNiLBT1=y>7c=@^f_4X;0z&P|c z9UjP3h@@CI9t#PlD8S%?i{{|wWMzRATpl-v5s)GgYn|s>DK3Kj8M{6k4ET69T0n*K zWWd4E)@uV1#C9p)pIsci^w;Je)MMnZlb^H}=H(n)d)w~%bk(|@JFirY9yxxy)VRtv zu=Smd13uP;`17zs8M>AwOQcDMPJ zt4;HpI~zS~4z?ss+z2*IEo-}%(K#ZQx~v|0RC_S|R^5$;3%{0xSZ_gnV8^ufd#~oq zyXiUk;f*6%^|SqxuHc(aPigyh|K2uGHrG5c7p=XXIwYZ^d%6E^cX@jIx#?TBGr{3) zZHpQnuRM3{;nUw+A5Te5K6;^RLZ*G~^t?ZI)PL47!ue6BdVV$5k?6y3V@tDs`gq95 z+PY#}jXf=RE#6j?#(;!aC-8-@!M{;mTpQ(+B$Q`w!NlDj!>0<9EoE@5# ziTs1yPtY3%*v=09swvsSHE+GOEqO(H|9)AB9kIPv(y|vxK>jstrVD>9h`^PfTj<}P HGk@iO=`|cV diff --git a/images/main_toolbar/help_osx.png b/images/main_toolbar/help_osx.png deleted file mode 100644 index 87cd400804cf437124e7a056fb89605028d51023..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 536 zcmV+z0_XjSP))Qi8iz=w5jWlOv-oZ%dPpWo-e4}QQ&{`;`w4@9(aw=C<15aNoa zY3CVZrvSLF>mErd50}g3lhJ6j0Wh}NQuF$OWmz{l=gB}I09947UavJNWqCH6J(^4= zdjM|#iuV*W8jbOIJU*RDrM|hYs|*H%n3PhDL?RGEbpKk=>2w|{igE$KdjNunZuR^9 zbB19+N*VCtJq3!QJOl6)04kM=S}Yd#g%Hp*4Vg^lizn|@0N}?E8Dj^I-FCG;kJf|ww*IX^q7cV5z&1j3jU<-kG&`P acli$DL%EGtfHPwN0000l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT-VtFWlg~VrW1CgG|37u|VHY&pf(~1RD?6IsxA(xEJ)Q4 zN-fSWElLK)N18HBGcfG%TLe-Fbd8mNQ6?}_5_4SglS^|`^GZBjY?XjAdMTMHR;G>y z22K`^CdRHV=B`GDhK`Po&aP(WW)?0+#-`2&ZZI>j>NT-+bTx7XDhFybbTzSbakFr9 za&? z$S+WE4mMNJ2+zz*$uBR~1VswznT4UDi8(HR zL-eMQ6K48A$LNC+2U22z2?0|ehzU>nKn^_fq~-y0Oc5|^^p{rc0_M0Uo-U3d6}R3* zMtcMoO8kHSY@NCUF@uKZp?970!;ze+R;x+pjb z#Byxykb^qW0{x@4` z_SsEdW~!?TCUc%(NntW#oO$5CuY>M4My}STty{Lp1gs1>KGo}K;DN?s_QtH3YYc`Z zzu(XFNi&`6S6#Sg`^JqM58LaP2?cc2Iz&g`ZgN{}$(wOC%amD=O~^9o&I6O?&pK1R zHl`R!vOfFpi>)K&Xx;u7JTJcf3UgR}`DH|CsOV#r4u(b<6{aUON)r<{M)>f@Fu(cn z5@gKu3M!xauiHbC|mf3<<;xg^A#s8E-fwXY;0`QFWYU) zq9nOXjDv-zySsaB-TwPde9bZYK2H%{{z56J>2HJNIh&A4;rn%X-(32{z%$Xq#njli zn58JF@c6=dF~0Ul1Bn!GZ||<6=@$i>K5*$bAK-o98@&8 zS-Ou3>Hk&|%i;4&@1Agb&WsrqT+j6{DXBBn6bkR!y}NnRiz7$psK0*w`f^@wZmjyv z2_c^y%}h+5On#$r@#00tTl-i~$~+Q$?%TU+;^mh-7BYR)gC<^(Z}Tb`fsHq6P-$ha|g?%Y`BmA@^v>sc}Z z*;^%a^Co>}kuqHIDBw$A>7mP)FWbe`_eP7WSo$4KdQ7r&hF&-3?|g5SS?n@dYeUuSv#c;miV!!TA*+@s{ZfCW`OZH+}c{vMS2rKTX-zP8X|HWYX z{?CUt`&iigJiYdKm+qZS?@w^)aIX1Xvo9-0JbQy!(B8d!tc; zop4&=WZNR{zv_!GzIfX8Ba)T-J70;t$F1|tY&$MpzFZu2iDiTEYS))Gp54={7})nN zpVam0$)qhU4;F}?)2a}DEcD1(rpjsc5@Q2<`~AsgvoDK$JfstloSmQF?>+0lhYuV0 zew^9fBT~sHaAHTyy6-{joo?rC|E;Wc?#ic6MZp>(Mhi;Pa?EbOJ8_~zUisT973s*v zUgqarbJTxUH24RpJCrd=u;wtBuHSwj_kpu&%7gi{|FF0FIH)NIPvGp>G@prwVUb_& UGAe#U-n z(n<)#jj9M#;KFWj8Pk9XB*ezF0)hi4#(@i$PMVOm69=H;Fu|VNrf?`6uw=h~zu))! zzVCgXPn8DyH*eg%k)o*0g#n{X#;*AN@(c3)tEs*r!!B%A@emrtO)G?y=Aaq`1hgB5#v+?E}>?;FtDQiuT$Vhgmqh94;{m0q%|ka@h#(qIXK$5ndS zscNwVbQD66VZ@}(rzDV-89pORLb?YC951q*%<}0Z$19wya6DLfXrdN6qe|JxuV|5# zO4l(C6qao^n@lsspm2=kWm#r9ffa-#K_sIoA6u=YAMI&dFkobdZh&3ngV>@~Llan~ ziKojUctNqaYS@of5=BzRwyc2V8IJY5IIbmhgv;=~8*8GY%2WW^GK|nfXp{RG-P0zM z+fwg7YvmqCye7dN+!#3IY~>WOe1RwJg;e*Zi-n^GK5q{ z=kjeEYjL%-Xc&4<5@bHl^JZ2~agv-e^b{v#@>G}DtZVl zjKT^+jdlf;>IkE#jsl<$iJ*Jf^&QlV_Q%(=9IXLEcM>}J5P4uJzlyttzR2ZuQR4Y@ z_G57`bDhu08B3gD6683^FW_;Oh{Toef`rJ(pC=&hE{1ktNr)x zU0)*Eu`O}>-j5sBcXWzcGI{ktqtW;cEM7k{&m6fkSv*taFZGxo z3I@N{X1hDu#i-q}J*AD-Bf8ggWi|76w>A%$T%dJ~)A3uC(&OKWA zeNYr-7(WkDL`lXhjfq+hEz|b)>ppf@PPx0i6U-w#G4LaEZ}+`pg}Yt%7VkJI zMHw9&GKZ;2C(&q({76H{(jjHE)EK47KGZM;GRvumve7Jc>^v_kG^?eSW{^ zdus~vXQriQr0R6Kw7gu-3s*e;rVNAMBK<$>;PRN}D%R%8el5bQKxY?aA3*Ygd;oX> zFIFsT2iZDZQl(T_tQC7^vw|En@^KwwG^jwdPM19+s_;T7&=4O8NFke{ueHs9NTSV9 zWcJ`5#R*EJ+?WdH#_|h=SgF8>h8fe5>?jKffpUcM#9X{r0H3N#0d+AGZC1H&HIm>LLlk zZnryK7OREkNXqQQ-3gBSVOj!7D((+#&TE8HcpR-wCGxA5$#0&-b={0qa zrcUf0)=*P@W4!WH)wua{HlFEB)}PAF`tH+~6LR3^7W#1C*S6A?`!t5^^M#QH_k0@efL_- zbMo?6^A7m-U4fig-~09{d*lg~+0!P`$9CD97TlWi+4=73sbf=LKY6)U8P`7K{jpn) zNaq?-57o_nN~pbriraKYN6jp_*!py9^Xdx+gDcvDIew zoOWIad;WG@yD)zEOJ_!CZ2gF{0c_K}ht`*#>+HSG^(evhYp~v{PxP#87=7kVs_o@) zZzy?pN%D!#=K7=y-N#lkzb;M>p!&eH4{J94+jeux_ROlK`+pHWKbrga;_`XSH!HsA zpx6W5+;Vzc?FnJem+q}@drtk^Wh0OG?&#Z4m$a?uVy36Ps>zg*_T+mz{+MuU%)*q8 zvi%EAFTs_G`nse$%J5>ML#-xsgW1_pJObqxYAVXnUqS^Wx a`cb-yy|IQ<)Y`WAzc$a6&+Tb;@5JjIOBbzk^HZ(>lh>(1NG!!Xv4!5)xja?zR$_;!7R~&+pCKo`WOHXAByp}da zy4Y(XNTMj>mpgyv&5U*zZu<8!J|8Hh0GQ2YkG5^+yH zHICz_s{m3;q9~ddMbU`$`+dga@wxil0DvsZwu8Z-F@a$i*G=GgURhO@ST2{^2}Yw4 zp68Vp0TzqJCeQQds;Y!-+s#DNWH=m_VHj?@0NURa2!Is0@5p}xUVt5Z{q^7UyLty* WtzYDG4RoFW0000wSwSLtq0l-5bGa~JF~yz?f1R=&6X!==Z+f_ zI0gWKadEM#6lO=9?`ThEO=CY^&1{oswVqC;a_A!5MgVdXWgx&f3!Y1)5V)y$VFwWj z0B)sbou1Zf5~N1T!o{5!uESzw*Z>e2<*?$$e1ZlIM6Q{XLH(^qA<%4+L1{t_qOmH8 zJacS`jYuug>Wn4%M$807%>g4FQbvJ=pmES)DIo1qhYT9hD`n13F${r25ISE54LhaR zB!NoGMu0-DkYhx6C@99bs8A>t^CCbVf(l>+g;72S#iRm(6hXj|2V$(*OgYjNRm_Mj z<|c#kXxb`;;i94YhN!!Q`(!8{&^L2&HFB#k>bq&?WBK}Fb&HnWvBQzYor zh#ROvS_Uzm4u@c|YBVnullGBBF)4!`xD`gZ2yC%9;~GNS=@jCBH(raj>x!)eoI=>C zLYtAPM^3Pd%;fIPhMYjg8)>4=%oGJLP*KK03qjIxDjCFl;hM}QsZfj{3W;36SF6No z9*WB4a-~`%7D-e*zEFw8xOBXZD^Z9szCs`ui5ViQ7Dy0Ou2iZJiCU!QBdE~DjU(+e zP8tc9T{B~Mgp0kAD^=PEoTh9#iYjn*KvEt>Q}#T{3Mx}YU}&0|G*LzNFlTv&qg4?$ z^CH3&W1}qKP=2N6*V)HVOlabXI7T66;9!`*$dQPIJdO}Ua|jX7#I%wC8sVE>$=h&$ zG7=^RtIHLsL?A$NFoT%m42OfFgn)yKco?(rg(e)qMG`Rv!HkQrvt?dsA(x2hOXu@J`r~mAzi^ zt3LdlfS|)G-~ZMx<*U;{?rZ%Yc`MFE#qNNrKh+)R$-mGm6i;3iJux@tjLJ4XLT7sT zP2s~XetuA2>72FmGrw!OyURV4^p>Tl2ND_%fzx}LAN ze~W&yC~{hqZx>vBdS}42Edk-lq5gNE_3gO|&XndN;N2zn#i z-D+RNcU)E@#iK8g2e&l;7%Jw98|L4;(%Z7B2dojWYUh#Z@bx|j_+*v_sC=k=p5C~z zDv7;ub7jjPqb?0rcN?cJ2q~T@(XTn4jZCeG$r_m4vf0<*SDg@|X@WwI?5q3tMtu7h zOSQXG8%Zs7HQECSd$;`Pdi=%N>~NnvKmML;R*8CEM(4@4CxeS;BCNLC8Rt!P8W?@n z>C-(4=O*8qT_yDC2&Dztuqepja+%E=dS-c^+9g) zrlp-?ReyI;@k)OXA68YGZeK;w&q;bEkEsp?mAq) z_qV^jL(ckDeI%gS+YAHsJJ(G}P4^6}ICb#{!@{HKbxj~U1zesui!ug$+~2Nm)Mo_O zG*@Ej)U8wAl^xgrDiD3xnAzZ0{Uq?|l&!zyRM-wZ+n3p}WOsMa&HltD_w5h5d@{2- zW^26Mbd?dTh%dFZKAF=uT~715Rz48>nPYl?T3KLN6)-c}D~U~J9fMh(fMbyK@L-kR Pbp9&h)LK=&B750?WdP)w8rR$*+{&KdA?U!EVM_)-a5vP$<+b2!cWg!QS59BLI)v z+S($7kSm*;n=>^#h(sdYe!u?}$8nD9x}Pbfs-|fi$8p%+-bOy3PZ2_{yRPdyI5@by zyu3V9lY^0w5qWxg+TnTLoAq0-&Sbcqcvo#3>gTaQz#>Qkg9Hxq*KoA6L zczF1Ys;VylAeYPC9UmXRWm#68X_|HMc>LPV&W>pqhIu9dO6i)SC>JG30%Huiu4hzL zy$>J{0II4!({(+)u&~fB2m+y$zO-%oD*)w80=lmIWm$$Oim+`P*=*K0Ca)l$&1Mb9 zaoT-8A2dxveSLk^ci^f8CnqOg_xJbD17HBKy1LpGjYhTOd^8%>R#sNJ0Knt%prxgy zI5sx+t{T^AYg!K=HZ(N!)^QwRcXtsVY8ep##M9~Yq^hd> zp-||<)YR0SR4Nr_j3Jp!eoQ11D;padt+`yzmq;Y~0lcr~;5RVFem-%=*k#5TGMUW7 z!NEamU|_&nTwLs~;|F8f!~O zO8@|@{d~CsbR3MKq6x35S~b-(&?m?7!rX<0SQEqNX8K%28F^P5HO!EENV?5 zj$sJ6KA&u%D<(EhrIIs1P_0(u)nq)Phy{rd1c3w+NFw1-37j%nrV?s!GNtRZ1}>}= zDI{{01d(B;Gzz1UBoz~jdipU0sXQRyvtpU@Q=-t6ff}J4B;pC6R5}&c2Wh2B0RP{O zFG?#zljSfdfR#v+LWG`2jO#QQ&E3Bnni534VFW28=%EM`xQHl83d>Y}TqYKMf)`7~ z3@St*usv85GLK8=k%&YVi^bv5=rj*5iA?1Xe5Q4L3Co7q9Ej$_rqNL#kw;aS4n<^Sga*^VS%=-^ z^TIb?vQo0>${SbOlHN%sSZiO$c9lF&uI$gzo$RV4b51D@Nf!sx9z%VpkNT6hx35d` zaQ-dXQ}r9<^(!#lToB+*-6QX?JJ~7=3yWiUc|kdWN2;II|1RsVeUOkeI5=pt|6Sd- z8L|gPUS5r{)@HhDlwDfOYhCX^wV^^6M_FoWX0~E-aO&WR-H^M)ar43 zfBzL`sd%A>g{17jfmIcc5@>JN@OZz^*on6_v8ldu?B&as&Ip1O@%j9eHBr&ghZdbg zu6CF>U2GbruQtO#P(8Qi-ge_#7B1kEKK!1M>|2!vgJBtm&9=h<_Ca$-8X6jc_U_%g z^kCXN;&;t`uAVQiUAqR}XlqM(G1t=6#H8zz$3o4CCUY~%tXaE^fc65mrKZ1PPG+h0 z$?}EXjn<+cwTUNYcr${J&mJr@$}cQDTYvWKGs=9kcRvQi<=52Igaq|KcVnC!Z$O%d zP^COYF8B7AC9nLpTd!Z4o15G16kdP3> zg9+$PQ?PC%5^24qrDfsMo}SUF%@GlVq0!N6d-C$u%qy+1QFBb7nSZ-nXHUK8xLoc~ z^oua9V8%gKZ*Ons`1p8r^z$7LDU%NN_TT>X>Q&$qtpyOd3m7RZD*DOZ#pUdI>CF2s zwLf5Wc39p;o14|Aa`VgRC4BeGnwWhqZI2fWCXOXLDBbGn>dLE3Z`o4%cd%od+J~b1 zJZBzEE`2W-bSGBY1NXjedYq`4uuMyBje71^$zI=m=n(d9rcL?VP)BgjuR#m@=B!$~ zac$Fg8CWGV@9l^|?K~<=9G~4Z5dTa)M6m4lSM`-g{zn+ggF{%me; z9+>xL{2ZoevUh#anVmuNS5<}siQg9%K61z7H*H(vDE-DRXC&fYSC?vTSXa@#99hT% zz5Y-rdg`f3x2;KJvb#>Ft6`NUa%(!}f;msCjvg&(Yj1ya<@Ta8-ceyKo>?2SHv&8T zgN^y~bKFYJf_>d@TU|=UF`4h6jz3nMzy1?%^v$e24SVXfeyqrj;!F7^&S7C;A%wI5 zyVIN0q0zEC$MgGNcdQs8R-~JFPwpOy$g@8>Ge4@2Go*E`E2J3>I7Utg1cLSJoN*qh z3l!adpD>xRE;lEK96#=E)S|p?4CJ0F=^Wwf({=$J@g_U8i_$lodtZ$^693H5J35eI zyQC*OH2-=2rrB0jAuY<&PJvH~8SSm}OYaS61?Cou&2hfv*M5LBp6@DZ<_@i31{jZ5 zn=Tjey4zY;E=@0H-VF>755IW{$i8ol(p7Qc`0)gWyZhDxZN1YU4Jq~Iv-{SdpOnVT zv;!SqC*#!V9&@fJUAlMZ_4=sO*6Qr6tV6;!84UL_2TBW%V|x;kRI1{x#@W1-1%fSO z>p2|Vk}+ffNIKu%-hQNMyK8j38=bDcw{NrCDNMMg!Q;JO#r-8M?om-uuQM|%7u`>!7r(EKyda_-s2Ld^cJtp` z*HIqXLoeTOe3h-%^MX(M#WcsBn{R|UHqNPp;zUnN+4igj?|*4+ZMEup!n~BRsWHqE zygOI^BGLUi^{eH_3*??;Z^`%{@2(ht diff --git a/images/rating0.png b/images/rating0.png deleted file mode 100644 index ba09981f045dd0ef2303b9885219f934ee9159a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 402 zcmV;D0d4+?P)##%NSrV*bjNl2Y2PfvgWIfs=6 z7)xOlec#LO%js13V)}B5a#{h=BKM-aH&%jGvc`1ZOd{rV^k_0xf>pAn1edQsk0xU! zShCS~rE9Lq)1%2)36^ZM6!sSNq{`^DlGDtQ+gJ-<^B!9`fOSUYFS*2@R14 ze6A#5>(=tN3vfitDX;<0+PWRQ366!BBv@Hd6r#SIP6Ywy&?!P}Ijs@iBKD%dJqz%8 z=SFxIVh_*CS!23Ak;NF(F-J4U+S`B_W0GOztSO_3w~;xTy;vJ85&EWd&5&8@DhVwU@z|mN}X^7HZQji!sTta@5@`ldllc21J(cTr6|6n&eqn#0ECtS+ z>wb=|32=W6X?zsdaxQekxi)QVbY{?@s#~6W?IZ|cC z{E(xu?r*f^fW3Cgiu3Ydo;0599~Kr*mbJba)-2kFuaavmp8v4{l@&909+~wkzyJUU V-#7bx@m>G`002ovPDHLkV1l$X&&B`% diff --git a/images/rating2.png b/images/rating2.png deleted file mode 100644 index b7f594923369cb47215b2d333b24e7b1d1a93cc8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 514 zcmV+d0{#7oP)*l1 zjlc#C6O>Wt1kepKLPp?~r)C5;pubN)r$jMut?uC}#gdgs*q`u^@tJH{7PDGemaq6Z z!L7Nsv-mVkR}*M4S$*H{vYMtzo|UaaLzoUfAMh^*&Ww41*YJ1vCj@E(M2^NnF+nU8 zl{Cu<4PgfSuOwir)7YT`91(Nc5jh$Q#dy|Mr?IOX3o*&EvZ5$NeR(<+ik=TTRi4%e zZxMS|u190xMm-BRIv;eGXCXF8R?ZpI9SI}Gn2tG`MQ0rqBgUAdSvhCQXu@q|j%H8R z21|s#DyQb2S>|Z=WNolSXc_D+W@Z(zO-M}39L=J$Fy{_gj7gf6V^&_6d_nPcM;N*0 zVwt1O-DoV#H_yTi+nr)Oi#bWMZujV#0QYLhVMReK_d>UvYa7DG_7R1}Q{J=WfMF4L zENw$biIpi|hTrfv1`a$m#}HAJT{#MiJE_VF5hVrIZAV)!*y~AIamO9ZFD)jEUGl&} zA^(cCei_yr+J>K!>-?PmAaXPoU(W|t$PSwt>qmeA0H99aH%kv+ApigX07*qoM6N<$ Ef_(AT9RL6T diff --git a/images/rating3.png b/images/rating3.png deleted file mode 100644 index d2c312d568605030f767be1d64c03a659af109d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 514 zcmV+d0{#7oP)*l1 zjlc#C6O>WN1kepKLPp?~r)C5;puf@2DNzhu(~EQuv1BC@_9y&fd?uNu$t;%V`8$3N zaBFVuBt8to#dun*thQ}8Syfd%g_SHqqnHLiU+`}Rj*NMOm+(*c5k=J=!bHh}FkUPO z6r42+jbb|dFC<{CJJ?kM>=AR=5GG0%gmJ93u4RYLEW`w5C0Uk<`to!N+~~N|UGlVg zc#YVTay?2Gigqj%J??a>V<9#eE9H!7_KFc>Ov4<_qGs(0BgUBEtdujQH~!W$N3$1e zg(X5?lv8udEORt_u~t|jv<&tdbFT2%03@bnj%HD_Ff(^qj0w(4G2hNiKI4Y%Mlo`2 zj%AKEE2Cs#Ryr1nw;RGZ7IT8JuJ`DYfce#s1BOLd?uGMmuAS;D8$)y~ZVZkkhZP06 zVQJgOe_4t0W%vXCU|`2nv-c@P*>9s`alchrJ_0|=y6$Mp1$#Lu3+|uvp>6mnxy-!r0b!zK@m0TL`Rv0XSib@c06?SPH#c*@<^TWy07*qoM6N<$ Ef`}mBBLDyZ diff --git a/images/rating4.png b/images/rating4.png deleted file mode 100644 index 2ce6f202ba947d857308c255cf9eef108adffee2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 498 zcmVke6UT{~86g~kF}e0;&b88|cM4PL@O;WsR#@pzcvSrFNa1+g0^ zG#1d~doBTcZt;WBjnl>jL;3rbM+$eph%*x>=4=oxVvjh%++{4lSZ}OlqhT8Gxsim_iSqOW7?5*V zS%9$=R#8=z?7o~%gD<8przoct5FK(a%6nraSS4#r|IH*~PEU^}V9qSKjwOr>A^?DCn$MCXS&a1}y?kBQFIkqI0KjJcU}#X+ zb&GS}8`vhu^V}Nh4+=Qv5JF56jIlS=V2tftJ|#CO_$_9^Ecm2tTez zgCFfHjIqY^yv%W&D*#N>wDUAgj{)reSRl)C<@^4VVHjrs9s$60-FG3xb&@2fRaG60 z&5u5js;a9n4DSuYSai$RJea1r2!h~FQIyrLOMZihKtzb+cv+U^4H5CKw&f^AQQSsR uwCrk=1w?c~M292GyCV_NAfV6~CR1j&HV=jYag z2ncd7G^C`_X_|PMjx=%!rw!L;G&5)jidbMX6S{0b!&;DOFv&SR6_p&=pqFz}g&I_2 zjs{tVxB?0+DM(1s6=dtAdd`AKIKn1l2#kOxV4E?=WRcnAoDp6bGk0$DIPi!Goh|2# z29>5sf}=?az(TGN(V=_{7E8I9P$(Aj!(l#(;XD-MVFCn`%5YqUqVU+mVZ2fL3|X>L zHRg+1$vIgxZIv!^lZQ#AQXb0Z@%ad2fmrfQG+{$bmJk<%5?FMU!Au)S z6YOLpv}7JF=P;3ureHK{G_Q$Gma#%HCF9u$GY{jUJfqQ>*NC-+P6q#n@m6a~O1>HJ zl7WTHqjb!DWQ4fDOzqz7$Z5z#BTJ+V%%u=HN>Z0+1SVRolyjI9uHK-R38Y$-FA?hy zDXtYDA`F)x1mH^%VFq7_3&c`f4}gp3ZFrRu#gr(n5Q&9K42!{|6hgj2A`}Z0LWv?K z3Uy)CCJRlNbin1?!1x}+M!gd&i>3fUlT->x=D1Xlltt2{C5tq}(a~^ds==fut(LjY z8yZbm2`IxFpjT0(5gsYA%^y+8!B>b zG17ESU-tyFc->XN#IzE{^h{9`IRk=Nb!uf)itXWF%Wj$`FAj(l_@EQ7UTx`xsP4_v zK5Q*-^@6L)y*~>`ua8N6!7hhQNY|7sZQz}NJrC#HqGz4EP2X0WHTYURhlb}BWA-jI z^R&Gq@#h1jMEleA!)-yYHZ2eLZxzi*G+o5p;-M*39*<6YEu3k-xFYvpLVpmP8x%Wn zwNL-7t>HK2RW)lWuAFSmPv}y$_rFZ^_1tpoUbok_0j$1+v*)pIZ9Oe}|BL!#_i{wW zeX1($*|>}!O1B-2^N2b!dDDX&mC7+`x{v4X_PJYI&nykYO5;5oAJ*J@IkBN~iF;@M z>>Y|E$j&|j;c>H`j7xtA=hl9+s^W$@^1$-vfbPou=}?*QgU0K7p*b79(pjSea@@0T zZCUK|Yllxv8hG${_u#q&&aUfGlAy?1%U1s$;-m^vhg3CE{L)7gJXmG6rY^d#``;IV z+inpvHG)8vrneJx-c^;xpJ-cCQCZzKZLhpK-P~k4-}C!w;jmePA7vlv7(VEy=)J$! zy?%T0$$#9gJ33}=DHB7ymVx4X-A|@&uj}7Edu8*LfnV(2Y3=j-evCZab8H2-hgBUi z5b9k!qtfr`{D9yGIp-V;kC%IE6Ougamzo=Peq0b4Xb*0sF0Sv~wg2g2Pj=y@qsAe2 zjl1Lag`$3KuETsF+Rk2O?;yUs(?y2`?1${+-^oRN62b`Z=T-%W{uYu)O zzAuh_%Kuboi6ckU*lUaUs;*>k!>^tjSo*`&Ekvl_M^;JD{D##Hk9+#s|$QEWHtX7D@x3U;Fc!D2QbJoqT`bkz`u< zca7gKd@ro6=FHBuq}$pH@vPrMjUiSj(Jg!9*LP#qEj#U3?^x+CPG9tF5!SZ=W0Zut g#a9&~%@vS4^r^Zzc%Nlxzw-~Gj!95{t4QDcA3-pTWB>pF diff --git a/images/viewer_toolbar/close_osx.png b/images/viewer_toolbar/close_osx.png deleted file mode 100755 index 760da504811d15c9af18c573d828509bb0ba8336..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 685 zcmV;e0#f~nP)*dyj@f@jlookix0fZ_kqvD^X1D6-0G&)(>f4B zTo2fD5h-1Zb_L0o8N`a?rQcL*ULn$6}$u~>X}8K>=vOw-H+ zgTd#rEMtFv|68?Moh+3~zs|w$1p=b=)m zpj<9H2L}gpnx-uc4i55QFbF~jCMG6|@p$|-faP`#I$cpbpU=NqUtfRVd0x-n-X7}p zI{N$jF)%OyLWr1}n)(ro#a;r)odLTD0D#!`_V$~#wKdc8JgL!WK$c|?LYmXl(}nTz z@uvVjUjTM_rW>|xuez=aLI_k<1tA2k>%z9})mC^rb!=c5#uLu@GUr_K`Fv;dqoX4@ zj?;7;C$Y1$^ZuV27>1D!g+eQoQb|!1sH*DD%*=dORn=7#1(Z@L6bh{vhLP^nplyI@ znisl^2eAs~d9&1SR3g@uJ`tyWtSLfk!> zpFXWtt1ZpX&sVeA>`x&?;?%op0E7^6A;eoDgwg^(eaeX+KR<8PfB&v;b@TcIIyfVB Tj7lbK00000NkvXXu0mjfV{ty1 diff --git a/images/viewer_toolbar/close_osx@2x.png b/images/viewer_toolbar/close_osx@2x.png deleted file mode 100644 index ef3c51c06bda9744402ae0a5dc49b21b5c6bf8ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2272 zcmaJ@X;2es8V-nxD3bxSI7ID<42aO_Tun$I3M4@yMvz0of8Ro&mw&+{J7_r6_S z7`}Fut&NKfiA1s$g$N>ukv4T(&mx{NmSY9P;EW3;cqEpL>k%zV3Y23~6cDM96f^=w z$4cSn((d9M^CmNUzsZ^-L+lHl z|6zO)t&2+6pil&=!_u@e;yjX2x8> zmk+~1K^zW^0rQ0dA!C{=QtNO;Ekmb$D+%8px$M8>a`{>m!7*(VhHaXzf^Y?fV>$(< z0r-4iS&ULG$MibSsT2B;umII6zeDB0T1*AJmzb;kf_oavH`y0u(Lff0B!dh(3kHdN z86cAb%b9Yi57UQ5r+nngKa=i5i4r?R3YzIixJ-lw6N(@_@4;n1ZZDq|-z zSTYu!BWF<{B1CAaYCfx?=`Er(r>38Jf>?a&DpXChl9uQhMeKv~B$CyrNDvrhxbY-b z91H2D@TG?9?tZ+PJlPCNp+pzog+3Ltitu*}%jwrW!Y6NlA2hdHICbF~|8ryWP3}?0P;o zO_*9>FJkWByVuMp>(Gmx#>dBt&L@quj*X4wYj9uJAN3XHs>a5~Q;A5x#gv4)(XwiX ze|2`Y?Af=kr`%`+l3Gj!ZNtOEE+e}yn#U%VakV;Kk-dXMj@8w?ZMhRt3=4ZRG3j;u z_;KF4r6lv&qw62r2IOut4b@nkJaww=+O<-0U#ih*oNOKlTf4TIyvQeh<{VQI>i~BL z)!3L8Rn~s@w?luvQ>3OI$tbb9XEr~wU3l+pU_!!e51mdon&?ri?=_B7zx}q2k``jw zbH43;P6HV%T|^~}u7fwmzJIyodLZ)zO&jj9qN&F6R7^}v=jh9q@h``+*6+DvJoBovdPUsRr%$_`ot>fQksh?1UpicO zR$A0rAB4Bh(?`3s_a^^h-!zD2UF7^6>MVXOY4yHs3Yb~{YgLsal2&_^@iw}TY%ht8 ztv`9<#QfU2y0}Tlr#ONjbce6+ZoXU1xN&oi`1O73B>e=bE%@73)UoI&rnG3@(bi$qH%V6y3keBLkVeX;P%!iwT9Wx;JK?|pW ziLh*2dpIgC?s08(byDIBu*D+F#uB?USvVkvrE|}nK3#KivDFRZKY-01sf&$+7B1AY zms+#M+1V3;iCYK10hdhXt-1*;baislFmRD%{qhZMLl@XjfX&QQ0t}Wh(%lUk5@%E{ z9{OEw?dB8k#Kk)7%4FdmHGFs86>q=p>I1XmseO^JSx4R8HXm+iNVB<6ckg-WZNs8M zyZ9B5r)T=5)BAR-wy!U-!e980_#cVhF=(-^u%PI|kY(K)KR>@5eq^w@uC=Q$=XyiV ze_XE~nuj)g@7dGUb!Us(J=-8kZ%kNXv46{|%F4=OKQ1@x%9SfO|M;Hdiez;MI$w^s z*x%nT8|uLe(9Zg+Gyay3M1HrxV0ZYd;S0A+>8jqPT(aPvMPaC^&vaV$(6{Q*vZAO0 l>AO(nXCIk4Keo(tBJs;u*B(vEgQosDM8dU#V?jxI{{uS{nz;Y~ diff --git a/images/viewer_toolbar/doubleMangaPage_osx.png b/images/viewer_toolbar/doubleMangaPage_osx.png deleted file mode 100644 index 4e5f241e6a37d3cc469c7b0889f37dcb7531fff4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1407 zcmbVMeM}o=7(dprF_tBhO*VCrvt$GV*SqTnZBJ?`y?$*gAnO87qh9ac!VTIx?hf0M z2&CdN2ul%?vBX68$6|0MMiX%xet;&TL`?knXQ*)nQ4|Kq0?T9@_!cPo2U(1l+`Z5H zzR&OZJ)hTJQRdo{`EVwJAbUJ+x)QDjlW)cj_)UZ@x8d@T;;2@R3jrm}NC2^Mf*+us zAX5V>0mDTbMnExws2X@*wNmXpMzKOr!z6Vyk)R0C2vTf~hzwf?6x0uD_>e_C|KXq- znVajHy$-) zlehp?Njo>V;Lf71RTPoJ@o+e-3F|b1RD+Xdvl%C}xK@in4NQ)P6efa&VyKhecuPX@PAFf{@~&Eoyk9;dqYna||GK1``Gt zKfts`y&f}bO$=sYNdpKNbS4v_P1)HBUrLfrosljoGCH8>(3ciDv<@3-a5`*eo1HF7 zVLc&PVL~iOar2OS18cZ1maC!3F&YfTQva_=pZsGc1i|*O0 z(koB7TvOJ9f`X3Mtt~4b-COv@b!+y=%T-zLmz+G=bgrvwZ_YPa`xoLl))*g+Mt3wf zH}5xJ82@bk=Z{}Y=dwOPxGQaK+f@Sv43zr%@>K)#t*!As6LR%X@AwtOZ5fEScTBdd zu8_aa%ve?5`pO-sy}!Tzjl+3)w^r`{)zkD=#@L^Wi;K@Wox>}0b8{u z;*{;i&70CA-GxZr6Q^DAM=j^g@^5XOot>*gXO`#=u3TBV{>e*sj&-M_;=Sd@x1rnR zv$L~bZ*!v8TEFVWb<@++%>kCRdrnA_bTRz_qKC}L%#3{(9`41TAG$HvvKsrf@$qp6dAhA2r|Zzjm*+%Dij5Jw^UEA1D%)81 zgMnQc`&1W}Gp1fnBoaqQM@I)e4Ts$pcTSPnS$N{j+`R`9`OlO{ciubGvTb75waJ67 fnaQ-v2s(r;)9u5(uO2;{{3UuEW%N6xFU0-^AJhFo diff --git a/images/viewer_toolbar/doubleMangaPage_osx@2x.png b/images/viewer_toolbar/doubleMangaPage_osx@2x.png deleted file mode 100644 index ffdab7909ae968233b07fed139885648320b8f24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1954 zcmaJ?ZB!Fi8Xf{F(1QXldO!|L2d!9{OeUF-j|G7wu%LoS(SRR&NHRAeLNYNKNT97q zpapH+#UECX)>@=yDF~+4u6%_=-Gy2_8*O)0sFk{FMJ)}WR#@onP7vJw@N~|Zx%a;J zectE&JaZsB>vutc5rGf{1!bhma+sClef<|RUpZ^KhFQYt)I9n%N==&;MgXOdloG%h zI)w)000mjL_Y05!LB18*+&nrjbF)}Q>DUUd4%?zLFlY!$NU|6dsvKN!kD>Sj3D09iSDkMOUmhi7ko9oLw=q z_lhwDo>QTV5|L+4isPw- zNQ(1QcsxD_=ZIuNDY1af(3@z5UIiAowG8(>7XMYOSZV|cnlk26RPjO=WEWC2Wh$f$ zuv7}i%C&luGMm!eNarGbd% zG`|bWo^JS3)A?Ss-JT+QlCiQ;)A!Wj`L_3U^B>x@#~vSFgY=pL0;>Hatd}e6od3;C z-aB*0<#KH$B6M}fFMk>tQ}V{LwKGb)``qx@1MKdjGBor+x*PnQZhJI6`}X6V9oM^G zdN=u_Y~jY$p?#&LrJ)C#(q)n*cl;JRHD?>z<63ezN|IvJ{hgcq64HKl^f(;H-S6M+ z@9*zU_79#)<2G!r+bEOx`$^#DFGwWB|E!Lpws=%yh06cMo|ebv{q{9qR8 zI=lImlRJ%O^YvXmYkg`bEOEU(J@q;`E6qJ)?HPD0IqJ=crH3k3)W3A~Ux7~BSNAL0 zMrBIz2gmm3L6L!oJ#R21p(ASfYH4g`h;z~xa!ONwR4v`}!}1m1oD3TIz(4O+t^8`2 z)p0S_*XmgGt$ef1UKVw@^|Y)Ye`|v@AycaWUv% zY29b9emG=tTz;@_pR@IoJyu(5eB@HJ?_lhZ_E!L0bL6Zgi)&-{CQ{6zTE2;co-9*?J_23zq?#D{l&^8FMVCcyG zKOc;A>|)EqW4n(vmP4whWl8;0MZ>;5toqv4*x6H~9~p-R8{IqHaji>)p6{wd-t29& zYFG*3PQ$4^)k#Ot+9UR^%R8SyM{VDjPdDDkVr^HM6%U)5KkKR+E-yGj>OYPp*Ho^b ziJR$=2d|oLLlD;tYo>B{!9)Mxt-k~^pg(7xQ2x3f8XdgWA7N<>j)dBzw3 z2z~n-*WjElhA)XR2KUE{fNyIBtbl(62qDZnK}+vu0Il_nh+cvakoB@<>o38r3o<*KF>AdXBD*ylh07*qoM6N<$f==Ffw*UYD diff --git a/images/viewer_toolbar/doublePage_osx@2x.png b/images/viewer_toolbar/doublePage_osx@2x.png deleted file mode 100644 index 950fd95fbd8d7898f51fb9cab1e344df48b707c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1536 zcmbVMX>8MG7&T2G@soFrhQSx?Zk(MV>)Bu-EmPGE!qCCm&(F*pwQJ&0ya z=KYMv;q0@ett?1|ss7UX)j@r z@2fA~JA3qy^ImSz1^LF6ql=Q#>*DgnSl6_R+v16C^+fg27U4@*W9t&*qXh@<)1#I@ zE;wCzx~pd9q+{orcDHr!D2l8r%(4S$S?m=0OJvH{t~G3WJv=XSn!oHq&CJ>4-3R+8 zjZYmyTu;t0M!RGFowb|R-~alzify{O&XBTiecn)AT9wY4bvV*Kf=9B)tu9#5R+ts* z$Zyc)w;kcwrXRikY}VB|zx^nC#N(z;|IW*U9La^PACCKOhQ5QW>w~(J^&je3K!}I?=4#ybxcNRQ8aCuD9&HHf-+5 zc}4uC41kYL4(|Q@YWAoTm(HHwM(O64KWVjWc(|ta%9?Y_p=E*3)}~%9V2U3`-=5u( z`*c+ql=7nVSRmDQ_orqBdxKok8Py%!ed_`Jw9%%&>Pc-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxOgGuU%v{0TQqR!T z+}y-mN5ROz&{W^RSl`${*T~q)#K6kLNC66zfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD#PU%0_}#n6BP2AO_EVu8M)o`HUDF34YC)x{-2sR(CaRb3oXS&*t9 zlv@T>SF0;YH4Wb zYU*fWXy9t;YUX5UX6fi^>G8yO;9vJeC?82lv$RV;#QQOs{jsXt4u6zAkO~~ z{VC*zpFYr0`k=&ulz3o5z!V8$!m|R91J6vUdB7Z01k5VC+Eo@ZFfd7Yx;TbZ+*=Q|7I_;q&vZ_ub`JLi@GmU#xJU^JTf0laipG%mC zVe`#`zjg5;#m{=D-DY88T)@!ja;T;MQFn>}51ZuPxcaAMySaBvW9DIFp5ddm^=@AH zk*}NiZX~nKKY#p!&$(T9-^FT8m6GORJCNY;+HZNWyV)bnJI&2T7A$Mb#kpGb1gEGz zTy!zx&y&i!E%)EsUzWQmU{l!t(=tM7|NVS#waM>4Oq11d=5^KmR%NSH=kh{u`ojVV zAGOP(X`u%gmY+>4wvpj;4V60bxbWn|f`+qc&2P)Nn-s2GdtEAce~x>Rj@V;cIsbzh zCQTY$2D8sDxSD0S>YmaXO^dmH7haY$NIIwpbt=C2kj!xALyFye=9ftuBc4Qdvzf2H z`l{M){`6H>S1q`5=k?c93ViQsm81(hywmx9T4@z64f?3ivb-rt%*Ii0Ud|E4b!rnc zb;P>2hpqm~e0tM;5y!V>)r~n3Qmz%Jo+Ryzi7S@*zTm6#WY*w0lNabs_crrc9xT!8 z7JvKgH}Tf*A@W<-I@twiO}&w0R-JD)yMD^)r^dHdUw^&5;&c3Y%WIe3ylA^ptuXzx zZNO@e<(JzuL(ohyE6|m(YRzzG~A1o^@0%8Ml@a%x%_76|zoSEh(zx$dq z2SYRRzyQ98Sm`sjHJNxuSWX@wmZf@siGGVlp-)C|4A>yo$S^Qag~Vba z43Vd7Z^66(fRw2eOY{<9Fb~zJJdhcThe4$!v;n|tok5GB378&~VX;cJH|0g$4-`-- z_ohTZLb_1vhs7xacH-EUogrd$X95b#DeHVdF9VM-pu+SBXiz1pbv%PNW!5f_*w2V* z6mS-zPw=L^B_$Dtf_@qt10fF%6{T~yAQ$#vKwK`Hy9Q*^84!)mqOs^yCX2_W^Vm%A z-9;h1;c^8}#238tMV!1TaeBR$N24VtCwnBbJT!PLjRC_jjn1SonN$Kn)upKQh=Hos zeKu!-kLgfcsnshrYH-FPBGV-4y(t9Kw;`ysLg9PEYTdg;5h%=Kqj3&Z#nj{=0>Y?~-PMOHvA3K@>5^Q*zaV1d{B$2N{lT?^mAISHn z5N|x>N;waOS+ERY$f-;i@uYgn*ccU|vzb%`<#@tu6lHJ~$ef)I=`-mZCWpy_U;zX( z82%8<^%VGfLTpbam*eM8XUypas&#rqjbd}Ym4xqiy6ivH<@wG zdW|klqXqr^W~&amMkv*CO|s5yrc7_6=3}^W2PPNb8WlL3XP)u{91yOYE{7EyDvQNH zsceLZABGT^>ZyR(Y=i^B2t!7Br!W6q{@(T}AtB<>&e7q)n1abt5ZQzk5SPkeU=US? zq7W5Ppb8jb$Wa17p%D~mGp+NxR+$_(Uh z5F2`jz6c6(4s$B)oXE)=_|9M4T>;L&E?y$d&gpiqSs3m3Bh!j+yW^WwxrG>%eS?&v-8QO)8pg%8_#gJqN1Yal+@JJ_~7%QHOGsKD^{*r>Q zz=EZ!$@YIe@}*Q-n!I~=ePR2R_H{w0hlUc9Qd6S}l-+jO8IZlby-5-sy{q}rdU3PQc*GrhWANA|*hOx5QPtPimq*_kX?uNX51Uk3QSmzPwHFMB zxvySL-4}Z%Z(_pWaBC5?xV5!aWHy^0BIBa5moFa-4i3sVHLmmE%gdK9zvLDJEHo;6 zi?@yp916Nay4?_&7Dnpm>UvyKT>SWN&0+hWUyq20NJ?=5NhQEYsNH4na`W)vN5&SC%P7WW;h(UPY@%hwu?e_liQn$;7(4x~i_O zE^yHa<+a+{|D<;KM~lU0+m5;Nb8N>SJz8&LW%&faE%=4YTC7))P8|(z2|b*#Z_ibB zuGP0!u6*M&U}wFeV4~#EJtyj#_2kox{JncE&Aq*mk_Apy4r9_Mc3qyNp;d7Of^>&6 z-^W>&drk#d#`yhRS)vn0-vwgwd`30o1`~C~29EIZL_>(x|Ax(i115 zvI3-o^L&4^-TNK-%20{jz2Z2$p9%N;Z8QwW+8y zQ^xw!zs?+F2cHaE-5+}2h+czKi@Z|G#4V6hg3C4%FfytY-1qOPO2_cH{dRl$e);BSyD`)ED}%R% zJ?I#~M=rV-y}YP$#T{Lj#b&rvO**fCb^O?|T{XXK>*l_SK78|GeM?J=%Br_vu&k^s zKCGM}+$a##qv5_C`81+;PomE+SmDJ7xR)armovQ&>2e%7Q=hJRbN<}9bKooRSDy>P zg)W6ZwHGaj_g=g9erHe5z>yY*C^<#4o)fnCWkA^hvemPPXn$RYFn(3F>AJ1(jd`1K m>r}dI_7f08GIRlNtm%N#bg4}EfHd<*0R;Mo@T+`d_Wlo6eR<3P diff --git a/images/viewer_toolbar/flow_osx.png b/images/viewer_toolbar/flow_osx.png deleted file mode 100644 index 3b90b92fb18a2dd47155194601c8a4e9bf8ff294..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 239 zcmV;qv|>bB5QYElpxA*p@CHcnFW{J-7%|{*Br% zMC7wVb*S7zM8$^GUA3KH~vF90AS^Zm@t pQ|3Gj!~2i&7DnOBKYe|rh%1jFfl3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT-VtFWlg~VrW1CgG|37u|VHY&pf(~1RD?6IsxA(xEJ)Q4 zN-fSWElLK)N18HBGcfG%TLe-Fbd8mNQ6?}_5_4SglS^|`^GZBjY?XjAdMTMHR)%TG zDMn^Vrn(l1W)`{@X(krBNhyYDx|RlJ$z}#dMkc9AMlf@*={ImSF?4e^bv83Mbu%<{ zHF0vYaIrKsF*P$cHUyes4AbkGS6q^qmz)Z-I}>O(RId|Wy;jaesfi`|MIrh5Ij~d^ zkda@KU!0L&py2GRpb?&#my%yztO<%Ch=*NLi!#enQ{0O3a}~frY?X<{dg8ne(Vs$Y z(CGsmr4LFcNa+S91Wb$|COj7aIq-axng`50MZjFLYE9J{1_s6zo-U3d6}R5Z%YHPwYMC4t&V8v|&Kgy6 zz4X=0vw{A3ObQGj^x+o6y?|DWzO$=$>3G+^-goWSLcW^sss-O7gZ;o1Pb-Yl7%Un9(Z-K>(CY7k8vDZWAJ>M(px-n8mtn2e!GY$ck z#+Nd-@0q2$7jZcHF8umV^49w@>);gu8T|Ge40!Y({gF8Ey_Pj~jicnNik&gDN|<}D z?M^?DaM>hl_uaT3tPZo5U3^)>Jb%S^1BN-5`W7xW*~-E5b-|3#{1XdmVy~}Swd%9! zmg53jHWtiD;fS@*oFMp0qA`%6sahuc_P5i*C$?=pJi&VYo{j$PuM6+_+gxVUYv8QO zayGW!_V|;U7z3jKGHUq0e`9I3d!ruf#t+A&uImZ!^!D1au)Az`puxB4;@k~ZXFu2Y zzE6$ZHqXiP(f4AWj>Ca-Ht#jus;HJ8?_um=|LgH@ed7&}?Eb1;`!qj-fyIG=<-tU;qFB diff --git a/images/viewer_toolbar/full_osx.png b/images/viewer_toolbar/full_osx.png deleted file mode 100755 index ab8f27662667151fa7fce99c49045fcd02bcba67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 646 zcmV;10(t$3P)*FwQDw}aVe|9~BH zFNOUHg(^rWN)1y)5F!kgRO7qD40PEd?Rw~?4+O&dB%kN|{l4!D-08MO!V8qrn*qt6 zNajYgE9hR7kab-%c-TkdwdG?&YLURqkx8RmC=lgR|lX7jIUEDXqG zG7tm-v)K%VLcy+7DrW(()oPtptJVI=$;k>K1mp4e`W*;@07;VIc^-ztVT)my8UP9a z48zns&wISQyu8A3TqJy90HqXbYioT%h;N$arYy_v9mjbM0EtARmQJT17K_C`%d$8= zK3=(Y!20^Sy|c6Pi4gMB^Sn2vX}%-nR}|%k zBuUS=wzll;?d?4Pa9#JUX_`8KDFC12I2}OgS^=q43b9zM;`=^|#iCs7AP}o%i g{!8J2JKes10Xhol4PlfIlmGw#07*qoM6N<$g7%6rnE(I) diff --git a/images/viewer_toolbar/full_osx@2x.png b/images/viewer_toolbar/full_osx@2x.png deleted file mode 100644 index 5436dd03373e9121c3ef84a5900a14997e82f017..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2128 zcmaJ?dsGuw8c!fq9;HPPk^1NuP>`C*B<4+mh6D;nLByO|!SP{@1OXycVmT6n zh~eZzO$Zl00&^R1-n@KB{DiIWrAaaG8N1UkrClOG< zJYp<85{lFckVHkeS%>T~M~S3nrIZa5w*>=S69*$uA*dKIsgl%sj)_Nn&C9{|b}^X< zyjDS#JmMRt;v%B~fkuY_bdXMxLR1RCWP=nsoynwb0jLm#MusS4%2pDE&7sja5Ckkf zM9i8FmT_W)VT-n~6OWjPqFN4_Y&04{<5p0klancIHk%Al$y6!{(;(@S)u`A+QtN$} z7=(yks#9oDg+>k78O0Kf0p$@fPv3-~(ndzUC06Sf6NROWY!Yk96c8e-RQ9-DYwOV% zM6WUEq*y&!!lsfKY=lCB=`9>7@xspKom+S zjSW$mAqj-mTHcXe$7!ZvFK@^z8lG#I- zAS{wZDq$fKEHRK&MqI?hzf0Yl7R4l32-+o2I0ze(v6vEw#9-28Bnkzgk=QH*CP^g- zjFCxYG^&J1##|)ZyXJRYv?Rh>)4qK>6WHPHR3U0?lyun4@C8lrI2=J9A>@lp569wm z>{zpVWxZ$r6-#qSKm+s8hQEC1&gY~3wov0fXCksz`1kxRmhP%UNUhZ}hbL8yhVZj9 z*Dz~VW!jc+OyM85-FWfpC|gX8baF2I;-~#pFje1LI8i%OFi{X>MfQ!PsW<$3t}=c5 zb^vg9cXA>S92^!d=QPuYpFS-=c<`VoU}cQ;!oagD7bIz^sj^2$%w{S`ChK$d%H>1e z_n-cwxUge-VBq@I$W5oMWdy6$DvFOUbjkgh;k2Ip>z&DPt!6~;nC4Lh1N=ipgC#uy67lN9=Jly9SLD5y0 zsT=|r?_f?#+vegu5W@TlK<|IkV zzqZNO`dYR^(8F(|hh+R>7YIt-sB`1A9 zhsUefZ7>)V(d#`y=_l@;lapF=YHIN2QoUB|-rH60c``jdE-oC;b)0tI-jjE?r6uZ% z@(izpCtY!dECzt|)koohjJCG67kzz_JLR!8rLA4v-ED5Z^`7TN=6lP=@!5T-W1dzL zdgeRyP!CHyRgc)2t-Mx zb>4M?9$Q9B7bPpWck~0+<4Tu+TdNvy2MWHuNb4#5rnBv=^v4>Ywzt;R%VA;@exbwt z+Q;8b?N2_orpqcDf>O2Pyt#?XXs2S!ObFRtd@;zg9gS_DW)i)0sjg^Ce73187>XMjS;!cC?m!6)4 zk-E^y+q2ojT*p<_8wLn&-( zb7f1)y`!mMa;Aq;!^8RR`XRODxz*tAT^tw$G#v8=SFBt}L4$V%c6&50#2nsU*b@Zn z8lDB=OD`9^_avb4d-C7@lkA71Wj`D`esOh5u{=}z9zV(R0B@oyZ%%h3%{6l-FTMHC zC%GF+f4(fBR+bUIJvy^KY4>+-nNwhi|NQ%qb9n#9ex?(x!oY#({=$;a?j=6Be)g9!OGWlv_5>&@ yy1wrGm+56UKOj5`b9BIGEROnbpO07K9C6V;l9#OS`q=h=d_-uJur%aA=KlcVZem9O diff --git a/images/viewer_toolbar/goto_osx.png b/images/viewer_toolbar/goto_osx.png deleted file mode 100644 index 75d810cab5fe386d025707ff15a72fc11f611359..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 597 zcmV-b0;>IqP)X?#;~1eAG1U+B62K_(q{nc%&%GRnPO5 zcXoE1cs-xbBbiKIlqBhWDwSI5bUH8p%0Sn3bA5gNvEw)oBuQEeg5Y%+hM#tKcL@Mw zSqA4Eq9~?CQG6i?!VTATtKDvQaFoH=6xp_YyH=}hT9%~@1_L;b1K;=iQ50Rs<#JF} z6`XU7MkBbci@m))n5OyFw(a}d+uN;U4Tvb!YPH_h>-Ae<7$$-sz;HMO00@ErMNyDW zrvU&_6d?!#^!t67raA2OdSj7|MZ_2jiD-#2_NvinEcm`J#%KFCi9`ajEMsgwv`4i0p3#c`ac&1UoR*49?uvaAdd9rs71OcbxNO##kq=F&5Dwcg8#b8vr(lh-I_cjOTd{=Nv>7 zmCNNXl}e=n;5lRL`y{QY(RG~+!|>Ye_6H)m`(H#4va+)BZGV4%gNQEulK>GNx1JDD j=1=uFr~X}^bN2iMQ@sndivVSW00000NkvXXu0mjfz783> diff --git a/images/viewer_toolbar/goto_osx@2x.png b/images/viewer_toolbar/goto_osx@2x.png deleted file mode 100644 index e7d4e2bada2c852837dad7e83cf9a492b0ce416d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2025 zcmaJ?dsGwY6%PRs5VnBm3X3oXWP!sZnJ^*AU`ogXh(L&d1vwsMGBc4ZBoimYf=Cqs zXDcRq@;k#O%Uq(El<|sCGY{hOc}Al>t~c5i zI+gg5#(T9b>6^_2FO{&61r)~ALmxB`W^(uQj_isI8zhA?FhxQ0l_XYRBuungDdjLX zT-<;okQmcRgpn8s>rogK;jkVQL$CzIBXK<{BBFF+oIh{pefU^~3R0+)QBfjc90aN0 zSh*06ldD9KfUgj$Ab1|DHd$!Ygc0+;4UF$Otng>Ch=L+enxxW6GJn1cw7DcrT5?G< zpilsz83q$h7FxpW6?z-6lAsKq5_lX%8i6+{Mhx$9FA_%zU^Frc#3UjZ6v8kDN(hXJ zA45?Qq=z68hH~cc_)k*zwnZ5U6M}i32_n(qumpzqAQO!qgdhS2C1L^xF&%;HM0!jQ z3v?VFLy>3inxAyhyohN{`}W;TFo$+7$srP+SgllSyzB^IGJJG(zTJp8~wuFcndXX6KznDYRC ziB)E?OojyW^DYjJUp3!7e(h%6H@yTGq} zv4c`A6bf(I1_uwi9dsOzj*jlKfR3MxEUn&>Q{v_2TYj#8Mapa_?|c?0UtQLx4iBrY zt81um|7zEcwl+}IU^{d6>Nwi?ECG>>8C&FJ_2j4k0IsRlr=R9foe;T zV>5qyRCs6N;wI}62_hC>DjHd(eq!SG_buIiqRO`U(Dx-P(`a@{3`u9>&SpL>vi>6G&i^g+NRSW4B-+1kzX}UVcF!m6iDe3pRqNtY8yu75oK) zi&l0EX$&Duk&Dg;SivdESR_h69}Ee@FQBfQXLmZQE`! z#_q_nd`%F91ORWnULUMhtEZ0RygE@R9Ip%&RIAm`nxnf%&r zx1Rubw=n_d{AMDN01=^9tG!heHN_E diff --git a/images/viewer_toolbar/help_osx@2x.png b/images/viewer_toolbar/help_osx@2x.png deleted file mode 100644 index 28865a05ca685549502e713d656fae6dd2b967aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2036 zcmaJ?dsGu=79Sp!haw30Kvx)oQlJcz$%7~wzGa&&o3CREn>jEl| zgW8tWuAU=SQI4gwD-_)x3#^I@?NY>26hW$jXxZv2puj=}DLYZH{ln8aXXg99``zEY zzxz5R{;xgqc#u6qKtYS_%g+)_6_cFH8)g=vpEoxrNkf%qeAB~ z5juo0)oLV^%jT-ND%v6*`%UUzwJ0T_LNF{bK`|Ab%SIF`$QliVAUF%+ad8Y%DRE56 zQLEG}hLQ$T6k%)E{HBYRL{w{9x36b{I=r4LoS;U@NX<-c+SOD5uwO0~MkJYkc=AVS z%;B7M3zz45>#BV4y+>SfhWoF$>`Rk4XF0ewhb$X&JLJ9Mvl=qcH^8y4PEt;5#^2i8 zByk(ww&jVyRkAkH9}f<_z?)HA&UgaDZSgmz*A6;(5BAU89h@)ho|z099UX0a5FC`( zCGxFyOK=RZ?|kQ&%m);^Gpnu@{4F;3-LuK*|LWPFwMMg%cw8->I+i|=-B)#W|>|5 zi9}y-!*Lw?Ag=bth*PV_+$KkGPdCQM&d)!3MpjpbF`l2Usd>=b+1dHvTzNuK(L(dk z_=WW=mVMIy*o)ujdcxzLH)so-e7pJL#d)_);rCYka?Zc;>PT#x-9g8s9Xk;8?ad!n zUgxDX)Yq%oY<3sMKx%qoiayU7j~@v8{>F{TOO1`sf`b2kejq!wqhhO6DizC9OSuhc za=9kr=T9fMCU>lwSYde!O)#$Fm1w69_CNkOg4?bbhDxw))zL!epM{f_5|(}+!EK+3dRP>0{cppNzf z^)NvYg%wdX68rc5^zp-6ckcXQ?P(9Y%5mVS#mmd9@!t<}*gJeJUtMpynK>Ug6<||b zYeT+Q`2NuyC5dW-;pzD=>??bhm0a7P+332_eXzHztnAY10!zuJVp-5B2Y&RSAI#!hi>0)88&c}pY?e8I#vJoj!-NN-&Wy!*S5Js@($mv@s*WGuS;iT(d2zgQ4gfy9GU0FAeKtL2@J@SsJ7X-d!AyG+ zY4^1MXTGp)<7T*YWzh8~iDWsu$>EE_c)4xNEy8(&ZMVnKX`tn9{N3l?t+gd-fpfF7 znQjdCq2(R3o^wJV^>$YAg6~xPidOfbc1LcyGA}PrQ*vU<{{6MQu5tzWoxSZIQMhH| z(P1NS&Yy2{Xl!h3w5UrGIP3&q%FN8p(aGloxcj?RnoU!+Jv}`c(d=^{{qy^dq3~T> zTK3K^tl69-_}|GBX}9*ZRS56%k5rw#KYny}uKZX#Fz-2%DA=4-|7ooH$FI{)4Ru|a z%}`jF>0{cDz>!I}`t&uZ!!8^uvWtklSWTb#sm*>S-g$J-z`%fg*_Z#|ljdlD#<~e* zq(`ff=Hlww@N5=Nar^eGo%PiZandfe&lx513JWi-KCpW=YFg*mzLq9eEcED8K Vk?E71!5r&97cgEji-9ybFfa^r&d2}H1z2d_Vv`F*^uIv%HPXmp_I-a@2yxCiUsp;U z4+ew7X`V~~&-1!Mh)p2`!Z17lFcpx?0_gR6s#>kauIo~#(|O3^{S*=XHCB@(Ia5kq z5mEQ2J(JRIQKQkY9LG7aZ94~mg<%*3K`_;)4XD*>Tb5;Q6bc0lheP!HeXirv2Gr~I zeE@JA2SgOL+wHrV0yyV8oO3Y7P^na&06gpXv~SU9G+HxF6LB0vN_nsA(*iV`&80Yw zrC}HtkH>Ib_j;xP-}iU(`8+u1NYj*Bt=5GuKJ_^3i`O<&ADQp#NQ;0t61oU!}f>c&g_2Qe)~S}^B&JT zyDv6orOQl@nE(K|M66Q9aVu=QXH4gw3HC4caLXb#ERkJDYgjYRP(TPtt0^!-k0(=c z6i!;VHB$iq;E<_{Ph=CLqcDQj3vru`(4seTXaEQZwit0Dg%a^7}3}@If6J z$WM?&!_h`1rPZy+p(DHaDU`c#7nvjp1aNGDRz8>6FNJ2sdm3&oWTvfxGt5yFsOZ_8`k+Qi0D|Ap~J zYg4?{NI`LwiB4k(t{)ojDKJ;Nw-eb6xoEI8jE-vxo~ojWG(BZtBUFKW?u(Grkr=8b z#3-sp1R@kg1-L}47RdbxR6w8-kw{Jw6pkQMe%^$K!=z$ZCX-2JQW1iLiT&j=QCK)E z36UY;urgFNg^e(nSlmERQ`|a^dlD;sD;85S6wcC2JWZ!gsUTKMv$RP|8$qQK^h?kg zNZM@rz}BIOgjE!yOQ*VE!r3nF|#$X9lvbY1{!C%?J-Ud@`mvnsJK{OZFR#}fMRgYumh)-EXL9ck{S1OD14 z0r(}me=q5V7g0G|vua!qhBsRaCBW$&IZJ$-3kJT?y07%~D~#0F2DdueXV1d2cvgnj z?o-f?4g-5%_SgM%%2^SVX*ZNFQG6M`~t}MF6kw!D0F<{V(=`PSk-M>{ohvb0_sH#8Qsc-X8qH}&Kf+9`UHi{`^o%L*gcbUKtel(Y?1 zErjiMUA}LZUJ7+O`0Zy%xBeIRcMp$|eqDuqiuSbfhLx8s%|k8KDZOY`;V(TeN76=n n-#anpUOXYFCEBbpduL$o-(DBHuI>5E_78~&i&1?Yx+Ujd_>zmm diff --git a/images/viewer_toolbar/magnifyingGlass_osx.png b/images/viewer_toolbar/magnifyingGlass_osx.png deleted file mode 100755 index ef0a57ad3383d257197b4515cf5f17cc483c888e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 705 zcmV;y0zUnTP)ka1%e9a+kwkKb`MFfBY1$?zy7UWgdGGh$=lA&i-UE*Gzh!B4 z5JLW}pyl_H_WcfeyL7$*XlUq^+wFei z@pyt9$C;uiR%*2xrR%!8TCFxKmCD^rCiA3|4)y?iJ|8Uz!iWC;{?k)aQ=eyMW^z3} zJt_dVEX#rU`FTlE6ql~+F z^a+>CWef}qyx1pa+c1oGcDo&8V`HOT1N!><8r5o*8W|a}?U$q|3JU;|Bz^4~AW4$a zY&NY7!#rr05DW&7YnpbQVHhJCji$N=Oixcg7e%qgFwDK-;o*magM;jknBVUo@9ph< zOVhNAq9|i-Zf^T9K)X3`tgo*p;_>*kOeVvYN~K1l(a2e?R*q%alY$@+j^ix#dL3(P zYk5u6E~~1#@w4DzbFlN(c+)f=C6meVbUJ-Z*L9oI=|mt9s83E#7P8r_XJuvOY`I*v z6bgmH*4EY)RaJA{006)SAPnFV00DpjKmqU?fV8^08ed*sK36K0ESjbjH#ax0=5o1@ z9q%Fl-vA_ctW_J~aQL>v;dr{Vv~->jBJwiz1V3%i&~rQRnJi5wy1M!QM= n8|!)$Kmfoipo3j>q<^mO{opXg@e>w500000NkvXXu0mjfgmFpE diff --git a/images/viewer_toolbar/magnifyingGlass_osx@2x.png b/images/viewer_toolbar/magnifyingGlass_osx@2x.png deleted file mode 100644 index 9748a4b75526a134096216e1c1a6d31bf8d646db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2391 zcmaJ@c~nx{9tP4-(^iQ$vn&bC%!C67G8m;m2Bd;RPrG$9wR73N@mQLd{>OQ%hxQAs8PCt(Ge}gwE=V1iT#N5W?sI zkW+ zYdM5(puz(rc%DiF;prqgQAVax@C+7-LZ>qrR1Z9rOrZf}3PABBQdn#njZG%wzdr=T zn+A+x2lM^D`$E1rglHI6vjHG3E{+uENm6N60~8jE1(2x#l}bb;h+4f8mg2-jPM$j*22Ni z|6%-8S{tfYLqIU3RmEy#NIs&R$CQ!S{k@|RK?Dt3tdS#0k;d>v*>?xe`>xY3Gil=^JZ4q>-(MEXgCG>+HVqC6DJTrTAM zhU%VtSf&sx51V>{(OwsAE2Fu)gU6PxrA@h*ObDFXls7&0o!`|Rzt(@T0|)BXS2?Zy z8guuZkEG&~2XznIac|JMVfT>sjAd5$-{rr(M`Y*xc{{r780EkReO#*B@xDhxN#ULX);TA3x=qd1La)2!#BCJ=^z zz(TFHvD#=feiru(H=8~B4=FP{+wK=TyL)bSRxdCnU6fBU+Oi^8lFMQ;SM`7TM67+I z`=U-rNEi;CBoGSqzj;habj=cEzjeqGTrpgEVd1l`{*{`%zWUJP*47QyH5_kmZ#duV z&Ye3YDHRFIb1GRnUa!1bwq~+1>F_}1ni)=yWjX?`czz8yzBY%mCbM8MxRJEG)KwK zRaCqnPqiMdv8`=ch`nk<-S00lJALd zeBa##lXy7qVVleLFSZ{aPmne&G_)yS%ip|z|GrS8)i&$;=(n(~FPNrezr)qx;o$>R z(x6zOQ0#wdw2m{eX98WeSeSiin%T-tgJh%8-`Dq2rzFArREbYle_eK*6HuR&(e-HS z?mq)gJvOOs=ad)YIzEGi9^NS(!|Cbi5%L8m z$8CLyT4~zigE&Q7&W><$aFE}PrbS3~LxP+gQ0E+1*NIzFQ#)_5P3KQ57XW65VXHxX zcbBMOSN^+`vK!O!7}(0rJO9X$kU=(@WjQ+o9VRgQ$IjQ?;SVh0))dA@b7E3*PvK5) zAbfc8>oiF{NOZ-Ssq-f-4q_-GjGN z6D=KQPcNux-l+R8*|yN=q4*n81AVIlZI{>xLhi)o}JtVNT#{ubilLE)g9}5?0ov=YlZN z?+E4JXV3OI`Ui1cjy>(A7K(k_$^e%kSD*fbd*k=RwnW$6bI(;)4my&`?tOMKZu>2z zYOpnAu+dQf9NvH}g({C9|8J70pe$&!YsMls0Jv!L`eIKkV<>r{P0xLwul4oy(LCO! zf~u+~X-v;erJd;W;%@OSL*YlP@^VbVR0jwBwYd?miZ}LW59RDiNRf|kK`Ck(8;!RM ypK<4Qj!Q7jo0ywEWdOU_;4?Z55r2r$$UW&_D?Z-buw?1TRY$lekYB=GmHa=JhskjO diff --git a/images/viewer_toolbar/next_osx.png b/images/viewer_toolbar/next_osx.png deleted file mode 100755 index eb76ac9a22b2a4307892fd90d8bf66c4b47e9698..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 358 zcmV-s0h#`ZP)cDRPFS2xOa_Ax%Ck zmt+(CgTg}C2Ve6syx)5;Gr&p5*5YtMMAHlxKP{E6!%-C7hhZqD06PJW;}o3pmpG0u zrIf$gP6lw!;rl)lLflxEwGP8j&I&LL1Ga5LN{Ju{E*!^sPLgCfrcEaR05nYlV+^kA z!uS0%A;k5VHoX8~doy-zJkQ&=iQ{0Q53yZ zRrTb$?s`^$q9`9lQEc)&zXPxW@Hz{iZCgkwcd1tZ9)^bM1*od}nPu6gEX!LAOx-CW z+D~2A?@iM@5>fem-!-EEM07<&e5m=o6aWAK diff --git a/images/viewer_toolbar/next_osx@2x.png b/images/viewer_toolbar/next_osx@2x.png deleted file mode 100644 index 9a32ec51445b7fa7af2aae99d3ec59a4d484fa28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1614 zcmaJ>drT8|96!)Ghmt7~WX-0x!{B4Ky}R~$?P;;KEmB7d)(TAUao0QGg!bz7u(g_q zMsReKXclqPh+)p*;!sfu7B@8xgJzD0h)msJ&MoK|K7vf#rtS)q`G@h6`#rw*`F!8s zD@(U7ijI;*0RRwfPBGfV9S*(Y$BAoZcN1Dc&=9%Exj zdi~l<%zOYCQ_R}4ge*%c;ozJyGK7)&oNkc~0P`34+@zy`5kQK`V_jP4{^_$2$kJLU z6SKe;w}HuLQ~W%$)Ni#r`~?mT4J}9l=lcjzfs+wP(B~|4c?h2t8q!OM=a5(qfkP0X zKno2!m1Ri>4IIyam<*FTU=#syjSRss97pGZD2yoOFd|13Qba>2l>`ifBM&56x!mjZ%Df60$LGlrjYcDfQ8|iAMTFF|-X)MesmqfP)?j2j4xV)j zEaw748cB*P610%$>2L^6x5YB5*yR~Xl$bKPk95ls87y}?LvanEJ%Ww--;I}|J@)l( zMs8y~ToLaO>yeufCX2aywV@DD^oB^|S+OW&p^J2J`T8W@4jaUdwVF+{0 zE{{OE98B0QE7~35Vz1;92A&}Wj<<7MVYma*^ErX@K@6I4hHN(VW*aJ5-|K zh>Z--u4CwAo^ygjIVRYb_@HnoNSsoWQj#JSQVLbVQVK(Jr5Xi8Dby57YbYEV;nOeV zZn#H9i5Q1F><;0e88wDs8mS6LVJU(zN-3#AHR7VcXc8t>YFq=!MHl6vwt1nA!XmLZ zL&wpf5HF)+#kj;-;>DpkZr}PB07TMequ%bj@#m*$1(GFGE_B}+>|T;NXMA8nTiu4; z`pKqA4M(r6yZhzzgcWg7?>@@@!jkbpsZO<--U*+YRk3x)NnuG1L1?`XcI~j-ynNX+ zuIt=pJmBBd^ArBKirSOd-ygd=>FkW+u{(emU1SRI#xL2$d~hQWJHnVi*>agNlj;OV(`?;qu2T1zsmhB-FF(E4Qx8|-97flINgCZc-gYLK-S#2 zLSo-DpfUUF1?5eSrDKb0;sO__)OKZswK{mE%t%c?I=!kU04-0c3%)-0!}M8=8HaZj zr4`Jm9kb%<8f>xS`KtCwl{z^7WS~6xz{KVg_Bj{O&nBiB-cS5wgR7c+FXG0z&AQ^Y zBrravX7+29<9=HsDW8Z&R{i?b>NfU}HNriIzVc@BLvVxIJ_5 z;?$OXB|eE=orrzZbo<)visga&*n8eq+tiLV19jCggV~aty^m8 z)V_XLvb}ji$@y=qBPv(s&pyz7zqfDQKXLVniw~4Q(6UXt=juV*T@sGZ>EVN#E~2DM z-(@L|npsuyv8(Nes l+4#Kk^U-P_>+7ut#sIsI`C$&ywTAxiW|P%;WZ~*9{{dt@U-bY0 diff --git a/images/viewer_toolbar/openFolder_osx.png b/images/viewer_toolbar/openFolder_osx.png deleted file mode 100644 index 0ea0222fdc97e1a1579ede7d6fdeb963f4a27480..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 280 zcmV+z0q6dSP)-D5S2mw;cRzO7Hx-Qgp{Zx=7NuagvYitx%6u#Y-0-G*HVt?2OOovB{VRjz7v(p*6K)c(@61T3~0viL-dE9MBx-;9E zp*t-YYBg3Av=I;zgOZSlS^*p05U7Y^p*92vB5ET_piz8anpB?Z-L{MTAWUZF-h1YJ z=kc9$W=*8}Ntd(G2>@_~76hYcrP9y1T=ZVzxY>@D$E?bjRinqPlxRRuuILiPLJ6@B zMxm%QH=cxL0A#OLYhzX{{FET;3AdQmaodR`LIY4X&rXW+a%f=^tWz~V{^#Lt98(oP zzJv`^;bZ{Ts|#8TSkqEnE4M6{c?F+07b~*`WFP@85wjBwnkm?ReAupl_GvMRW5X)e zaz8#2R4g390=fY)*3A+!#n2eXyJ?o?IA%7+P_&n%Xp;62G%t9)0!3k?7mmCcN?eEr zt44jHlOM0QtfWAasZ`3H^0;-Qj-+{>Cn<(x7y@Y!X0v9AHldl*G8Tf+lnpg$sk(-x zEsB!9!t&!N(vcJr$#D3dVa*&R3QK zh8f=~@;!3$Cgm%+)hDyI_KuGp`Z?!do~wQ9)}HZa z8*`_B?W$Pcw&|t5J0)*`88r391f}X(QQ5pj|98v9uE}!Vvfce>Hoog9X-(gEbUSy$C>Iy#yh)$hFAa^#=IPi(CC@$WT7Lw_`0 z+OyO>D}3%Rsq4Vhyxgm&v%H0_n$GhdMnCEpXkO_At=ZdeuBzUBvB7jDkL81w1)wF71G-d_iY`59rU%#xLDmxd~kR-;42F)Pu{s4!f#zF@XTtxpti;L8ut1b1e9d0kByGu){=pwj@ z6xyYwMK|4|K~XUHbvjjS{HX1v+~q!ShI1ay`*F_U0NiueVCDsc(Cq?ZzlXHkD%!sg z3WYw(vMl|rI|X505ClP8uh-v5l6+zq#@oSQfK2W?Ns>jwFmCqUDGrW^=XnSO0*oX{ zZ=6nNQWx-~%f!%I@plRAytJPYx*=#rYeEvtP)e2D* zMbI?8bBo2|WH(1InIH&Y7zRX9gg_u*mn7-hYPB{wj(c7%m)ns@WbE;HcJ5p^2hTK{ z%_5HDcJs|<1M~SDCX)%wX0y55?S59P)r3Z)@u*&}E7R$e&~+U&O`GewUhMUHum9M= zJ~)m8!!RHS0*InWg~MTgG#Y){>2#W_)e0OA2Z*8w!C;U|r_+&(j>rr`2oyybSF6=_ zGMW4Y0L^Z<`*^ur5&!^-qKvPuuG*DKrD@)KaLET1SS)K*Rr`rV;(aEQ8IDGyS6;7| zak*ST)AY^(Ko!HV(Zvb2+b#J0{&6ms`yz^B6~nMbEEYpN&jZ6S5DW(OLZR^ampc{b zXaXF^H}QD9pGu|P?N`RKEbu(PNhA_|RaHM=81~{=)n_S{O8Rg(Y$1eFXWT=C(7_A5 u2!zl}gbX#iV93Jc|RZmc>ocDfFM{`Aek9R#AJpflt)oPi-D@3 zwqR8h!4?n|gd6uyF%chLg;8*BAH1HP=(OXBpK&?J4jT#FC_VN`*Tq-uFG5{1a& z%+xN#k3g8eTNNFrkCTP*AyiF~TXZNHY79pc2!8$fz$^dtq6tkMX`V^^<{Nh(-C zj%CR}874xMs*o%#vMDP(8p=w6cre+2J;^VFj}xd7y_}Sx-l5U)GX&(fynK9b5mU*e zw<`J+0r{O%ak2=K2-PAa7KH^sAe~0y@F+AEi^HM&kmw+dNd;+C8Uvv5_)I1r1WB_G z8Mmf|llW2Mpjlh^NkCTW^%$Q@O;1m!q%$a}HknG}@px2_PNmZUTm#T$YV`69K%-kd z#~?;@kXD81Rj7t!VU#P-G`)a~d-^T}H71k2C)Vg@6NRUYnjy!iGzv&nt1WT8)z;~w zkU!k`sJ1RT6GNy`hz?EDLU=urR?mU)-2J&Biz4m~f1_4~7e&59j6!K@M5C9A1!Vk& z0;^y?oyTL)8FU4J$eBz4ftWNv4l5V{l*C}Ocrb&8@W45qkKtJ$OUUFg0@)lkgGQ4u zg&dJs2#UC3CdigZMD#hVRHM_&H4rjqTZP-6#q$0X%NJ=8xgOO!bsw5vF67y0Cugos8*V!!0B@Xg+V#t3D9-?rzKj`cDp z$5_cwWz#l~){Aj9eG4Voo~f^P8Xtf+O&(ttTmqN>^;pO6Nw=p?>h3fQnNqC-!30u7{gjTIyOfpn3D;^Q(1L z6N$O!YHM3hbuEfp_FK@f*$jK7WoP@??7hx07z~`FB_*w@)k{)-x_57TDkC^Jn3FT@ zET9eyU_vXIOxDnwv?<hp;Ti zrW+@nB%*r(C|Y;xXrJv7+dScha5q<1kk~gmT07C>+99A09snqmC-oB#1_vv5W@kTW zX>Hw=8%g@x@FU0Y^Y*o84=nAxb0;<`rw}ZT*y5NxIW@KV_94g7-W=1xyu3W`oL~1m zoz8A;=<4bUZTsgXD`m(yZ^QRQYpVo?Fz30*%GJZ&u|H@p9KFnU^SORsf#7%N!&m2b zHeR>@Oq)z!exX+P{zExLCUqz1nL|I40vFPP3vP~#j35CTBk@4tK8=;a^wmD_$c>k) z{!1L2nVInpyVj%Jfug|`?ytUNJ9`~l${`#rBB^UpY3mSVFuZJ|MJ=R_;|;}#Dv?A z@d*j2N~3Ab&ySaE0buzOlTG1LcMS}Sub;Hb9m>7$W*!?$n9T4y!5uK#K+ z!J|#}*fU|k)zjWyUb`v^Y&L|3E>2CEH+j0eyxgvL{L@?4cikAg`Axam%EfMBPqwv* z97N2!a^*_NFZb_PKctLAhKBa6Ih0k{K2~nj$FI24AMR!z8j91PXwjp@^~OnISIv4Z zcg5Ou>k6t3e;+fIF2{b7wl_PK+rB(DRa{(5q{Q^!^~6fdA$Da~PVVw#?;)#|+uLo^ z($j}GZ(Bak>r_ZuWAug!zrNJT#fRz9t1ka45{X_nG&Ia_sTuYR=y)u?TvcT-?=0FZ zxW_J48KEVM7(YkKTcOvVRQh>P1{OPSZD_t7KCErtC3@*#R>koj%h4JaYA^h$oiiWToz-Dn3n?pB+3OUs|645AHtm!4SjPj8h^Z X-66+j#(qJlwY;GpeV`%j^oa%_INxeiA16okH_Dp)9G)9VZ0DUk@kAMK+`nX?e>cv0RSx8G?hx- z4Fm#CQ53=Lc7th}(CKvAkx1lGC=}WeMbYW=`G8@VjpmjC#bU8tE|-sGSvCLw7K??W z+wJB7pdE|FK9x$PV_BAsZ3pt)Bm)3oj0FHVR8@7a*=)+w>C`cqOkg&f{p5N6alKx@ zqpIqjs;csGxjcL3(P#v1Ax)@4v6>8(qJC19UX_uoEz)kpKVy07*qoM6N<$f-8?5 AEC2ui diff --git a/images/viewer_toolbar/openPrevious_osx@2x.png b/images/viewer_toolbar/openPrevious_osx@2x.png deleted file mode 100644 index 7cc39da2ec6be65c23cb88cd7830de3383e1161f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2065 zcmaJ?dsGv579Im4Dt6hGY7C+wJT`!nOy0?qM?(T7CA>m-3p&Y6NQ7i!GC*M4BcKIE z6ezp0yte{HK*3WVfLNj6ss($nrMgsWmmX=^Qi@dc)K}M?D7gK@(>Z76_qyMAzk7f8 zo;eU3{nolQv^4+#tW!kDRpbcSUuP%sn?!k3N)DTduw)`0*AaP$1p}lguEFREBa(@! zFa*ut{V5g*01kT$>SQ80N(pOmBMY(Huxv&%i3Whc5Stm%W?=+fgJl{_L5#ZtgABR> z4Pqn-qM#_V4AUDT3M^QBL9|+1kfoKNjF4b@pbaJoj2MB?ZN_Yq6}AO2p7X-w+`i3b z(4U(SSwV~!qLQOx=`!4c(FH64sD-#3x=6y}2m~S#cN?7xarkVA!{+cnjs)iOVF;ox zJq*&D1=YbSdH9kqauvkT6NDLNv-9%uSb01aZpmbGBoYZ5;=CB~P(P)qBxwVy0 zVgHx$N^7e+-;A+Um=({lXvzD~c`bv<-2J{IyCJCtjbxHiX#nFxhEh(VsP zPy-618X*@FLntT`V-N^Q_!mX3XL$#2Q$Jg*N@iNb=@FGE&B$OkP2}MF4hZDvZ z%lMoyX((SJlE|eJxnvouFj)!2q{Wtf8%WxRL%m#jxQO?sbq3L4_hN$PRyy6xkH9vURDANxhN!pcnD~Z2IO!sI}wJ0S`CJ3L^`dG z&($#4q(rv8YJO8i%Ufh=+NUpjf?T}pD$GQ-l7;M)z!(LxG(U$1k3T`-O{w~}*U0vojcQi!Wv2x>k#SfF!=Z@9yub@f^ z&m+Zee4swCe~MA&bb430LOCw7$?9h0Jip=X;;Y`(yk8m?Z*SaJA!mFoGp(5~5`9&e z{icxaUb*gy6YB7Xo51*@Auc{%OWB|bin&f@$3OG;o9O82xtqXrYY{_7bR(ydw|yKI z7IxJ3J{79}%-5M3z+~E9b7+`c&vscGcp@>Nt|s2$%$YOqAPBNm{>~SAep}zh5(U$3 z^olV%d+xo3&$IJ8H@{Z1iwNva>@vCzOP${eW&X3PD7Wy&XR)fc2px zg({cQksoYc4~>d#F&%2lCp#+#`unSH0KRECyLbOA-q~`v)>$o$sG@x@?Hd@lb*iuL z?`Kn8Ah-0}-d%5|r#Dt^ft3-Bj>pvgp1*c>`Zte!JISFPDt`aN4}G^>H&5kLDr$XM z3FZEkrrM8B6)8Kafz~avv$OXmf68SuYlb#m04 zYdtJ%uD)>LLgVP@D4?&WI(Z4}fAVSCGjjL7ca!{bd-QgSd$2@cF8z{SINsRUI9T~O z$vexdS{ayrCw@GfNOYpnXc;Z>o;iQ=sE5;fQf8g@7O9@CEIsFdXLR!>uPVG5$*H7{cl8GI!4{spO%)^wF%ejnc&@T+L5YNC)P{_ zEle*goYe2yHTu!u;Erg&FX}v;9s3R*Ts!~tX~V$z^V8iuJ60gSmL$JkJM_23C%;nkt9<@w>s_na(bL@> ztPAYD1uhK5wbflz(ISprnx1aOaJ;8MxE1~-R&WIY4Iwm>7=RL zBT^6b_e*&2;l#ZzC(EwQJa~}v-`ws=UV_&SCvM{2i`A|a|Dnsuhh@Zdx&y!F9#ROl zeXdSt)l_w^aCn;*>ODO-SDu!U@qP92?TRjGg7;!R&$YSpUq2?qD3$!V`S~MNuH3>q z{ASIgsADCU@A&EZ-}%f7>An`;(AxNpy|TyVMu#Q1!ByO+Wk>hxS) qQS+?rug{zFqZMSYPKBHuq__YQKjf1`87VCLPg)TcE$_QjCMX-X~6j!cnQIR68e}bE!NOx}B72HUrD7Y4+ zkabZIsfbHOf~2&93Di!~N2cS93#&Af#IXpv>9;(b^Zm}bj{}_Qe~Y4lFbx0BkoqkL z0LLYSusP?~Ip-G{V`qsdd(=eR_x-n?=hZ#Wd(vz++arO)f~8W4R8_rYn&zTm7-PDw zLs1kk#sC1m@1xi2q1)}E)9LKFuDiIuzkh#YV`E_a0e}#KOw(MkZF?@8%|h38aL&OP zgCt1+fFKCq`#wC+L$}*SyWK{s)q3o@?u}-%*#}`!fMr=X^ZEST`1m+D&dxrH#)tjnbfeLDy1cx6!F63N`ZI^*!!*s^g@uJR$8oL^(bwMs zj*8A4930%M*X!rk*VhX>J3C`hP#A_trBZv9N@a6;diqr|nXD1fX6yvV3}gV8wzs!0 z*J`yZoO6U>h)gEasaC6>9LL$s=kxCYJOi*wM2EwCMm`rJIxLsVt3rsYg+c+cEF+yx zyYut&&xH^V0DL5(FQe*X0gmIGOD2;`wr!UtCnrBwDwX!s)YMB!lI{{wE6#W%;Mlr$ v0lWe54!{QhYXDyVNEyA-;~vGS{=L2f?hCvj-w#=h00000NkvXXu0mjf<>)s3 diff --git a/images/viewer_toolbar/open_osx@2x.png b/images/viewer_toolbar/open_osx@2x.png deleted file mode 100644 index 5ad3413a7bf1dc3020398d60d020c73db3cacfe1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2162 zcmaJ@c~nz(7JeX`ELHYJ0&kuQqGaVIAsM!8Xuzw3A@U7kpT0xXG2jDmcHNQNe$ zBFUlb0W<^vHXM@+Q*Ljyoac)nVMWTHAyjLPK7Q0V!W1_+c( zLZM`;fFw|J&qRbJI2v z0#{9RnW4~HQYnHskfYL|AeBJHBP0qLq%#O)DwR&B1cDS2877j*L~;CSI%7 zT3rJAQyTBI)(Q`)QDOqBRpn?9>^`Jh*TI-}zZ}S9h-Jf!)yT0+5oK{zNR9$k>iFDH z2sPR_dc^CrEv4a_E{?}Otk-t=jx1KpS-Ce?p!!jG@m9 zKehdcJ@{k(~bqX$%>AZ>?Slkqk<6iecJ#1%H6u8+Y z?i69(yR+0N+wA;+W@c$=Nlp8_W7EAWLr*-+?ue>voO)OlCECr03}e2IpMz^}#9f4oDWA z!xuc-K*zMuyvR!)SN8I7#os?3Igs@QtE1oVdH&*4VSp-pV%)X zz8|wN2-&paHse8me_3{SFP~uc8;dMrsasrXDnk%|+&4l)pI{}&$G;G?1JwgdR@q~H z)#U42u5oB}wY8&|o8DPeCNp~A;KP1XOJU)|U0q#Stv^PUmCd0Da^Y%MS3#M^{W{lX z@j`8F?Lcv{)s}Qa6|R(bkthyonfW3v$N|O9Ua{;7(nwc|JUEn*VWDH zPjsiIrZzM+LCI3-_d5-3Km(9xHj=ylQtsXu@mGn<>@ln{tXnOC+Eb4Q0Pw23}6~$V%#se_rY% zbVNl*FE=I>mPE~fkLPbT;kGxsTQ|Bs>G2K=wY%A2n2}y?ZEdwoHx$i(5)T41eRj}lLj7J4oA(;M-ml^VG{lPbIA?07!~7542c>!0*==51hW4kYKjXUoHE~=% zZrgvVzqY$9rN~;Zb&2`N(fO6j{hFfFHoYq}GZ%KOnQMEgS=1qaJyCBtpJja79`*Ws k%4+}bFki_u3%Bq9HU(GLRQ5+YnEnFzycq6f_JI%o4?sduPXGV_ diff --git a/images/viewer_toolbar/options_osx.png b/images/viewer_toolbar/options_osx.png deleted file mode 100755 index 30be20e5cfb33b5d8b9c6dda5662e58ac2807d86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 864 zcmV-m1E2hfP)poc;aC5MJAq{b#c?DfIfkd5m&-Ib80muz7hW$~>&?1N$87k_j#U&q9_mq0jjD3fN2=U zS3J+d_x)t8Rx1EFjpMq@qI=uh+rKuOP4mr-1VISX>GWThmzR^i?i7-OO9x=&B76QQ4)m284q-VBm ze>;{yp-}jGdU`smswxN}5JmA?*Y!sLMmH%VUDqFpqIgXRfubldP4k0%KL2nmfkvaz zEtkt9K@b1{{eFMaah$iTbQ~wy@AoGGKomt}G8rr_Exi~^V10ev+uYpTO{G%TH=!h@ z^r>Z8DgaoPrBX_t0!R`<5JeG|mzUcc8yk<~1mYg~F(Kr;FbqFpj7gMI7>4ml7=}H^ zaoV|Du3{JlrIdm(hI~H%ve9UK17J5!Ahu2G_4=%B+ka%US&k3_-}f;ZjSvI@c%BEP z6oMdtF@}qai?G#d)%N!GTEOi#y=4&qxUQ>9k`xg_qQ%9`uZ z#XaM>*hj;+b4a4}pTrU51aBwi2%jHf8A)f(YrBdl0fZz@J qSa`=M{*p2F^UXf?xPFiS9)ANbC~L3bg*4y*0000RK_+rQj25SyDg*setIyx`9AZuxbS=ix`wQsI>i~r}v(jd+&F@-?x8rW>@6eU@Ybf z3;+PwkTn59bS2I{7G~%>%6O^}T^x|WXk;BMLo!5a2;fR#F@y_Ih&Dk&NF>cnZG(IO zz+|g@eKZoy4`)kYg_mfS$4jeFp=bc`@zttCk`xHRiJ?t$B?muT`x71~mvZn?G(M59 z@`sY-YqHePx~#S9C0QvFmK5*18t0>BqXHBVBEo4Eo0S^2mV^HwmyPac$pk#^0}GPE z!GAO=njeYtht&{{=0yV~L^27-V0n>fGzNpb3P&cAs01R3K%#&o7Mn_C6N$J_1CMG` zOJ!_fK+q>$=!t_*LJ$?3K*-3*@XDZg!Rk!}5{tzm5Xl5G8ALfiO{NkNX+fpNbxuM6 zq>-rQDnt$|akCOdVmJ-q;89CIx}Z?;`F{#lYCZ)D4H-czQV~dAM1n#w>(>Wv4I+g8 zGUFe)HS04~5J3oO;54-a&4|3U4JgWky<)pzgS z{o(iY+Sa3!fiL!lSe-8@EOa({z~k|9hEq~f==)kV^Y-;l53Quu<#uc~c<1&uKWXJ$i-}f7L@{YHHeY@ZiBj(xD|bHvLPsPuLy0QO#yB zGR}Pe{jhsKKO$nEdGCCmn#!A*F9&{cZ1|RwjqmG?;=)}sRgd+0{o|cFT~}Avq4eJ$ zrdcdnVd_y-RI~&b92&9%qBE!8q;gi>-kG)|=;SDV;`(Vz)qjuLxL+=`a;`};-CtG~ zXWp?TbTSXv{dUy-eG=J2AP|Hi$R#no%q}($_ZzP=&uShpl8b%8TkP6xg0W_tbzZ!f zc{at;kGa6~WV%P?7pL^zrg&oKXlLf#P(A4}%Zy)W;XCx>7P&km-xRDdAKkIQKB%m$ z%zm_S1t!Gk3>Oou5c-)BhjWH}=4A_!kxrU%>F~lQ^XJch)zZ=;=vfexo<8xs?ST8R zU`^~cFaHde#+lqBryKA~^KIrC$)|pkHAO@|efspXSM`qaOB{Fi3Jk9vaw0 zT3lQ_c;LW+gq(Ed(!sX2kOkZj#r_lsy7q%pgH!78??7c_V&aT<_r{a+!f?fXmftL64CwWa-A45uq9I-VS&)oFuA-Z$2#MVt%_41AiJntIRgIAXfXldDGiF3~wPaPXPFu0O zYG%s{iLX&(Y*f{`l{lbsRD|(*uoEcVacaN7V4cjpTQ}rUe%5@tqR}vT=gz@EjKgFx z+a>=SLx0|P0t>~)6u)AOr%t$X6s_L9KRuc@`P$`=+sO}Y!+`F%*N&0~aYJ%7yS1fd zVUkQybOJC2jFPte(%?$CX94VT_sH3+Yi%kYaiRSixPjDJ)Y^-^OMS`78he&&L9m-T z>9^rmyDt9tR7%cBuZ1l&2s* ze(65f0oZy)$dUrv0)oYT)iG{dZ~)d*_E2 zHP?ZPJn1q_aAUNq#hUCc7Yi2!#hsM*aD?12k~3X(0T7GD8?H?*-yRtWjBc~Ejf}Od zy0Ep^m6vk8DLUPNq+v`(si3vv(5{6Vf+|uRCO#hL!EYy&EMF z5fSlmadE2)=*e+dC)NFA$>xFW8ja?-qoZRRP`k6~sb75Vwtjfr%=)x!4{toz@{V!V zvGjez<=z=e=e$!w!x1VAd3m2SIGN~2ImRsUjp?bdM|KBG>$huT-dX#0CSG{h@1!oS zG0tyAKgRmz#${hlm&eRE>b%-vzSpk9p+CF(Kip~XS>bui4Bi*?+M|27wfkB&A?xJp zgoFgFtE=ni(y*{F&97Zs1fF$2*8!fsCj|GLdVLqN1X-ii*lsLh4vZHCRqgj*)|dBSB0|Yyt}l3m;W2 zP*hZu_<@cZ{~f_jLuKu%7Mk&}}%MO<9GPgGQtM@UGBft#C~;r;vf zlv@CEwWz45tEi|b13y1M13NoAMr4v@fts3HDzdA2cz76?nVE?)m?#T^gM+mmK77c* z!^1<8tC0cTWZK@|zO%Qt_n?Z3%3E^t2cdkhLsC*QqO7cJj*pMe4JIb0Kh(B>fq{YH z4Fdy1g@=bnVR?D^K^YmDxBveAqpAfk0QZfjr{_&(X6C;n=tY44|Nj$%y`MaJvah_n y{2jU+wJc!x|Np<(|NsBH30W|BOVd#>bN~Rdr;GM91p0VY^Z4mpQzik?o{c4Lz{6+}U|>4~T(iVx6R3Y7VWXYTTQeDnQ$zn||b z8_ntOjf|QU1pvTEQ>wut?`ZHH9wD!p;ZN4f+eFEjCCwEalAjSdAc+-h9B6VeOE?S1 zu*;V#5}Nm*&LX}jQ3GC>_>z~zzA01%fD@G$mVP6BP*65g$Y?jAi3fjp~& zGSz8lnn%w$`P2fDn_G}>wHM^tDHckI2jc>?Y{11y3>a|bxxI8i2ld&d<#SMsKwzJW zl&gdKNoA#(LA@YypjxSh?I@0c8cK<&)fx>R3*sn7ASi}lDj1_^f}l|p9C#qvo5(t7 ziy>vemweMfPD%362;%qqm41~{5SJhrMNtTfBRCGr8nAb{TVevR+dDO6!N7U#BJYuS z!3_p2GB&{{=^&YDe+Vv5TH2stw|5{>a>|eZ<3TVbinv_Cxcaocl7;)9#!I!m*5w`! zv2b3&C)(wDIHrcca_(O3D5xm2q34LaTofkHAlQ8_&Mlb?I!OMaWO>!6gS^pyF2y7b8MrjE$1<+ywcTk zY)hG5G4A7GUH9)}CCI4yFf9<-223s-5}1@YdTniK>NLe3-m$7-`VGt8KMywEIC=uD z>zoeEn^(FR4Rk!}=>irzD%(E^o3_RD_UPd|Djw&)zxD94s>7Ri^LHW>kDki7w=hOQ zZ!kcw1I57EXASJNoWeO58sisUtvERn$WUC8Xs+wY<(V|w{#x+YiVue?033S;F{ZUVHX$v zFt%yW?wFsy&#uaU?W2>bf*kvsIgYUG-?0Z@G~Vbbo%v04$(gIpW4pX7qxZwZYRV?K z)?969zdokuP)ld4qh@b-a<(tJNuNhdI@s^tB5HGxKM9EwjVY29A`Eg{xjp0(F{tL^5BO2S#L za+SA^_+ZxcP3P(>FFT3ud!wz9AFkfe@$joaN<#HMb$83^>hhkP{g2GC<02j1<0n5Y zDW06LMhQ-Ae$-q>iB(}c6X$$-WyqJSYR?W!?)zikpX3UXVxanV>$N%x2b2z~N>~~1v0O$PQ z3d!%4MSz_W3N-V^Ct57{Jn*Rg^zy(mMX8VuD)DRQE}Ta z43RMgS(X6+p64N#%OR7=@JuFib8T&HB#}rI=}Wtn*Voq%`h31yrfEXgb(EErZTkKG ztSE{+l}fQ(E+-p?LDK2;^~J?S4Zx*68`RX))CB^88Nc5zP)bo-Tf5xb+dFF*#ybG( zuItu~jg8e!PELkw+a{@03dv-$Egp}*+LJ*r7`$Q_hQJtuWm(?_1_mAwLhchnvH-w2 zm%6&T&O45CYkGP*WSS- zkaYl0mzI|Fsi~=llu}~b_Nl@?p>SY$c$fwPfh&~K1B#-6bB>vrnTA*_#^&eei!RYL z%_p)f=Ve)jBuV8Z0nupm#n8~uJ4)%MD2fmSf%obicFQhK?(yd0kAp{=d$Wl`5ofS=)< zA8l-G3}~7*AxY8!$8lC2$9WB4Lsiuim6eqTeLf#FO+#~Y^XFJBc8(D8p`^h!lVnd% zPt>+;Mk$5sy3BE$(*U5VDk!B;RTV8QEuXr(yYCj3mo(V2IGao+uZ@q72j}MI4rR01 zGR`>|WBG76{Jo>2<8veuc?jU~PLE)(zo`k}Jb;q`j%@8q19$`A8GujQtp5tI=M)0| bXaDm9eKHKweO(3t00000NkvXXu0mjfct?6* diff --git a/images/viewer_toolbar/rotateL_osx@2x.png b/images/viewer_toolbar/rotateL_osx@2x.png deleted file mode 100644 index 5e296332e1b4024a8010e717aee149c100b86798..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2540 zcmaJ@c~leU7LRN~kVsSrqGF7oR0)}cgeRgNhS~_3&}`Av>HW&iV6y0 z5fRHGw1{YtO;B6_!Q~ZEQCtv|rwFJ};i0(DLB-cUJe}{%eA~Uh`@7pYvpb0EYlgN) zqfjU_j-OWuG6R#Zu@Ul((0iMNOmkuHNO+Z02rEH3gjy+(@*q4%3`RpC5GY89YlU1; zDE+OX&`3Bkz@NpJiXFj88Ap{^hG?TuF77HB$ln0LcpeljlDHCH)in_CB7rL*f))S- z$ULDKk)K))tx|JC`RWaPrhwq?hIdi15CAa*gLsuVR-$03TnV3WS;%_wm_)#T5`j0k z5GHksyIV6;YyCJcZx| zDfn`c3>HZx_(?>NC*26U5)h`JT@cFx0=@!E6kh^`gp8yDWhAmAKoW~5{rV)WfJ31F z)A**eA~Zn;kwPGabfcV)?F@Q^{m+ zDw9Ta_GXiv0UrjPxstYWN|z&1z@UT=P1zP9w!i37|5caeDThE8|L{81^@wMh{!-l6P=u? zLL$hZGKqWv=mZIPAelmE629mQ{t>#*C5oINF36^su*e{f3OG@i#7S?6WHLl0G8vG7 z$mbzgbRl0zrSJ$Ogd%COYW`70Q%6W?PA>ptQw?T3G zZQLC*=bzD6SjBvt(ZH?g0~!6t^0UvZDPEvead?t5uT0-&`op*Fg0INCpBzp*{M!A| zSY6)ilMM|d*VY_=^+kFE>dVkfRHJH(O$`hT-am1%v$JymfT4WZz%#t{yWR+Q}`xKhpR1$o^SukM--j%r^CX>?J zXA(c?YHMq|R^d{0y4x1k*5mP!ky&2dk@?1G^WL2(w`9GTUsB_FN@WBk=Q_9h4c|Dy zv`cn)k7jUiP_mPK18ZaBh@B%#t>3hNSF}l>G1gW}$u7*zUGUO9DV6^8*|V`<4mIK@ zto@W;K0e=Lu~_aj+dofYEmQXGqX~sV$-0K*lX9yW+SH~dZ#(lu;Nb8YtYpX4wbl<< z(|>%OJ>A?n4)2Pyuqe_y+&h%<(?m+#yq%OuD$W`<+>~O9&8Nbl6Js$ z=~C(G)2IDCujx6S#jxEMRvDcL*PD&IW~iPPMUYpnd66Emg6#0l z<+z32tc>1V(^kR%?%lh$I&}h5JnDNusp|^pHo}k=UkeA*!wweXYLBh;uIn8Q*5kZ8 zzNr#?Jlunn#~7c-+tO(F5FhO-ocY$UZvUP=d))8h`n;`oY;Y> zTAT_TFb&$frpy^*X7*yyaMw;KFr+8^#x)0rVx9{#cK>)evrWHUsaC6xr5!w2)wFl< zu4FS^>w||6%e+;hxN*$KiaguujyrcOW-MhNH`(J>IC^s4{UO;^PD=r*7vH6uzBMH!g|03|9|%hNzG%FxvN9}r{z)Lpq^47A zP@kEV^=3sHws+ssve?Kczh~tb_v}V8mel1?VB3K%?K^bnkku0B$VX8T5%itPZ4fTu z5~mesX&Ke%Qi#<*TH-(A;NsNtB6zz2so+Ue(rrk#$y|Hp-J2KamU7Ss?P0Qc?vc5x z*Q`;;Cj06yPozsvmCH(I2OQ`f78d)az3afeYTO!Z(BfvlY?)f~q!iz^d2aJUKYap&avYer zT)i4`%BHweVp(u=R*)VHny1a2F{9*ibMq}#9Xftt2PQtUdic_T%*^WWu&~O#OIl3g zt=?!{{|a?4UAOPY`BfDOJco<`fB#1RfPmk^!^87O)W2A5NvpH&u<Ro$KGHu?X>@#cD+V6WT$H}Rnn!2kdN diff --git a/images/viewer_toolbar/rotateR_osx.png b/images/viewer_toolbar/rotateR_osx.png deleted file mode 100644 index 4f39d11f3300209382a6585bc6ea50e7096f877c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 827 zcmV-B1H}A^P)_O=v5NHm1=q2WmgV=72N>-O;vP5B6{1{w!GW+I|Kr*}ekREc$bA0~r{NCsN zzr4VEy=zg};GF-zKzcc{0q~+M%Q_Q{M!%IL=?g&+OaMFxf>NzkyIrf*ek&G>58nuE zW~Nf9NJ~r0^+X~uok%2zF$PJJ006%4i}XiGairs($Udz zsjaOInx=s<_9U519tJ@`<#IV*tyUwtt_yp6dq0VyD6X%s-+1c=y}iAIot>TkB$G)n z#xOKAw3Ex_)@50K06?r%Dj(0y&7IxY*f2cLL%Ce8JC1X1b93`SGe9J4SeA9gFbt@w zih+TF;_&eB6_|%&>;Mun~*Jd?J!u*OmMG`-SkFh&bo`W+s#Q za$#ZN6G0G&F;*WRA78U=`_|~_=<6G#)9F3VIUCKs4##o0<2aWO4-bDWl}a@LNTpJmBuUeXqAcX| zd1Gg1=UP`+*Y`wpr|DtB2Iu_j?Ck9A)z#IHJkP`K?k-%{b*t6tJt7hmMfprol$h`P z`^U$}*|oJbhln0E3kRC)fQatb>-8J+^Yc?HD=U_1n$UIq!;_Pf^8lbI3S?P^=Xo(z zRX-=9>#quL+Td9W0&t;FD15WLylif7Z+~!ba1bRTw6?ZZdwP1@Y&KgoP4fpL`ukLX z&~KUs@HK!>0T=){fX4vt0{9ESZj&2072wng1K#W1>nR_+6aUS^boT%N002ovPDHLk FV1kNJnfd?# diff --git a/images/viewer_toolbar/rotateR_osx@2x.png b/images/viewer_toolbar/rotateR_osx@2x.png deleted file mode 100644 index 18beffc7c6a8f78572a030f7c9640d53b3bb976b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2568 zcmaJ@c~leU79TJIQNbu8h!>EdrB`EF>DX1dt_wKq0aynPf15Y$lNecq#-JmWqgd zmO_1i3M#G$3ND3!N{hI`Q&e~;;sOzUDEfqgO9vHS|L}CqnfbQ+yZ3ju?@VrZXn^Gm z`xyWLSO%`(Mj#_;^0hESzA>hMY(s_x8b7`!Qjw(53RE!QBT_&xHc%#53rD~LQQEpT zcsT$}+a!tNYxuknmQW!h2qt9+I++qd1Hf`Gol+o7fi+kNUMrEa@x$ku@K}k6jgO)6 zNIWG67E4y7tKi7=&?sSgijXP7dwF7)>sW{a8LSatbuy`3&C;>)AN8`3`Q$bckNqg3 zNnztZk>c~hu^fd8#?lBhP)MSXu?!}GOrtRv6gMn|M5Yo+WFpxeBr{o5DvLzIetz(X zHI*od6~XoYYztYj@nVfe$s!W9S}j5APEe@U63I*^lSrZvDHITq0M%)7jX(#=)s9md zxUgENk|;G2g&aGnQ2;5{YuI>%=_eOtN*?cvV!8TrppcLebpj=kOdt_uvPr)_N~<*y z@c(IiRazaDri6(Ruv)QRB}DR(=hX#(<;p0DA3Jg6j+2Z>H+(5Ymy zAC>9BAo=?<7&JdJoyqj|pTY*p)f$0Z2v6CTAhthaX@84laa6ECqfkXD6w;|G2p20f z3bk0F#Bw-T=NO4xq|mCDPG;zn!(3P;NrgrJDuoRDF~ls%SIjdh9t?K@lY|rt%$)Qe z1|f(>2R*0|lR={jMKBG*f5wac61q<%itHdRD5sdPJm@eZN$9}@C%pm5WS9yvJzx6e~B7GJswmLsjCLVBjsIR7R9m@N+E`b6ov zpRHOI692tjqwUrWYoNP&tKit(=J58-7+GB&IqGRP7xJ}^P@XxikZ zef0df%(%`$-YN8qGIcTeXJ(N1w=X^{DPNbW9~&FPG8pxyeVfmn%P4Vcf7$TtQpUj% zv&7EiQ};|a-s|puT3k{>>24a9euwpXibA8&EA6*ewO+XJkXmpLv$|!a>CO+!%`0s9 zZu6lwDV_0f^l@8TTO|hvY;VVm%fiC0n-Ph`HQp^}Hm58@q0r(D0XhqUOfC;vvMaY? z$E%T=nwqX@-xd}ZTdZOqPtVA(ofsbv^7Qnai^e#4yN2r;I;>25^eE@It*u){RC}Ag zw+|~SD)P;JftGWe7tt0QJMZ6LbMiay2hV9l3k%z{Le!QuadD9+8XMoY_4V~_n{c>@ zc~ewYcE2q%69~kV58aSClM14bMjtlcot>S{Q_dOPvSs@4g9i^ti{6bb${qRUr31KC zOWa>oWtDl6F_C2AR%lsq&UD(eUI5LVceRJwxM$BEb|jy#o2@U^W;E5;Ga8N_1x>hb z&o~_QiP<|nIyyS%(yd#!_9+icOh6{$4-|`rl@o7TIQhGaii+;LQz)->QtL5GJJft2 z3_Djx2SHwGQBh~l&6^sjM)Mk-T=w6!wu2Rhw6|{!kLT;`9i5#At?FD?PQ({i4YX8N zR-V0b<%-|(R7-KzGPhy6d6&*?n-(YX<#0GpU%%Ga^%mSkld&L?Xzdyt92{U~W=4;X z&8>LOaIUl9&j_s@pC@@4--c0RO`uUD(&PC4Gc zH1&-{n|5znu*-GkI-l4d?(Q!y?<2@>`!@7g{T#d72(8EAa16Cd^?v_!Ui!xE_dT%E zy|?93V@YwbbLwSNOn1Qkn17uCisOs?UyY2UqfBX*f4>4oRMK&X+-V5@)rK%-PD4cS5~AmuEub!tuu$&B+ib3*4Ou03y&<16loe!qDj ztRgMW>mc~J6!R=ZtybgnB7VdQ>aX|Wuo3(24CcS1n3q*tN@Sm1jf*!G(5-0Zwj=L@56ulnA4Gk;nGLvt bP1EfFYX#r0qDM=c{5K2q3*{d3P1OGhI^!nV diff --git a/images/viewer_toolbar/save_osx.png b/images/viewer_toolbar/save_osx.png deleted file mode 100644 index a0b1bd2f71295ab6881a0fb5101393a1ea0503a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 468 zcmV;_0W1EAP)^ob@CAroy?9s6{J$B<4`EHmAP%(o|p%~7z1N$D?q>B-wdGZ zx@X~JGC@9{e-4MklUy!$6bJ-1f=ZiaXWKTK&E{1k5;?HumrA8ZHk*A1fO5Iq$Ye5Y&iQTt)oRr!6bk36s#*Y0EEdlym5Q+w zfFwx}LMZim{f>wP0Mu%=Ti10JN%HTo=b9RZG31=@O@BpMmcbaqU@*8yBoYq*Tt!hX z8Do&;ukAtz7=|%i^jr2-JObEXkAPN``1yPYrb^|L(HYTeCMk^{- z)LN_*lzL!AnGprGq89N$(4bc9Er8+;0N|sIP{%T>!2No8FyDkeUCWte7#)^K$5BQ)1G5o;0;lu@s5N7$L@a^fnR8DQ zAppQ$M8+r5iBXX<17+r6ZXKS(Y-P{@5HitW#SG~L4eE(h(jw=&s*iC&5|?um#8HAM ztBOb?BeHBnTvl|vAuHX0;@pW7zz~OwAutm(20F|pi(TfBbKmpIn7v!f=YsE5=yW;v zgHwr7I#5N~2vE!uLk58m2Bjzu7K^1);W$tzfDyg`=EEWgMr8;h69~Ybhs#*A;YL}k zTGL~TImx+cG;Njf`574*ybKYKvZeB26h-+0Azvtj7!AmtX`wL(WU&YJGN=i=!A4qX zlCpqqModr5qvc%2(+?q-tx-`Qi7ob?L@_DjJ1{FB<_Y*_vpcT$+IBjY_}`7sYTM&8 ztpq=ouv7DF2Bsdypk6SOyDuAZD>B~5rr1cPD40o28RnS@3$0blxy%g@CvlkwA%qAj zAs|#_G(r*t!63a6Lm;tOKVB+E$HQWYv6ts_c$Fedh^mxAiBy8Xa2TRgBd|&%5Q{`o zg#Z?X^%?SjiM=g8f67lDsW5!X~C%s zd$7Ag9|BerHgZ0JYiyJme4k<&`5E&fsSp(#Q4|uQdJ!ZNBN7M|GBuYPq*8*A;+Rn+ z;`ZS2Pg3`xMHvYbg0i4p1}1|qrr#>^;|yVBH!IL zpL9{Lh-ppt_Tx-2hmTW5SeQ|=F*DOR-Sm(dMV(fyh<7wSo_=JNzhZFli#NWPH36KE8vwdnjo-ATpAw#aF zWcSAC`y*r2F@sskx_-X?dG)DkS5o=4&Zxd?%KQFG^gnU8vo$bp^qu+DoW<)m1RXz_ zh778^{lp{~dNUpIf8=CEj2iT)qod+U*MizM+qvlg5MjOOdUf*Z)vM2kW#c)*qyyJY zfs?EJat3-V)u*P0*LZ9C3$l}UdrppE-D<^VC4Hw%A8~1C0FV|~%k}~uK!T#koQC#I zouLjBFP*iEy=s1Sb1v=I&d#_PP|w-S^4o&H^)Eb;rTdW{p!>e+Ze&+?@dVGpB(Ny5 zETG1T9I9}hX3f>@ZYU_PtZBVtX#-1Drb5zkxzB~8MWBQO@J@IZU60Q-A*pkg*HupY zMRR;rvOkbse4Zs*qOzaVcUHH$inV(V9$dGCa}H4Whp7T0*fpgWLULw%0JYCBkK63U zHK)=zyO#a1BjrS@lYo5m6?wX(D|7Y-_#8>m7aw>XI0ph!vc}f(PEX~n7aZsWo?Gw% zp@(P07if%-m@{E)!O^*7a``mZy1&}OHzv8REK7V=FsW_i3-5(TRx5wMFebqFJcs2Jgr^Ky z-LN)$e&Sb^ehk5%&$_w?&gwXZ?3q$;ubR2D*-||$dz@D=;2gN%b>9V>CT-tLR?QYa zNxpD1?oMXO`B-Cn$^I%o&yor!y0ZRm3#UO8_-KO2HTGn46Kji6u_@ diff --git a/images/viewer_toolbar/shortcuts_osx.png b/images/viewer_toolbar/shortcuts_osx.png deleted file mode 100755 index b57f7ae1b39c676da6fe843c26f70356c94f02bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 531 zcmV+u0_^>XP)nwTPmrI5x#4kgHSLI|<9u}NWZg>a-! zu|%{rDX&PAREL~}NWdr?b~3Ehf$Sf%NYLg!m}2JRz27|M%>!=qzoqyOOw)Ws2zirC zCXW;)UFx1 zVlWtd%49OTeaRI?L9f?)0Dy-10f44y5JF%+pFeK5+gEWaa9wv3RdFKhPzZs=V(}Be zkLzWcrdq95FKe~hrc$Zg|J@TpM8X3VM2U0$k}<{-i3IZb{4s#{*PiEjk#V6F_+?oZ zqm(|W*Xv&yW1y7Yj(f3K0M7YII-S;At=2m!B^<}Ob1;BqSxndUQ$h&({r)oma9uYx zVDB3g3WXD0*E5Yq<1&}aZ6}k--Q8{%+LC_-AcUNj%jHeC+kFM#YBrm_T`rfm4hFDo z`vZV407d{X91hO_+&dTmz(e2uMcm|}078h6QmWJG^z(Q;{$q~=fMFOYl}bpZQlY;s z0O)i&7q)HJ0H~bvy#Q5JVHk#JHk%h=eqbJZo_7r3IU@NTS diff --git a/images/viewer_toolbar/shortcuts_osx@2x.png b/images/viewer_toolbar/shortcuts_osx@2x.png deleted file mode 100644 index 7e8e5f9233c758856e360a6cc5fda59a51d22ae8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2012 zcmaJ?Yg7|w8XgcSpkP`Q)LI&X3gMXhHq zzA*PoBpv`}Y(+D)gjT&$0^?>T*W1XYJ@L@_CC^n44Ait44b zOum|}w#X49y24>a(j6%ou)_q4^|S;THNHSX8ZaXSL@hAqU^YpCl=j4~gq(Y~Sv2Ys z2w{@ao(82=Yp8PEictAXJ_BZRIaHyT$>H;bLhdpum(2lLYz~XVV{pV05R|al)TxI? zdb8>ck~Br~lrM56r5OprB4M%Yc01F~W8&70ERI+#X0f>}E|)&lia}N~Lg`tHNvqgu%$PZs#a;fFT#4L@Km=~h!10`E6=;k&f!mC@g({a* zV=_@pkK1i@?+raoSb41~)T z=nXuBn8Oy)ruh0lmF}rT$sIBU%XB0X1QHAQIw8dHX2alc5Rf4jA$kU^L-abK0XBeK z9gRhX$nvV@Pb!+;BBkk_KI;i`@vN&5jBF(<*)!~>BW|)4$5e`>jDp@@tJH6-TSa*% zwR!g{xl6NT8#TPsZ}Gyb)x80$w{Htm9PMTvr5M9Uu0HlXbq)`InnGPqze;W^O=zl54+W!vw;~G zfpgiX!iwPZ^zs|JQ(rGHQZFqJj_sj5h#G9|@9)nX{AFZhB$?B~o7dI8cJ10?1VM&1 zr9GSGIVpa7XYLcedC{^j<&)Nli3vJ*vZ<*la*1z9DSYCD>t`uZC~M3CUz*Jo_#{dNrepd^xpDi$;1e2WFwZfh5%FLYLq-TS?@^=)ld z)@CW2O*s(koJ=tIiNdZ`_}31^+bV#VT-61&@ygc9pd&u*h1qc*pOMv`nA<&kb@+bD zB{$FS>&kY!+wC6x-~E?mU;NPBFb@chRB+0}=@gx;t9&x}!f1I>%SK_Q|cLEvx!mQ&>1LH}*h)e@UOoWa=t*y_7=_1X}uDUEZewA{`D#$X+b^ z{ez{YrMLD27Z(>_+NsUVwD;b;`KY0>@xOb=63v=Mf9Lo^s5rr;tl4qo`Y8TSco`p$Bf@>=i$3X?X!)tDX!M13o0dS*%0vFWhx*ht zS>2by8aMf8eRq{xn4iCN&z?OB+P?Ot0Vv~VpVg6PzKgjly-@G?a97~3uWrBI|CO2E zkbn8~=~=U88R#!+<}QhFC7X-^!_ulL5Ws2g{8ZO)J5h`#Ubs;YJXkR*vI!x_9?a=@L002ovPDHLkV1n8rm0th= diff --git a/images/viewer_toolbar/showBookmarks_osx@2x.png b/images/viewer_toolbar/showBookmarks_osx@2x.png deleted file mode 100644 index f7cd5014688341c95928af20505b643414de41ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1615 zcmaJ>YfKbZ6dpjVrGg|7-CC4!XzHWP&SPKfxGPz9L5M&Jtn#q7&d%IjHn216%peN| zM0_9`OIoWHTWyJvN^O0kL2V&1R;?0Jjm0QpD^;vk9#LDVt@bXk)*r^now;}JobPNw z$ObH5w(Kl0AxOvyw>?kE%SdN9(W7SlHfo>83(*K-O7wYIt_Uco1GwCR85=m>hM{iW zjOFSw$PBL)6uMK(C6H5|Y3Is|I3tfG&O=Q;20HKng++ayVnJqnW^BYS1K0j-0z*ek zlp-@WDk?7{3$=<8Ky_*z&XF{Q8jNa6r!yGnc$6k7EkRNQrNJp9qt!AbiH=_85z$U3-VZ^V9E#|>m?{PNq9W|xJImHB^&%Ne??`TVC~UD!41Q7bZk|cdu{u_(2RLm6 z0Owh)17|e`2M%ZlWze%Ur{TDOpBLe^DYS*8EJ=EUUPn>MT8lo#YE4PD7&K%OX`wU$ zY?>e|tiXW)w;OVgVJ$DkGFAz&iYVDdu{cl#S%sn^%7vmAwOY|xxo&|MOXb=A6B-TJ z1|;`#z^6!}2OUW<<9-1>;2j!RHwGL^ci^;6tHD{4<8j)_QU-%oLz8+ZHiqY)OWkOR z!W|fbH=u;kBmmN=r=7Sz8l0kl7B?mU9_Jj8$Kd3gTH1jTP$J>4n&+x0umwxgzkJpc z@a0)o0Rgs>1bZgECoUdAf}LqLi`{qSkFDo~D_N0i>o>M;T^v0e`t|yA^Vall3cbp& zI(XyNkCS7oXYP)koqg)aW2I~685xb7RBdnmvF5WNSJmmLhKrbGe@;$EYTW5sxnbb^ z=fGLs+qd>05!h! zeED~a_FM`pXQpnfx_f`oo`v@x9X#wiM1zdQ-g}H_UCW8xwLWcX6~%$=$6M} z>-M)lx+yhJ-mqp{XWxqLhA%qzq`$QjSy{HEt7LbgeojHPtjE`G?rr(g)IfH)P}my!6oU#v8|P) zs$!?~Tb$tPjvM!I<&`!$d{k?K@L z`>%~p+uG6Y9fe3l!;%ZdHzI}_-PwX8C=wYR>pWM5?jO9BhdT@AhA7PTpoJf*=Pep~ zHq)$ diff --git a/images/viewer_toolbar/toHeight_osx.png b/images/viewer_toolbar/toHeight_osx.png deleted file mode 100755 index 96b85efc5eed25b4c5e5c40574208b3a4615e3b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 401 zcmV;C0dD?@P)xm>eI=gsi|iX9O@5lIo{{}9e2kI9N0Ih_y)Oqr1e0sqZb71wx3k zTrT%S5|hc~!uS1`oe8Sd>T$VTek~LVB>)(Y$8TX6o(4hizDc01J#LJAK7XIhW=p1N z0sy3xrTKjR0N`p?t7gTcpQu~@y)R56Dm)xs6OedC=7w&kA)>h*fpb=^?YG^EpMG#U*GA-X#g z^m@I(vaCqgb?CZ|TCEoK`~5&A`va2eR>t!@*S77YZQD!F^IVddb+vyLfTU=*+rv($ vm>U?tAZh-|str-|VjV zxTPNMzU}}3cqo?1RqTp5U#=_rO>}vZ%`QGnw1!zp>zQ=IN&yiht))PPiAbVU6hUtM zxPb}*0M1sUTEl3Ru~Hpv;uB6CzTISD(Etz_G)Bf_BOOb@WKk+#7&hC+3&oZUwi6Z@uXp5BWTTO;uo~H>5UFxnmu8~Oj6yEsu{V6uNJ@plB%;Uk zVn~Mv3m^%C6OdS}MIgPFB-nBa#F#`oVdqtNF)oh8Fu5pL6f8v1Xj~E@h>j2m<$@*A z0)a#*oWLr~Hij_ks0rUj*7rCz__bJRl$9bF+N!4M)Cm^E8)$~M8E6X_6$LI#G@3~| z-4^KV&{)E9%4*y|kxQ(!2^=l4)c6Yb7>4L2n4W_46rqK12`+-f7==PwHg8-{A;Dsu zm^Y3mUn<=gMOg`(f@LBSsR-8zNP!50oY_DqO5u=1Op%aIOOaZUUZ=+~Ee~cxgq^H; ziA574mYUA(i-_b53}XgxgWkyP$bOWP~TYXxoHaEvJC)%XLW!}X7$v;LtFjqJ# zubEG^^-h7a)KI{G98ZF ze>InLb}w=?>r-*x(k{#KABTy77?wb_ph=lb`rDJhx?1T6M~4qfsd zEXxV@u$_RyBydqN$w==^%#+tXaV z4VOu*X50OOwmwklG3{i3$YS3UXsc5c;NL&X)i@4*nA zoaYrwcxyYw+}de}FkgY!=9yJJ*Hop(MGn3uNDLVnXJ(-Pkg4N*5y?S?=SPQPu63kygnkpKDeOawcDx n{ODT^ZX0D37jUZ_aYukJ3b_g0gUcPxe~2PFPJS$M{r3L=e14Yz diff --git a/images/viewer_toolbar/toWidthSlider_osx.png b/images/viewer_toolbar/toWidthSlider_osx.png deleted file mode 100644 index 469b702bcbbc8f15715650d119b8e42f4adcab95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1321 zcmaJ>eMlQ;7{3^tMQs^agR2FvR|qTga`#^Da=F9!v7D}f#YxOG>&ooq?oDztxi`H# zmnfUlGAy0jZ1>M#8?3Mo+EF@C#yUE&;$L-)G8lt>l(j1;!oVqvcB{p`QRDiD^x*D& z-{*aP&+~h}?reA0vwN!#R1*ZTH*!pg;kBXk?s)=#Zx=%M@$!_@k#KrY$|za(Va7N%Y{8!4uDCWlph-H_+CnxLWo#e^9hEHRvZgH;L)4~S8ShJC zh9WmroPiLvMJf^PCd0^rq~H^1jpYC-NmCMZED+24E|4JS8Y2!l!r_V z+Gx( z%f1cldmAe}7AuD>s5;1sBa|(7L3ai@$j+cV84i!(+06?Br1;I~4&d;hM5V)YoQ4FTYl)C1TE-H&~YnHYtN*10O zzo+slLAcr?N_)KcOLBcfGO`We#e^$>M;7Z*n+FMAIi8hh!)iDu%{eVOw|d^HU}OjHjJ{(bPm=Pegf zyAf7b4OD5AH_->!nn zTNNJ1g%Fxwy7}?+Xf5G7H%DGySXlV$!96sNp<^_$ipOit%4V}iQ>oN=Vuo0A9oY9x zarKWInC{B*^72OO>;F0pZ}!Au*Z-VsYCXL=oxb^QTG!XBF1asNEzc)Cy)|u#ySJ_t z1{xb1`&~abcYoV-_WS9Phr?ejE-v=1{65=X6Puhr_>pInWu6r8oUeNE$335&`d~hI jyy@-Z>?9%f%$XLU^z({zbSYP!IeGd&$o9n= diff --git a/images/viewer_toolbar/toWidthSlider_osx@2x.png b/images/viewer_toolbar/toWidthSlider_osx@2x.png deleted file mode 100644 index a952762e48f82493a99947162da7d8e50e5c702f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1793 zcmaJ?2~ZPP7+%4FD2V8wf`ijFQbmW&?uOlLb}=d;i7=XQ#X{|YOR_*T$;Rwr0*csL zu~HSUv7%U1suZbG50sjsptcqfypM_%GnP7P6%Q))!frUMGj)73``-Ki_kaKW&n`>Q zO&v6FtT3gNoq{c9V@a zu~yKdkxpl`d4*W;v?m0MO{;ya*vj=LN=O;(q-`)NL12r;6IZu1$0srWx$#zMPM>3A z;3S4)v+V|<9vNf$z(VfcZO9`ictge8O+ry+Je-+2auBAgylsXPSzuAQ?4o=+Dv_n3Y z4^jD!K9nGjH;&lbX6W&*u;|RX-jthurpLX@+y^C8-Hnm%;P=nWGS~VB zXjl98_d2)5wpCPAbh>TMreC9w{;sr$;g)48am}GaxjNr1HK`E?F4T}CR|MF;DK0*H zX%m+av9gdN$sDcktnvr75At{(YoF(8OwAoI-*TZm(7P?rnQk_Jzfo5XH=RE1n}99> zzMEM+H&U`yMpO|2%G(a_Q5Ay%0v0Y;iA(!+4y!7ydsMJ+;KikWPl9Eu8rzyrH8&Sr zx_sGEp+9+Xf4esC@Ke_mj^jqGX)xB`e7H`d(M;;->}1o6N6q(XF@HFu-&IUGxc<7; zY>rr2RFwZ*eaf-F?2#@$KJ8n0Wt-S=(Jt#c+T^rZ@gFIq znlALj7oD^G#(lXbp=kAFE1>Sm|6d!v8h)c3@CNp$?YIXieF{B4r8u=twOcvs^M3)a C(5|)s diff --git a/images/viewer_toolbar/toWidth_osx.png b/images/viewer_toolbar/toWidth_osx.png deleted file mode 100755 index 988348c332c19363bf4ad41fd0b4558aa5af3d2c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 379 zcmV->0fhdEP)4%f`VOK=KEY3Ms-ap>ma19U3%0TRbRr@n$)B`?tjkW9XT7(|I6 zloa{8IB5KXt%FNGI9$%X_k2GNoO^*n*OrpsAbFXgvTLbc2FpX0~CMJ^#O&h ZuU{8!rsl`vS~LIv002ovPDHLkV1n@kuR;I- diff --git a/images/viewer_toolbar/toWidth_osx@2x.png b/images/viewer_toolbar/toWidth_osx@2x.png deleted file mode 100644 index cea0b4bef39651e382f53406a72b94433c73ddf0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1702 zcmbVNX;2eq7+wS!R1ie89t>;)BcLSN-E2+>a%_}Xf+1pI6d0210xKpPk|haLrA5R+ z$7{4jL6Y5W@ed7%aZ98R0eHP8wnr^r!)j8*QqlJ6`{uS za$1RS0C3JB6O-v=MVv%S={RbK4#%o9FlYb>Uu-p~wb=v>YKTlyFJ-;B*vJA&T*^w~ zD>bBk7C5Rx zXG>XQP9-apU<_p>Kt6}h)6JPu{dGwWig(Pg`hJi6z_=jrtw5EDdSqz1}@BjxH_F9u2F3hts?$&m88_9Ab$rMGs7NfMeIzms&F)53=;ou}L5r_ye z4)Zl^NQem7dEFYQ9_|8TE@d< zVv!KxqtFCat~b$Yy_T4;O)|E}vBHmHB{4=qO;g51ids9-1h+s&=Mo~n=CU_{pRtv;9n}>)|99H8z z0zz5ic>MpSj>|a3b@a)5eKT>yG^1ntZVDLT-5e2mW_XOulx+QJ*dG8U-I8NbiPoOq z%kE^)Oz^q!Yg`c76Np_cJh~N|>8&!%^!lW*;pVcFbq%5V4sVyqQPHP^Z7NM~Y~i#K zrx~XWNft$Y2!<{2sh%7a!trij_gzVU(QQ?E+4N<9Nk#bHC%u+}{$B9P~>j+_(=j0q>v;SD3UNKmQtk?o!J?7-uc=2t<$LFMzC0|Nu++HIEz z;_?x)&@^}BskaLw(Ru69u&|3y%@_aS@p#|NPD@KO2Nb8fH%H%Yxtgwobw%>d^_)_B zT}$72kN)c&9eYIK;b&cd!A+g^Sv56C@gasWt8P{2spj5_ii)1YIeX*#+Me;iFSzv97u6~ADrU3v8M!k91}YG!5NchXq4xgx_#5UcJ=o5 z@?3%4cQekc9&S54RMP6_>zh>;_pHY0%5RU#UOKnhBPvg9TYaLc-dqvwJ}~2}q}{D} zqcS+9tE;QQrNxKi-uWhD`KQ;6BW<~7??Qe%3eu93UrlXzVGVP(nf(vBTm7enr>3M_ zDqdmBjHujkdSOFBduZgTGQer*j(PmsYKO9!fV|Tjx12{f+A}MGs=$P}WyC ySanBxz00?y?U<|b$%ylNtuxw3!}UO;%N#&mOZ{2;^2b5PpF=K-$Bsv*7yb+98j2PG diff --git a/images/viewer_toolbar/translator_osx.png b/images/viewer_toolbar/translator_osx.png deleted file mode 100755 index dc30f36f19fb44677a686ac8c9215e231602e0d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 526 zcmV+p0`dKcP)K(}hH6bI$mMd-G!2PF z0@-X9wrw93970nC2_d+C)hMF&D+PxTLSQnPe3{K=pGu|D_b?2P=EN3ADUnX6ea6_+ z@p$~wahx+D#NQJHL4ZP`@U`3Rp7_51tl4b7<(waW{F@5)`#s9#@(0iJo`hl8tJmuv z9mm;56&N_sMJfm(qTlbo8I4Bw0Js2tFvixa)#`rKoW#085Crf%@7r>@ylA)EuR5L1 zi&m@kxKgRiIp>kNu>?X06pO{r)9JKEDLu*O^Qcy<&j*9SJJU3O{;@zxiTQl~$g-?+ zN+}%2!EU#EI2;Zyx7)25RfkwLFbo5>Z9_^4(=?%J8Yra@LLiw;Mh;~xfv)SYEbB@v zl}g1)RX>sIy8f~D`yDAIT-WtgYs&8$z-s_^0XzWkKBngq!1yMA*e(BtUk9F;I+|l{ Qy#N3J07*qoM6N<$f|*(I3IG5A diff --git a/images/viewer_toolbar/translator_osx@2x.png b/images/viewer_toolbar/translator_osx@2x.png deleted file mode 100644 index 16c641c45fe6da5ab529d5ebcb51932b3d09e0d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2024 zcmaJ?dr%X19$!*m0E@IZBB=D1;9K(8O~Pg)4}lO20zv?Tj#f6wh6G49ZWai5P@vPJ z!o|w9KoO@}>p48yf)uD?DU@D8#q-pXp>VuA9<->m7{*56xQ&R{Kb-E&?(h5k{=T2@ z`#XCwJ}%1LZKE3i0PfO#Vi|pM?XQb7{gpFpCG_D#MW#@Rgqq61NE`@L5egiX>aa9i zhGVMS<2Udi0C?psZBh!A5*s5@5;`_!*I}D<1{w_jL7^rCrp&-8P=Tju^})>9Yn@C` zs|sey1+m;%LjXc}w1ghCTf`JZ78T5-BV9>BXNZk`VOVc`UMRX`91~{XKx{5Yr?cnvOxsAw z@c)PLQf*^Wt^w!Ba3hgLD(QZx{a3+s?f%%2U6GDPbb!>-O~Eq7gfdHq>nW)?m`UHT zRa%t@MHH|Qfnb(W4J%kYln=3l3O<(w^B}I8C*TPcLglKRm*FFXfm~jAq$Cgt6hKfU zALWG!BgF`eNQ8WWSb(l#rFtWU>6Q4ZZ!PWnIX3bSv7!hP$0&kKB8be@DTvn)6k*g5 z1~4K5+#%QMRYZ<)r@ccf35#)3n~kd^B%uSJl~|;GiF>{3RWP*#aSwpuVA4x z$x;dEk_eSBA4BNWSMaLem2PE3X$hTzVKoww0_DRP!WFXY*{~o8=d(~Du3{+_xJrSj zm1;h$U~=dXIrgdf-4v~g=+U&3FLr`vUThVvr&o!jcjmF|eI>n$%TjSzl427#d7F~6*wf~==P5De!ye&6QoeiA$>KF3%ll-YGQ?}7#V<)Klk8|&DDXTwgIPM~J z+{{>8G*^1?!P^fXKK!zwzW&njP2;BA+(FCW;NUcQwJj+*x%LXj$7SaA`SEekspE_0 z=DB_u@v9(?yip6*3{X#>>ZKe+HbKq1-)?qt1@0a zg0a2IEZaO?-+64YSlj|sHyMMO2M0$+lJEUQb&(t9Y=3SEF9LE(C$q0fKiylHp>~OH zT6o9YwAFc<9bUL6+2o`5AD5n1^1MI?w>QZh}#Xrz*gr|pI0##H}wv_d*PEf z_^;J5%3eZKYVJ<0diC1|fLB8}R|H8eB~Og!m?3P$eUEoT;$wg9fLdAnMz)&Pd}_UPy+037Jf zANFp<{=06#cJ`2G+oAJqZP|$D$t~6ouQ)RbZk?MlX*3!yTS(v3t@iSCIq+?Mf#S+_ z^tVNKuN_Gb8}cqkPf|7YLdIl>bvAy7b^W8}jb=%{p^CdZ@RUC?9~G)ts`*EekLMZ7 zwZ;WXpPHIliQG`Z?u8HhZ-<|2DhxBu%*^~NO|51&6_-Vo$kx=PM?KBV$oTi%!V+Oc zJ=kGO<;J;8qw#THWo6|t^-Pg^tI0K0RsE+ApLXS@O#1A4R9olD^^RM~~F=NAJ{}FU!n!IkFF|NS|)M z@HAu1H>q5_hjAu(JkoG4$oIY8&iBmb^&8h^r{DWb+UxYBdXukja!+rs$H|I{!pnYs z@ondZll{7&8Nl+JQ*p1>b_QDS94xAG zjs$#8sOv8uEm#9CsHs&_Y$lq^dxrS}xL7b&fw1$5y?xO`0W$lqd~bg{px+o>Qx}pRr#X zw;<@~s)`AOHiY1?ow#h$R;FGi#74DML*v33Au%|?1+hsx0HbSpPLsl++5t=U`@i@8 zzu*7c@0Ul9weNp^KS2=f#X_!v*RJS&Y9IdoTvz|Z%X4UC9F0K>)ioawLnhP#S#-1- zr~u8Jd-Gc`KoGH6yE=}>OD`)1bP`&mlL#FTqX}Xl6MC941rVu&n(eC8y|30N(l%A< zM6$$|yeycs3-dl0n;)$j^HYXwQkkRVK&W5>2Oy0MooP2vLX~RpDp-z=8H#MEpedEw zc51v-CbQ57WHOPW4K^i_lAPd@k|at;NS@`A3@b1KOY?#vvWm!)&4lAvj*Cv_tF$%|zjpF`?!$T!LjBCyJ|~9iR&M*Nt7ZgX)|Im~OC=PR3E$RHp5ybHKM}ftmNALpJiP*t_@u zSY8rzQ^KLA1=>uCfY!N`MT@${r({C{_?T+q&HtM}20O(>&GMh-X&vE?jKrN$z?+?6 z0xq5)ACF39wsISf+3&^NP&NEP-`Lv9#OStzu@7%v+#7>!@xC)N2yF^H&%gcX;j8!W z-gv9$qI>H4^?}%(J@I(lB|m-GdH=x!f#o=k6@-IVmd}>+vAyyB{{F><1!D31`R?zZ z{HP~mg$+DzyL|b`;_1^*tS@);9R8#2nctSV z)z#JRK~$^#df?>AyP2|f?4^${^*$XN>sY@Af9m?>y9+OzdU5ndVe`@7Qu^H5yIWZP z=D@_)gBweoo#o7-^>ckIzwzEb{hgKl diff --git a/images/viewer_toolbar/zoom_osx@2x.png b/images/viewer_toolbar/zoom_osx@2x.png deleted file mode 100644 index 6d9b428f3a8d7b9947581edd1b10324d28f1fae3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1487 zcmaJ>eQeZZ81HU?Fb5g(5kAIJx@dN2uOD~4yEb=>``E$6jmzz1LuJ@&-)?o+58JZc zE)y;bpkSt`nMBOy1YrSDSpdx>WMmHK;13j{6VV8Z1`rk?kPHOT-nK*jAT(*;_kG^y z_dLJntDD2+OQ+_{%Yh(hYU#3I#9Z<8J9(1%t+d>J-CX7xB~?a+A{Y&<1|T1=!~k3> zu{9t9SibSq0pNk4>_2}w245acONs4Q0p3^)dAMA?g6J=}x9 zBJV{isWQAw4S-s4SyBTP$?_lv8D2@1pQm>ow+JLA9^2MLcqi0Mt^ z1tt;EuqsB_a7>cYagA#0Mg;s%Z6lTC??jG$Zt!T1gR%oJG6gD1IxU~|HjnbeOF>h?V$TK9MIgYdos5>SQ zD9Jhql#Kxz1%lm4xNySmf5;Ik@zWv7O%NrNFX-}zs1m}72c3R@fX-k` zW!+$94rF|brtfjA?~zz0paIrUw5X!QGhGm_RSZS1Ra7_-7_B;7R4K~5(x6+@Wg3e* z2sE)C@F7i+;L$uY;zKy_E|zxDoEs%^CyNre!;QKD5kql7umgdMu>x;L#_{|E`5Ws~ zQ)0%UX6P_(Knon}B2ZeO+$cc+3XO3bg|Y%C&=kRQG!PKXq==Z|@I= zdAL7XKsM(|GY99^7xsA&ly$x|=!+(Px$=Qm?hWVmuYsFpPdIb9*E;8TR?_nG^qTYG z)yXZn@wQ8O*XJ&~@i>`nu|7X}V8)mHKvz5R?{H7c8g)kz>0ExS%9gVvs|cFd0nJQV ziXy-6!_@o>yVv7$g008t;?C0p`EM^(x?j3i{n3f9-|TJ#yML4C4|;nR=LQa(9lo+7 z{MA|NNcG8^cmC;XFYi=#ee%6mJoLh5f7dIAl6y8$(7cvSqVvOT1zXqcpS0w&mCK{a z)S^EYmj7hM^QRRy7k)D#S7O@Uy6(Zc-Wjg1Tls10l;)%R2J3WpK2Og5eWcC*^wEQR z1}{(P&q|?-2bgtDvFy~|Dtq>LH=tV?sQ-8`nwaRLEru*9IzHZz9~?= z`AIdp2<}L1azf|w>(6`hP7I0(_HSSPM#o0KdT;uS3zufT`_!@7&#uZ&?b{hEjtzMZJvKB_ zy`uBvt@yQz1^e%X-hXl8spBUqVSR=^(keyk3-%(5R?Ti*Bb*7*)!QY<@UD&LmUp-8 zK5}sD?TEZnyn2N1xq0?tF@N_|#dklfx6Vpg!ce*vDa)TLQdv-Y%TTwc?lMUKVoOWP KgP;3fZvGDy0vYT8 From f0a6fe74ca3b27c0e35fc08e8944dd10134d6ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20A=CC=81ngel=20San=20Marti=CC=81n=20Rodri=CC=81guez?= Date: Fri, 6 Feb 2026 17:58:54 +0100 Subject: [PATCH 057/187] Remove enforcing ligth theme on macos --- YACReader/Info.plist | 2 -- YACReaderLibrary/Info.plist | 2 -- 2 files changed, 4 deletions(-) diff --git a/YACReader/Info.plist b/YACReader/Info.plist index 26134f11d..2bcd0f184 100644 --- a/YACReader/Info.plist +++ b/YACReader/Info.plist @@ -137,8 +137,6 @@ - NSRequiresAquaSystemAppearance - NSSupportsAutomaticGraphicsSwitching diff --git a/YACReaderLibrary/Info.plist b/YACReaderLibrary/Info.plist index 3c9f79f70..44a203e8c 100644 --- a/YACReaderLibrary/Info.plist +++ b/YACReaderLibrary/Info.plist @@ -12,8 +12,6 @@ ???? CFBundleExecutable YACReaderLibrary - NSRequiresAquaSystemAppearance - CFBundleIdentifier com.yacreader.YACReaderLibrary NOTE From 63d9129dccc1e6ed7248f9d0d365967a04f0d5e9 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 9 Feb 2026 18:59:17 +0100 Subject: [PATCH 058/187] Fix YACReaderLibraryListWidget::mousePressEvent --- custom_widgets/yacreader_library_list_widget.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/custom_widgets/yacreader_library_list_widget.cpp b/custom_widgets/yacreader_library_list_widget.cpp index 5084024d1..679024bfe 100644 --- a/custom_widgets/yacreader_library_list_widget.cpp +++ b/custom_widgets/yacreader_library_list_widget.cpp @@ -75,9 +75,12 @@ void YACReaderLibraryListWidget::removeItem(int index) void YACReaderLibraryListWidget::mousePressEvent(QMouseEvent *event) { if (librariesList.count() > 0) { - int h = librariesList.at(0)->height(); - int item = event->pos().y() / h; - if (item != currentLibraryIndex) { + QWidget *child = childAt(event->pos()); + while (child && child->parentWidget() != this) { + child = child->parentWidget(); + } + int item = librariesList.indexOf(qobject_cast(child)); + if (item != -1 && item != currentLibraryIndex) { setCurrentIndex(item); } } From 1ef1029cf5f9953c3d8763dff228b8bad070791a Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 12 Feb 2026 19:26:51 +0100 Subject: [PATCH 059/187] Replace the info-*.png files used in qml with svg variants --- YACReaderLibrary/qml.qrc | 12 ++++-------- YACReaderLibrary/qml/InfoFavorites.qml | 2 +- YACReaderLibrary/qml/InfoFavorites6.qml | 11 +++-------- YACReaderLibrary/qml/InfoRating.qml | 2 +- YACReaderLibrary/qml/InfoRating6.qml | 11 +++-------- YACReaderLibrary/qml/InfoTick.qml | 2 +- YACReaderLibrary/qml/InfoTick6.qml | 11 +++-------- YACReaderLibrary/qml/info-favorites.png | Bin 371 -> 0 bytes YACReaderLibrary/qml/info-favorites.svg | 11 +++++++++++ YACReaderLibrary/qml/info-favorites@2x.png | Bin 615 -> 0 bytes YACReaderLibrary/qml/info-rating.png | Bin 322 -> 0 bytes YACReaderLibrary/qml/info-rating.svg | 11 +++++++++++ YACReaderLibrary/qml/info-rating@2x.png | Bin 551 -> 0 bytes YACReaderLibrary/qml/info-tag.png | Bin 289 -> 0 bytes YACReaderLibrary/qml/info-tag.svg | 11 +++++++++++ YACReaderLibrary/qml/info-tag@2x.png | Bin 459 -> 0 bytes YACReaderLibrary/qml/info-tick.png | Bin 244 -> 0 bytes YACReaderLibrary/qml/info-tick.svg | 11 +++++++++++ YACReaderLibrary/qml/info-tick@2x.png | Bin 367 -> 0 bytes YACReaderLibrary/qml6.qrc | 12 ++++-------- 20 files changed, 64 insertions(+), 43 deletions(-) delete mode 100644 YACReaderLibrary/qml/info-favorites.png create mode 100644 YACReaderLibrary/qml/info-favorites.svg delete mode 100644 YACReaderLibrary/qml/info-favorites@2x.png delete mode 100644 YACReaderLibrary/qml/info-rating.png create mode 100644 YACReaderLibrary/qml/info-rating.svg delete mode 100644 YACReaderLibrary/qml/info-rating@2x.png delete mode 100644 YACReaderLibrary/qml/info-tag.png create mode 100644 YACReaderLibrary/qml/info-tag.svg delete mode 100644 YACReaderLibrary/qml/info-tag@2x.png delete mode 100644 YACReaderLibrary/qml/info-tick.png create mode 100644 YACReaderLibrary/qml/info-tick.svg delete mode 100644 YACReaderLibrary/qml/info-tick@2x.png diff --git a/YACReaderLibrary/qml.qrc b/YACReaderLibrary/qml.qrc index 8bdd2e314..c5f21e934 100644 --- a/YACReaderLibrary/qml.qrc +++ b/YACReaderLibrary/qml.qrc @@ -16,14 +16,10 @@ qml/info-shadow-light@2x.png qml/info-top-shadow.png qml/ComicInfoView.qml - qml/info-favorites.png - qml/info-favorites@2x.png - qml/info-rating.png - qml/info-rating@2x.png - qml/info-tag.png - qml/info-tag@2x.png - qml/info-tick.png - qml/info-tick@2x.png + qml/info-favorites.svg + qml/info-rating.svg + qml/info-tag.svg + qml/info-tick.svg qml/InfoTick.qml qml/InfoFavorites.qml qml/InfoRating.qml diff --git a/YACReaderLibrary/qml/InfoFavorites.qml b/YACReaderLibrary/qml/InfoFavorites.qml index 57b43a9ae..2b24c0ab3 100644 --- a/YACReaderLibrary/qml/InfoFavorites.qml +++ b/YACReaderLibrary/qml/InfoFavorites.qml @@ -20,7 +20,7 @@ Item { Image { anchors.centerIn: parent id: favorites_button_compact - source: "info-favorites.png" + source: "info-favorites.svg" } ColorOverlay { diff --git a/YACReaderLibrary/qml/InfoFavorites6.qml b/YACReaderLibrary/qml/InfoFavorites6.qml index be98fd1d4..ce88142c2 100644 --- a/YACReaderLibrary/qml/InfoFavorites6.qml +++ b/YACReaderLibrary/qml/InfoFavorites6.qml @@ -1,6 +1,6 @@ import QtQuick -import Qt5Compat.GraphicalEffects +import QtQuick.Controls.impl Item { width: 20 @@ -17,15 +17,10 @@ Item { } } - Image { + ColorImage { anchors.centerIn: parent id: favorites_button_compact - source: "info-favorites.png" - } - - ColorOverlay { - anchors.fill: favorites_button_compact - source: favorites_button_compact + source: "info-favorites.svg" color: active ? favCheckedColor : favUncheckedColor } } diff --git a/YACReaderLibrary/qml/InfoRating.qml b/YACReaderLibrary/qml/InfoRating.qml index fd039701a..0f20b9939 100644 --- a/YACReaderLibrary/qml/InfoRating.qml +++ b/YACReaderLibrary/qml/InfoRating.qml @@ -18,7 +18,7 @@ Row { Image { id: star - source: "info-rating.png" + source: "info-rating.svg" } ColorOverlay { diff --git a/YACReaderLibrary/qml/InfoRating6.qml b/YACReaderLibrary/qml/InfoRating6.qml index ca3eda60c..2a7b482ac 100644 --- a/YACReaderLibrary/qml/InfoRating6.qml +++ b/YACReaderLibrary/qml/InfoRating6.qml @@ -1,6 +1,6 @@ import QtQuick -import Qt5Compat.GraphicalEffects +import QtQuick.Controls.impl Row { spacing: 0 @@ -16,14 +16,9 @@ Row { width: 25 height: 20 - Image { + ColorImage { id: star - source: "info-rating.png" - } - - ColorOverlay { - anchors.fill: star - source: star + source: "info-rating.svg" color: index < (mouseIndex > 0 ? mouseIndex : rating) ? ratingSelectedColor : ratingUnselectedColor } diff --git a/YACReaderLibrary/qml/InfoTick.qml b/YACReaderLibrary/qml/InfoTick.qml index 7bfe4e83f..6659724c6 100644 --- a/YACReaderLibrary/qml/InfoTick.qml +++ b/YACReaderLibrary/qml/InfoTick.qml @@ -17,7 +17,7 @@ Item { Image { id: read_compact - source: "info-tick.png" + source: "info-tick.svg" } ColorOverlay { diff --git a/YACReaderLibrary/qml/InfoTick6.qml b/YACReaderLibrary/qml/InfoTick6.qml index e7f260676..5b50a31fe 100644 --- a/YACReaderLibrary/qml/InfoTick6.qml +++ b/YACReaderLibrary/qml/InfoTick6.qml @@ -1,6 +1,6 @@ import QtQuick -import Qt5Compat.GraphicalEffects +import QtQuick.Controls.impl Item { @@ -15,14 +15,9 @@ Item { } } - Image { + ColorImage { id: read_compact - source: "info-tick.png" - } - - ColorOverlay { - anchors.fill: read_compact - source: read_compact + source: "info-tick.svg" color: read ? readTickCheckedColor : readTickUncheckedColor } } diff --git a/YACReaderLibrary/qml/info-favorites.png b/YACReaderLibrary/qml/info-favorites.png deleted file mode 100644 index f8b613954db8edcc6faaf3f0e006d4ccc54a3f93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 371 zcmV-(0gV2MP)ItE5t*YbuMhyF@`2a^ zD)az|7XtBwyAL0HfT|GyQUyR955x*kbq9cWB2di+41<9h<^!n&91geu#Eww*ejql$ zp>6@t@I<)5Ktmm%8t{PyP&$EtI!B=42Uwt-d?JD^fym$mnRS2($_b!iyn)SPqE)J3 zLW)&tfdj|}Z=|BZ8<7nL#rOv*82SO0dYD1P`;Q-f2nh)M1TsA+G`JF!)Uf5e^%SI# z4M0N!(IXEA5}~<_RB!>R7kgQOR2JaNwpg<}tSrH4Fo}j^H56wCfhq(QIvenXDK10d zsRA1Sr4%4u2}~`FNW~}&Gy)CG1gRmaJjMlpK?4es^-yjg(9jDE!wvuh7y!xGTsD&M Rg%tn*002ovPDHLkV1n)6f~^1m diff --git a/YACReaderLibrary/qml/info-favorites.svg b/YACReaderLibrary/qml/info-favorites.svg new file mode 100644 index 000000000..1fe077be8 --- /dev/null +++ b/YACReaderLibrary/qml/info-favorites.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/YACReaderLibrary/qml/info-favorites@2x.png b/YACReaderLibrary/qml/info-favorites@2x.png deleted file mode 100644 index 19aedd321166b90e7e3a4413a1f006ca2b221ba5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 615 zcmV-t0+{`YP)M5#v7Q@PEO!ZS|KNZ)(%T6!U@>Y#xb0Lcmv-uAD9UnlKlfLGkG&_GJ(u{zihs@ zyKfn*tg_R#TG0bHSIt|x1mtaUPA=~w{QW^b`Ci0vnPe2JiCFjesY5Qv6Y?2i2_s;D z4iL1+#^gOpmgL0Zi1k<^R)kohG%zKQfk&EOOTu=uiSXi6d>tJNDb~0U*bp`i-C9co z5||sn=0evM8XH*D1kb$e$O2Z{08AS@%RKO6nP62&lq5(M6|)=w$rNr$0νX!e=l z8aRq~y_Q*860U-;N4DcIUZB!&+hGFkKw3=2R?j5y)wpt&I0ZXt;F-sqGZnD#7+5Hm zW}1ta9u{9hbMQr;h9@45?s!+x^*sb0rf(YQo8@nkTyicYapwu_8_D6lXj`8W)7%_Q=RxOOf^C^D&0X^NfUq%gn(ZZ^ zp@#z%;VM^N=Uw_-!m{(V>bQ-8_Y7ScRttDf&|0wCz^PN5se{==09LC$v^VfbAS*et zfQ?LGjYc>#+Varl*{^W;1F0Vh=JCqXYV2YeAtz*ZxdC;nObokLHOWcbJS&Z7HoyrndkC0RK%; Un=00g$^ZZW07*qoM6N<$g8aaNxBvhE diff --git a/YACReaderLibrary/qml/info-rating.svg b/YACReaderLibrary/qml/info-rating.svg new file mode 100644 index 000000000..54f4199dd --- /dev/null +++ b/YACReaderLibrary/qml/info-rating.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/YACReaderLibrary/qml/info-rating@2x.png b/YACReaderLibrary/qml/info-rating@2x.png deleted file mode 100644 index 01048c8090143e8f08d6e83e2528690813456d91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 551 zcmV+?0@(eDP)(RCwC#m_bg%Fc1Lk&<9w2AgTC3 zcmeGXxN>WM&>x__fHSu~gB#%nC-MPAcmd%CC)kBWirOSyN4t(I)smICYB%F)vK!l& zV>9L~%`)s7u_sE**K}M;2euk^;qXes>C0PHNybkU>@HeN$7vYsIjT@_}~m54lrd2rvU6Iwzy%+Tu|q>nFesm z1jW4i+i6iyNM?$OkYQX6EVl~)jSDI`H$5>jjaBn^2k08WHq00c^S5Wb0|+s!81UAv zx;H2joV8oey@#{LM#!2Lg`1%%0e=g9O0jC6+v0@trBmlF;qV0g3NCc_{!xEQ|6H_V+Po~-c6&?0;aSW-rm6RayreUIltC5irr^71w4%QDEzdt-VDeNew z#5>!+WpBdi87opGWDF)I-e6VWYk9=|VvFVdQ&MBb@0LqDHjQ{`u diff --git a/YACReaderLibrary/qml/info-tag.svg b/YACReaderLibrary/qml/info-tag.svg new file mode 100644 index 000000000..5d3b00bbe --- /dev/null +++ b/YACReaderLibrary/qml/info-tag.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/YACReaderLibrary/qml/info-tag@2x.png b/YACReaderLibrary/qml/info-tag@2x.png deleted file mode 100644 index 04a995f87e4c1f7a276c13423346f2954f780bc5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 459 zcmV;+0W|)JP)DTyfs+Pf>g51U+w0h^b$cP*rS-zSpWE)m}TKx*4_ zcbH{a1(zX?$Sxibr>^VX>>~)c8ZK7?ZfFI>oqdWm?#$F(!3t!?@g_+~92poIN6KPP z+y_EIH2Qa`GySmk#}u>GA#f#>jn?QR*I+9Wo=;IzjF?ts;xwSuqsq4ik!!9&-tz-) zkq~Gg5mzGbxd9nQuF?sSSdye7WijKldY73oi)Vqc)|^wBiH%!agFr4Tt_VW1Pa(&slOnUAS;8KoMUSVz#dU0{|(F)`SiTQ`i6i002ovPDHLkV1jY5 BxZMB% diff --git a/YACReaderLibrary/qml/info-tick.png b/YACReaderLibrary/qml/info-tick.png deleted file mode 100644 index aa6b80b9689b635735069ff11eb54fa4964ef5c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 244 zcmeAS@N?(olHy`uVBq!ia0vp^0w6XA8<1SE`<)7qk}PqJC<)F_D=AMbN@Z|N$xljE z@XSq2PYp^dzh0`BHf!7Z& p^&~RPQfzP7!8bomfPuq+A?bLuYw=d~zd#o + + + + + + \ No newline at end of file diff --git a/YACReaderLibrary/qml/info-tick@2x.png b/YACReaderLibrary/qml/info-tick@2x.png deleted file mode 100644 index 46455b1d2ffedb4102f65393c7a3d12eab5fe4f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 367 zcmV-#0g(QQP)h;P57}i#G{m z0eSQ;px`j%kW0wSl#rg`I%H{&#$00FMzEzO4g||82`UK9F#l0uN0oMX4P9#fk z!Rx0OHeBI`d&}GsWd#?!@fQ#!J~%Eo;H}SyC?UAut%nE~4&4bhcxON0DB%R}ZAeB+ zIK!qml/info-shadow-light@2x.png qml/info-top-shadow.png qml/ComicInfoView.qml - qml/info-favorites.png - qml/info-favorites@2x.png - qml/info-rating.png - qml/info-rating@2x.png - qml/info-tag.png - qml/info-tag@2x.png - qml/info-tick.png - qml/info-tick@2x.png + qml/info-favorites.svg + qml/info-rating.svg + qml/info-tag.svg + qml/info-tick.svg qml/prerendered_cover_shadow.png From 87b215cfb0e9ea30a2c3426ef3642e2faf280246 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 12 Feb 2026 21:26:28 +0100 Subject: [PATCH 060/187] Remove Qt5Compat dependency from qml --- YACReaderLibrary/qml/FlowView6.qml | 10 ++-- YACReaderLibrary/qml/FolderContentView6.qml | 29 ++++++++---- YACReaderLibrary/qml/GridComicsView6.qml | 51 ++++++++++----------- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/YACReaderLibrary/qml/FlowView6.qml b/YACReaderLibrary/qml/FlowView6.qml index 3e96df8c7..75da010a0 100644 --- a/YACReaderLibrary/qml/FlowView6.qml +++ b/YACReaderLibrary/qml/FlowView6.qml @@ -2,7 +2,7 @@ import QtQuick import QtQuick.Controls -import Qt5Compat.GraphicalEffects +import QtQuick.Effects import com.yacreader.ComicModel 1.0 @@ -39,14 +39,16 @@ Rectangle { mipmap: true asynchronous : true cache: false //TODO clear cache only when it is needed - opacity: 0 + layer.enabled: true visible: false } - FastBlur { + MultiEffect { anchors.fill: backgroundImg source: backgroundImg - radius: backgroundBlurRadius + blurEnabled: true + blur: 1.0 + blurMax: 64 opacity: backgroundBlurOpacity visible: backgroundBlurVisible } diff --git a/YACReaderLibrary/qml/FolderContentView6.qml b/YACReaderLibrary/qml/FolderContentView6.qml index 6b27c713c..015eeb141 100644 --- a/YACReaderLibrary/qml/FolderContentView6.qml +++ b/YACReaderLibrary/qml/FolderContentView6.qml @@ -3,7 +3,7 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts -import Qt5Compat.GraphicalEffects +import QtQuick.Effects import com.yacreader.ComicModel 1.0 @@ -119,18 +119,31 @@ Rectangle { mipmap: true asynchronous : true cache: true + visible: false + } + Item { + id: coverMask + anchors.fill: parent layer.enabled: true - layer.effect: OpacityMask { + layer.smooth: true + visible: false + + Rectangle { anchors.fill: parent - cached: true - maskSource: Rectangle { - width: coverElement.width - height: coverElement.height - radius: 10 - } + radius: 10 + color: "black" } } + + MultiEffect { + source: coverImage + anchors.fill: coverImage + maskEnabled: true + maskSource: coverMask + maskThresholdMin: 0.5 + maskSpreadAtMin: 1.0 + } } //is new diff --git a/YACReaderLibrary/qml/GridComicsView6.qml b/YACReaderLibrary/qml/GridComicsView6.qml index 9e0ff61b7..47c949260 100644 --- a/YACReaderLibrary/qml/GridComicsView6.qml +++ b/YACReaderLibrary/qml/GridComicsView6.qml @@ -3,7 +3,7 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts -import Qt5Compat.GraphicalEffects +import QtQuick.Effects import com.yacreader.ComicModel 1.0 @@ -33,14 +33,16 @@ SplitView { mipmap: true asynchronous : true cache: false //TODO clear cache only when it is needed - opacity: 0 + layer.enabled: true visible: false } - FastBlur { + MultiEffect { anchors.fill: backgroundImg source: backgroundImg - radius: backgroundBlurRadius + blurEnabled: true + blur: 1.0 + blurMax: 64 opacity: backgroundBlurOpacity visible: backgroundBlurVisible } @@ -472,18 +474,16 @@ SplitView { mipmap: true asynchronous : true cache: false //TODO clear cache only when it is needed - } - DropShadow { - anchors.fill: currentCoverElement - horizontalOffset: 0 - verticalOffset: 0 - radius: 8.0 - transparentBorder: true - //samples: 17 - color: "#FF000000" - source: currentCoverElement - visible: showDropShadow; + layer.enabled: showDropShadow + layer.effect: MultiEffect { + shadowEnabled: true + shadowColor: "#FF000000" + shadowBlur: 1.0 + blurMax: 8 + shadowHorizontalOffset: 0 + shadowVerticalOffset: 0 + } } ColumnLayout @@ -685,19 +685,16 @@ SplitView { color: "white" text: readButton.text } - } - - DropShadow { - anchors.fill: readButton - transparentBorder: true - horizontalOffset: 0 - verticalOffset: 0 - radius: 8.0 - //samples: 17 - color: "#AA000000" - source: readButton - visible: showDropShadow && !readButton.pressed + layer.enabled: showDropShadow && !readButton.pressed + layer.effect: MultiEffect { + shadowEnabled: true + shadowColor: "#AA000000" + shadowBlur: 1.0 + blurMax: 8 + shadowHorizontalOffset: 0 + shadowVerticalOffset: 0 + } } } } From 3ff93a570e1096b97de30689470970de3c99b06d Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 13 Feb 2026 12:37:33 +0100 Subject: [PATCH 061/187] Use only the qt6 versions of the qml implementations --- YACReaderLibrary/YACReaderLibrary.pro | 6 +- YACReaderLibrary/qml.qrc | 10 +- YACReaderLibrary/qml/FlowView.qml | 48 +- YACReaderLibrary/qml/FlowView6.qml | 227 ----- YACReaderLibrary/qml/FolderContentView.qml | 45 +- YACReaderLibrary/qml/FolderContentView6.qml | 490 ----------- YACReaderLibrary/qml/GridComicsView.qml | 112 +-- YACReaderLibrary/qml/GridComicsView6.qml | 924 -------------------- YACReaderLibrary/qml/InfoComicsView.qml | 6 +- YACReaderLibrary/qml/InfoComicsView6.qml | 131 --- YACReaderLibrary/qml/InfoFavorites.qml | 11 +- YACReaderLibrary/qml/InfoFavorites6.qml | 27 - YACReaderLibrary/qml/InfoRating.qml | 11 +- YACReaderLibrary/qml/InfoRating6.qml | 43 - YACReaderLibrary/qml/InfoTick.qml | 11 +- YACReaderLibrary/qml/InfoTick6.qml | 23 - YACReaderLibrary/qml6.qrc | 28 - 17 files changed, 144 insertions(+), 2009 deletions(-) delete mode 100644 YACReaderLibrary/qml/FlowView6.qml delete mode 100644 YACReaderLibrary/qml/FolderContentView6.qml delete mode 100644 YACReaderLibrary/qml/GridComicsView6.qml delete mode 100644 YACReaderLibrary/qml/InfoComicsView6.qml delete mode 100644 YACReaderLibrary/qml/InfoFavorites6.qml delete mode 100644 YACReaderLibrary/qml/InfoRating6.qml delete mode 100644 YACReaderLibrary/qml/InfoTick6.qml delete mode 100644 YACReaderLibrary/qml6.qrc diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index c1a88482c..ce7e78785 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -314,11 +314,7 @@ HEADERS += grid_comics_view.h \ SOURCES += grid_comics_view.cpp \ comics_view_transition.cpp -greaterThan(QT_MAJOR_VERSION, 5) { - RESOURCES += qml6.qrc -} else { - RESOURCES += qml.qrc -} +RESOURCES += qml.qrc win32:RESOURCES += qml_win.qrc unix:!macx:RESOURCES += qml_win.qrc macx:RESOURCES += qml_osx.qrc diff --git a/YACReaderLibrary/qml.qrc b/YACReaderLibrary/qml.qrc index c5f21e934..29badf8ef 100644 --- a/YACReaderLibrary/qml.qrc +++ b/YACReaderLibrary/qml.qrc @@ -2,12 +2,15 @@ qml/GridComicsView.qml qml/FolderContentView.qml + qml/FlowView.qml + qml/InfoTick.qml + qml/InfoFavorites.qml + qml/InfoRating.qml + qml/InfoComicsView.qml qml/tick.png qml/reading.png qml/star_menu.png qml/star_menu@2x.png - qml/InfoComicsView.qml - qml/FlowView.qml qml/info-indicator.png qml/info-shadow.png qml/info-indicator-light.png @@ -20,9 +23,6 @@ qml/info-rating.svg qml/info-tag.svg qml/info-tick.svg - qml/InfoTick.qml - qml/InfoFavorites.qml - qml/InfoRating.qml qml/prerendered_cover_shadow.png diff --git a/YACReaderLibrary/qml/FlowView.qml b/YACReaderLibrary/qml/FlowView.qml index 1953054a1..75da010a0 100644 --- a/YACReaderLibrary/qml/FlowView.qml +++ b/YACReaderLibrary/qml/FlowView.qml @@ -1,7 +1,8 @@ -import QtQuick 2.15 -import QtQuick.Controls 2.15 +import QtQuick -import QtGraphicalEffects 1.0 +import QtQuick.Controls + +import QtQuick.Effects import com.yacreader.ComicModel 1.0 @@ -38,14 +39,16 @@ Rectangle { mipmap: true asynchronous : true cache: false //TODO clear cache only when it is needed - opacity: 0 + layer.enabled: true visible: false } - FastBlur { + MultiEffect { anchors.fill: backgroundImg source: backgroundImg - radius: backgroundBlurRadius + blurEnabled: true + blur: 1.0 + blurMax: 64 opacity: backgroundBlurOpacity visible: backgroundBlurVisible } @@ -112,26 +115,32 @@ Rectangle { color:"transparent" + scale: mouseArea.containsMouse ? 1.025 : 1 + + Behavior on scale { + NumberAnimation { duration: 90 } + } + BusyIndicator { scale: 0.5 anchors.centerIn: parent running: coverElement.status === Image.Loading } - BorderImage { - anchors { - top: coverElement.top - left: coverElement.left - right: coverElement.right - bottom: coverElement.bottom - margins: -6 + BorderImage { + anchors { + top: coverElement.top + left: coverElement.left + right: coverElement.right + bottom: coverElement.bottom + margins: -6 + } + border { left: 10; top: 10; right: 10; bottom: 10 } + horizontalTileMode: BorderImage.Stretch + verticalTileMode: BorderImage.Stretch + source: "prerendered_cover_shadow.png" + visible: showDropShadow } - border { left: 10; top: 10; right: 10; bottom: 10 } - horizontalTileMode: BorderImage.Stretch - verticalTileMode: BorderImage.Stretch - source: "prerendered_cover_shadow.png" - visible: showDropShadow - } Image { id: coverElement @@ -144,6 +153,7 @@ Rectangle { cache: false } + //mark Image { id: mark diff --git a/YACReaderLibrary/qml/FlowView6.qml b/YACReaderLibrary/qml/FlowView6.qml deleted file mode 100644 index 75da010a0..000000000 --- a/YACReaderLibrary/qml/FlowView6.qml +++ /dev/null @@ -1,227 +0,0 @@ -import QtQuick - -import QtQuick.Controls - -import QtQuick.Effects - -import com.yacreader.ComicModel 1.0 - -Rectangle { - id: mainFlowContainer - - property url backgroundImageURL; - - property real backgroundBlurRadius : 100; //85; - property real backgroundBlurOpacity : 0.25; //0.35; - property bool backgroundBlurVisible : true; - - property real additionalBottomSpace : 0; - - property real verticalPadding: 12 - - property real itemsSpacing: 17 - - signal currentCoverChanged(int index) - - Rectangle { - id: background - color: "#2A2A2A" - anchors.fill: backgroundImg - } - - Image { - id: backgroundImg - width: parent.width - height: parent.height + additionalBottomSpace - source: backgroundImage - fillMode: Image.PreserveAspectCrop - smooth: true - mipmap: true - asynchronous : true - cache: false //TODO clear cache only when it is needed - layer.enabled: true - visible: false - } - - MultiEffect { - anchors.fill: backgroundImg - source: backgroundImg - blurEnabled: true - blur: 1.0 - blurMax: 64 - opacity: backgroundBlurOpacity - visible: backgroundBlurVisible - } - - anchors.margins: 0 - - MouseArea { - anchors.fill : list - onWheel: wheel => { - - if(list.moving) - return; - - var ci - if(wheel.angleDelta.y < 0) { - ci = Math.min(list.currentIndex+1, list.count - 1); - } - else if(wheel.angleDelta.y > 0) { - ci = Math.max(0,list.currentIndex-1); - } else { - return; - } - - list.currentIndex = ci; - } - } - - ListView { - id: list - objectName: "list" - anchors.fill: parent - - property int previousIndex; - - orientation: Qt.Horizontal - pixelAligned: true - - model: comicsList - - spacing: itemsSpacing - anchors.leftMargin: Math.floor(verticalPadding * 1.1) - - snapMode: ListView.SnapToItem - - highlightFollowsCurrentItem: true - highlightRangeMode: ListView.StrictlyEnforceRange - preferredHighlightEnd: 50 - - highlightMoveDuration: 250 - - onCurrentIndexChanged: currentIndex => { - if (list.currentIndex !== -1) { - mainFlowContainer.currentCoverChanged(list.currentIndex); - } - } - - delegate: Component { - - //cover - Rectangle { - width: Math.floor((list.height - (verticalPadding * 2)) * 0.65); - height: list.height - (verticalPadding * 2); - anchors.verticalCenter: parent.verticalCenter - - color:"transparent" - - scale: mouseArea.containsMouse ? 1.025 : 1 - - Behavior on scale { - NumberAnimation { duration: 90 } - } - - BusyIndicator { - scale: 0.5 - anchors.centerIn: parent - running: coverElement.status === Image.Loading - } - - BorderImage { - anchors { - top: coverElement.top - left: coverElement.left - right: coverElement.right - bottom: coverElement.bottom - margins: -6 - } - border { left: 10; top: 10; right: 10; bottom: 10 } - horizontalTileMode: BorderImage.Stretch - verticalTileMode: BorderImage.Stretch - source: "prerendered_cover_shadow.png" - visible: showDropShadow - } - - Image { - id: coverElement - anchors.fill: parent - source: cover_path - fillMode: Image.PreserveAspectCrop - smooth: true - mipmap: true - asynchronous : true - cache: false - } - - - //mark - Image { - id: mark - width: 23 - height: 23 - source: read_column&&show_marks?"tick.png":has_been_opened&&show_marks?"reading.png":"" - anchors {right: coverElement.right; top: coverElement.top; topMargin: 9; rightMargin: 9} - asynchronous : true - } - - //border - Rectangle { - width: coverElement.width - height: coverElement.height - anchors.centerIn: coverElement - color: "transparent" - border { - color: "#30FFFFFF" - width: 1 - } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton - - hoverEnabled: true - - onDoubleClicked: { - list.currentIndex = index; - currentIndexHelper.selectedItem(index); - } - - onReleased: mouse => { - list.currentIndex = index; - - if(mouse.button === Qt.RightButton) // context menu is requested - { - var coordinates = mainFlowContainer.mapFromItem(coverElement,mouseX,mouseY) - contextMenuHelper.requestedContextMenu(Qt.point(coordinates.x,coordinates.y)); - } - - mouse.accepted = true; - } - } - } - } - - focus: true - Keys.onPressed: event => { - - if (event.modifiers & Qt.ControlModifier || event.modifiers & Qt.ShiftModifier) - return; - var ci - if (event.key === Qt.Key_Right || event.key === Qt.Key_Down) { - ci = Math.min(list.currentIndex+1, list.count - 1); - } - else if (event.key === Qt.Key_Left || event.key === Qt.Key_Up) { - ci = Math.max(0,list.currentIndex-1); - } else { - return; - } - - list.currentIndex = ci; - - event.accepted = true; - } - - } -} diff --git a/YACReaderLibrary/qml/FolderContentView.qml b/YACReaderLibrary/qml/FolderContentView.qml index d49d42d16..015eeb141 100644 --- a/YACReaderLibrary/qml/FolderContentView.qml +++ b/YACReaderLibrary/qml/FolderContentView.qml @@ -1,15 +1,17 @@ -import QtQuick 2.15 +import QtQuick -import QtQuick.Controls 2.15 -import QtQuick.Layouts 1.12 +import QtQuick.Controls +import QtQuick.Layouts -import QtGraphicalEffects 1.0 +import QtQuick.Effects import com.yacreader.ComicModel 1.0 import com.yacreader.ComicInfo 1.0 import com.yacreader.ComicDB 1.0 +import QtQuick.Controls.Basic + Rectangle { id: main @@ -117,18 +119,31 @@ Rectangle { mipmap: true asynchronous : true cache: true + visible: false + } + Item { + id: coverMask + anchors.fill: parent layer.enabled: true - layer.effect: OpacityMask { + layer.smooth: true + visible: false + + Rectangle { anchors.fill: parent - cached: true - maskSource: Rectangle { - width: coverElement.width - height: coverElement.height - radius: 10 - } + radius: 10 + color: "black" } } + + MultiEffect { + source: coverImage + anchors.fill: coverImage + maskEnabled: true + maskSource: coverMask + maskThresholdMin: 0.5 + maskSpreadAtMin: 1.0 + } } //is new @@ -403,6 +418,14 @@ Rectangle { } } + onOriginYChanged: { + console.log(" origin changed ", grid.originY) + } + + onContentYChanged: { + console.log(" content y changed ", grid.contentY) + } + ScrollBar.vertical: ScrollBar { visible: grid.contentHeight > grid.height diff --git a/YACReaderLibrary/qml/FolderContentView6.qml b/YACReaderLibrary/qml/FolderContentView6.qml deleted file mode 100644 index 015eeb141..000000000 --- a/YACReaderLibrary/qml/FolderContentView6.qml +++ /dev/null @@ -1,490 +0,0 @@ -import QtQuick - -import QtQuick.Controls -import QtQuick.Layouts - -import QtQuick.Effects - -import com.yacreader.ComicModel 1.0 - -import com.yacreader.ComicInfo 1.0 -import com.yacreader.ComicDB 1.0 - -import QtQuick.Controls.Basic - -Rectangle { - id: main - - property int continuReadingHeight: 430; - property int topContentMargin: 20; - - color: backgroundColor - anchors.margins: 0 - - Component { - id: appDelegate - Rectangle - { - id: cell - width: grid.cellWidth - height: grid.cellHeight - color: "#00000000" - - scale: mouseArea.containsMouse ? 1.025 : 1 - - Behavior on scale { - NumberAnimation { duration: 90 } - } - - Rectangle { - id: realCell - - property int position : 0 - - width: itemWidth - height: itemHeight - - color: "transparent" - anchors.horizontalCenter: parent.horizontalCenter - - MouseArea { - id: mouseArea - - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton - - hoverEnabled: true - - onDoubleClicked: { - openHelper.openFolder(index); - } - - onPressed: mouse => { - var ci = grid.currentIndex; //save current index - - mouse.accepted = true; - - if(mouse.button === Qt.RightButton) // context menu is requested - { - var coordinates = main.mapFromItem(realCell,mouseX,mouseY) - contextMenuHelper.requestedFolderContextMenu(Qt.point(coordinates.x,coordinates.y), index); - mouse.accepted = false; - - } - } - - } - } - - /**/ - - Rectangle { - transform: Rotation { origin.x: coverWidth / 2; origin.y: coverHeight / 2; angle: -4} - width: coverElement.width - height: coverElement.height - radius: 10 - anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0} - color: "#20000000" - border { - color: "#20FFFFFF" - width: 1 - } - } - - Rectangle { - transform: Rotation { origin.x: coverWidth / 2; origin.y: coverHeight / 2; angle: 3} - width: coverElement.width - height: coverElement.height - radius: 10 - anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0} - color: "#88000000" - border { - color: "#20FFFFFF" - width: 1 - } - } - - Item { - width: coverWidth - height: coverHeight - anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0} - id: coverElement - - Image { - id: coverImage - anchors.fill: parent - source: cover_path - fillMode: Image.PreserveAspectCrop - smooth: true - mipmap: true - asynchronous : true - cache: true - visible: false - } - - Item { - id: coverMask - anchors.fill: parent - layer.enabled: true - layer.smooth: true - visible: false - - Rectangle { - anchors.fill: parent - radius: 10 - color: "black" - } - } - - MultiEffect { - source: coverImage - anchors.fill: coverImage - maskEnabled: true - maskSource: coverMask - maskThresholdMin: 0.5 - maskSpreadAtMin: 1.0 - } - } - - //is new - Rectangle { - width: 10 - height: 10 - radius: 5 - anchors { left: coverElement.left; top: coverElement.top; topMargin: 10; leftMargin: 10; } - color: "#FFFFCC00" - visible: (((new Date() / 1000) - added) < recent_range || ((new Date() / 1000) - updated) < recent_range) && show_recent - } - - //border - Rectangle { - width: coverElement.width - height: coverElement.height - radius: 10 - anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0} - color: "transparent" - border { - color: "#20FFFFFF" - width: 1 - } - } - - //folder name - Text { - id : titleText - anchors { top: coverElement.bottom; left: realCell.left; leftMargin: 4; rightMargin: 4; topMargin: 10; } - width: itemWidth - 8 - maximumLineCount: 2 - wrapMode: Text.WordWrap - text: name - elide: Text.ElideRight - color: titleColor - font.letterSpacing: fontSpacing - font.pointSize: fontSize - font.family: fontFamily - } - } - } - - Rectangle { - id: scrollView - objectName: "topScrollView" - anchors.fill: parent - anchors.margins: 0 - children: grid - - color: "transparent" - - function scrollToOrigin() { - grid.contentY = grid.originY - grid.contentX = grid.originX - } - - property Component continueReadingView: Component { - id: continueReadingView - Rectangle { - id: continueReadingTopView - color: "#00000000" - - height: list.count > 0 && showContinueReading ? main.continuReadingHeight : main.topContentMargin - - Rectangle { - color: continueReadingBackgroundColor - - id: continueReadingBackground - - width: main.width - height: main.continuReadingHeight - main.topContentMargin - - visible: list.count > 0 && showContinueReading - - Text { - id: continueReadingText - text: qsTr("Continue Reading...") - color: continueReadingColor - anchors.left: parent.left - anchors.top: parent.top - anchors.topMargin: 15 - anchors.bottomMargin: 20 - anchors.leftMargin: 25 - anchors.rightMargin: 0 - font.pointSize: 18 - font.weight: Font.DemiBold - } - - ListView { - id: list - objectName: "list" - anchors { top: continueReadingText.bottom; left: parent.left; right: parent.right; bottom: parent.bottom; } - - property int previousIndex; - property int verticalPadding: 20 - - orientation: Qt.Horizontal - pixelAligned: true - - model: comicsList - - spacing: 20 - anchors.topMargin: 15 - anchors.bottomMargin: 20 - anchors.leftMargin: 25 - anchors.rightMargin: 20 - - WheelHandler { - onWheel: event => { - if (list.contentWidth <= list.width) { - return; - } - - var newValue = Math.min(list.contentWidth - list.width - anchors.leftMargin, (Math.max(list.originX , list.contentX - event.angleDelta.y))); - list.contentX = newValue - } - } - - delegate: Component { - - //cover - Rectangle { - width: Math.floor((list.height - (list.verticalPadding * 2)) * 0.65); - height: list.height - (list.verticalPadding * 2); - - color:"transparent" - - scale: mouseArea.containsMouse ? 1.025 : 1 - - Behavior on scale { - NumberAnimation { duration: 90 } - } - - Image { - id: coverElement - anchors.fill: parent - source: cover_path - fillMode: Image.PreserveAspectCrop - smooth: true - mipmap: true - asynchronous : true - cache: true - } - - //title - Text { - id : comicTitleText - anchors { top: coverElement.bottom; left: coverElement.left; right: coverElement.right; leftMargin: 4; rightMargin: 4; topMargin: 4; } - width: itemWidth - 8 - maximumLineCount: 2 - wrapMode: Text.WordWrap - text: readable_title - elide: Text.ElideRight - color: titleColor - font.letterSpacing: fontSpacing - font.pointSize: fontSize - font.family: fontFamily - } - - //border - Rectangle { - width: coverElement.width - height: coverElement.height - anchors.centerIn: coverElement - color: "transparent" - border { - color: "#30FFFFFF" - width: 1 - } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton - - hoverEnabled: true - - onDoubleClicked: { - list.currentIndex = index; - openHelper.openComicFromContinueReadingList(index); - } - - onReleased: mouse => { - list.currentIndex = index; - - if(mouse.button === Qt.RightButton) // context menu is requested - { - var coordinates = main.mapFromItem(coverElement,mouseX,mouseY) - contextMenuHelper.requestedContinueReadingComicContextMenu(Qt.point(coordinates.x,coordinates.y), index); - } - - mouse.accepted = true; - } - } - } - } - - focus: true - } - } - } - } - - GridView { - id:grid - objectName: "grid" - anchors.fill: parent - cellHeight: cellCustomHeight - header: continueReadingView - focus: true - model: foldersList - delegate: appDelegate - anchors.topMargin: 0 - anchors.bottomMargin: 10 - anchors.leftMargin: 0 - anchors.rightMargin: 0 - pixelAligned: true - highlightFollowsCurrentItem: true - - currentIndex: 0 - cacheBuffer: 0 - - interactive: true - - move: Transition { - NumberAnimation { properties: "x,y"; duration: 250 } - } - - moveDisplaced: Transition { - NumberAnimation { properties: "x,y"; duration: 250 } - } - - remove: Transition { - ParallelAnimation { - NumberAnimation { property: "opacity"; to: 0; duration: 250 } - - } - } - - removeDisplaced: Transition { - NumberAnimation { properties: "x,y"; duration: 250 } - } - - displaced: Transition { - NumberAnimation { properties: "x,y"; duration: 250 } - } - - function numCellsPerRow() { - return Math.floor(width / cellCustomWidth); - } - - onWidthChanged: { - calculateCellWidths(cellCustomWidth); - } - - function calculateCellWidths(cWidth) { - var wholeCells = Math.floor(width / cWidth); - var rest = width - (cWidth * wholeCells) - - grid.cellWidth = cWidth + Math.floor(rest / wholeCells); - } - - WheelHandler { - onWheel: event => { - if (grid.contentHeight <= grid.height) { - return; - } - - var newValue = Math.min((grid.contentHeight - grid.height + grid.originY), (Math.max(grid.originY , grid.contentY - event.angleDelta.y))); - grid.contentY = newValue; - } - } - - onOriginYChanged: { - console.log(" origin changed ", grid.originY) - } - - onContentYChanged: { - console.log(" content y changed ", grid.contentY) - } - - ScrollBar.vertical: ScrollBar { - visible: grid.contentHeight > grid.height - - contentItem: Item { - implicitWidth: 12 - implicitHeight: 26 - Rectangle { - color: "#88424242" - anchors.fill: parent - anchors.topMargin: 6 - anchors.leftMargin: 3 - anchors.rightMargin: 2 - anchors.bottomMargin: 6 - border.color: "#AA313131" - border.width: 1 - radius: 3.5 - } - } - } - - DropArea { - anchors.fill: parent - - onEntered: drag => { - if(drag.hasUrls) - { - if(dropManager.canDropUrls(drag.urls, drag.action)) - { - drag.accepted = true; - }else - drag.accepted = false; - } - else if (dropManager.canDropFormats(drag.formats)) { - drag.accepted = true; - } else - drag.accepted = false; - } - - onDropped: drop => { - if(drop.hasUrls && dropManager.canDropUrls(drop.urls, drop.action)) - { - dropManager.droppedFiles(drop.urls, drop.action); - } - else{ - if (dropManager.canDropFormats(drop.formats)) - { - var destItem = grid.itemAt(drop.x,drop.y + grid.contentY); - var destLocalX = grid.mapToItem(destItem,drop.x,drop.y + grid.contentY).x - var realIndex = grid.indexAt(drop.x,drop.y + grid.contentY); - - if(realIndex === -1) - realIndex = grid.count - 1; - - var destIndex = destLocalX < (grid.cellWidth / 2) ? realIndex : realIndex + 1; - dropManager.droppedComicsForResortingAt("", destIndex); - } - } - } - } - } - } -} diff --git a/YACReaderLibrary/qml/GridComicsView.qml b/YACReaderLibrary/qml/GridComicsView.qml index bede0f79b..47c949260 100644 --- a/YACReaderLibrary/qml/GridComicsView.qml +++ b/YACReaderLibrary/qml/GridComicsView.qml @@ -1,15 +1,17 @@ -import QtQuick 2.15 +import QtQuick -import QtQuick.Controls 2.15 -import QtQuick.Layouts 1.12 +import QtQuick.Controls +import QtQuick.Layouts -import QtGraphicalEffects 1.0 +import QtQuick.Effects import com.yacreader.ComicModel 1.0 import com.yacreader.ComicInfo 1.0 import com.yacreader.ComicDB 1.0 +import QtQuick.Controls.Basic + SplitView { orientation: Qt.Horizontal handle: Rectangle { @@ -31,14 +33,16 @@ SplitView { mipmap: true asynchronous : true cache: false //TODO clear cache only when it is needed - opacity: 0 + layer.enabled: true visible: false } - FastBlur { + MultiEffect { anchors.fill: backgroundImg source: backgroundImg - radius: backgroundBlurRadius + blurEnabled: true + blur: 1.0 + blurMax: 64 opacity: backgroundBlurOpacity visible: backgroundBlurVisible } @@ -377,30 +381,38 @@ SplitView { comicsSelectionHelper.clear(); comicsSelectionHelper.selectIndex(index); grid.currentIndex = index; - ratingConextMenu.popup(); - } - } - - Menu { - background: Rectangle { - implicitWidth: 42 - implicitHeight: 100 - //border.color: "#222" - //color: "#444" - } + ratingLoader.active = true; + ratingLoader.item.popup(); + } + } + + Loader { + id: ratingLoader + active: false + sourceComponent: ratingConextMenuComponent + } + + Component { + id: ratingConextMenuComponent + Menu { + background: Rectangle { + implicitWidth: 42 + implicitHeight: 100 + } - id: ratingConextMenu + id: ratingConextMenu - Action { text: "1"; enabled: true; onTriggered: comicRatingHelper.rate(index,1) } - Action { text: "2"; enabled: true; onTriggered: comicRatingHelper.rate(index,2) } - Action { text: "3"; enabled: true; onTriggered: comicRatingHelper.rate(index,3) } - Action { text: "4"; enabled: true; onTriggered: comicRatingHelper.rate(index,4) } - Action { text: "5"; enabled: true; onTriggered: comicRatingHelper.rate(index,5) } + Action { text: "1"; enabled: true; onTriggered: comicRatingHelper.rate(index,1) } + Action { text: "2"; enabled: true; onTriggered: comicRatingHelper.rate(index,2) } + Action { text: "3"; enabled: true; onTriggered: comicRatingHelper.rate(index,3) } + Action { text: "4"; enabled: true; onTriggered: comicRatingHelper.rate(index,4) } + Action { text: "5"; enabled: true; onTriggered: comicRatingHelper.rate(index,5) } - delegate: MenuItem { - implicitHeight: 30 - } - } + delegate: MenuItem { + implicitHeight: 30 + } + } + } } //comic rating @@ -462,17 +474,16 @@ SplitView { mipmap: true asynchronous : true cache: false //TODO clear cache only when it is needed - } - DropShadow { - anchors.fill: currentCoverElement - horizontalOffset: 0 - verticalOffset: 0 - radius: 8.0 - samples: 17 - color: "#FF000000" - source: currentCoverElement - visible: showDropShadow; + layer.enabled: showDropShadow + layer.effect: MultiEffect { + shadowEnabled: true + shadowColor: "#FF000000" + shadowBlur: 1.0 + blurMax: 8 + shadowHorizontalOffset: 0 + shadowVerticalOffset: 0 + } } ColumnLayout @@ -503,7 +514,8 @@ SplitView { font.pixelSize: 21 wrapMode: Text.WordWrap - text: currentComic ? currentComic.getTitleIncludingNumber() : "" } + text: currentComic?.getTitleIncludingNumber() ?? "" + } Flow { spacing: 0 @@ -615,6 +627,7 @@ SplitView { ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + contentWidth: -1 contentItem: currentComicInfoSinopsis id: synopsisScroller @@ -645,6 +658,7 @@ SplitView { } Button { + containmentMask: null text: "Read" id: readButton x: currentCoverElement.anchors.rightMargin + currentCoverElement.paintedWidth + currentCoverElement.anchors.rightMargin @@ -671,18 +685,16 @@ SplitView { color: "white" text: readButton.text } - } - - DropShadow { - anchors.fill: readButton - horizontalOffset: 0 - verticalOffset: 0 - radius: 8.0 - samples: 17 - color: "#AA000000" - source: readButton - visible: showDropShadow && !readButton.pressed + layer.enabled: showDropShadow && !readButton.pressed + layer.effect: MultiEffect { + shadowEnabled: true + shadowColor: "#AA000000" + shadowBlur: 1.0 + blurMax: 8 + shadowHorizontalOffset: 0 + shadowVerticalOffset: 0 + } } } } diff --git a/YACReaderLibrary/qml/GridComicsView6.qml b/YACReaderLibrary/qml/GridComicsView6.qml deleted file mode 100644 index 47c949260..000000000 --- a/YACReaderLibrary/qml/GridComicsView6.qml +++ /dev/null @@ -1,924 +0,0 @@ -import QtQuick - -import QtQuick.Controls -import QtQuick.Layouts - -import QtQuick.Effects - -import com.yacreader.ComicModel 1.0 - -import com.yacreader.ComicInfo 1.0 -import com.yacreader.ComicDB 1.0 - -import QtQuick.Controls.Basic - -SplitView { - orientation: Qt.Horizontal - handle: Rectangle { - border.width : 0 - implicitWidth: 10 - color: info_container.color - } - - Rectangle { - id: main - clip: true - - Image { - id: backgroundImg - anchors.fill: parent - source: backgroundImage - fillMode: Image.PreserveAspectCrop - smooth: true - mipmap: true - asynchronous : true - cache: false //TODO clear cache only when it is needed - layer.enabled: true - visible: false - } - - MultiEffect { - anchors.fill: backgroundImg - source: backgroundImg - blurEnabled: true - blur: 1.0 - blurMax: 64 - opacity: backgroundBlurOpacity - visible: backgroundBlurVisible - } - - color: backgroundColor - width: parent.width - (info_container.visible ? info_container.width : 0) - SplitView.fillWidth: true - SplitView.minimumWidth: coverWidth + 100 - height: parent.height - anchors.margins: 0 - - Component { - id: appDelegate - Rectangle - { - id: cell - width: grid.cellWidth - height: grid.cellHeight - color: "#00000000" - - scale: mouseArea.containsMouse ? 1.025 : 1 - - Behavior on scale { - NumberAnimation { duration: 90 } - } - - BorderImage { - anchors { - top: realCell.top - left: realCell.left - right: realCell.right - bottom: realCell.bottom - margins: -10 - } - border { left: 10; top: 10; right: 10; bottom: 10 } - horizontalTileMode: BorderImage.Stretch - verticalTileMode: BorderImage.Stretch - source: "prerendered_cover_shadow.png" - visible: showDropShadow - } - - Rectangle { - id: realCell - - property int position : 0 - property bool dragging: false; - Drag.active: mouseArea.drag.active - Drag.hotSpot.x: 32 - Drag.hotSpot.y: 32 - Drag.dragType: Drag.Automatic - //Drag.mimeData: { "x": 1 } - Drag.proposedAction: Qt.CopyAction - Drag.onActiveChanged: { - if(!dragging) - { - dragManager.startDrag(); - dragging = true; - }else - dragging = false; - } - - width: itemWidth - height: itemHeight - - color: ((dummyValue || !dummyValue) && comicsSelectionHelper.isSelectedIndex(index))?selectedColor:cellColor; - //border.color: ((dummyValue || !dummyValue) && comicsSelectionHelper.isSelectedIndex(index))?selectedBorderColor:borderColor; - //border.width: ?1:0; - anchors.horizontalCenter: parent.horizontalCenter - - Rectangle - { - id: mouseOverBorder - - property bool commonBorder : false - - property int lBorderwidth : 2 - property int rBorderwidth : 2 - property int tBorderwidth : 2 - property int bBorderwidth : 2 - - property int commonBorderWidth : 1 - - z : -1 - - color: "#00000000" - - anchors - { - left: parent.left - right: parent.right - top: parent.top - bottom: parent.bottom - - topMargin : commonBorder ? -commonBorderWidth : -tBorderwidth - bottomMargin : commonBorder ? -commonBorderWidth : -bBorderwidth - leftMargin : commonBorder ? -commonBorderWidth : -lBorderwidth - rightMargin : commonBorder ? -commonBorderWidth : -rBorderwidth - } - - border.color: selectedBorderColor - border.width: 3 - - opacity: (dummyValue || !dummyValue) && comicsSelectionHelper.isSelectedIndex(index) ? 1 : 0 - - Behavior on opacity { - NumberAnimation { duration: 300 } - } - - radius : 2 - } - - - MouseArea { - id: mouseArea - drag.target: realCell - - drag.minimumX: 0 - drag.maximumX: 0 - drag.minimumY: 0 - drag.maximumY: 0 - - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton - - hoverEnabled: true - - onDoubleClicked: { - comicsSelectionHelper.clear(); - - comicsSelectionHelper.selectIndex(index); - grid.currentIndex = index; - currentIndexHelper.selectedItem(index); - } - - function selectAll(from,to) - { - for(var i = from;i<=to;i++) - { - comicsSelectionHelper.selectIndex(i); - } - } - - onPressed: mouse => { - var ci = grid.currentIndex; //save current index - - /*if(mouse.button != Qt.RightButton && !(mouse.modifiers & Qt.ControlModifier || mouse.modifiers & Qt.ShiftModifier)) - { - if(!comicsSelectionHelper.isSelectedIndex(index)) - comicsSelectionHelper.clear(); - }*/ - - if(mouse.modifiers & Qt.ShiftModifier) - if(index < ci) - { - selectAll(index,ci); - grid.currentIndex = index; - } - else if (index > ci) - { - selectAll(ci,index); - grid.currentIndex = index; - } - - mouse.accepted = true; - - if(mouse.button === Qt.RightButton) // context menu is requested - { - if(!comicsSelectionHelper.isSelectedIndex(index)) //the context menu is requested outside the current selection, the selection will be - { - currentIndexHelper.setCurrentIndex(index) - grid.currentIndex = index; - } - - var coordinates = main.mapFromItem(realCell,mouseX,mouseY) - contextMenuHelper.requestedContextMenu(Qt.point(coordinates.x,coordinates.y)); - mouse.accepted = false; - - } else //left button - { - - if(mouse.modifiers & Qt.ControlModifier) - { - if(comicsSelectionHelper.isSelectedIndex(index)) - { - if(comicsSelectionHelper.numItemsSelected()>1) - { - comicsSelectionHelper.deselectIndex(index); - if(grid.currentIndex === index) - grid.currentIndex = comicsSelectionHelper.lastSelectedIndex(); - } - } - else - { - comicsSelectionHelper.selectIndex(index); - grid.currentIndex = index; - } - } - - if(mouse.button !== Qt.RightButton && !(mouse.modifiers & Qt.ControlModifier || mouse.modifiers & Qt.ShiftModifier)) //just left button click - { - if(comicsSelectionHelper.isSelectedIndex(index)) //the context menu is requested outside the current selection, the selection will be - { - - } - else - { - currentIndexHelper.setCurrentIndex(index) - } - - grid.currentIndex = index; - } - } - - } - - onReleased: mouse => { - if(mouse.button === Qt.LeftButton && !(mouse.modifiers & Qt.ControlModifier || mouse.modifiers & Qt.ShiftModifier)) - { - if(comicsSelectionHelper.isSelectedIndex(index)) - { - currentIndexHelper.setCurrentIndex(index) - grid.currentIndex = index; - } - } - } - } - } - - /**/ - - //cover - Image { - id: coverElement - width: coverWidth - height: coverHeight - 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 needed - - } - - //is new - Rectangle { - width: 10 - height: 10 - radius: 5 - anchors { left: coverElement.left; top: coverElement.top; topMargin: 5; leftMargin: 5; } - color: "#FFFFCC00" - visible: (((new Date() / 1000) - added_date) < recent_range) && show_recent - } - - //border - Rectangle { - width: coverElement.width - height: coverElement.height - 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: 9; rightMargin: 9} - asynchronous : true - } - - //title - Text { - id : titleText - anchors { top: coverElement.bottom; left: realCell.left; leftMargin: 4; rightMargin: 4; topMargin: 4; } - width: itemWidth - 8 - maximumLineCount: 2 - wrapMode: Text.WordWrap - text: title - elide: Text.ElideRight - color: titleColor - clip: true - font.letterSpacing: fontSpacing - font.pointSize: fontSize - font.family: fontFamily - } - - //number - Text { - anchors {bottom: realCell.bottom; left: realCell.left; margins: 4} - text: number?"#"+number:"" - color: textColor - font.letterSpacing: fontSpacing - font.pointSize: fontSize - font.family: fontFamily - } - - //page icon - Image { - id: pageImage - anchors {bottom: realCell.bottom; right: realCell.right; bottomMargin: 5; rightMargin: 4; leftMargin: 4} - source: "page.png" - width: 8 - height: 10 - } - - //numPages - Text { - id: pages - anchors {bottom: realCell.bottom; right: pageImage.left; margins: 4} - text: has_been_opened?current_page+"/"+num_pages:num_pages - color: textColor - font.letterSpacing: fontSpacing - font.pointSize: fontSize - font.family: fontFamily - } - - //rating icon - Image { - id: ratingImage - anchors {bottom: realCell.bottom; right: pageImage.left; bottomMargin: 5; rightMargin: Math.floor(pages.width)+12} - source: "star.png" - width: 13 - height: 11 - - MouseArea { - anchors.fill: parent - onPressed: { - console.log("rating"); - comicsSelectionHelper.clear(); - comicsSelectionHelper.selectIndex(index); - grid.currentIndex = index; - ratingLoader.active = true; - ratingLoader.item.popup(); - } - } - - Loader { - id: ratingLoader - active: false - sourceComponent: ratingConextMenuComponent - } - - Component { - id: ratingConextMenuComponent - Menu { - background: Rectangle { - implicitWidth: 42 - implicitHeight: 100 - } - - id: ratingConextMenu - - Action { text: "1"; enabled: true; onTriggered: comicRatingHelper.rate(index,1) } - Action { text: "2"; enabled: true; onTriggered: comicRatingHelper.rate(index,2) } - Action { text: "3"; enabled: true; onTriggered: comicRatingHelper.rate(index,3) } - Action { text: "4"; enabled: true; onTriggered: comicRatingHelper.rate(index,4) } - Action { text: "5"; enabled: true; onTriggered: comicRatingHelper.rate(index,5) } - - delegate: MenuItem { - implicitHeight: 30 - } - } - } - } - - //comic rating - Text { - id: comicRating - anchors {bottom: realCell.bottom; right: ratingImage.left; margins: 4} - text: rating>0?rating:"-" - color: textColor - } - } - } - - Rectangle { - id: scrollView - objectName: "topScrollView" - anchors.fill: parent - anchors.margins: 0 - children: grid - - color: "transparent" - - function scrollToOrigin() { - grid.contentY = grid.originY - grid.contentX = grid.originX - } - - property Component currentComicView: Component { - id: currentComicView - Rectangle { - id: currentComicViewTopView - color: "#00000000" - - height: showCurrentComic ? 270 : 20 - - Rectangle { - color: currentComicBackgroundColor - - id: currentComicVisualView - - width: main.width - height: 250 - - visible: showCurrentComic - - //cover - Image { - id: currentCoverElement - anchors.fill: parent - - anchors.leftMargin: 15 - anchors.topMargin: 15 - anchors.bottomMargin: 15 - anchors.rightMargin: 15 - horizontalAlignment: Image.AlignLeft - anchors {horizontalCenter: parent.horizontalCenter; top: parent.top; topMargin: 0} - source: comicsList.getCoverUrlPathForComicHash(currentComicInfo.hash.toString()) - fillMode: Image.PreserveAspectFit - smooth: true - mipmap: true - asynchronous : true - cache: false //TODO clear cache only when it is needed - - layer.enabled: showDropShadow - layer.effect: MultiEffect { - shadowEnabled: true - shadowColor: "#FF000000" - shadowBlur: 1.0 - blurMax: 8 - shadowHorizontalOffset: 0 - shadowVerticalOffset: 0 - } - } - - ColumnLayout - { - id: currentComicInfoView - - x: currentCoverElement.anchors.rightMargin + currentCoverElement.paintedWidth + currentCoverElement.anchors.rightMargin - //y: currentCoverElement.anchors.topMargin - - anchors.top: currentCoverElement.top - anchors.right: parent.right - anchors.left: readButton.left - - spacing: 9 - - Text { - Layout.topMargin: 7 - Layout.fillWidth: true - Layout.rightMargin: 20 - - Layout.alignment: Qt.AlignTop | Qt.AlignLeft - - id: currentComicInfoTitleView - - color: infoTitleColor - font.family: "Arial" - font.bold: true - font.pixelSize: 21 - wrapMode: Text.WordWrap - - text: currentComic?.getTitleIncludingNumber() ?? "" - } - - Flow { - spacing: 0 - Layout.alignment: Qt.AlignTop | Qt.AlignLeft - Layout.fillWidth: true - Layout.fillHeight: false - - id: currentComicDetailsFlowView - property font infoFont: Qt.font({ - family: "Arial", - pixelSize: 14 - }); - property string infoFlowTextColor: infoTextColor - - Text { - id: currentComicInfoVolume - color: currentComicDetailsFlowView.infoFlowTextColor - font: currentComicDetailsFlowView.infoFont - text: currentComicInfo.volume ? currentComicInfo.volume : "" - rightPadding: 20 - visible: currentComicInfo.volume ? true : false - } - - Text { - id: currentComicInfoNumbering - color: currentComicDetailsFlowView.infoFlowTextColor - font: currentComicDetailsFlowView.infoFont - text: currentComicInfo.number + "/" + currentComicInfo.count - rightPadding: 20 - visible : currentComicInfo.number ? true : false - } - - Text { - id: currentComicInfoArc - color: currentComicDetailsFlowView.infoFlowTextColor - font: currentComicDetailsFlowView.infoFont - text: currentComicInfo.getStoryArcInfoString() - rightPadding: 20 - visible : currentComicInfo.getStoryArcInfoString().length > 0 - } - - Text { - id: currentComicInfoAlternate - color: currentComicDetailsFlowView.infoFlowTextColor - font: currentComicDetailsFlowView.infoFont - text: currentComicInfo.getAlternateSeriesString() - rightPadding: 20 - visible : currentComicInfo.getStoryArcInfoString().length > 0 - } - - Text { - id: currentComicInfoSeriesGroup - color: currentComicDetailsFlowView.infoFlowTextColor - font: currentComicDetailsFlowView.infoFont - text: currentComicInfo.seriesGroup ? currentComicInfo.seriesGroup : "" - rightPadding: 20 - visible: currentComicInfo.seriesGroup ? true : false - } - - Text { - id: currentComicInfoGenre - color: currentComicDetailsFlowView.infoFlowTextColor - font: currentComicDetailsFlowView.infoFont - text: currentComicInfo.genere ? currentComicInfo.genere : "" - rightPadding: 20 - visible: currentComicInfo.genere ? true : false - } - - Text { - id: currentComicInfoDate - color: currentComicDetailsFlowView.infoFlowTextColor - font: currentComicDetailsFlowView.infoFont - text: currentComicInfo.date ? currentComicInfo.date : "" - rightPadding: 20 - visible: currentComicInfo.date ? true : false - } - - Text { - id: currentComicInfoPages - color: currentComicDetailsFlowView.infoFlowTextColor - font: currentComicDetailsFlowView.infoFont - text: (currentComicInfo.numPages ? currentComicInfo.numPages : "") + " pages" - rightPadding: 20 - visible: currentComicInfo.numPages ? true : false - } - - Text { - id: currentComicInfoShowInComicVine - font: currentComicDetailsFlowView.infoFont - color: "#ffcc00" - text: "Show in Comic Vine" - visible: currentComicInfo.comicVineID ? true : false - MouseArea { - anchors.fill: parent - onClicked: { - Qt.openUrlExternally("http://www.comicvine.com/comic/4000-%1/".arg(comicInfo.comicVineID)); - } - } - } - } - - ScrollView { - Layout.topMargin: 6 - Layout.rightMargin: 30 - Layout.bottomMargin: 5 - Layout.fillWidth: true - Layout.maximumHeight: (currentComicVisualView.height * 0.32) - Layout.maximumWidth: 960 - - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - - contentWidth: -1 - contentItem: currentComicInfoSinopsis - - id: synopsisScroller - - clip: true - - Text { - Layout.maximumWidth: 960 - - width: synopsisScroller.width - - id: currentComicInfoSinopsis - color: infoTitleColor - font.family: "Arial" - font.pixelSize: 14 - wrapMode: Text.WordWrap - - text: '' + currentComicInfo.synopsis ?? "" + '' - visible: currentComicInfo.synopsis ?? false - textFormat: Text.RichText - } - } - } - - Button { - containmentMask: null - text: "Read" - id: readButton - x: currentCoverElement.anchors.rightMargin + currentCoverElement.paintedWidth + currentCoverElement.anchors.rightMargin - anchors.bottom: currentCoverElement.bottom - anchors.bottomMargin: 15 - - onClicked: comicOpener.triggerOpenCurrentComic() - background: Rectangle { - implicitWidth: 100 - implicitHeight: 30 - border.width: readButton.activeFocus ? 2 : 1 - border.color: "#FFCC00" - radius: height / 2 - color: "#FFCC00" - } - - contentItem: Text { - renderType: Text.NativeRendering - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font.family: "Arial" - font.pointSize: 12 - font.bold: true - color: "white" - text: readButton.text - } - - layer.enabled: showDropShadow && !readButton.pressed - layer.effect: MultiEffect { - shadowEnabled: true - shadowColor: "#AA000000" - shadowBlur: 1.0 - blurMax: 8 - shadowHorizontalOffset: 0 - shadowVerticalOffset: 0 - } - } - } - } - } - - GridView { - id:grid - objectName: "grid" - anchors.fill: parent - cellHeight: cellCustomHeight - header: currentComicView - focus: true - model: comicsList - delegate: appDelegate - anchors.topMargin: 0 - anchors.bottomMargin: 10 - anchors.leftMargin: 0 - anchors.rightMargin: 0 - pixelAligned: true - highlightFollowsCurrentItem: true - - currentIndex: 0 - cacheBuffer: 0 - - interactive: true - - move: Transition { - NumberAnimation { properties: "x,y"; duration: 250 } - } - - moveDisplaced: Transition { - NumberAnimation { properties: "x,y"; duration: 250 } - } - - remove: Transition { - ParallelAnimation { - NumberAnimation { property: "opacity"; to: 0; duration: 250 } - - } - } - - removeDisplaced: Transition { - NumberAnimation { properties: "x,y"; duration: 250 } - } - - - - displaced: Transition { - NumberAnimation { properties: "x,y"; duration: 250 } - } - - function numCellsPerRow() { - return Math.floor(width / cellCustomWidth); - } - - onWidthChanged: { - calculateCellWidths(cellCustomWidth); - } - - function calculateCellWidths(cWidth) { - var wholeCells = Math.floor(width / cWidth); - var rest = width - (cWidth * wholeCells) - - grid.cellWidth = cWidth + Math.floor(rest / wholeCells); - } - - WheelHandler { - onWheel: { - if (grid.contentHeight <= grid.height) { - return; - } - - var newValue = Math.min((grid.contentHeight - grid.height + grid.originY), (Math.max(grid.originY , grid.contentY - event.angleDelta.y))); - grid.contentY = newValue; - } - } - - ScrollBar.vertical: ScrollBar { - visible: grid.contentHeight > grid.height - - contentItem: Item { - implicitWidth: 12 - implicitHeight: 26 - Rectangle { - color: "#88424242" - anchors.fill: parent - anchors.topMargin: 6 - anchors.leftMargin: 3 - anchors.rightMargin: 2 - anchors.bottomMargin: 6 - border.color: "#AA313131" - border.width: 1 - radius: 3.5 - } - } - } - - Keys.onPressed: { - if (event.modifiers & Qt.ControlModifier || event.modifiers & Qt.ShiftModifier) { - event.accepted = true - return; - } - - var numCells = grid.numCellsPerRow(); - var ci = 0; - if (event.key === Qt.Key_Right) { - ci = Math.min(grid.currentIndex+1,grid.count - 1); - } - else if (event.key === Qt.Key_Left) { - ci = Math.max(0,grid.currentIndex-1); - } - else if (event.key === Qt.Key_Up) { - ci = Math.max(0,grid.currentIndex-numCells); - } - else if (event.key === Qt.Key_Down) { - ci = Math.min(grid.currentIndex+numCells,grid.count - 1); - } else { - return; - } - - event.accepted = true; - grid.currentIndex = -1 - comicsSelectionHelper.clear(); - currentIndexHelper.setCurrentIndex(ci); - grid.currentIndex = ci; - } - - DropArea { - anchors.fill: parent - - onEntered: drag => { - if(drag.hasUrls) - { - if(dropManager.canDropUrls(drag.urls, drag.action)) - { - drag.accepted = true; - }else - drag.accepted = false; - } - else if (dropManager.canDropFormats(drag.formats)) { - drag.accepted = true; - } else - drag.accepted = false; - } - - onDropped: drop => { - if(drop.hasUrls && dropManager.canDropUrls(drop.urls, drop.action)) - { - dropManager.droppedFiles(drop.urls, drop.action); - } - else{ - if (dropManager.canDropFormats(drop.formats)) - { - var destItem = grid.itemAt(drop.x,drop.y + grid.contentY); - var destLocalX = grid.mapToItem(destItem,drop.x,drop.y + grid.contentY).x - var realIndex = grid.indexAt(drop.x,drop.y + grid.contentY); - - if(realIndex === -1) - realIndex = grid.count - 1; - - var destIndex = destLocalX < (grid.cellWidth / 2) ? realIndex : realIndex + 1; - dropManager.droppedComicsForResortingAt("", destIndex); - } - } - } - } - } - } - } - - Rectangle { - id: info_container - objectName: "infoContainer" - SplitView.preferredWidth: 350 - SplitView.minimumWidth: 350 - SplitView.maximumWidth: 960 - height: parent.height - - color: infoBackgroundColor - - visible: showInfo - - Flickable{ - id: infoFlickable - anchors.fill: parent - anchors.margins: 0 - - contentWidth: infoView.width - contentHeight: infoView.height - - ComicInfoView { - id: infoView - width: info_container.width - } - - WheelHandler { - onWheel: { - if (infoFlickable.contentHeight <= infoFlickable.height) { - return; - } - - var newValue = Math.min((infoFlickable.contentHeight - infoFlickable.height), (Math.max(infoFlickable.originY , infoFlickable.contentY - event.angleDelta.y))); - infoFlickable.contentY = newValue; - } - } - - ScrollBar.vertical: ScrollBar { - visible: infoFlickable.contentHeight > infoFlickable.height - - contentItem: Item { - implicitWidth: 12 - implicitHeight: 26 - Rectangle { - color: "#424246" - anchors.fill: parent - anchors.topMargin: 6 - anchors.leftMargin: 5 - anchors.rightMargin: 4 - anchors.bottomMargin: 6 - radius: 2 - } - } - } - } - - } -} diff --git a/YACReaderLibrary/qml/InfoComicsView.qml b/YACReaderLibrary/qml/InfoComicsView.qml index 650a3bc1d..e4adaf4bf 100644 --- a/YACReaderLibrary/qml/InfoComicsView.qml +++ b/YACReaderLibrary/qml/InfoComicsView.qml @@ -1,9 +1,11 @@ -import QtQuick 2.15 +import QtQuick -import QtQuick.Controls 2.15 +import QtQuick.Controls import com.yacreader.ComicModel 1.0 +import QtQuick.Controls.Basic + Rectangle { id: main diff --git a/YACReaderLibrary/qml/InfoComicsView6.qml b/YACReaderLibrary/qml/InfoComicsView6.qml deleted file mode 100644 index e4adaf4bf..000000000 --- a/YACReaderLibrary/qml/InfoComicsView6.qml +++ /dev/null @@ -1,131 +0,0 @@ -import QtQuick - -import QtQuick.Controls - -import com.yacreader.ComicModel 1.0 - -import QtQuick.Controls.Basic - -Rectangle { - id: main - - color: infoBackgroundColor - - //width: parent.width - //height: parent.height - anchors.margins: 0 - - FlowView { - id: flow - objectName: "flow" - height: 256 //TODO dynamic size? - - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - - additionalBottomSpace: indicator.height - } - - Image { - id: top_shadow - source: topShadow - width: parent.width - fillMode: Image.TileHorizontally - } - - Rectangle { - id: indicator_container - width: parent.width - y: 250 - - Image { - id: indicator - source: infoIndicator - } - - Image { - id: bottom_shadow - x: indicator.width - width: parent.width - indicator.width - source: infoShadow - fillMode: Image.TileHorizontally - } - } - - Rectangle { - id: info_container - width: parent.width - y: flow.height + flow.additionalBottomSpace - 6 - height: parent.height - y - - clip: true - - color: infoBackgroundColor - - Flickable{ - id: infoFlickable - anchors.fill: parent - anchors.margins: 0 - - contentWidth: infoView.width - contentHeight: infoView.height - - ComicInfoView { - id: infoView - width: info_container.width - 14 - } - - WheelHandler { - onWheel: { - if (infoFlickable.contentHeight <= infoFlickable.height) { - return; - } - - var newValue = Math.min((infoFlickable.contentHeight - infoFlickable.height), (Math.max(infoFlickable.originY , infoFlickable.contentY - event.angleDelta.y))); - infoFlickable.contentY = newValue; - } - } - - ScrollBar.vertical: ScrollBar { - visible: infoFlickable.contentHeight > infoFlickable.height - - contentItem: Item { - implicitWidth: 12 - implicitHeight: 26 - Rectangle { - color: "#424246" - anchors.fill: parent - anchors.topMargin: 6 - anchors.leftMargin: 5 - anchors.rightMargin: 4 - anchors.bottomMargin: 6 - radius: 2 - } - } - } - } - } - - DropArea { - anchors.fill: parent - - onEntered: { - if(drag.hasUrls) - { - if(dropManager.canDropUrls(drag.urls, drag.action)) - { - drag.accepted = true; - }else - drag.accepted = false; - } - } - - onDropped: { - if(drop.hasUrls && dropManager.canDropUrls(drop.urls, drop.action)) - { - dropManager.droppedFiles(drop.urls, drop.action); - } - } - } -} diff --git a/YACReaderLibrary/qml/InfoFavorites.qml b/YACReaderLibrary/qml/InfoFavorites.qml index 2b24c0ab3..ce88142c2 100644 --- a/YACReaderLibrary/qml/InfoFavorites.qml +++ b/YACReaderLibrary/qml/InfoFavorites.qml @@ -1,6 +1,6 @@ -import QtQuick 2.15 +import QtQuick -import QtGraphicalEffects 1.0 +import QtQuick.Controls.impl Item { width: 20 @@ -17,15 +17,10 @@ Item { } } - Image { + ColorImage { anchors.centerIn: parent id: favorites_button_compact source: "info-favorites.svg" - } - - ColorOverlay { - anchors.fill: favorites_button_compact - source: favorites_button_compact color: active ? favCheckedColor : favUncheckedColor } } diff --git a/YACReaderLibrary/qml/InfoFavorites6.qml b/YACReaderLibrary/qml/InfoFavorites6.qml deleted file mode 100644 index ce88142c2..000000000 --- a/YACReaderLibrary/qml/InfoFavorites6.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick - -import QtQuick.Controls.impl - -Item { - width: 20 - height: 20 - - property bool active - - signal activeChangedByUser(bool active) - - MouseArea { - anchors.fill: favorites_button_compact - onClicked: { - activeChangedByUser(!active); - } - } - - ColorImage { - anchors.centerIn: parent - id: favorites_button_compact - source: "info-favorites.svg" - color: active ? favCheckedColor : favUncheckedColor - } -} - diff --git a/YACReaderLibrary/qml/InfoRating.qml b/YACReaderLibrary/qml/InfoRating.qml index 0f20b9939..2a7b482ac 100644 --- a/YACReaderLibrary/qml/InfoRating.qml +++ b/YACReaderLibrary/qml/InfoRating.qml @@ -1,6 +1,6 @@ -import QtQuick 2.15 +import QtQuick -import QtGraphicalEffects 1.0 +import QtQuick.Controls.impl Row { spacing: 0 @@ -16,14 +16,9 @@ Row { width: 25 height: 20 - Image { + ColorImage { id: star source: "info-rating.svg" - } - - ColorOverlay { - anchors.fill: star - source: star color: index < (mouseIndex > 0 ? mouseIndex : rating) ? ratingSelectedColor : ratingUnselectedColor } diff --git a/YACReaderLibrary/qml/InfoRating6.qml b/YACReaderLibrary/qml/InfoRating6.qml deleted file mode 100644 index 2a7b482ac..000000000 --- a/YACReaderLibrary/qml/InfoRating6.qml +++ /dev/null @@ -1,43 +0,0 @@ -import QtQuick - -import QtQuick.Controls.impl - -Row { - spacing: 0 - property int rating : 0 - property int mouseIndex : 0 - - signal ratingChangedByUser(int rating) - - Repeater { - id: rating_compact - model: 5 - Item { - width: 25 - height: 20 - - ColorImage { - id: star - source: "info-rating.svg" - color: index < (mouseIndex > 0 ? mouseIndex : rating) ? ratingSelectedColor : ratingUnselectedColor - } - - MouseArea { - anchors.fill: parent - hoverEnabled: true - - onPositionChanged: { - mouseIndex = index + 1; - } - - onClicked: { - ratingChangedByUser(mouseIndex); - } - - onExited: { - mouseIndex = 0; - } - } - } - } -} diff --git a/YACReaderLibrary/qml/InfoTick.qml b/YACReaderLibrary/qml/InfoTick.qml index 6659724c6..5b50a31fe 100644 --- a/YACReaderLibrary/qml/InfoTick.qml +++ b/YACReaderLibrary/qml/InfoTick.qml @@ -1,6 +1,6 @@ -import QtQuick 2.15 +import QtQuick -import QtGraphicalEffects 1.0 +import QtQuick.Controls.impl Item { @@ -15,14 +15,9 @@ Item { } } - Image { + ColorImage { id: read_compact source: "info-tick.svg" - } - - ColorOverlay { - anchors.fill: read_compact - source: read_compact color: read ? readTickCheckedColor : readTickUncheckedColor } } diff --git a/YACReaderLibrary/qml/InfoTick6.qml b/YACReaderLibrary/qml/InfoTick6.qml deleted file mode 100644 index 5b50a31fe..000000000 --- a/YACReaderLibrary/qml/InfoTick6.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick - -import QtQuick.Controls.impl - -Item { - - property bool read - - signal readChangedByUser(bool read) - - MouseArea { - anchors.fill: read_compact - onClicked: { - readChangedByUser(!read); - } - } - - ColorImage { - id: read_compact - source: "info-tick.svg" - color: read ? readTickCheckedColor : readTickUncheckedColor - } -} diff --git a/YACReaderLibrary/qml6.qrc b/YACReaderLibrary/qml6.qrc deleted file mode 100644 index d838abe2b..000000000 --- a/YACReaderLibrary/qml6.qrc +++ /dev/null @@ -1,28 +0,0 @@ - - - qml/GridComicsView6.qml - qml/FolderContentView6.qml - qml/FlowView6.qml - qml/InfoTick6.qml - qml/InfoFavorites6.qml - qml/InfoRating6.qml - qml/InfoComicsView6.qml - qml/tick.png - qml/reading.png - qml/star_menu.png - qml/star_menu@2x.png - qml/info-indicator.png - qml/info-shadow.png - qml/info-indicator-light.png - qml/info-shadow-light.png - qml/info-indicator-light@2x.png - qml/info-shadow-light@2x.png - qml/info-top-shadow.png - qml/ComicInfoView.qml - qml/info-favorites.svg - qml/info-rating.svg - qml/info-tag.svg - qml/info-tick.svg - qml/prerendered_cover_shadow.png - - From 5762b32fda73adb2d710a6dcfc53e68488b9846c Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 13 Feb 2026 16:22:28 +0100 Subject: [PATCH 062/187] More png to svg conversions on qml side --- YACReaderLibrary/YACReaderLibrary.pro | 3 --- YACReaderLibrary/qml.qrc | 8 ++++---- YACReaderLibrary/qml/FlowView.qml | 2 +- YACReaderLibrary/qml/GridComicsView.qml | 19 +++++++++++-------- YACReaderLibrary/qml/page-macosx.png | Bin 171 -> 0 bytes YACReaderLibrary/qml/page-macosx@2x.png | Bin 218 -> 0 bytes YACReaderLibrary/qml/page.png | Bin 163 -> 0 bytes YACReaderLibrary/qml/page.svg | 18 ++++++++++++++++++ YACReaderLibrary/qml/reading.png | Bin 374 -> 0 bytes YACReaderLibrary/qml/reading.svg | 20 ++++++++++++++++++++ YACReaderLibrary/qml/star-macosx.png | Bin 288 -> 0 bytes YACReaderLibrary/qml/star-macosx@2x.png | Bin 472 -> 0 bytes YACReaderLibrary/qml/star.png | Bin 288 -> 0 bytes YACReaderLibrary/qml/star.svg | 13 +++++++++++++ YACReaderLibrary/qml/star_menu.png | Bin 277 -> 0 bytes YACReaderLibrary/qml/star_menu@2x.png | Bin 468 -> 0 bytes YACReaderLibrary/qml/tick.png | Bin 488 -> 0 bytes YACReaderLibrary/qml/tick.svg | 18 ++++++++++++++++++ YACReaderLibrary/qml_osx.qrc | 8 -------- YACReaderLibrary/qml_win.qrc | 6 ------ 20 files changed, 85 insertions(+), 30 deletions(-) delete mode 100644 YACReaderLibrary/qml/page-macosx.png delete mode 100644 YACReaderLibrary/qml/page-macosx@2x.png delete mode 100644 YACReaderLibrary/qml/page.png create mode 100644 YACReaderLibrary/qml/page.svg delete mode 100644 YACReaderLibrary/qml/reading.png create mode 100644 YACReaderLibrary/qml/reading.svg delete mode 100644 YACReaderLibrary/qml/star-macosx.png delete mode 100644 YACReaderLibrary/qml/star-macosx@2x.png delete mode 100644 YACReaderLibrary/qml/star.png create mode 100644 YACReaderLibrary/qml/star.svg delete mode 100644 YACReaderLibrary/qml/star_menu.png delete mode 100644 YACReaderLibrary/qml/star_menu@2x.png delete mode 100644 YACReaderLibrary/qml/tick.png create mode 100644 YACReaderLibrary/qml/tick.svg delete mode 100644 YACReaderLibrary/qml_osx.qrc delete mode 100644 YACReaderLibrary/qml_win.qrc diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index ce7e78785..4d6d00594 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -315,9 +315,6 @@ SOURCES += grid_comics_view.cpp \ comics_view_transition.cpp RESOURCES += qml.qrc -win32:RESOURCES += qml_win.qrc -unix:!macx:RESOURCES += qml_win.qrc -macx:RESOURCES += qml_osx.qrc unix:!macx { diff --git a/YACReaderLibrary/qml.qrc b/YACReaderLibrary/qml.qrc index 29badf8ef..d216b4f83 100644 --- a/YACReaderLibrary/qml.qrc +++ b/YACReaderLibrary/qml.qrc @@ -7,10 +7,10 @@ qml/InfoFavorites.qml qml/InfoRating.qml qml/InfoComicsView.qml - qml/tick.png - qml/reading.png - qml/star_menu.png - qml/star_menu@2x.png + qml/tick.svg + qml/reading.svg + qml/star.svg + qml/page.svg qml/info-indicator.png qml/info-shadow.png qml/info-indicator-light.png diff --git a/YACReaderLibrary/qml/FlowView.qml b/YACReaderLibrary/qml/FlowView.qml index 75da010a0..9ece421a2 100644 --- a/YACReaderLibrary/qml/FlowView.qml +++ b/YACReaderLibrary/qml/FlowView.qml @@ -159,7 +159,7 @@ Rectangle { id: mark width: 23 height: 23 - source: read_column&&show_marks?"tick.png":has_been_opened&&show_marks?"reading.png":"" + source: read_column&&show_marks?"tick.svg":has_been_opened&&show_marks?"reading.svg":"" anchors {right: coverElement.right; top: coverElement.top; topMargin: 9; rightMargin: 9} asynchronous : true } diff --git a/YACReaderLibrary/qml/GridComicsView.qml b/YACReaderLibrary/qml/GridComicsView.qml index 47c949260..1c5edc01b 100644 --- a/YACReaderLibrary/qml/GridComicsView.qml +++ b/YACReaderLibrary/qml/GridComicsView.qml @@ -11,6 +11,7 @@ import com.yacreader.ComicInfo 1.0 import com.yacreader.ComicDB 1.0 import QtQuick.Controls.Basic +import QtQuick.Controls.impl SplitView { orientation: Qt.Horizontal @@ -315,7 +316,7 @@ SplitView { id: mark width: 23 height: 23 - source: read_column&&show_marks?"tick.png":has_been_opened&&show_marks?"reading.png":"" + source: read_column&&show_marks?"tick.svg":has_been_opened&&show_marks?"reading.svg":"" anchors {right: coverElement.right; top: coverElement.top; topMargin: 9; rightMargin: 9} asynchronous : true } @@ -347,10 +348,11 @@ SplitView { } //page icon - Image { + ColorImage { id: pageImage - anchors {bottom: realCell.bottom; right: realCell.right; bottomMargin: 5; rightMargin: 4; leftMargin: 4} - source: "page.png" + anchors {bottom: realCell.bottom; right: realCell.right; bottomMargin: 6; rightMargin: 4; leftMargin: 4} + source: "page.svg" + color: textColor width: 8 height: 10 } @@ -367,11 +369,12 @@ SplitView { } //rating icon - Image { + ColorImage { id: ratingImage - anchors {bottom: realCell.bottom; right: pageImage.left; bottomMargin: 5; rightMargin: Math.floor(pages.width)+12} - source: "star.png" - width: 13 + anchors {bottom: realCell.bottom; right: pageImage.left; bottomMargin: 6.5; rightMargin: Math.floor(pages.width)+12} + source: "star.svg" + color: textColor + width: 11 height: 11 MouseArea { diff --git a/YACReaderLibrary/qml/page-macosx.png b/YACReaderLibrary/qml/page-macosx.png deleted file mode 100644 index c8216591679ffb2e0dac358288275c4ce8d539ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MZTUcjv*Ddl6d&}|DSK*6bfGxv60~nlO_Wbn*`g(g%*rQ z(i0ExF*Q~=y12A3>9M|ESYq48wBT-!f!T$Y|2{k{46-5{4#+fnGdeUdGC1cdp31NN R!3#8)!PC{xWt~$(697>)GP3{x diff --git a/YACReaderLibrary/qml/page-macosx@2x.png b/YACReaderLibrary/qml/page-macosx@2x.png deleted file mode 100644 index a69a9428dd45c587f92b0bd1f218ef3368832e0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRn!3HE-lJ=GZDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MKzu-jv*Ddl6d&}|DSh|5s2BCbdF5)R@*ySMiN|t>R4};Zjrb&u_ z9QMd(crbErWLwb6%JXINBi1zytsKiA_sVv~8e|<DSr z1<%~X^wgl##FWaylc_d9MXsJMjv*Ddl43R{9j#~cNstf}EMz?66wdI7`D3+$AH&B; zi4Dyz3iJ3wR2sYwR%zTl-*A|>;Png%4hAcYgo9#YCm0kCFdXKQ&D#-lJq2hWgQu&X J%Q~loCIBv)G8X^< diff --git a/YACReaderLibrary/qml/page.svg b/YACReaderLibrary/qml/page.svg new file mode 100644 index 000000000..446162fb4 --- /dev/null +++ b/YACReaderLibrary/qml/page.svg @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/YACReaderLibrary/qml/reading.png b/YACReaderLibrary/qml/reading.png deleted file mode 100644 index a26a81d63a321ff8c73407b041c96b3c22c3576b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 374 zcmV-+0g3*JP)+7*9lVSQEwMA4ff7z&p)DoQSkRc@A2T3PiBWd_$!B1)`!d-qGqS2G(IqLR zi?D!Q_7E=NlpSM#+PVK79MCDk2DZd!6>tE~=_4HA6@n+eR|M9f6Amy{I~Ttz0WYXO z)KkTMz@#~I9&kQmPw0`yyr%Mv(5pL7@pZE_!!6<3cmIAa4Ep2b$qQ(_6UFN1DJ + + + + + + + + + + + \ No newline at end of file diff --git a/YACReaderLibrary/qml/star-macosx.png b/YACReaderLibrary/qml/star-macosx.png deleted file mode 100644 index 37577a74c8a41fc0fefcab1b1fe49c750f2ee8ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 288 zcmV+*0pI?KP)C24IAC14hUQ z{YySGLN_QQFan?XWQ4LoH)uNnY>?WLi7H4=I{CQR_rj!rre}xA-v7M^7fDX>;cf~LG0Dm%$F|N521bkdXAUS~WA?lm?MZ7#7tIvulm>39y z^0RoR(IeYhR2qTw+usVKMhmq=u>Go$FUqaTSFcB63jr5@3tQ!@qV0MlUxilrY|T!@ m`KRr){7>jM>~=Ii0R{k?6P)oSV53vb0+5-RT_9^Bjd(UDpMV zeczu$aGNOHI*dgK=;Z-5J9ee)Ux>&W%lE3qzBwWVDGgWc=ZtbSJX?{<%@HntdyXPa zO@{FrqUskB4rR~D6I2(^-&hG9+F;)Y4SVt%ITLZYkK`Ag>*NcO0J?0sy(MS5Efdn&H!Ujw O0000HysUm;l(I z-2iUAW&%c_8vqkj+9>x*o!GfVv~63b&ZY@Nf$XLK znaluh=}%0e?m4mo>%N0E+~EWrJgTY+<0K4r*uw#q;3=?4UjLTwRX1L*R5vHX#Xh87 z`A&5%)1i$m>C~XcHhMy%tNGL-o)C29xpG1I + + + + + + \ No newline at end of file diff --git a/YACReaderLibrary/qml/star_menu.png b/YACReaderLibrary/qml/star_menu.png deleted file mode 100644 index 4472e5a31f0e0cbcd83edaad25020ec221020a18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 277 zcmeAS@N?(olHy`uVBq!ia0vp@K+Mg-1|*kkVowB8k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XwtKobhE&{2N;trnl9D1N;lb#@%jfV%-X(c*`k{sE*%4FkLg~A%fLcuI0kBv+r zZbP0l+XkKon2l~ diff --git a/YACReaderLibrary/qml/star_menu@2x.png b/YACReaderLibrary/qml/star_menu@2x.png deleted file mode 100644 index 9e1644855ddb8c0e69ec94e4578dca8e89883aea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 468 zcmV;_0W1EAP)B+t_KUJDoB1^W#af$me;^Qmn3P#iQ2x zoPvAF(yhm+Qb3yr)EwB2vVS2WYdz1amdECZ6qGdFt=ARhYIwFHlbaJU4;qf-U*t^0d5=1% zc*Fcg{)sOf?F$OR9A#br+gSL{89D+L2mx=NIBay_HL@!Az-~dp*wI;aSWwu=fHMyG z6N$6DQ^{gTy!XgK)&vAKYb3!73xENI@?_RVA4yDSFd-XcW3?LUVC_xo45+|ws552U zqkFSmc+O={Yvzz$a_GbtPIM3_TMLp5&l+pfnyMJ0tspp|*Hxmi9dkl~Sc|?Gen600RJ2+W`vWoZ?yl0000< KMNUMnLSTZKHO?9U diff --git a/YACReaderLibrary/qml/tick.png b/YACReaderLibrary/qml/tick.png deleted file mode 100644 index 78a20644c27b468c50767aa4a44597662f7253de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 488 zcmVP)wXM;%Yz~3&g? zC_;UD5u4#56c~&gN1%AQ2I4Rwg|QO@b$}DpJhgt^2k28-cbAj1Q&xen-6dqYD*IeUA1 zMJ6Vu&map(Fc<__K{>P+nl>?9e*E}xKTw#0_9*{be eYPCN=fB^su{-6g#-^-l<0000 + + + + + + + + + \ No newline at end of file diff --git a/YACReaderLibrary/qml_osx.qrc b/YACReaderLibrary/qml_osx.qrc deleted file mode 100644 index 1649991a5..000000000 --- a/YACReaderLibrary/qml_osx.qrc +++ /dev/null @@ -1,8 +0,0 @@ - - - qml/page-macosx.png - qml/page-macosx@2x.png - qml/star-macosx.png - qml/star-macosx@2x.png - - diff --git a/YACReaderLibrary/qml_win.qrc b/YACReaderLibrary/qml_win.qrc deleted file mode 100644 index 59e2872fa..000000000 --- a/YACReaderLibrary/qml_win.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - qml/page.png - qml/star.png - - From ed28c94f66bb109c442a6f6b35a9299a626e1321 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 13 Feb 2026 16:37:20 +0100 Subject: [PATCH 063/187] Fix tick and favorites vertical alignment --- YACReaderLibrary/qml/ComicInfoView.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/YACReaderLibrary/qml/ComicInfoView.qml b/YACReaderLibrary/qml/ComicInfoView.qml index de2d4442f..5fd4be1b1 100644 --- a/YACReaderLibrary/qml/ComicInfoView.qml +++ b/YACReaderLibrary/qml/ComicInfoView.qml @@ -80,7 +80,8 @@ Rectangle { Layout.topMargin: topMargin InfoTick { - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + Layout.alignment: Qt.AlignTop | Qt.AlignLeft + Layout.topMargin: 5 read: comicInfo ? comicInfo.read ?? false : false @@ -95,7 +96,7 @@ Rectangle { } InfoFavorites { - Layout.topMargin: 1 + Layout.topMargin: 2 Layout.rightMargin: 17 Layout.alignment: Qt.AlignTop From 044176d6b7fde911f68d498cb585391a74b38b23 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 19 Feb 2026 17:39:22 +0100 Subject: [PATCH 064/187] Initial implementation of theming --- Qt5-DROP.md | 208 +++ YACReader/goto_flow_widget.h | 3 +- YACReader/main_window_viewer.cpp | 77 +- YACReader/main_window_viewer.h | 3 +- YACReader/options_dialog.cpp | 15 +- YACReader/options_dialog.h | 6 +- YACReader/themes/theme.h | 16 + YACReader/themes/theme_factory.cpp | 89 ++ YACReader/yacreader_images.qrc | 6 +- YACReaderLibrary/YACReaderLibrary.pro | 2 + YACReaderLibrary/add_label_dialog.cpp | 52 +- YACReaderLibrary/add_label_dialog.h | 5 +- YACReaderLibrary/add_library_dialog.cpp | 16 +- YACReaderLibrary/add_library_dialog.h | 8 +- YACReaderLibrary/classic_comics_view.cpp | 25 +- YACReaderLibrary/classic_comics_view.h | 7 +- YACReaderLibrary/comic_flow_widget.cpp | 21 +- YACReaderLibrary/comic_flow_widget.h | 6 +- .../comic_vine/scraper_results_paginator.h | 1 + YACReaderLibrary/comic_vine/title_header.h | 1 + YACReaderLibrary/comics_view_transition.cpp | 27 +- YACReaderLibrary/comics_view_transition.h | 5 +- YACReaderLibrary/create_library_dialog.cpp | 14 +- YACReaderLibrary/create_library_dialog.h | 7 +- YACReaderLibrary/db/folder_model.cpp | 55 +- YACReaderLibrary/db/folder_model.h | 6 +- YACReaderLibrary/db/reading_list_item.cpp | 35 +- YACReaderLibrary/db/reading_list_item.h | 3 - YACReaderLibrary/empty_container_info.cpp | 18 +- YACReaderLibrary/empty_container_info.h | 6 +- YACReaderLibrary/empty_folder_widget.cpp | 15 + YACReaderLibrary/empty_folder_widget.h | 17 + YACReaderLibrary/empty_label_widget.cpp | 20 +- YACReaderLibrary/empty_label_widget.h | 8 +- .../empty_reading_list_widget.cpp | 8 +- YACReaderLibrary/empty_reading_list_widget.h | 3 + YACReaderLibrary/empty_special_list.cpp | 42 + YACReaderLibrary/empty_special_list.h | 18 + .../export_comics_info_dialog.cpp | 14 +- YACReaderLibrary/export_comics_info_dialog.h | 8 +- YACReaderLibrary/export_library_dialog.cpp | 14 +- YACReaderLibrary/export_library_dialog.h | 9 +- YACReaderLibrary/folder_content_view.cpp | 155 +- YACReaderLibrary/folder_content_view.h | 10 +- YACReaderLibrary/grid_comics_view.cpp | 165 +-- YACReaderLibrary/grid_comics_view.h | 10 +- YACReaderLibrary/images.qrc | 90 +- YACReaderLibrary/images_osx.qrc | 25 - YACReaderLibrary/images_win.qrc | 26 - .../import_comics_info_dialog.cpp | 14 +- YACReaderLibrary/import_comics_info_dialog.h | 8 +- YACReaderLibrary/import_library_dialog.cpp | 17 +- YACReaderLibrary/import_library_dialog.h | 7 +- YACReaderLibrary/import_widget.cpp | 116 +- YACReaderLibrary/import_widget.h | 10 +- YACReaderLibrary/info_comics_view.cpp | 74 +- YACReaderLibrary/info_comics_view.h | 7 +- YACReaderLibrary/library_window.cpp | 47 +- YACReaderLibrary/library_window.h | 8 +- YACReaderLibrary/library_window_actions.cpp | 156 +- YACReaderLibrary/library_window_actions.h | 3 +- YACReaderLibrary/no_libraries_widget.cpp | 33 +- YACReaderLibrary/no_libraries_widget.h | 14 +- YACReaderLibrary/no_search_results_widget.cpp | 48 +- YACReaderLibrary/no_search_results_widget.h | 15 +- YACReaderLibrary/properties_dialog.cpp | 8 +- YACReaderLibrary/rename_library_dialog.cpp | 11 +- YACReaderLibrary/rename_library_dialog.h | 8 +- YACReaderLibrary/server_config_dialog.cpp | 95 +- YACReaderLibrary/server_config_dialog.h | 15 +- YACReaderLibrary/themes/theme.h | 354 +++++ YACReaderLibrary/themes/theme_factory.cpp | 1311 ++++++++++++++++- .../yacreader_content_views_manager.cpp | 46 +- .../yacreader_content_views_manager.h | 8 +- YACReaderLibrary/yacreader_folders_view.cpp | 19 +- YACReaderLibrary/yacreader_main_toolbar.cpp | 41 +- YACReaderLibrary/yacreader_main_toolbar.h | 9 +- .../yacreader_navigation_controller.cpp | 17 +- YACReaderLibrary/yacreaderlibrary_de.ts | 13 - YACReaderLibrary/yacreaderlibrary_en.ts | 13 - YACReaderLibrary/yacreaderlibrary_es.ts | 13 - YACReaderLibrary/yacreaderlibrary_fr.ts | 13 - YACReaderLibrary/yacreaderlibrary_it.ts | 13 - YACReaderLibrary/yacreaderlibrary_nl.ts | 13 - YACReaderLibrary/yacreaderlibrary_pt.ts | 13 - YACReaderLibrary/yacreaderlibrary_ru.ts | 13 - YACReaderLibrary/yacreaderlibrary_source.ts | 13 - YACReaderLibrary/yacreaderlibrary_tr.ts | 13 - YACReaderLibrary/yacreaderlibrary_zh_CN.ts | 13 - YACReaderLibrary/yacreaderlibrary_zh_HK.ts | 13 - YACReaderLibrary/yacreaderlibrary_zh_TW.ts | 13 - common/rhi/yacreader_flow_rhi.cpp | 14 +- common/themes/icon_utils.cpp | 21 + common/themes/icon_utils.h | 5 + common/themes/shared/whats_new_dialog_theme.h | 17 + common/themes/theme_manager.cpp | 2 + common/themes/themes_common.pri | 1 + common/yacreader_global_gui.cpp | 16 - common/yacreader_global_gui.h | 1 - .../custom_widgets_yacreaderlibrary.pri | 2 - custom_widgets/rounded_corners_dialog.cpp | 8 +- custom_widgets/rounded_corners_dialog.h | 5 + custom_widgets/whats_new_dialog.cpp | 157 +- custom_widgets/whats_new_dialog.h | 18 +- .../yacreader_deleting_progress.cpp | 105 -- custom_widgets/yacreader_deleting_progress.h | 25 - .../yacreader_library_item_widget.cpp | 69 +- .../yacreader_library_item_widget.h | 9 +- custom_widgets/yacreader_macosx_toolbar.h | 88 -- custom_widgets/yacreader_macosx_toolbar.mm | 405 +---- custom_widgets/yacreader_search_line_edit.cpp | 79 +- custom_widgets/yacreader_search_line_edit.h | 7 +- custom_widgets/yacreader_sidebar.cpp | 117 +- custom_widgets/yacreader_sidebar.h | 11 +- custom_widgets/yacreader_table_view.cpp | 83 +- custom_widgets/yacreader_table_view.h | 19 +- custom_widgets/yacreader_titled_toolbar.cpp | 58 +- custom_widgets/yacreader_titled_toolbar.h | 9 +- custom_widgets/yacreader_treeview.cpp | 40 +- custom_widgets/yacreader_treeview.h | 8 +- images/clearSearch.png | Bin 296 -> 0 bytes images/clearSearch@2x.png | Bin 538 -> 0 bytes images/clearSearchNew.svg | 2 +- images/comics_view_toolbar/asignNumber.svg | 16 +- .../big_size_grid_zoom.svg | 16 +- images/comics_view_toolbar/editComic.svg | 15 +- images/comics_view_toolbar/getInfo.svg | 14 +- images/comics_view_toolbar/hideComicFlow.svg | 13 +- .../comics_view_toolbar/openInYACReader.svg | 13 +- images/comics_view_toolbar/selectAll.svg | 14 +- images/comics_view_toolbar/setManga.svg | 14 +- images/comics_view_toolbar/setNormal.svg | 14 +- images/comics_view_toolbar/setReadButton.svg | 13 +- images/comics_view_toolbar/setUnread.svg | 13 +- images/comics_view_toolbar/showMarks.svg | 14 +- .../showRecentIndicator.svg | 9 +- .../comics_view_toolbar/show_comic_info.svg | 16 +- .../small_size_grid_zoom.svg | 18 +- images/comics_view_toolbar/trash.svg | 14 +- images/custom_dialog/custom_close_button.svg | 2 +- images/deleting_progress/icon.png | Bin 292 -> 0 bytes images/deleting_progress/imgBottomLeft.png | Bin 281 -> 0 bytes images/deleting_progress/imgBottomMiddle.png | Bin 124 -> 0 bytes images/deleting_progress/imgBottomRight.png | Bin 288 -> 0 bytes images/deleting_progress/imgLeftMiddle.png | Bin 114 -> 0 bytes images/deleting_progress/imgRightMiddle.png | Bin 114 -> 0 bytes images/deleting_progress/imgTopLeft.png | Bin 123 -> 0 bytes images/deleting_progress/imgTopMiddle.png | Bin 113 -> 0 bytes images/deleting_progress/imgTopRight.png | Bin 123 -> 0 bytes images/edit.png | Bin 1063 -> 0 bytes .../empty_current_readings.svg | 11 + images/empty_container/empty_favorites.svg | 11 + images/empty_container/empty_folder.svg | 11 + images/empty_container/empty_label.svg | 12 + images/empty_container/empty_reading_list.svg | 16 + images/empty_current_readings.png | Bin 1550 -> 0 bytes images/empty_favorites.png | Bin 2839 -> 0 bytes images/empty_folder.png | Bin 2515 -> 0 bytes images/empty_folder_osx.png | Bin 2446 -> 0 bytes images/empty_label.png | Bin 2046 -> 0 bytes images/empty_reading_list.png | Bin 2471 -> 0 bytes images/empty_reading_list_osx.png | Bin 2346 -> 0 bytes images/empty_search.png | Bin 4498 -> 0 bytes images/empty_search_osx.png | Bin 4212 -> 0 bytes images/exportComicsInfo.png | Bin 1448 -> 0 bytes images/exportLibrary.png | Bin 1233 -> 0 bytes images/find_folder.png | Bin 289 -> 0 bytes images/find_folder.svg | 1 + images/folder_finished_macosx.png | Bin 158 -> 0 bytes images/hiddenCovers.png | Bin 446 -> 0 bytes images/iconSearch.png | Bin 282 -> 0 bytes images/iconSearch@2x.png | Bin 482 -> 0 bytes images/iconSearchNew.svg | 2 +- images/import/coversToggle.svg | 12 + .../import/importBottomCoversDecoration.svg | 11 + images/import/importTopCoversDecoration.svg | 11 + images/import/importingIcon.svg | 51 + images/import/updatingIcon.svg | 77 + images/importBottomCoversDecoration.png | Bin 188 -> 0 bytes images/importComicsInfo.png | Bin 1170 -> 0 bytes images/importLibrary.png | Bin 1279 -> 0 bytes images/importTopCoversDecoration.png | Bin 132 -> 0 bytes images/importingIcon.png | Bin 3162 -> 0 bytes images/library_dialogs/edit.svg | 26 + images/library_dialogs/exportComicsInfo.svg | 29 + images/library_dialogs/exportLibrary.svg | 22 + images/library_dialogs/importComicsInfo.svg | 13 + images/library_dialogs/importLibrary.svg | 26 + images/library_dialogs/new.svg | 12 + images/library_dialogs/openLibrary.svg | 21 + images/lists/default_0.svg | 18 +- images/lists/default_1.svg | 18 +- images/lists/default_2.svg | 27 +- images/lists/label_blue.svg | 1 - images/lists/label_cyan.svg | 1 - images/lists/label_dark.svg | 1 - images/lists/label_green.svg | 1 - images/lists/label_light.svg | 1 - images/lists/label_orange.svg | 1 - images/lists/label_pink.svg | 1 - images/lists/label_purple.svg | 1 - images/lists/label_red.svg | 1 - images/lists/label_template.svg | 17 + images/lists/label_violet.svg | 1 - images/lists/label_white.svg | 1 - images/lists/label_yellow.svg | 1 - images/lists/list.svg | 2 +- images/lists/original colors.md | 24 + images/main_toolbar/back.svg | 2 +- images/main_toolbar/back_disabled.png | Bin 225 -> 0 bytes images/main_toolbar/flow.svg | 2 +- images/main_toolbar/forward.svg | 2 +- images/main_toolbar/forward_disabled.png | Bin 240 -> 0 bytes images/main_toolbar/fullscreen.svg | 2 +- images/main_toolbar/grid.svg | 2 +- images/main_toolbar/help.svg | 2 +- images/main_toolbar/info.svg | 2 +- images/main_toolbar/server.svg | 2 +- images/main_toolbar/settings.svg | 2 +- images/menus_icons/editIcon.svg | 2 +- images/menus_icons/exportComicsInfoIcon.svg | 2 +- images/menus_icons/exportLibraryIcon.svg | 2 +- images/menus_icons/importComicsInfoIcon.svg | 2 +- images/menus_icons/importLibraryIcon.svg | 2 +- images/menus_icons/open_containing_folder.svg | 2 +- images/menus_icons/removeLibraryIcon.svg | 2 +- images/menus_icons/updateLibraryIcon.svg | 2 +- images/menus_icons/update_current_folder.svg | 2 +- .../{ => metadata_dialog}/loadCustomCover.svg | 0 images/metadata_dialog/nextCoverPage.svg | 11 + images/metadata_dialog/previousCoverPage.svg | 11 + images/{ => metadata_dialog}/resetCover.svg | 0 images/new.png | Bin 454 -> 0 bytes images/nextCoverPage.png | Bin 153 -> 0 bytes images/noLibrariesIcon.png | Bin 6047 -> 0 bytes images/noLibrariesIcon.svg | 11 + images/openLibrary.png | Bin 821 -> 0 bytes images/previousCoverPage.png | Bin 152 -> 0 bytes images/search_result.svg | 11 + images/searching_icon.png | Bin 1788 -> 0 bytes images/serverConfigBackground.png | Bin 7912 -> 0 bytes images/serverConfigBackground.svg | 16 + images/{ => shortcuts}/accept_shortcut.svg | 0 images/{ => shortcuts}/clear_shortcut.svg | 0 images/shortcuts/shortcuts_group_comics.svg | 2 +- images/shortcuts/shortcuts_group_folders.svg | 2 +- images/shortcuts/shortcuts_group_general.svg | 2 +- .../shortcuts/shortcuts_group_libraries.svg | 2 +- images/shortcuts/shortcuts_group_mglass.svg | 2 +- images/shortcuts/shortcuts_group_page.svg | 2 +- images/shortcuts/shortcuts_group_reading.svg | 2 +- .../shortcuts_group_visualization.svg | 2 +- images/shownCovers.png | Bin 445 -> 0 bytes images/sidebar/addLabelIcon.svg | 12 +- images/sidebar/addLabelIcon_osx.png | Bin 242 -> 0 bytes images/sidebar/addLabelIcon_osx@2x.png | Bin 342 -> 0 bytes images/sidebar/addNew_sidebar.svg | 12 +- images/sidebar/addNew_sidebar_osx.png | Bin 175 -> 0 bytes images/sidebar/addNew_sidebar_osx@2x.png | Bin 245 -> 0 bytes images/sidebar/branch-closed.svg | 10 +- images/sidebar/branch-open.svg | 10 +- images/sidebar/colapse.svg | 18 +- images/sidebar/colapse_osx.png | Bin 216 -> 0 bytes images/sidebar/colapse_osx@2x.png | Bin 319 -> 0 bytes images/sidebar/delete_sidebar.svg | 26 +- images/sidebar/delete_sidebar_osx.png | Bin 195 -> 0 bytes images/sidebar/delete_sidebar_osx@2x.png | Bin 212 -> 0 bytes images/sidebar/expand.svg | 18 +- images/sidebar/expand_osx.png | Bin 183 -> 0 bytes images/sidebar/expand_osx@2x.png | Bin 245 -> 0 bytes images/sidebar/folder.svg | 20 +- images/sidebar/folder_finished.svg | 25 +- images/sidebar/folder_read_overlay.svg | 13 + images/sidebar/libraryIcon.svg | 20 +- images/sidebar/libraryIconSelected.svg | 14 +- images/sidebar/libraryIcon_osx.png | Bin 258 -> 0 bytes images/sidebar/libraryOptions.svg | 10 +- images/sidebar/newLibraryIcon.svg | 12 +- images/sidebar/newLibraryIcon_osx.png | Bin 171 -> 0 bytes images/sidebar/newLibraryIcon_osx@2x.png | Bin 245 -> 0 bytes images/sidebar/openLibraryIcon.svg | 38 +- images/sidebar/openLibraryIcon_osx.png | Bin 244 -> 0 bytes images/sidebar/openLibraryIcon_osx@2x.png | Bin 331 -> 0 bytes images/sidebar/renameListIcon.svg | 26 +- images/sidebar/renameListIcon_osx.png | Bin 256 -> 0 bytes images/sidebar/renameListIcon_osx@2x.png | Bin 370 -> 0 bytes images/sidebar/setRoot.svg | 39 +- images/sidebar/setRoot_osx.png | Bin 276 -> 0 bytes images/sidebar/setRoot_osx@2x.png | Bin 438 -> 0 bytes images/social_dialog/close.png | Bin 246 -> 0 bytes images/social_dialog/facebook.png | Bin 181 -> 0 bytes images/social_dialog/google+.png | Bin 344 -> 0 bytes images/social_dialog/icon.png | Bin 1324 -> 0 bytes images/social_dialog/separator.png | Bin 247 -> 0 bytes images/social_dialog/shadow.png | Bin 122 -> 0 bytes images/social_dialog/twitter.png | Bin 301 -> 0 bytes images/updatingIcon.png | Bin 5746 -> 0 bytes images/whats_new/whatsnew_header.svg | 56 +- shortcuts_management/actions_groups_model.cpp | 14 + shortcuts_management/actions_groups_model.h | 2 + .../edit_shortcut_item_delegate.cpp | 4 +- .../edit_shortcuts_dialog.cpp | 26 + shortcuts_management/edit_shortcuts_dialog.h | 10 +- 303 files changed, 4636 insertions(+), 2121 deletions(-) create mode 100644 Qt5-DROP.md create mode 100644 YACReaderLibrary/empty_folder_widget.cpp create mode 100644 YACReaderLibrary/empty_folder_widget.h create mode 100644 common/themes/shared/whats_new_dialog_theme.h delete mode 100644 custom_widgets/yacreader_deleting_progress.cpp delete mode 100644 custom_widgets/yacreader_deleting_progress.h delete mode 100644 images/clearSearch.png delete mode 100644 images/clearSearch@2x.png delete mode 100644 images/deleting_progress/icon.png delete mode 100644 images/deleting_progress/imgBottomLeft.png delete mode 100644 images/deleting_progress/imgBottomMiddle.png delete mode 100644 images/deleting_progress/imgBottomRight.png delete mode 100644 images/deleting_progress/imgLeftMiddle.png delete mode 100644 images/deleting_progress/imgRightMiddle.png delete mode 100644 images/deleting_progress/imgTopLeft.png delete mode 100644 images/deleting_progress/imgTopMiddle.png delete mode 100644 images/deleting_progress/imgTopRight.png delete mode 100644 images/edit.png create mode 100644 images/empty_container/empty_current_readings.svg create mode 100644 images/empty_container/empty_favorites.svg create mode 100644 images/empty_container/empty_folder.svg create mode 100644 images/empty_container/empty_label.svg create mode 100644 images/empty_container/empty_reading_list.svg delete mode 100644 images/empty_current_readings.png delete mode 100644 images/empty_favorites.png delete mode 100644 images/empty_folder.png delete mode 100644 images/empty_folder_osx.png delete mode 100644 images/empty_label.png delete mode 100644 images/empty_reading_list.png delete mode 100644 images/empty_reading_list_osx.png delete mode 100644 images/empty_search.png delete mode 100644 images/empty_search_osx.png delete mode 100644 images/exportComicsInfo.png delete mode 100644 images/exportLibrary.png delete mode 100644 images/find_folder.png create mode 100644 images/find_folder.svg delete mode 100644 images/folder_finished_macosx.png delete mode 100644 images/hiddenCovers.png delete mode 100644 images/iconSearch.png delete mode 100644 images/iconSearch@2x.png create mode 100644 images/import/coversToggle.svg create mode 100644 images/import/importBottomCoversDecoration.svg create mode 100644 images/import/importTopCoversDecoration.svg create mode 100644 images/import/importingIcon.svg create mode 100644 images/import/updatingIcon.svg delete mode 100644 images/importBottomCoversDecoration.png delete mode 100644 images/importComicsInfo.png delete mode 100644 images/importLibrary.png delete mode 100644 images/importTopCoversDecoration.png delete mode 100644 images/importingIcon.png create mode 100644 images/library_dialogs/edit.svg create mode 100644 images/library_dialogs/exportComicsInfo.svg create mode 100644 images/library_dialogs/exportLibrary.svg create mode 100644 images/library_dialogs/importComicsInfo.svg create mode 100644 images/library_dialogs/importLibrary.svg create mode 100644 images/library_dialogs/new.svg create mode 100644 images/library_dialogs/openLibrary.svg delete mode 100644 images/lists/label_blue.svg delete mode 100644 images/lists/label_cyan.svg delete mode 100644 images/lists/label_dark.svg delete mode 100644 images/lists/label_green.svg delete mode 100644 images/lists/label_light.svg delete mode 100644 images/lists/label_orange.svg delete mode 100644 images/lists/label_pink.svg delete mode 100644 images/lists/label_purple.svg delete mode 100644 images/lists/label_red.svg create mode 100644 images/lists/label_template.svg delete mode 100644 images/lists/label_violet.svg delete mode 100644 images/lists/label_white.svg delete mode 100644 images/lists/label_yellow.svg create mode 100644 images/lists/original colors.md delete mode 100644 images/main_toolbar/back_disabled.png delete mode 100644 images/main_toolbar/forward_disabled.png rename images/{ => metadata_dialog}/loadCustomCover.svg (100%) create mode 100644 images/metadata_dialog/nextCoverPage.svg create mode 100644 images/metadata_dialog/previousCoverPage.svg rename images/{ => metadata_dialog}/resetCover.svg (100%) delete mode 100644 images/new.png delete mode 100644 images/nextCoverPage.png delete mode 100644 images/noLibrariesIcon.png create mode 100644 images/noLibrariesIcon.svg delete mode 100644 images/openLibrary.png delete mode 100644 images/previousCoverPage.png create mode 100644 images/search_result.svg delete mode 100644 images/searching_icon.png delete mode 100644 images/serverConfigBackground.png create mode 100644 images/serverConfigBackground.svg rename images/{ => shortcuts}/accept_shortcut.svg (100%) rename images/{ => shortcuts}/clear_shortcut.svg (100%) delete mode 100644 images/shownCovers.png delete mode 100755 images/sidebar/addLabelIcon_osx.png delete mode 100755 images/sidebar/addLabelIcon_osx@2x.png delete mode 100755 images/sidebar/addNew_sidebar_osx.png delete mode 100755 images/sidebar/addNew_sidebar_osx@2x.png delete mode 100755 images/sidebar/colapse_osx.png delete mode 100755 images/sidebar/colapse_osx@2x.png delete mode 100755 images/sidebar/delete_sidebar_osx.png delete mode 100755 images/sidebar/delete_sidebar_osx@2x.png delete mode 100755 images/sidebar/expand_osx.png delete mode 100755 images/sidebar/expand_osx@2x.png create mode 100644 images/sidebar/folder_read_overlay.svg delete mode 100644 images/sidebar/libraryIcon_osx.png delete mode 100755 images/sidebar/newLibraryIcon_osx.png delete mode 100755 images/sidebar/newLibraryIcon_osx@2x.png delete mode 100755 images/sidebar/openLibraryIcon_osx.png delete mode 100755 images/sidebar/openLibraryIcon_osx@2x.png delete mode 100755 images/sidebar/renameListIcon_osx.png delete mode 100755 images/sidebar/renameListIcon_osx@2x.png delete mode 100755 images/sidebar/setRoot_osx.png delete mode 100755 images/sidebar/setRoot_osx@2x.png delete mode 100644 images/social_dialog/close.png delete mode 100644 images/social_dialog/facebook.png delete mode 100644 images/social_dialog/google+.png delete mode 100644 images/social_dialog/icon.png delete mode 100644 images/social_dialog/separator.png delete mode 100644 images/social_dialog/shadow.png delete mode 100644 images/social_dialog/twitter.png delete mode 100644 images/updatingIcon.png diff --git a/Qt5-DROP.md b/Qt5-DROP.md new file mode 100644 index 000000000..658c4c283 --- /dev/null +++ b/Qt5-DROP.md @@ -0,0 +1,208 @@ +# Qt5 Drop - Cleanup Checklist + +Inventory of all Qt5 compatibility code and version branching across the project. +Goal: support only Qt6, remove all Qt5 conditionals and dead branches. + +--- + +## 1. Build System (.pro / .pri files) + +### core5compat module additions +These add `QT += core5compat` for Qt6 builds. Needed by third-party QtWebApp (QTextCodec, QRegExp). + +| File | Line | Code | +|------|------|------| +| `YACReaderLibrary/YACReaderLibrary.pro` | 51 | `greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat` | +| `YACReader/YACReader.pro` | 53 | `greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat` | +| `YACReaderLibraryServer/YACReaderLibraryServer.pro` | 20 | `greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat` | +| `YACReaderLibraryServer/YACReaderLibraryServer.pro` | 40 | `greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat` (duplicate) | + +**Action**: Replace conditionals with unconditional `QT += core5compat` (still needed for QtWebApp). Remove the duplicate in YACReaderLibraryServer. + +### macextras module (Qt5-only, removed in Qt6) + +| File | Line | Code | +|------|------|------| +| `YACReaderLibrary/YACReaderLibrary.pro` | 44 | `lessThan(QT_MAJOR_VERSION, 6): QT += macextras` | +| `YACReader/YACReader.pro` | 48 | `lessThan(QT_MAJOR_VERSION, 6): QT += macextras` | + +**Action**: Remove these lines entirely. + +### gui-private module (Qt 6.7+) + +| File | Line | Code | +|------|------|------| +| `YACReaderLibrary/YACReaderLibrary.pro` | 53-55 | `greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { QT += gui-private }` | +| `YACReader/YACReader.pro` | 55-57 | Same | + +**Action**: Simplify to `greaterThan(QT_MINOR_VERSION, 6): QT += gui-private` (drop the Qt5 guard). + +### Poppler backend version branching + +| File | Lines | What | +|------|-------|------| +| `dependencies/pdf_backend.pri` | 60-84 | Qt5 uses poppler-qt5, Qt6 uses poppler-qt6 (pkg-config, include paths, link flags) | + +**Action**: Keep only the Qt6 (poppler-qt6) branch, remove poppler-qt5 paths. + +### Minimum version check + +| File | Lines | What | +|------|-------|------| +| `config.pri` | 18-41 | `minQtVersion()` function, enforces minimum Qt 5.15.0 | + +**Action**: Update minimum to Qt 6.x. + +### QML resource branching (DONE) + +| File | Lines | What | +|------|-------|------| +| `YACReaderLibrary/YACReaderLibrary.pro` | 317-321 | Was `greaterThan(QT_MAJOR_VERSION, 5) { qml6.qrc } else { qml.qrc }` | + +**Action**: Already cleaned up - now unconditional `RESOURCES += qml.qrc`. + +### Qt4 compatibility in third-party + +| File | Line | Code | +|------|------|------| +| `third_party/QsLog/QsLog.pri` | 11 | `greaterThan(QT_MAJOR_VERSION, 4): QT += widgets` | + +**Action**: Replace with unconditional `QT += widgets`. + +--- + +## 2. C++ Source Code (#if QT_VERSION checks) + +### Qt5 vs Qt6 API changes (own code) + +| File | Line(s) | Qt5 branch | Qt6 branch | API change | +|------|---------|------------|------------|------------| +| `common/pdf_comic.h` | 49 | `#include "poppler-qt5.h"` | `#include ` | Poppler header | +| `common/pdf_comic.mm` | 3 | (nothing) | `#undef __OBJC_BOOL_IS_BOOL` | macOS ObjC compat | +| `common/comic.cpp` | 812 | `auto _pdfComic = Poppler::Document::load()` | `pdfComic = Poppler::Document::load()` | Poppler return type | +| `YACReaderLibrary/initial_comic_info_extractor.cpp` | 44 | Same Poppler pattern | Same | Poppler return type | +| `YACReader/mouse_handler.cpp` | 22, 56, 107 | `QPointF(event->x(), event->y())` | `event->position()` | QMouseEvent API | +| `YACReader/viewer.cpp` | 762 | `pixmap(Qt::ReturnByValue)` | `pixmap()` | QPixmap return semantics | +| `custom_widgets/help_about_dialog.cpp` | 14, 88 | `QTextCodec` / `setCodec()` | `QStringConverter` / `setEncoding()` | Text encoding API | +| `YACReader/translator.cpp` | 291 | `player->setMedia()` | `player->setSource()` | QMediaPlayer API | +| `YACReaderLibrary/comic_vine/comic_vine_dialog.cpp` | 149, 160 | `QtConcurrent::run(this, &fn, args)` | `QtConcurrent::run(&fn, this, args)` | Argument order | +| `YACReaderLibrary/library_window.cpp` | 173 | Different key handling | `keySequence[0]` (QKeyCombination) | Key event API | +| `YACReaderLibrary/library_window.cpp` | 790-793 | Qt5 toolbar connections | Qt6 toolbar connections | macOS toolbar | +| `YACReader/main_window_viewer.cpp` | 483, 1357 | Qt5 toolbar/slider | Qt6 toolbar/slider | macOS toolbar | +| `YACReaderLibrary/trayhandler.mm` | 3 | (nothing) | `#undef __OBJC_BOOL_IS_BOOL` | macOS ObjC compat | +| `YACReader/main.cpp` | 102 | (nothing) | `QImageReader::setAllocationLimit(0)` | Image reader limit | +| `YACReaderLibraryServer/main.cpp` | 53 | (nothing) | `QImageReader::setAllocationLimit(0)` | Image reader limit | + +**Action**: For each, keep only the Qt6 branch, remove the `#if`/`#else`/`#endif` and the Qt5 code. + +### Qt4 vs Qt5 leftovers (very old) + +| File | Line(s) | What | +|------|---------|------| +| `custom_widgets/yacreader_table_view.cpp` | 31, 39, 46 | `#if QT_VERSION >= 0x050000` — `setResizeMode` vs `setSectionResizeMode` | +| `YACReaderLibrary/comic_vine/scraper_tableview.cpp` | 9, 16, 23 | Same Qt4 vs Qt5 header API | +| `YACReader/translator.cpp` | 3, 164 | `#if QT_VERSION >= 0x050000` — Phonon vs QMediaPlayer | +| `YACReader/main.cpp` | 135 | `#if QT_VERSION >= 0x050800` — QCommandLineOption::HiddenFromHelp | + +**Action**: Remove the `#if` guards entirely, keep only the Qt5+ code (which is also valid Qt6). + +### Qt 6.7+ specific (RHI widget) + +| File | Lines | What | +|------|-------|------| +| `common/rhi/yacreader_flow_rhi.h` | 8-302 | `#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)` — entire QRhiWidget implementation | + +**Action**: Keep this conditional (gates on Qt 6.7 minor version, not Qt5 vs Qt6). + +### Qt 6.9+ specific (test code) + +| File | Line | What | +|------|------|------| +| `tests/concurrent_queue_test/concurrent_queue_test.cpp` | 212 | `#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)` — QDebug for std::array | + +**Action**: Keep this conditional (Qt6 minor version gate). + +--- + +## 3. Third-Party Libraries + +### QtWebApp (`third_party/QtWebApp/`) + +| File | Lines | What | +|------|-------|------| +| `templateengine/templateengine.pri` | 5 | `QT += core5compat` | +| `templateengine/templateloader.cpp` | 13, 77, 86, 107 | QRegExp→QRegularExpression, QString::split flag | +| `httpserver/httpconnectionhandler.h` | 23 | `tSocketDescriptor` typedef (Qt4 vs Qt5) | +| `httpserver/httpconnectionhandlerpool.cpp` | 152 | SSL cert handling (Qt <5.15 vs 5.15+) | + +**Action**: Decide whether to update QtWebApp or replace it. If updating: remove Qt4/Qt5 branches, keep Qt6 code, potentially drop core5compat dependency by migrating QTextCodec→QStringConverter and QRegExp→QRegularExpression. + +### QsLog (`third_party/QsLog/`) + +| File | Lines | What | +|------|-------|------| +| `QsLog.pri` | 11 | Qt4 widgets guard | +| `QsLogDestFile.cpp` | 32, 157, 179 | QTextCodec vs QStringConverter | +| `QsLogWindow.cpp` | 129 | Qt4 header resize API | + +**Action**: Same approach — remove Qt4/Qt5 branches, keep Qt6 code. + +--- + +## 4. CI/CD and Build Scripts + +### GitHub Actions (`.github/workflows/build.yml`) + +**Qt5 build targets to remove:** +- Ubuntu Linux Qt5 build (~line 63) +- Windows x64 Qt5 build (~line 346) +- Windows x86 Qt5 build (~line 798) +- macOS Qt5 build (~line 201) + +**Qt6 build targets to keep (and simplify):** +- Linux Qt6 builds (~lines 90, 116) +- macOS Qt6 Universal (~line 145) — still installs `qt5compat` module (needed for QtWebApp) +- Windows x64 Qt6 (~line 408) — same +- Windows ARM64 Qt6 (~line 574) — same + +### Build scripts + +| File | What | +|------|------| +| `build_scripts/ubuntu_24.04/build.sh` | Qt6 — installs `libqt6core5compat6-dev`, `qml6-module-qt5compat-graphicaleffects` | +| `build_scripts/ubuntu_22.04/build.sh` | Qt5 — entire script is Qt5-only | + +**Action**: Remove `ubuntu_22.04` build script. In `ubuntu_24.04`, remove `qml6-module-qt5compat-graphicaleffects` (no longer used in QML). Keep `libqt6core5compat6-dev` (needed for QtWebApp). + +### Docker + +| File | What | +|------|------| +| `docker/Dockerfile` | Ubuntu x64 Qt6 — installs `libqt6core5compat6-dev` (build) and `libqt6core5compat6` (runtime) | +| `docker/Dockerfile.aarch64` | Ubuntu ARM64 Qt5-only build | + +**Action**: Remove or convert `Dockerfile.aarch64` to Qt6. Keep core5compat packages in main Dockerfile (QtWebApp). + +--- + +## 5. Summary + +### Safe to remove now (no dependencies) +- All `lessThan(QT_MAJOR_VERSION, 6)` lines (macextras) +- All `#if QT_VERSION >= 0x050000` / `0x050800` guards (Qt4 leftovers) +- All Qt5 CI build targets +- `build_scripts/ubuntu_22.04/` (Qt5-only) +- `qml6-module-qt5compat-graphicaleffects` from build scripts (QML migration done) + +### Requires code changes (keep Qt6 branch only) +- ~15 `#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)` blocks in own code +- Poppler backend selection in `pdf_backend.pri` +- `config.pri` minimum version bump + +### Keep as-is (Qt6 minor version gates) +- `QT_VERSION_CHECK(6, 7, 0)` — RHI widget +- `QT_VERSION_CHECK(6, 9, 0)` — test code +- `gui-private` for Qt 6.7+ (simplify guard only) + +### Depends on third-party decisions +- `core5compat` — still needed unless QtWebApp and QsLog are updated to drop QTextCodec/QRegExp diff --git a/YACReader/goto_flow_widget.h b/YACReader/goto_flow_widget.h index 6456463a9..7d5c73a2c 100644 --- a/YACReader/goto_flow_widget.h +++ b/YACReader/goto_flow_widget.h @@ -18,8 +18,6 @@ class QKeyEvent; class GoToFlowWidget : public QWidget, protected Themable { Q_OBJECT -protected: - void applyTheme(const Theme &theme) override; public: GoToFlowWidget(QWidget *parent = nullptr, FlowType flowType = CoverFlowLike); @@ -42,6 +40,7 @@ public slots: protected: void keyPressEvent(QKeyEvent *event) override; void resizeEvent(QResizeEvent *event) override; + void applyTheme(const Theme &theme) override; private: QVBoxLayout *mainLayout; diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 67f545e51..4c671ca1f 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -18,6 +18,7 @@ #include "yacreader_global.h" #include "edit_shortcuts_dialog.h" #include "shortcuts_manager.h" +#include "theme_manager.h" #include "whats_new_controller.h" @@ -186,7 +187,7 @@ void MainWindowViewer::setupUI() void MainWindowViewer::createActions() { openAction = new QAction(tr("&Open"), this); - openAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/open"))); + openAction->setIcon(QIcon(":/images/viewer_toolbar/open.svg")); openAction->setToolTip(tr("Open a comic")); openAction->setData(OPEN_ACTION_Y); openAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_ACTION_Y)); @@ -213,7 +214,7 @@ void MainWindowViewer::createActions() #endif openFolderAction = new QAction(tr("Open Folder"), this); - openFolderAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/openFolder"))); + openFolderAction->setIcon(QIcon(":/images/viewer_toolbar/openFolder.svg")); openFolderAction->setToolTip(tr("Open image folder")); openFolderAction->setData(OPEN_FOLDER_ACTION_Y); openFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_FOLDER_ACTION_Y)); @@ -237,28 +238,28 @@ void MainWindowViewer::createActions() connect(clearRecentFilesAction, &QAction::triggered, this, &MainWindowViewer::clearRecentFiles); saveImageAction = new QAction(tr("Save"), this); - saveImageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/save"))); + saveImageAction->setIcon(QIcon(":/images/viewer_toolbar/save.svg")); saveImageAction->setToolTip(tr("Save current page")); saveImageAction->setData(SAVE_IMAGE_ACTION_Y); saveImageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SAVE_IMAGE_ACTION_Y)); connect(saveImageAction, &QAction::triggered, this, &MainWindowViewer::saveImage); openComicOnTheLeftAction = new QAction(tr("Previous Comic"), this); - openComicOnTheLeftAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/openPrevious"))); + openComicOnTheLeftAction->setIcon(QIcon(":/images/viewer_toolbar/openPrevious.svg")); openComicOnTheLeftAction->setToolTip(tr("Open previous comic")); openComicOnTheLeftAction->setData(OPEN_PREVIOUS_COMIC_ACTION_Y); openComicOnTheLeftAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_PREVIOUS_COMIC_ACTION_Y)); connect(openComicOnTheLeftAction, &QAction::triggered, this, &MainWindowViewer::openLeftComic); openComicOnTheRightAction = new QAction(tr("Next Comic"), this); - openComicOnTheRightAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/openNext"))); + openComicOnTheRightAction->setIcon(QIcon(":/images/viewer_toolbar/openNext.svg")); openComicOnTheRightAction->setToolTip(tr("Open next comic")); openComicOnTheRightAction->setData(OPEN_NEXT_COMIC_ACTION_Y); openComicOnTheRightAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_NEXT_COMIC_ACTION_Y)); connect(openComicOnTheRightAction, &QAction::triggered, this, &MainWindowViewer::openRightComic); goToPageOnTheLeftAction = new QAction(tr("&Previous"), this); - goToPageOnTheLeftAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/previous"))); + goToPageOnTheLeftAction->setIcon(QIcon(":/images/viewer_toolbar/previous.svg")); goToPageOnTheLeftAction->setShortcutContext(Qt::WidgetShortcut); goToPageOnTheLeftAction->setToolTip(tr("Go to previous page")); goToPageOnTheLeftAction->setData(PREV_ACTION_Y); @@ -266,7 +267,7 @@ void MainWindowViewer::createActions() connect(goToPageOnTheLeftAction, &QAction::triggered, viewer, &Viewer::left); goToPageOnTheRightAction = new QAction(tr("&Next"), this); - goToPageOnTheRightAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/next"))); + goToPageOnTheRightAction->setIcon(QIcon(":/images/viewer_toolbar/next.svg")); goToPageOnTheRightAction->setShortcutContext(Qt::WidgetShortcut); goToPageOnTheRightAction->setToolTip(tr("Go to next page")); goToPageOnTheRightAction->setData(NEXT_ACTION_Y); @@ -274,7 +275,7 @@ void MainWindowViewer::createActions() connect(goToPageOnTheRightAction, &QAction::triggered, viewer, &Viewer::right); adjustHeightAction = new QAction(tr("Fit Height"), this); - adjustHeightAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/toHeight"))); + adjustHeightAction->setIcon(QIcon(":/images/viewer_toolbar/toHeight.svg")); // adjustWidth->setCheckable(true); adjustHeightAction->setToolTip(tr("Fit image to height")); // adjustWidth->setIcon(QIcon(":/images/fitWidth.svg")); @@ -284,7 +285,7 @@ void MainWindowViewer::createActions() connect(adjustHeightAction, &QAction::triggered, this, &MainWindowViewer::fitToHeight); adjustWidthAction = new QAction(tr("Fit Width"), this); - adjustWidthAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/toWidth"))); + adjustWidthAction->setIcon(QIcon(":/images/viewer_toolbar/toWidth.svg")); // adjustWidth->setCheckable(true); adjustWidthAction->setToolTip(tr("Fit image to width")); // adjustWidth->setIcon(QIcon(":/images/fitWidth.svg")); @@ -294,7 +295,7 @@ void MainWindowViewer::createActions() connect(adjustWidthAction, &QAction::triggered, this, &MainWindowViewer::fitToWidth); adjustToFullSizeAction = new QAction(tr("Show full size"), this); - adjustToFullSizeAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/full"))); + adjustToFullSizeAction->setIcon(QIcon(":/images/viewer_toolbar/full.svg")); adjustToFullSizeAction->setCheckable(false); adjustToFullSizeAction->setData(ADJUST_TO_FULL_SIZE_ACTION_Y); adjustToFullSizeAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_TO_FULL_SIZE_ACTION_Y)); @@ -302,7 +303,7 @@ void MainWindowViewer::createActions() connect(adjustToFullSizeAction, &QAction::triggered, this, &MainWindowViewer::adjustToFullSizeSwitch); fitToPageAction = new QAction(tr("Fit to page"), this); - fitToPageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/fitToPage"))); + fitToPageAction->setIcon(QIcon(":/images/viewer_toolbar/fitToPage.svg")); fitToPageAction->setData(FIT_TO_PAGE_ACTION_Y); fitToPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FIT_TO_PAGE_ACTION_Y)); fitToPageAction->setCheckable(true); @@ -338,7 +339,7 @@ void MainWindowViewer::createActions() connect(resetZoomAction, &QAction::triggered, this, &MainWindowViewer::resetZoomLevel); showZoomSliderlAction = new QAction(tr("Show zoom slider"), this); - showZoomSliderlAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/zoom"))); + showZoomSliderlAction->setIcon(QIcon(":/images/viewer_toolbar/zoom.svg")); increasePageZoomAction = new QAction(tr("Zoom+"), this); increasePageZoomAction->setData(ZOOM_PLUS_ACTION_Y); @@ -351,20 +352,20 @@ void MainWindowViewer::createActions() connect(decreasePageZoomAction, &QAction::triggered, this, &MainWindowViewer::decreasePageZoomLevel); leftRotationAction = new QAction(tr("Rotate image to the left"), this); - leftRotationAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/rotateL"))); + leftRotationAction->setIcon(QIcon(":/images/viewer_toolbar/rotateL.svg")); leftRotationAction->setData(LEFT_ROTATION_ACTION_Y); leftRotationAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(LEFT_ROTATION_ACTION_Y)); connect(leftRotationAction, &QAction::triggered, viewer, &Viewer::rotateLeft); rightRotationAction = new QAction(tr("Rotate image to the right"), this); - rightRotationAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/rotateR"))); + rightRotationAction->setIcon(QIcon(":/images/viewer_toolbar/rotateR.svg")); rightRotationAction->setData(RIGHT_ROTATION_ACTION_Y); rightRotationAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RIGHT_ROTATION_ACTION_Y)); connect(rightRotationAction, &QAction::triggered, viewer, &Viewer::rotateRight); doublePageAction = new QAction(tr("Double page mode"), this); doublePageAction->setToolTip(tr("Switch to double page mode")); - doublePageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/doublePage"))); + doublePageAction->setIcon(QIcon(":/images/viewer_toolbar/doublePage.svg")); doublePageAction->setCheckable(true); doublePageAction->setChecked(Configuration::getConfiguration().getDoublePage()); doublePageAction->setData(DOUBLE_PAGE_ACTION_Y); @@ -374,7 +375,7 @@ void MainWindowViewer::createActions() // inversed pictures mode doubleMangaPageAction = new QAction(tr("Double page manga mode"), this); doubleMangaPageAction->setToolTip(tr("Reverse reading order in double page mode")); - doubleMangaPageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/doubleMangaPage"))); + doubleMangaPageAction->setIcon(QIcon(":/images/viewer_toolbar/doubleMangaPage.svg")); doubleMangaPageAction->setCheckable(true); doubleMangaPageAction->setChecked(Configuration::getConfiguration().getDoubleMangaPage()); doubleMangaPageAction->setData(DOUBLE_MANGA_PAGE_ACTION_Y); @@ -383,7 +384,7 @@ void MainWindowViewer::createActions() connect(doubleMangaPageAction, &QAction::triggered, this, &MainWindowViewer::doubleMangaPageSwitch); goToPageAction = new QAction(tr("Go To"), this); - goToPageAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/goto"))); + goToPageAction->setIcon(QIcon(":/images/viewer_toolbar/goto.svg")); goToPageAction->setToolTip(tr("Go to page ...")); goToPageAction->setData(GO_TO_PAGE_ACTION_Y); goToPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(GO_TO_PAGE_ACTION_Y)); @@ -393,20 +394,20 @@ void MainWindowViewer::createActions() optionsAction->setToolTip(tr("YACReader options")); optionsAction->setData(OPTIONS_ACTION_Y); optionsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPTIONS_ACTION_Y)); - optionsAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/options"))); + optionsAction->setIcon(QIcon(":/images/viewer_toolbar/options.svg")); connect(optionsAction, &QAction::triggered, optionsDialog, &OptionsDialog::show); helpAboutAction = new QAction(tr("Help"), this); helpAboutAction->setToolTip(tr("Help, About YACReader")); - helpAboutAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/help"))); + helpAboutAction->setIcon(QIcon(":/images/viewer_toolbar/help.svg")); helpAboutAction->setData(HELP_ABOUT_ACTION_Y); helpAboutAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HELP_ABOUT_ACTION_Y)); connect(helpAboutAction, &QAction::triggered, had, &QWidget::show); showMagnifyingGlassAction = new QAction(tr("Magnifying glass"), this); showMagnifyingGlassAction->setToolTip(tr("Switch Magnifying glass")); - showMagnifyingGlassAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/magnifyingGlass"))); + showMagnifyingGlassAction->setIcon(QIcon(":/images/viewer_toolbar/magnifyingGlass.svg")); showMagnifyingGlassAction->setCheckable(true); showMagnifyingGlassAction->setData(SHOW_MAGNIFYING_GLASS_ACTION_Y); showMagnifyingGlassAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_MAGNIFYING_GLASS_ACTION_Y)); @@ -414,7 +415,7 @@ void MainWindowViewer::createActions() setBookmarkAction = new QAction(tr("Set bookmark"), this); setBookmarkAction->setToolTip(tr("Set a bookmark on the current page")); - setBookmarkAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/bookmark"))); + setBookmarkAction->setIcon(QIcon(":/images/viewer_toolbar/bookmark.svg")); setBookmarkAction->setCheckable(true); setBookmarkAction->setData(SET_BOOKMARK_ACTION_Y); setBookmarkAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_BOOKMARK_ACTION_Y)); @@ -424,38 +425,38 @@ void MainWindowViewer::createActions() showBookmarksAction = new QAction(tr("Show bookmarks"), this); showBookmarksAction->setToolTip(tr("Show the bookmarks of the current comic")); - showBookmarksAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/showBookmarks"))); + showBookmarksAction->setIcon(QIcon(":/images/viewer_toolbar/showBookmarks.svg")); showBookmarksAction->setData(SHOW_BOOKMARKS_ACTION_Y); showBookmarksAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_BOOKMARKS_ACTION_Y)); connect(showBookmarksAction, &QAction::triggered, viewer->getBookmarksDialog(), &QWidget::show); showShorcutsAction = new QAction(tr("Show keyboard shortcuts"), this); - showShorcutsAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/shortcuts"))); + showShorcutsAction->setIcon(QIcon(":/images/viewer_toolbar/shortcuts.svg")); showShorcutsAction->setData(SHOW_SHORCUTS_ACTION_Y); showShorcutsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_SHORCUTS_ACTION_Y)); connect(showShorcutsAction, &QAction::triggered, editShortcutsDialog, &QWidget::show); showInfoAction = new QAction(tr("Show Info"), this); - showInfoAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/info"))); + showInfoAction->setIcon(QIcon(":/images/viewer_toolbar/info.svg")); showInfoAction->setData(SHOW_INFO_ACTION_Y); showInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_INFO_ACTION_Y)); connect(showInfoAction, &QAction::triggered, viewer, &Viewer::informationSwitch); closeAction = new QAction(tr("Close"), this); - closeAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/close"))); + closeAction->setIcon(QIcon(":/images/viewer_toolbar/close.svg")); closeAction->setData(CLOSE_ACTION_Y); closeAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(CLOSE_ACTION_Y)); connect(closeAction, &QAction::triggered, this, &QWidget::close); showDictionaryAction = new QAction(tr("Show Dictionary"), this); - showDictionaryAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/translator"))); + showDictionaryAction->setIcon(QIcon(":/images/viewer_toolbar/translator.svg")); // showDictionaryAction->setCheckable(true); showDictionaryAction->setData(SHOW_DICTIONARY_ACTION_Y); showDictionaryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_DICTIONARY_ACTION_Y)); connect(showDictionaryAction, &QAction::triggered, viewer, &Viewer::translatorSwitch); showFlowAction = new QAction(tr("Show go to flow"), this); - showFlowAction->setIcon(QIcon(addExtensionToIconPath(":/images/viewer_toolbar/flow"))); + showFlowAction->setIcon(QIcon(":/images/viewer_toolbar/flow.svg")); showFlowAction->setData(SHOW_FLOW_ACTION_Y); showFlowAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_FLOW_ACTION_Y)); connect(showFlowAction, &QAction::triggered, viewer, &Viewer::goToFlowSwitch); @@ -1159,10 +1160,22 @@ void MainWindowViewer::processReset() void MainWindowViewer::setUpShortcutsManagement() { + // Set up icon mapping for theme changes + QMap> iconMapping; + iconMapping[tr("Comics")] = [](const Theme &t) { return t.shortcutsIcons.comicsIcon; }; + iconMapping[tr("General")] = [](const Theme &t) { return t.shortcutsIcons.generalIcon; }; + iconMapping[tr("Magnifiying glass")] = [](const Theme &t) { return t.shortcutsIcons.magnifyingGlassIcon; }; + iconMapping[tr("Page adjustement")] = [](const Theme &t) { return t.shortcutsIcons.pageIcon; }; + iconMapping[tr("Reading")] = [](const Theme &t) { return t.shortcutsIcons.readingIcon; }; + editShortcutsDialog->setGroupIconMapping(iconMapping); + QList allActions; QList tmpList; - editShortcutsDialog->addActionsGroup(tr("Comics"), QIcon(":/images/shortcuts/shortcuts_group_comics.svg"), + // Get current theme for initial icons + const auto &theme = ThemeManager::instance().getCurrentTheme(); + + editShortcutsDialog->addActionsGroup(tr("Comics"), theme.shortcutsIcons.comicsIcon, tmpList = { openAction, openLatestComicAction, openFolderAction, @@ -1178,7 +1191,7 @@ void MainWindowViewer::setUpShortcutsManagement() auto *const toggleToolbarsAction = addActionWithShortcut(tr("Hide/show toolbar"), TOGGLE_TOOL_BARS_ACTION_Y); connect(toggleToolbarsAction, &QAction::triggered, this, &MainWindowViewer::toggleToolBars); - editShortcutsDialog->addActionsGroup(tr("General"), QIcon(":/images/shortcuts/shortcuts_group_general.svg"), + editShortcutsDialog->addActionsGroup(tr("General"), theme.shortcutsIcons.generalIcon, tmpList = QList() << optionsAction << helpAboutAction @@ -1216,7 +1229,7 @@ void MainWindowViewer::setUpShortcutsManagement() zoomInMglassAction, zoomOutMglassAction, resetMglassAction }; - editShortcutsDialog->addActionsGroup(tr("Magnifiying glass"), QIcon(":/images/shortcuts/shortcuts_group_mglass.svg"), + editShortcutsDialog->addActionsGroup(tr("Magnifiying glass"), theme.shortcutsIcons.magnifyingGlassIcon, tmpList = QList() << showMagnifyingGlassAction << mglassActions); @@ -1227,7 +1240,7 @@ void MainWindowViewer::setUpShortcutsManagement() CHANGE_FIT_ACTION_Y); connect(toggleFitToScreenAction, &QAction::triggered, this, &MainWindowViewer::toggleWidthHeight); - editShortcutsDialog->addActionsGroup(tr("Page adjustement"), QIcon(":/images/shortcuts/shortcuts_group_page.svg"), + editShortcutsDialog->addActionsGroup(tr("Page adjustement"), theme.shortcutsIcons.pageIcon, tmpList = QList() << adjustHeightAction << adjustWidthAction @@ -1304,7 +1317,7 @@ void MainWindowViewer::setUpShortcutsManagement() offsetDoublePageToTheLeft, offsetDoublePageToTheRight }; - editShortcutsDialog->addActionsGroup(tr("Reading"), QIcon(":/images/shortcuts/shortcuts_group_reading.svg"), + editShortcutsDialog->addActionsGroup(tr("Reading"), theme.shortcutsIcons.readingIcon, tmpList = QList() << goToPageOnTheRightAction << goToPageOnTheLeftAction diff --git a/YACReader/main_window_viewer.h b/YACReader/main_window_viewer.h index db24d2f54..f480ef28c 100644 --- a/YACReader/main_window_viewer.h +++ b/YACReader/main_window_viewer.h @@ -174,8 +174,6 @@ public slots: void setMglassActionsEnabled(bool enabled); void setLoadedComicActionsEnabled(bool enabled); - void applyTheme(const Theme &theme) override; - //! Manejadores de evento: // void resizeEvent(QResizeEvent * event); void mouseDoubleClickEvent(QMouseEvent *event) override; @@ -201,6 +199,7 @@ public slots: void sendComic(); void updatePrevNextActions(bool thereIsPrevious, bool thereIsNext); void afterLaunchTasks(); + void applyTheme(const Theme &theme) override; public: MainWindowViewer(); diff --git a/YACReader/options_dialog.cpp b/YACReader/options_dialog.cpp index 03ee97650..4df071c36 100644 --- a/YACReader/options_dialog.cpp +++ b/YACReader/options_dialog.cpp @@ -33,7 +33,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) auto path = new QHBoxLayout(); path->addWidget(pathEdit = new QLineEdit()); - path->addWidget(pathFindButton = new QPushButton(QIcon(":/images/find_folder.png"), "")); + path->addWidget(pathFindButton = new QPushButton("")); pathBox->setLayout(path); QGroupBox *displayBox = new QGroupBox(tr("Display")); @@ -223,6 +223,13 @@ OptionsDialog::OptionsDialog(QWidget *parent) setWindowTitle(tr("Options")); this->layout()->setSizeConstraint(QLayout::SetFixedSize); + + initTheme(this); +} + +void OptionsDialog::applyTheme(const Theme &theme) +{ + pathFindButton->setIcon(theme.dialogIcons.findFolderIcon); } void OptionsDialog::findFolder() @@ -247,7 +254,7 @@ void OptionsDialog::saveOptions() Configuration::getConfiguration().setShowTimeInInformation(showTimeInInformationLabel->isChecked()); - if (currentColor != ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor) { + if (currentColor != theme.viewer.defaultBackgroundColor) { settings->setValue(BACKGROUND_COLOR, currentColor); } else { settings->remove(BACKGROUND_COLOR); @@ -285,7 +292,7 @@ void OptionsDialog::restoreOptions(QSettings *settings) showTimeInInformationLabel->setChecked(Configuration::getConfiguration().getShowTimeInInformation()); - updateColor(settings->value(BACKGROUND_COLOR, ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor).value()); + updateColor(settings->value(BACKGROUND_COLOR, theme.viewer.defaultBackgroundColor).value()); // fitToWidthRatioS->setSliderPosition(settings->value(FIT_TO_WIDTH_RATIO).toFloat()*100); quickNavi->setChecked(settings->value(QUICK_NAVI_MODE).toBool()); @@ -402,5 +409,5 @@ void OptionsDialog::clearBackgroundColor() { settings->remove(BACKGROUND_COLOR); - updateColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor); + updateColor(theme.viewer.defaultBackgroundColor); } diff --git a/YACReader/options_dialog.h b/YACReader/options_dialog.h index f1d96767a..7c2ef6cc9 100644 --- a/YACReader/options_dialog.h +++ b/YACReader/options_dialog.h @@ -2,6 +2,7 @@ #define __OPTIONS_DIALOG_H #include "yacreader_options_dialog.h" +#include "themable.h" class QDialog; class QLabel; @@ -12,12 +13,15 @@ class QPushButton; class QRadioButton; class YACReaderSpinSliderWidget; -class OptionsDialog : public YACReaderOptionsDialog +class OptionsDialog : public YACReaderOptionsDialog, protected Themable { Q_OBJECT public: OptionsDialog(QWidget *parent = nullptr); +protected: + void applyTheme(const Theme &theme) override; + private: // QLabel * pathLabel; QLineEdit *pathEdit; diff --git a/YACReader/themes/theme.h b/YACReader/themes/theme.h index 9754f30c7..509942093 100644 --- a/YACReader/themes/theme.h +++ b/YACReader/themes/theme.h @@ -4,6 +4,7 @@ #include #include "help_about_dialog_theme.h" +#include "whats_new_dialog_theme.h" struct ToolbarThemeTemplates { QString toolbarQSS = "QToolBar { border: none; background: %1; }\n" @@ -126,11 +127,26 @@ struct GoToFlowWidgetTheme { QIcon goToIcon; }; +struct ShortcutsIconsTheme { + QIcon comicsIcon; + QIcon generalIcon; + QIcon magnifyingGlassIcon; + QIcon pageIcon; + QIcon readingIcon; +}; + +struct DialogIconsTheme { + QIcon findFolderIcon; +}; + struct Theme { ToolbarTheme toolbar; ViewerTheme viewer; GoToFlowWidgetTheme goToFlowWidget; HelpAboutDialogTheme helpAboutDialog; + WhatsNewDialogTheme whatsNewDialog; + ShortcutsIconsTheme shortcutsIcons; + DialogIconsTheme dialogIcons; }; #endif // THEME_H diff --git a/YACReader/themes/theme_factory.cpp b/YACReader/themes/theme_factory.cpp index 3f48955a7..7fd7d1f76 100644 --- a/YACReader/themes/theme_factory.cpp +++ b/YACReader/themes/theme_factory.cpp @@ -1,5 +1,7 @@ #include "theme_factory.h" +#include + #include "icon_utils.h" struct ToolbarParams { @@ -39,6 +41,20 @@ struct GoToFlowWidgetParams { QColor iconColor; }; +struct WhatsNewDialogParams { + QColor backgroundColor; + QColor headerTextColor; + QColor versionTextColor; + QColor contentTextColor; + QColor linkColor; + QColor closeButtonColor; + QColor headerDecorationColor; +}; + +struct ShortcutsIconsParams { + QColor iconColor; // Main icon color (replaces #f0f) +}; + struct ThemeParams { QString themeName; @@ -46,6 +62,8 @@ struct ThemeParams { ViewerParams viewerParams; GoToFlowWidgetParams goToFlowWidgetParams; HelpAboutDialogTheme helpAboutDialogParams; + WhatsNewDialogParams whatsNewDialogParams; + ShortcutsIconsParams shortcutsIconsParams; }; void setToolbarIconPair(QIcon &icon, @@ -157,6 +175,38 @@ Theme makeTheme(const ThemeParams ¶ms) theme.helpAboutDialog = params.helpAboutDialogParams; // end HelpAboutDialog + // WhatsNewDialog + const auto &wn = params.whatsNewDialogParams; + theme.whatsNewDialog.backgroundColor = wn.backgroundColor; + theme.whatsNewDialog.headerTextColor = wn.headerTextColor; + theme.whatsNewDialog.versionTextColor = wn.versionTextColor; + theme.whatsNewDialog.contentTextColor = wn.contentTextColor; + theme.whatsNewDialog.linkColor = wn.linkColor; + theme.whatsNewDialog.closeButtonIcon = QPixmap(recoloredSvgToThemeFile(":/images/custom_dialog/custom_close_button.svg", wn.closeButtonColor, params.themeName)); + theme.whatsNewDialog.headerDecoration = QPixmap(recoloredSvgToThemeFile(":/images/whats_new/whatsnew_header.svg", wn.headerDecorationColor, params.themeName)); + // end WhatsNewDialog + + // ShortcutsIcons + const auto &sci = params.shortcutsIconsParams; + auto makeShortcutsIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, sci.iconColor, params.themeName); + return QIcon(path); + }; + + theme.shortcutsIcons.comicsIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_comics.svg"); + theme.shortcutsIcons.generalIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_general.svg"); + theme.shortcutsIcons.magnifyingGlassIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_mglass.svg"); + theme.shortcutsIcons.pageIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_page.svg"); + theme.shortcutsIcons.readingIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_reading.svg"); + // end ShortcutsIcons + + // FindFolder icon (used in OptionsDialog) + { + const QString path = recoloredSvgToThemeFile(":/images/find_folder.svg", params.toolbarParams.iconColor, params.themeName); + const qreal dpr = qApp->devicePixelRatio(); + theme.dialogIcons.findFolderIcon = QIcon(renderSvgToPixmap(path, 13, 13, dpr)); + } + return theme; } @@ -220,6 +270,19 @@ ThemeParams classicThemeParams() params.helpAboutDialogParams.headingColor = QColor(0x302f2d); params.helpAboutDialogParams.linkColor = QColor(0xC19441); + params.whatsNewDialogParams.backgroundColor = QColor(0xFFFFFF); + params.whatsNewDialogParams.headerTextColor = QColor(0x0A0A0A); + params.whatsNewDialogParams.versionTextColor = QColor(0x858585); + params.whatsNewDialogParams.contentTextColor = QColor(0x0A0A0A); + params.whatsNewDialogParams.linkColor = QColor(0xE8B800); + params.whatsNewDialogParams.closeButtonColor = QColor(0x444444); + params.whatsNewDialogParams.headerDecorationColor = QColor(0xE8B800); + + // ShortcutsIcons + ShortcutsIconsParams sci; + sci.iconColor = QColor(0x404040); // Dark icons for light background + params.shortcutsIconsParams = sci; + return params; } @@ -267,6 +330,19 @@ ThemeParams lightThemeParams() params.helpAboutDialogParams.headingColor = QColor(0x302f2d); params.helpAboutDialogParams.linkColor = QColor(0xC19441); + params.whatsNewDialogParams.backgroundColor = QColor(0xFFFFFF); + params.whatsNewDialogParams.headerTextColor = QColor(0x0A0A0A); + params.whatsNewDialogParams.versionTextColor = QColor(0x858585); + params.whatsNewDialogParams.contentTextColor = QColor(0x0A0A0A); + params.whatsNewDialogParams.linkColor = QColor(0xE8B800); + params.whatsNewDialogParams.closeButtonColor = QColor(0x444444); + params.whatsNewDialogParams.headerDecorationColor = QColor(0xE8B800); + + // ShortcutsIcons + ShortcutsIconsParams sci; + sci.iconColor = QColor(0x606060); // Dark icons for light background + params.shortcutsIconsParams = sci; + return params; } @@ -314,6 +390,19 @@ ThemeParams darkThemeParams() params.helpAboutDialogParams.headingColor = QColor(0xE0E0E0); params.helpAboutDialogParams.linkColor = QColor(0xD4A84B); + params.whatsNewDialogParams.backgroundColor = QColor(0x2A2A2A); + params.whatsNewDialogParams.headerTextColor = QColor(0xE0E0E0); + params.whatsNewDialogParams.versionTextColor = QColor(0x858585); + params.whatsNewDialogParams.contentTextColor = QColor(0xE0E0E0); + params.whatsNewDialogParams.linkColor = QColor(0xE8B800); + params.whatsNewDialogParams.closeButtonColor = QColor(0xDDDDDD); + params.whatsNewDialogParams.headerDecorationColor = QColor(0xE8B800); + + // ShortcutsIcons + ShortcutsIconsParams sci; + sci.iconColor = QColor(0xD0D0D0); // Light icons for dark background + params.shortcutsIconsParams = sci; + return params; } diff --git a/YACReader/yacreader_images.qrc b/YACReader/yacreader_images.qrc index 3a145e43e..ed7b9a8e2 100644 --- a/YACReader/yacreader_images.qrc +++ b/YACReader/yacreader_images.qrc @@ -2,7 +2,7 @@ ../images/icon-new.svg ../images/goto.png - ../images/find_folder.png + ../images/find_folder.svg ../images/flow1.png ../images/flow2.png ../images/flow3.png @@ -19,8 +19,8 @@ ../images/dropDownArrow.png ../images/translatorSearch.png ../images/speaker.png - ../images/clear_shortcut.svg - ../images/accept_shortcut.svg + ../images/shortcuts/clear_shortcut.svg + ../images/shortcuts/accept_shortcut.svg ../images/shortcuts/shortcuts_group_comics.svg ../images/shortcuts/shortcuts_group_folders.svg ../images/shortcuts/shortcuts_group_general.svg diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index 4d6d00594..e7ca65bce 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -125,6 +125,7 @@ HEADERS += \ yacreader_history_controller.h \ yacreader_navigation_controller.h \ empty_label_widget.h \ + empty_folder_widget.h \ empty_container_info.h \ empty_special_list.h \ empty_reading_list_widget.h \ @@ -210,6 +211,7 @@ SOURCES += \ yacreader_history_controller.cpp \ yacreader_navigation_controller.cpp \ empty_label_widget.cpp \ + empty_folder_widget.cpp \ empty_container_info.cpp \ empty_special_list.cpp \ empty_reading_list_widget.cpp \ diff --git a/YACReaderLibrary/add_label_dialog.cpp b/YACReaderLibrary/add_label_dialog.cpp index 18f3f9ed7..1e06fa363 100644 --- a/YACReaderLibrary/add_label_dialog.cpp +++ b/YACReaderLibrary/add_label_dialog.cpp @@ -1,5 +1,22 @@ #include "add_label_dialog.h" +namespace { +const char *labelColorNames[] = { + QT_TR_NOOP("red"), + QT_TR_NOOP("orange"), + QT_TR_NOOP("yellow"), + QT_TR_NOOP("green"), + QT_TR_NOOP("cyan"), + QT_TR_NOOP("blue"), + QT_TR_NOOP("violet"), + QT_TR_NOOP("purple"), + QT_TR_NOOP("pink"), + QT_TR_NOOP("white"), + QT_TR_NOOP("light"), + QT_TR_NOOP("dark") +}; +} + AddLabelDialog::AddLabelDialog(QWidget *parent) : QDialog(parent) { @@ -11,21 +28,10 @@ AddLabelDialog::AddLabelDialog(QWidget *parent) layout->addWidget(new QLabel(tr("Choose a color:"))); layout->addWidget(list = new QListWidget()); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_red.svg"), tr("red"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_orange.svg"), tr("orange"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_yellow.svg"), tr("yellow"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_green.svg"), tr("green"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_cyan.svg"), tr("cyan"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_blue.svg"), tr("blue"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_violet.svg"), tr("violet"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_purple.svg"), tr("purple"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_pink.svg"), tr("pink"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_white.svg"), tr("white"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_light.svg"), tr("light"))); - list->addItem(new QListWidgetItem(QIcon(":/images/lists/label_dark.svg"), tr("dark"))); - - QColor backgroundColor = this->palette().window().color(); - list->setStyleSheet(QString("QListWidget {border : none; background-color: rgb(%1,%2,%3);}").arg(backgroundColor.red()).arg(backgroundColor.green()).arg(backgroundColor.blue())); + for (const auto &colorName : labelColorNames) { + list->addItem(new QListWidgetItem(tr(colorName))); + } + list->setMinimumHeight(225); setModal(true); @@ -50,6 +56,22 @@ AddLabelDialog::AddLabelDialog(QWidget *parent) connect(edit, &QLineEdit::textChanged, this, &AddLabelDialog::validateName); connect(cancelButton, &QAbstractButton::clicked, this, &QWidget::close); connect(acceptButton, &QAbstractButton::clicked, this, &QDialog::accept); + + initTheme(this); +} + +void AddLabelDialog::applyTheme(const Theme &theme) +{ + const auto &icons = theme.readingListIcons.labelIcons; + + for (int i = 0; i < list->count(); ++i) { + const QString colorName = labelColorNames[i]; + if (icons.contains(colorName)) { + list->item(i)->setIcon(icons[colorName]); + } + } + + list->setStyleSheet("QListWidget {border : none;}"); } YACReader::LabelColors AddLabelDialog::selectedColor() diff --git a/YACReaderLibrary/add_label_dialog.h b/YACReaderLibrary/add_label_dialog.h index f18351be8..e16216d64 100644 --- a/YACReaderLibrary/add_label_dialog.h +++ b/YACReaderLibrary/add_label_dialog.h @@ -4,8 +4,9 @@ #include #include "yacreader_global.h" +#include "themable.h" -class AddLabelDialog : public QDialog +class AddLabelDialog : public QDialog, protected Themable { Q_OBJECT public: @@ -21,6 +22,8 @@ protected slots: void validateName(const QString &name); protected: + void applyTheme(const Theme &theme) override; + QLineEdit *edit; QListWidget *list; diff --git a/YACReaderLibrary/add_library_dialog.cpp b/YACReaderLibrary/add_library_dialog.cpp index 80c2e8a1b..d5ebc09b7 100644 --- a/YACReaderLibrary/add_library_dialog.cpp +++ b/YACReaderLibrary/add_library_dialog.cpp @@ -30,7 +30,7 @@ void AddLibraryDialog::setupUI() cancel = new QPushButton(tr("Cancel")); connect(cancel, &QPushButton::clicked, this, &AddLibraryDialog::close); - find = new QPushButton(QIcon(":/images/find_folder.png"), ""); + find = new QPushButton(""); connect(find, &QAbstractButton::clicked, this, &AddLibraryDialog::findPath); auto content = new QGridLayout; @@ -54,16 +54,22 @@ void AddLibraryDialog::setupUI() mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/openLibrary.png"); - imgLabel->setPixmap(p); - imgMainLayout->addWidget(imgLabel); //,0,Qt::AlignTop); + imgLabel = new QLabel(this); + imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); setLayout(imgMainLayout); setModal(true); setWindowTitle(tr("Add an existing library")); + + initTheme(this); +} + +void AddLibraryDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.openLibraryIcon); + find->setIcon(theme.dialogIcons.findFolderIcon); } void AddLibraryDialog::add() diff --git a/YACReaderLibrary/add_library_dialog.h b/YACReaderLibrary/add_library_dialog.h index 1176d9330..041c79911 100644 --- a/YACReaderLibrary/add_library_dialog.h +++ b/YACReaderLibrary/add_library_dialog.h @@ -1,19 +1,25 @@ #ifndef __ADD_LIBRARY_DIALOG_H #define __ADD_LIBRARY_DIALOG_H +#include "themable.h" + #include #include #include #include #include -class AddLibraryDialog : public QDialog +class AddLibraryDialog : public QDialog, protected Themable { Q_OBJECT public: AddLibraryDialog(QWidget *parent = nullptr); +protected: + void applyTheme(const Theme &theme) override; + private: + QLabel *imgLabel; QLabel *nameLabel; QLabel *textLabel; QLineEdit *path; diff --git a/YACReaderLibrary/classic_comics_view.cpp b/YACReaderLibrary/classic_comics_view.cpp index e3280f1ee..e3eccd485 100644 --- a/YACReaderLibrary/classic_comics_view.cpp +++ b/YACReaderLibrary/classic_comics_view.cpp @@ -5,10 +5,8 @@ #include "QStackedWidget" #include "comic_flow_widget.h" -#include "QsLog.h" #include "shortcuts_manager.h" #include "yacreader_table_view.h" -#include "yacreader_tool_bar_stretch.h" ClassicComicsView::ClassicComicsView(QWidget *parent) : ComicsView(parent), searching(false) @@ -87,11 +85,23 @@ ClassicComicsView::ClassicComicsView(QWidget *parent) 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/comics_view_toolbar/hideComicFlow.svg")); hideFlowViewAction->setCheckable(true); hideFlowViewAction->setChecked(false); connect(hideFlowViewAction, &QAction::toggled, this, &ClassicComicsView::hideComicFlow); + + initTheme(this); +} + +void ClassicComicsView::applyTheme(const Theme &theme) +{ + // Update searching icon background to match comic flow + searchingIcon->setStyleSheet(QString("QWidget {border: none; background-color: %1;}").arg(theme.comicFlow.backgroundColor.name())); + searchingIconLabel->setPixmap(theme.emptyContainer.searchingIcon); + + sVertical->setStyleSheet(theme.contentSplitter.verticalSplitterQSS); + + hideFlowViewAction->setIcon(theme.comicsViewToolbar.hideComicFlowIcon); } void ClassicComicsView::hideComicFlow(bool hide) @@ -406,15 +416,10 @@ void ClassicComicsView::setupSearchingIcon() auto h = new QHBoxLayout; - QPixmap p(":/images/searching_icon.png"); - QLabel *l = new QLabel(searchingIcon); - l->setPixmap(p); - l->setFixedSize(p.size()); - h->addWidget(l, 0, Qt::AlignCenter); + searchingIconLabel = new QLabel(searchingIcon); + h->addWidget(searchingIconLabel, 0, Qt::AlignCenter); searchingIcon->setLayout(h); - searchingIcon->setStyleSheet(QString("QWidget {border : none; background-color: #000000;}")); - hideSearchingIcon(); } diff --git a/YACReaderLibrary/classic_comics_view.h b/YACReaderLibrary/classic_comics_view.h index c492a033e..af67ee676 100644 --- a/YACReaderLibrary/classic_comics_view.h +++ b/YACReaderLibrary/classic_comics_view.h @@ -2,6 +2,7 @@ #define CLASSIC_COMICS_VIEW_H #include "comics_view.h" +#include "themable.h" #include #include @@ -15,11 +16,14 @@ class ComicModel; class YACReaderTableView; class YACReaderToolBarStretch; -class ClassicComicsView : public ComicsView +class ClassicComicsView : public ComicsView, protected Themable { Q_OBJECT public: explicit ClassicComicsView(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; void setToolBar(QToolBar *toolBar) override; void setModel(ComicModel *model) override; @@ -69,6 +73,7 @@ protected slots: QByteArray previousSplitterStatus; QWidget *searchingIcon; + QLabel *searchingIconLabel; bool searching; void setupSearchingIcon(); void showSearchingIcon(); diff --git a/YACReaderLibrary/comic_flow_widget.cpp b/YACReaderLibrary/comic_flow_widget.cpp index 5df9bd08f..7e54ae6ae 100644 --- a/YACReaderLibrary/comic_flow_widget.cpp +++ b/YACReaderLibrary/comic_flow_widget.cpp @@ -14,10 +14,25 @@ ComicFlowWidget::ComicFlowWidget(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); setLayout(l); - QPalette Pal(palette()); - Pal.setColor(QPalette::Window, Qt::black); setAutoFillBackground(true); - setPalette(Pal); + + initTheme(this); +} + +void ComicFlowWidget::applyTheme(const Theme &theme) +{ + setBackgroundColor(theme.comicFlow.backgroundColor); + setTextColor(theme.comicFlow.textColor); +} + +void ComicFlowWidget::setBackgroundColor(const QColor &color) +{ + flow->setBackgroundColor(color); +} + +void ComicFlowWidget::setTextColor(const QColor &color) +{ + flow->setTextColor(color); } QSize ComicFlowWidget::minimumSizeHint() const diff --git a/YACReaderLibrary/comic_flow_widget.h b/YACReaderLibrary/comic_flow_widget.h index b99c90a8d..8492bfa27 100644 --- a/YACReaderLibrary/comic_flow_widget.h +++ b/YACReaderLibrary/comic_flow_widget.h @@ -7,14 +7,17 @@ #include "yacreader_comic_flow_rhi.h" #include "yacreader_global_gui.h" +#include "themable.h" -class ComicFlowWidget : public QWidget +class ComicFlowWidget : public QWidget, protected Themable { Q_OBJECT public: ComicFlowWidget(QWidget *parent = nullptr); public slots: + void setBackgroundColor(const QColor &color); + void setTextColor(const QColor &color); void setShowMarks(bool value); void setMarks(QVector marks); void setMarkImage(QImage &image); @@ -39,6 +42,7 @@ public slots: void selected(unsigned int); protected: + void applyTheme(const Theme &theme) override; void keyPressEvent(QKeyEvent *event) override; void paintEvent(QPaintEvent *event) override; void mousePressEvent(QMouseEvent *event) override; diff --git a/YACReaderLibrary/comic_vine/scraper_results_paginator.h b/YACReaderLibrary/comic_vine/scraper_results_paginator.h index 873ece507..ca7591f02 100644 --- a/YACReaderLibrary/comic_vine/scraper_results_paginator.h +++ b/YACReaderLibrary/comic_vine/scraper_results_paginator.h @@ -16,6 +16,7 @@ class ScraperResultsPaginator : public QWidget, protected Themable void update(const QString &json); int getCurrentPage(); void setCustomLabel(const QString &label); + signals: void loadNextPage(); void loadPreviousPage(); diff --git a/YACReaderLibrary/comic_vine/title_header.h b/YACReaderLibrary/comic_vine/title_header.h index 7ce33d6c8..1ad00c8e9 100644 --- a/YACReaderLibrary/comic_vine/title_header.h +++ b/YACReaderLibrary/comic_vine/title_header.h @@ -12,6 +12,7 @@ class TitleHeader : public QWidget, protected Themable Q_OBJECT public: TitleHeader(QWidget *parent = nullptr); + public slots: void setTitle(const QString &title); void setSubTitle(const QString &title); diff --git a/YACReaderLibrary/comics_view_transition.cpp b/YACReaderLibrary/comics_view_transition.cpp index bde188b3f..0c083d93a 100644 --- a/YACReaderLibrary/comics_view_transition.cpp +++ b/YACReaderLibrary/comics_view_transition.cpp @@ -1,32 +1,21 @@ #include "comics_view_transition.h" -#include -#include -#include -#include -#include -#include #include -#include "yacreader_global.h" - ComicsViewTransition::ComicsViewTransition(QWidget *parent) : QWidget(parent) { -#ifdef Y_MAC_UI - setStyleSheet("QWidget {background:#FFFFFF}"); -#else - setStyleSheet("QWidget {background:#2A2A2A}"); -#endif + initTheme(this); +} + +void ComicsViewTransition::applyTheme(const Theme &theme) +{ + setStyleSheet(QString("QWidget {background:%1}").arg(theme.defaultContentBackgroundColor.name())); + update(); } void ComicsViewTransition::paintEvent(QPaintEvent *) { QPainter painter(this); - -#ifdef Y_MAC_UI - painter.fillRect(0, 0, width(), height(), QColor("#FFFFFF")); -#else - painter.fillRect(0, 0, width(), height(), QColor("#2A2A2A")); -#endif + painter.fillRect(0, 0, width(), height(), theme.defaultContentBackgroundColor); } diff --git a/YACReaderLibrary/comics_view_transition.h b/YACReaderLibrary/comics_view_transition.h index 78a08c3e3..d428e6744 100644 --- a/YACReaderLibrary/comics_view_transition.h +++ b/YACReaderLibrary/comics_view_transition.h @@ -3,13 +3,16 @@ #include -class ComicsViewTransition : public QWidget +#include "themable.h" + +class ComicsViewTransition : public QWidget, protected Themable { Q_OBJECT public: explicit ComicsViewTransition(QWidget *parent = nullptr); protected: + void applyTheme(const Theme &theme) override; void paintEvent(QPaintEvent *) override; }; diff --git a/YACReaderLibrary/create_library_dialog.cpp b/YACReaderLibrary/create_library_dialog.cpp index 8fbce0930..4fe223278 100644 --- a/YACReaderLibrary/create_library_dialog.cpp +++ b/YACReaderLibrary/create_library_dialog.cpp @@ -35,7 +35,7 @@ void CreateLibraryDialog::setupUI() connect(cancel, &QAbstractButton::clicked, this, &CreateLibraryDialog::cancelCreate); connect(cancel, &QAbstractButton::clicked, this, &CreateLibraryDialog::close); - find = new QPushButton(QIcon(":/images/find_folder.png"), ""); + find = new QPushButton(""); connect(find, &QAbstractButton::clicked, this, &CreateLibraryDialog::findPath); auto content = new QGridLayout; @@ -66,9 +66,7 @@ void CreateLibraryDialog::setupUI() mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/new.png"); - imgLabel->setPixmap(p); + imgLabel = new QLabel(this); imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); @@ -76,6 +74,14 @@ void CreateLibraryDialog::setupUI() setModal(true); setWindowTitle(tr("Create new library")); + + initTheme(this); +} + +void CreateLibraryDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.newLibraryIcon); + find->setIcon(theme.dialogIcons.findFolderIcon); } void CreateLibraryDialog::open(const YACReaderLibraries &libs) diff --git a/YACReaderLibrary/create_library_dialog.h b/YACReaderLibrary/create_library_dialog.h index 836580348..6adfb6614 100644 --- a/YACReaderLibrary/create_library_dialog.h +++ b/YACReaderLibrary/create_library_dialog.h @@ -2,6 +2,7 @@ #define __CREATE_LIBRARY_DIALOG_H #include "yacreader_libraries.h" +#include "themable.h" #include #include @@ -10,13 +11,17 @@ #include #include -class CreateLibraryDialog : public QDialog +class CreateLibraryDialog : public QDialog, protected Themable { Q_OBJECT public: CreateLibraryDialog(QWidget *parent = nullptr); +protected: + void applyTheme(const Theme &theme) override; + private: + QLabel *imgLabel; QLabel *nameLabel; QLabel *textLabel; QLabel *message; diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 74bb75c41..d659a19cd 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -10,48 +10,47 @@ #include "yacreader_global_gui.h" #include +#include #include using namespace YACReader; -#ifdef Y_MAC_UI -#include -QIcon finishedFolderIcon; -void drawMacOSXFinishedFolderIcon() +QIcon drawFinishedFolderIcon(const QPixmap &overlay) { + QIcon finishedIcon; QIcon ico = QFileIconProvider().icon(QFileIconProvider::Folder); QPixmap pixNormalOff = ico.pixmap(16, 16, QIcon::Normal, QIcon::Off); QPixmap pixNormalOn = ico.pixmap(16, 16, QIcon::Normal, QIcon::On); QPixmap pixSelectedOff = ico.pixmap(16, 16, QIcon::Selected, QIcon::Off); QPixmap pixSelectedOn = ico.pixmap(16, 16, QIcon::Selected, QIcon::On); - QPixmap tick(":/images/folder_finished_macosx.png"); { QPainter p(&pixNormalOff); - p.drawPixmap(4, 7, tick); + p.drawPixmap(4, 7, overlay); } - finishedFolderIcon.addPixmap(pixNormalOff, QIcon::Normal, QIcon::Off); + finishedIcon.addPixmap(pixNormalOff, QIcon::Normal, QIcon::Off); { QPainter p(&pixNormalOn); - p.drawPixmap(4, 7, tick); + p.drawPixmap(4, 7, overlay); } - finishedFolderIcon.addPixmap(pixNormalOn, QIcon::Normal, QIcon::On); + finishedIcon.addPixmap(pixNormalOn, QIcon::Normal, QIcon::On); { QPainter p(&pixSelectedOff); - p.drawPixmap(4, 7, tick); + p.drawPixmap(4, 7, overlay); } - finishedFolderIcon.addPixmap(pixSelectedOff, QIcon::Selected, QIcon::Off); + finishedIcon.addPixmap(pixSelectedOff, QIcon::Selected, QIcon::Off); { QPainter p(&pixSelectedOn); - p.drawPixmap(4, 7, tick); + p.drawPixmap(4, 7, overlay); } - finishedFolderIcon.addPixmap(pixSelectedOn, QIcon::Selected, QIcon::On); + finishedIcon.addPixmap(pixSelectedOn, QIcon::Selected, QIcon::On); + + return finishedIcon; } -#endif #define ROOT 1 @@ -132,8 +131,22 @@ FolderItem *createRoot(QSqlDatabase &db) } FolderModel::FolderModel(QObject *parent) - : QAbstractItemModel(parent), isSubfolder(false), rootItem(nullptr), folderIcon(YACReader::noHighlightedIcon(":/images/sidebar/folder.svg")), folderFinishedIcon(YACReader::noHighlightedIcon(":/images/sidebar/folder_finished.svg")), showRecent(false), recentDays(1) + : QAbstractItemModel(parent), isSubfolder(false), rootItem(nullptr), showRecent(false), recentDays(1) +{ + initTheme(this); +} + +void FolderModel::applyTheme(const Theme &theme) { + const auto &sidebarIcons = theme.sidebarIcons; + + if (sidebarIcons.useSystemFolderIcons) { + folderIcon = QFileIconProvider().icon(QFileIconProvider::Folder); + folderFinishedIcon = drawFinishedFolderIcon(sidebarIcons.folderReadOverlay); + } else { + folderIcon = sidebarIcons.folderIcon; + folderFinishedIcon = sidebarIcons.folderFinishedIcon; + } } FolderModel::~FolderModel() @@ -368,22 +381,10 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const } if (role == Qt::DecorationRole) { -#ifdef Y_MAC_UI - if (item->data(FolderModel::Finished).toBool()) { - if (finishedFolderIcon.isNull()) { - drawMacOSXFinishedFolderIcon(); - } - - return QVariant(finishedFolderIcon); - } else { - return QVariant(QFileIconProvider().icon(QFileIconProvider::Folder)); - } -#else if (item->data(FolderModel::Finished).toBool()) return QVariant(folderFinishedIcon); else return QVariant(folderIcon); -#endif } if (role == FolderModel::FolderNameRole) { diff --git a/YACReaderLibrary/db/folder_model.h b/YACReaderLibrary/db/folder_model.h index 85ccfa23d..84a759d26 100644 --- a/YACReaderLibrary/db/folder_model.h +++ b/YACReaderLibrary/db/folder_model.h @@ -13,6 +13,7 @@ #include "folder.h" #include "folder_query_result_processor.h" #include "yacreader_global.h" +#include "themable.h" class FolderItem; @@ -35,7 +36,7 @@ class FolderModelProxy : public QSortFilterProxyModel bool filterEnabled; }; -class FolderModel : public QAbstractItemModel +class FolderModel : public QAbstractItemModel, protected Themable { Q_OBJECT @@ -146,6 +147,9 @@ public slots: bool showRecent; qlonglong recentDays; + +protected: + void applyTheme(const Theme &theme) override; }; #endif diff --git a/YACReaderLibrary/db/reading_list_item.cpp b/YACReaderLibrary/db/reading_list_item.cpp index fc3c6a5d4..98e3bf57f 100644 --- a/YACReaderLibrary/db/reading_list_item.cpp +++ b/YACReaderLibrary/db/reading_list_item.cpp @@ -4,6 +4,7 @@ #include #include "QsLog.h" +#include "theme_manager.h" ListItem::ListItem(const QList &data) : itemData(data) @@ -35,8 +36,18 @@ SpecialListItem::SpecialListItem(const QList &data) QIcon SpecialListItem::getIcon() const { if (itemData.count() > Id) { - QString id = itemData.at(Id).toString(); - return YACReader::noHighlightedIcon(QString(":/images/lists/default_%1.svg").arg(id)); + int id = itemData.at(Id).toInt(); + const auto &icons = ThemeManager::instance().getCurrentTheme().readingListIcons; + switch (id) { + case 0: + return icons.readingListIcon; + case 1: + return icons.favoritesIcon; + case 2: + return icons.currentlyReadingIcon; + default: + break; + } } QLOG_WARN() << "Icon for SpecialListItem not available"; @@ -75,8 +86,11 @@ LabelItem::LabelItem(const QList &data) QIcon LabelItem::getIcon() const { if (itemData.count() > Color) { - QString color = itemData.at(Color).toString(); - return YACReader::noHighlightedIcon(QString(":/images/lists/label_%1.svg").arg(color).toLower()); + QString color = itemData.at(Color).toString().toLower(); + const auto &icons = ThemeManager::instance().getCurrentTheme().readingListIcons; + if (icons.labelIcons.contains(color)) { + return icons.labelIcons[color]; + } } QLOG_WARN() << "Icon for label item not available"; @@ -127,20 +141,19 @@ qulonglong LabelItem::getId() const //------------------------------------------------------ ReadingListItem::ReadingListItem(const QList &data, ReadingListItem *p) - : ListItem(data), parent(p), list(YACReader::noHighlightedIcon(":/images/lists/list.svg")), folder(YACReader::noHighlightedIcon(":/images/sidebar/folder.svg")) + : ListItem(data), parent(p) { } QIcon ReadingListItem::getIcon() const { + const auto &theme = ThemeManager::instance().getCurrentTheme(); if (parent->getId() == 0) - return list; // top level list - else -#ifdef Y_MAC_UI + return theme.readingListIcons.listIcon; // top level list + else if (theme.sidebarIcons.useSystemFolderIcons) return QFileIconProvider().icon(QFileIconProvider::Folder); -#else - return folder; // sublist -#endif + else + return theme.sidebarIcons.folderIcon; // sublist } int ReadingListItem::childCount() const diff --git a/YACReaderLibrary/db/reading_list_item.h b/YACReaderLibrary/db/reading_list_item.h index b7d06685a..58af7483c 100644 --- a/YACReaderLibrary/db/reading_list_item.h +++ b/YACReaderLibrary/db/reading_list_item.h @@ -82,9 +82,6 @@ class ReadingListItem : public ListItem private: QList childItems; - QIcon list; - QIcon folder; - enum DataIndexes { Name, Id, diff --git a/YACReaderLibrary/empty_container_info.cpp b/YACReaderLibrary/empty_container_info.cpp index 5fb1d514d..e06eabfe3 100644 --- a/YACReaderLibrary/empty_container_info.cpp +++ b/YACReaderLibrary/empty_container_info.cpp @@ -5,16 +5,10 @@ EmptyContainerInfo::EmptyContainerInfo(QWidget *parent) : QWidget(parent), iconLabel(new QLabel()), titleLabel(new QLabel()) { -#ifdef Y_MAC_UI - backgroundColor = "#FFFFFF"; - titleLabel->setStyleSheet("QLabel {color:#888888; font-size:24px;font-family:Arial;font-weight:bold;}"); -#else - backgroundColor = "#2A2A2A"; - titleLabel->setStyleSheet("QLabel {color:#CCCCCC; font-size:24px;font-family:Arial;font-weight:bold;}"); -#endif - iconLabel->setAlignment(Qt::AlignCenter); titleLabel->setAlignment(Qt::AlignCenter); + + initTheme(this); } void EmptyContainerInfo::setPixmap(const QPixmap &pixmap) @@ -45,5 +39,11 @@ QVBoxLayout *EmptyContainerInfo::setUpDefaultLayout(bool addStretch) void EmptyContainerInfo::paintEvent(QPaintEvent *) { QPainter painter(this); - painter.fillRect(0, 0, width(), height(), QColor(backgroundColor)); + painter.fillRect(0, 0, width(), height(), theme.emptyContainer.backgroundColor); +} + +void EmptyContainerInfo::applyTheme(const Theme &theme) +{ + titleLabel->setStyleSheet(theme.emptyContainer.titleLabelQSS); + update(); // Trigger repaint for background color } diff --git a/YACReaderLibrary/empty_container_info.h b/YACReaderLibrary/empty_container_info.h index 1a1b36321..ac61a3ec6 100644 --- a/YACReaderLibrary/empty_container_info.h +++ b/YACReaderLibrary/empty_container_info.h @@ -3,7 +3,9 @@ #include -class EmptyContainerInfo : public QWidget +#include "themable.h" + +class EmptyContainerInfo : public QWidget, protected Themable { Q_OBJECT public: @@ -17,10 +19,10 @@ public slots: protected: void paintEvent(QPaintEvent *) override; + void applyTheme(const Theme &theme) override; QLabel *iconLabel; QLabel *titleLabel; - QString backgroundColor; }; #endif // EMPTY_CONTAINER_INFO_H diff --git a/YACReaderLibrary/empty_folder_widget.cpp b/YACReaderLibrary/empty_folder_widget.cpp new file mode 100644 index 000000000..421a501c6 --- /dev/null +++ b/YACReaderLibrary/empty_folder_widget.cpp @@ -0,0 +1,15 @@ +#include "empty_folder_widget.h" + +EmptyFolderWidget::EmptyFolderWidget(QWidget *parent) + : EmptyContainerInfo(parent) +{ + setUpDefaultLayout(true); + setPixmap(theme.emptyContainer.emptyFolderIcon); + setText(tr("This folder doesn't contain comics yet")); +} + +void EmptyFolderWidget::applyTheme(const Theme &theme) +{ + EmptyContainerInfo::applyTheme(theme); + setPixmap(theme.emptyContainer.emptyFolderIcon); +} diff --git a/YACReaderLibrary/empty_folder_widget.h b/YACReaderLibrary/empty_folder_widget.h new file mode 100644 index 000000000..028039257 --- /dev/null +++ b/YACReaderLibrary/empty_folder_widget.h @@ -0,0 +1,17 @@ +#ifndef EMPTY_FOLDER_WIDGET_H +#define EMPTY_FOLDER_WIDGET_H + +#include +#include "empty_container_info.h" + +class EmptyFolderWidget : public EmptyContainerInfo +{ + Q_OBJECT +public: + explicit EmptyFolderWidget(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; +}; + +#endif // EMPTY_FOLDER_WIDGET_H diff --git a/YACReaderLibrary/empty_label_widget.cpp b/YACReaderLibrary/empty_label_widget.cpp index 0680dea8c..75c36c0b1 100644 --- a/YACReaderLibrary/empty_label_widget.cpp +++ b/YACReaderLibrary/empty_label_widget.cpp @@ -4,18 +4,20 @@ EmptyLabelWidget::EmptyLabelWidget(QWidget *parent) : EmptyContainerInfo(parent) { setUpDefaultLayout(true); - - iconLabel->setPixmap(QPixmap(":/images/empty_label.png")); - - // titleLabel->setText(tr("This label doesn't contain comics yet") + QString("

%1

").arg(tr("Drag and drop folders and comics here"))); titleLabel->setText(tr("This label doesn't contain comics yet")); } void EmptyLabelWidget::setColor(YACReader::LabelColors color) { - QPixmap p(":/images/empty_label.png"); - QImage img = p.toImage().convertToFormat(QImage::Format_ARGB32); - QColor destColor(YACReader::labelColorToRGBString(color)); - YACReader::colorize(img, destColor); - iconLabel->setPixmap(QPixmap::fromImage(img)); + currentColor = color; + auto it = theme.emptyContainer.emptyLabelIcons.find(static_cast(color)); + if (it != theme.emptyContainer.emptyLabelIcons.end()) { + setPixmap(it.value()); + } +} + +void EmptyLabelWidget::applyTheme(const Theme &theme) +{ + EmptyContainerInfo::applyTheme(theme); + setColor(currentColor); } diff --git a/YACReaderLibrary/empty_label_widget.h b/YACReaderLibrary/empty_label_widget.h index 850b6fd9f..a9ac9826e 100644 --- a/YACReaderLibrary/empty_label_widget.h +++ b/YACReaderLibrary/empty_label_widget.h @@ -12,11 +12,11 @@ class EmptyLabelWidget : public EmptyContainerInfo explicit EmptyLabelWidget(QWidget *parent = nullptr); void setColor(YACReader::LabelColors color); -signals: - -public slots: - protected: + void applyTheme(const Theme &theme) override; + +private: + YACReader::LabelColors currentColor = YACReader::YRed; }; #endif // EMPTY_LABEL_WIDGET_H diff --git a/YACReaderLibrary/empty_reading_list_widget.cpp b/YACReaderLibrary/empty_reading_list_widget.cpp index 1e79943a3..59b3e3297 100644 --- a/YACReaderLibrary/empty_reading_list_widget.cpp +++ b/YACReaderLibrary/empty_reading_list_widget.cpp @@ -4,6 +4,12 @@ EmptyReadingListWidget::EmptyReadingListWidget(QWidget *parent) : EmptyContainerInfo(parent) { setUpDefaultLayout(true); - setPixmap(QPixmap(":/images/empty_reading_list")); + setPixmap(theme.emptyContainer.emptyReadingListIcon); setText(tr("This reading list does not contain any comics yet")); } + +void EmptyReadingListWidget::applyTheme(const Theme &theme) +{ + EmptyContainerInfo::applyTheme(theme); + setPixmap(theme.emptyContainer.emptyReadingListIcon); +} diff --git a/YACReaderLibrary/empty_reading_list_widget.h b/YACReaderLibrary/empty_reading_list_widget.h index 4fa7fa257..70ef65eb5 100644 --- a/YACReaderLibrary/empty_reading_list_widget.h +++ b/YACReaderLibrary/empty_reading_list_widget.h @@ -8,6 +8,9 @@ class EmptyReadingListWidget : public EmptyContainerInfo { public: EmptyReadingListWidget(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; }; #endif // EMPTY_READING_LIST_WIDGET_H diff --git a/YACReaderLibrary/empty_special_list.cpp b/YACReaderLibrary/empty_special_list.cpp index 44a428d3f..8f0b9d1a6 100644 --- a/YACReaderLibrary/empty_special_list.cpp +++ b/YACReaderLibrary/empty_special_list.cpp @@ -5,3 +5,45 @@ EmptySpecialListWidget::EmptySpecialListWidget(QWidget *parent) { setUpDefaultLayout(true); } + +void EmptySpecialListWidget::showFavorites() +{ + currentType = Favorites; + setPixmap(theme.emptyContainer.emptyFavoritesIcon); + setText(tr("No favorites")); +} + +void EmptySpecialListWidget::showReading() +{ + currentType = Reading; + setPixmap(theme.emptyContainer.emptyCurrentReadingsIcon); + setText(tr("You are not reading anything yet, come on!!")); +} + +void EmptySpecialListWidget::showRecent() +{ + currentType = Recent; + setPixmap(QPixmap()); + setText(tr("There are no recent comics!")); +} + +void EmptySpecialListWidget::applyTheme(const Theme &theme) +{ + EmptyContainerInfo::applyTheme(theme); + updateIcon(); +} + +void EmptySpecialListWidget::updateIcon() +{ + switch (currentType) { + case Favorites: + setPixmap(theme.emptyContainer.emptyFavoritesIcon); + break; + case Reading: + setPixmap(theme.emptyContainer.emptyCurrentReadingsIcon); + break; + case Recent: + case None: + break; + } +} diff --git a/YACReaderLibrary/empty_special_list.h b/YACReaderLibrary/empty_special_list.h index 481bd9e7a..0c926144a 100644 --- a/YACReaderLibrary/empty_special_list.h +++ b/YACReaderLibrary/empty_special_list.h @@ -7,7 +7,25 @@ class EmptySpecialListWidget : public EmptyContainerInfo { public: + enum SpecialListType { + None, + Favorites, + Reading, + Recent + }; + EmptySpecialListWidget(QWidget *parent = nullptr); + + void showFavorites(); + void showReading(); + void showRecent(); + +protected: + void applyTheme(const Theme &theme) override; + +private: + void updateIcon(); + SpecialListType currentType = None; }; #endif // EMPTY_SPECIAL_LIST_H diff --git a/YACReaderLibrary/export_comics_info_dialog.cpp b/YACReaderLibrary/export_comics_info_dialog.cpp index 1cd9c7fa3..dac2ac808 100644 --- a/YACReaderLibrary/export_comics_info_dialog.cpp +++ b/YACReaderLibrary/export_comics_info_dialog.cpp @@ -23,7 +23,7 @@ ExportComicsInfoDialog::ExportComicsInfoDialog(QWidget *parent) connect(cancel, &QAbstractButton::clicked, this, &ExportComicsInfoDialog::close); connect(cancel, &QAbstractButton::clicked, this, &QDialog::rejected); - find = new QPushButton(QIcon(":/images/find_folder.png"), ""); + find = new QPushButton(""); connect(find, &QAbstractButton::clicked, this, &ExportComicsInfoDialog::findPath); auto libraryLayout = new QHBoxLayout; @@ -45,9 +45,7 @@ ExportComicsInfoDialog::ExportComicsInfoDialog(QWidget *parent) mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/exportComicsInfo.png"); - imgLabel->setPixmap(p); + imgLabel = new QLabel(this); imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); @@ -55,6 +53,14 @@ ExportComicsInfoDialog::ExportComicsInfoDialog(QWidget *parent) setModal(true); setWindowTitle(tr("Export comics info")); + + initTheme(this); +} + +void ExportComicsInfoDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.exportComicsInfoIcon); + find->setIcon(theme.dialogIcons.findFolderIcon); } ExportComicsInfoDialog::~ExportComicsInfoDialog() diff --git a/YACReaderLibrary/export_comics_info_dialog.h b/YACReaderLibrary/export_comics_info_dialog.h index f5a8e82fc..fb679c380 100644 --- a/YACReaderLibrary/export_comics_info_dialog.h +++ b/YACReaderLibrary/export_comics_info_dialog.h @@ -1,12 +1,14 @@ #ifndef EXPORT_COMICS_INFO_DIALOG_H #define EXPORT_COMICS_INFO_DIALOG_H +#include "themable.h" + #include #include #include #include -class ExportComicsInfoDialog : public QDialog +class ExportComicsInfoDialog : public QDialog, protected Themable { Q_OBJECT @@ -15,12 +17,16 @@ class ExportComicsInfoDialog : public QDialog ~ExportComicsInfoDialog() override; QString source; +protected: + void applyTheme(const Theme &theme) override; + public slots: void findPath(); void exportComicsInfo(); void close(); private: + QLabel *imgLabel; QLabel *progress; QLabel *textLabel; QLineEdit *path; diff --git a/YACReaderLibrary/export_library_dialog.cpp b/YACReaderLibrary/export_library_dialog.cpp index 971ca9af1..066f7192c 100644 --- a/YACReaderLibrary/export_library_dialog.cpp +++ b/YACReaderLibrary/export_library_dialog.cpp @@ -20,7 +20,7 @@ ExportLibraryDialog::ExportLibraryDialog(QWidget *parent) connect(cancel, &QAbstractButton::clicked, this, &ExportLibraryDialog::close); connect(cancel, &QAbstractButton::clicked, this, &QDialog::rejected); - find = new QPushButton(QIcon(":/images/find_folder.png"), ""); + find = new QPushButton(""); connect(find, &QAbstractButton::clicked, this, &ExportLibraryDialog::findPath); auto libraryLayout = new QHBoxLayout; @@ -48,9 +48,7 @@ ExportLibraryDialog::ExportLibraryDialog(QWidget *parent) mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/exportLibrary.png"); - imgLabel->setPixmap(p); + imgLabel = new QLabel(this); imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); @@ -58,6 +56,14 @@ ExportLibraryDialog::ExportLibraryDialog(QWidget *parent) setModal(true); setWindowTitle(tr("Create covers package")); + + initTheme(this); +} + +void ExportLibraryDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.exportLibraryIcon); + find->setIcon(theme.dialogIcons.findFolderIcon); } void ExportLibraryDialog::exportLibrary() diff --git a/YACReaderLibrary/export_library_dialog.h b/YACReaderLibrary/export_library_dialog.h index 1c3e8025d..5321dcb42 100644 --- a/YACReaderLibrary/export_library_dialog.h +++ b/YACReaderLibrary/export_library_dialog.h @@ -1,6 +1,8 @@ #ifndef EXPORT_LIBRARY_DIALOG_H #define EXPORT_LIBRARY_DIALOG_H +#include "themable.h" + #include #include #include @@ -10,17 +12,22 @@ #include #include -class ExportLibraryDialog : public QDialog +class ExportLibraryDialog : public QDialog, protected Themable { Q_OBJECT public: ExportLibraryDialog(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; + public slots: void exportLibrary(); void findPath(); void close(); private: + QLabel *imgLabel; int progressCount; QProgressBar *progressBar; QLabel *textLabel; diff --git a/YACReaderLibrary/folder_content_view.cpp b/YACReaderLibrary/folder_content_view.cpp index d3cc901d0..79d87fa3c 100644 --- a/YACReaderLibrary/folder_content_view.cpp +++ b/YACReaderLibrary/folder_content_view.cpp @@ -7,6 +7,7 @@ #include "yacreader_tool_bar_stretch.h" #include "comic.h" #include "comic_files_manager.h" +#include "theme_manager.h" #include "QsLog.h" @@ -17,7 +18,7 @@ using namespace YACReader; FolderContentView::FolderContentView(QAction *toogleRecentVisibilityAction, QWidget *parent) - : QWidget { parent }, parent(QModelIndex()), comicModel(new ComicModel()), folderModel(new FolderModel()) + : QWidget { parent }, parent(QModelIndex()), comicModel(new ComicModel()), folderModel(new FolderModel()), smallZoomLabel(nullptr), bigZoomLabel(nullptr) { qmlRegisterType("com.yacreader.FolderModel", 1, 0, "FolderModel"); @@ -41,14 +42,16 @@ FolderContentView::FolderContentView(QAction *toogleRecentVisibilityAction, QWid coverSizeSlider->setOrientation(Qt::Horizontal); coverSizeSlider->setRange(YACREADER_MIN_GRID_ZOOM_WIDTH, YACREADER_MAX_GRID_ZOOM_WIDTH); + const auto &comicsToolbar = theme.comicsViewToolbar; + auto horizontalLayout = new QHBoxLayout(); - QLabel *smallLabel = new QLabel(); - smallLabel->setPixmap(hdpiPixmap(":/images/comics_view_toolbar/small_size_grid_zoom.svg", QSize(18, 18))); - horizontalLayout->addWidget(smallLabel); + smallZoomLabel = new QLabel(); + smallZoomLabel->setPixmap(comicsToolbar.smallGridZoomIcon.pixmap(18, 18)); + horizontalLayout->addWidget(smallZoomLabel); horizontalLayout->addWidget(coverSizeSlider, 0, Qt::AlignVCenter); - QLabel *bigLabel = new QLabel(); - bigLabel->setPixmap(hdpiPixmap(":/images/comics_view_toolbar/big_size_grid_zoom.svg", QSize(18, 18))); - horizontalLayout->addWidget(bigLabel); + bigZoomLabel = new QLabel(); + bigZoomLabel->setPixmap(comicsToolbar.bigGridZoomIcon.pixmap(18, 18)); + horizontalLayout->addWidget(bigZoomLabel); horizontalLayout->addSpacing(10); horizontalLayout->setContentsMargins(0, 0, 0, 0); @@ -57,10 +60,6 @@ FolderContentView::FolderContentView(QAction *toogleRecentVisibilityAction, QWid connect(coverSizeSlider, &QAbstractSlider::valueChanged, this, &FolderContentView::setCoversSize); toolbar = new QToolBar(); - toolbar->setStyleSheet(R"( - QToolBar { border: none; } - QToolButton:checked { background-color: #cccccc; } - )"); toolbar->setIconSize(QSize(18, 18)); toolbar->addWidget(new YACReaderToolBarStretch); toolbar->addAction(toogleRecentVisibilityAction); @@ -77,84 +76,16 @@ FolderContentView::FolderContentView(QAction *toogleRecentVisibilityAction, QWid QQmlContext *ctxt = view->rootContext(); - LibraryUITheme theme; -#ifdef Y_MAC_UI - theme = Light; -#else - theme = Dark; -#endif - - if (theme == Light) { - ctxt->setContextProperty("continueReadingBackgroundColor", "#E8E8E8"); - ctxt->setContextProperty("continueReadingColor", "#000000"); - - ctxt->setContextProperty("backgroundColor", "#F6F6F6"); - ctxt->setContextProperty("cellColor", "#FFFFFF"); - ctxt->setContextProperty("selectedColor", "#FFFFFF"); - ctxt->setContextProperty("selectedBorderColor", "#007AFF"); - ctxt->setContextProperty("borderColor", "#DBDBDB"); - ctxt->setContextProperty("titleColor", "#121212"); - ctxt->setContextProperty("textColor", "#636363"); - // fonts settings - ctxt->setContextProperty("fontSize", 11); - ctxt->setContextProperty("fontFamily", QApplication::font().family()); - ctxt->setContextProperty("fontSpacing", 0.5); - - // info - copy/pasted from info_comics_view TODO create helpers for setting the UI config - ctxt->setContextProperty("infoBackgroundColor", "#FFFFFF"); - ctxt->setContextProperty("topShadow", QUrl()); - ctxt->setContextProperty("infoShadow", "info-shadow-light.png"); - ctxt->setContextProperty("infoIndicator", "info-indicator-light.png"); - - ctxt->setContextProperty("infoTextColor", "#404040"); - ctxt->setContextProperty("infoTitleColor", "#2E2E2E"); - - ctxt->setContextProperty("ratingUnselectedColor", "#DEDEDE"); - ctxt->setContextProperty("ratingSelectedColor", "#2B2B2B"); - - ctxt->setContextProperty("favUncheckedColor", "#DEDEDE"); - ctxt->setContextProperty("favCheckedColor", "#E84852"); - - ctxt->setContextProperty("readTickUncheckedColor", "#DEDEDE"); - ctxt->setContextProperty("readTickCheckedColor", "#E84852"); - } else { - ctxt->setContextProperty("continueReadingBackgroundColor", "#88000000"); - ctxt->setContextProperty("continueReadingColor", "#FFFFFF"); - - ctxt->setContextProperty("backgroundColor", "#2A2A2A"); - ctxt->setContextProperty("cellColor", "#212121"); - ctxt->setContextProperty("selectedColor", "#121212"); - ctxt->setContextProperty("selectedBorderColor", "#121212"); - ctxt->setContextProperty("borderColor", "#121212"); - ctxt->setContextProperty("titleColor", "#FFFFFF"); - ctxt->setContextProperty("textColor", "#A8A8A8"); - ctxt->setContextProperty("dropShadow", QVariant(false)); - // fonts settings - 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); - - // info - copy/pasted from info_comics_view TODO create helpers for setting the UI config - ctxt->setContextProperty("infoBackgroundColor", "#2E2E2E"); - ctxt->setContextProperty("topShadow", "info-top-shadow.png"); - ctxt->setContextProperty("infoShadow", "info-shadow.png"); - ctxt->setContextProperty("infoIndicator", "info-indicator.png"); - - ctxt->setContextProperty("infoTextColor", "#B0B0B0"); - ctxt->setContextProperty("infoTitleColor", "#FFFFFF"); - - ctxt->setContextProperty("ratingUnselectedColor", "#1C1C1C"); - ctxt->setContextProperty("ratingSelectedColor", "#FFFFFF"); - - ctxt->setContextProperty("favUncheckedColor", "#1C1C1C"); - ctxt->setContextProperty("favCheckedColor", "#E84852"); - - ctxt->setContextProperty("readTickUncheckedColor", "#1C1C1C"); - ctxt->setContextProperty("readTickCheckedColor", "#E84852"); - } + // fonts settings (not theme-dependent) + 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); + + // Apply theme colors + initTheme(this); updateCoversSizeInContext(YACREADER_MIN_COVER_WIDTH, ctxt); @@ -328,3 +259,49 @@ void FolderContentView::droppedFiles(const QList &urls, Qt::DropAction act emit copyComicsToCurrentFolder(droppedFiles); } } + +void FolderContentView::applyTheme(const Theme &theme) +{ + QQmlContext *ctxt = view->rootContext(); + const auto &qv = theme.qmlView; + + toolbar->setStyleSheet(theme.comicsViewToolbar.toolbarQSS); + + // Continue reading section colors + ctxt->setContextProperty("continueReadingBackgroundColor", qv.continueReadingBackgroundColor); + ctxt->setContextProperty("continueReadingColor", qv.continueReadingColor); + + // Grid colors + ctxt->setContextProperty("backgroundColor", qv.backgroundColor); + ctxt->setContextProperty("cellColor", qv.cellColor); + ctxt->setContextProperty("selectedColor", qv.selectedColor); + ctxt->setContextProperty("selectedBorderColor", qv.selectedBorderColor); + ctxt->setContextProperty("borderColor", qv.borderColor); + ctxt->setContextProperty("titleColor", qv.titleColor); + ctxt->setContextProperty("textColor", qv.textColor); + ctxt->setContextProperty("dropShadow", QVariant(qv.showDropShadow)); + + // Info panel colors + ctxt->setContextProperty("infoBackgroundColor", qv.infoBackgroundColor); + ctxt->setContextProperty("topShadow", qv.topShadow.isEmpty() ? QUrl() : QUrl(qv.topShadow)); + ctxt->setContextProperty("infoShadow", qv.infoShadow); + ctxt->setContextProperty("infoIndicator", qv.infoIndicator); + ctxt->setContextProperty("infoTextColor", qv.infoTextColor); + ctxt->setContextProperty("infoTitleColor", qv.infoTitleColor); + + // Rating and favorite colors + ctxt->setContextProperty("ratingUnselectedColor", qv.ratingUnselectedColor); + ctxt->setContextProperty("ratingSelectedColor", qv.ratingSelectedColor); + ctxt->setContextProperty("favUncheckedColor", qv.favUncheckedColor); + ctxt->setContextProperty("favCheckedColor", qv.favCheckedColor); + ctxt->setContextProperty("readTickUncheckedColor", qv.readTickUncheckedColor); + ctxt->setContextProperty("readTickCheckedColor", qv.readTickCheckedColor); + + // Update zoom slider icons + if (smallZoomLabel) { + smallZoomLabel->setPixmap(theme.comicsViewToolbar.smallGridZoomIcon.pixmap(18, 18)); + } + if (bigZoomLabel) { + bigZoomLabel->setPixmap(theme.comicsViewToolbar.bigGridZoomIcon.pixmap(18, 18)); + } +} diff --git a/YACReaderLibrary/folder_content_view.h b/YACReaderLibrary/folder_content_view.h index f199491b2..cd0187f72 100644 --- a/YACReaderLibrary/folder_content_view.h +++ b/YACReaderLibrary/folder_content_view.h @@ -4,6 +4,7 @@ #include #include "comic_model.h" +#include "themable.h" #include "folder.h" #include "comic_db.h" @@ -15,7 +16,7 @@ class YACReaderToolBarStretch; class QQuickWidget; class QQmlContext; -class FolderContentView : public QWidget +class FolderContentView : public QWidget, protected Themable { Q_OBJECT public: @@ -28,6 +29,7 @@ class FolderContentView : public QWidget void setRecentRange(int days); FolderModel *currentFolderModel() { return folderModel; } + public slots: void updateSettings(); @@ -62,6 +64,8 @@ protected slots: std::unique_ptr comicModel; FolderModel *folderModel; + void applyTheme(const Theme &theme) override; + private: QSettings *settings; QToolBar *toolbar; @@ -72,6 +76,10 @@ protected slots: QAction *coverSizeSliderAction; QAction *showInfoAction; QAction *showInfoSeparatorAction; + + // Zoom slider labels (for theming) + QLabel *smallZoomLabel; + QLabel *bigZoomLabel; }; #endif // FOLDERCONTENTVIEW_H diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index 485128636..f30e4f906 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -5,6 +5,7 @@ #include #include "comic.h" +#include "theme_manager.h" #include "comic_files_manager.h" #include "QsLog.h" #include "yacreader_global.h" @@ -15,7 +16,7 @@ #include "current_comic_view_helper.h" GridComicsView::GridComicsView(QWidget *parent) - : ComicsView(parent), filterEnabled(false) + : ComicsView(parent), filterEnabled(false), smallZoomLabel(nullptr), bigZoomLabel(nullptr) { settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat, this); settings->beginGroup("libraryConfig"); @@ -29,83 +30,13 @@ GridComicsView::GridComicsView(QWidget *parent) QQmlContext *ctxt = view->rootContext(); - LibraryUITheme theme; -#ifdef Y_MAC_UI - theme = Light; -#else - theme = Dark; -#endif - - if (theme == Light) { - ctxt->setContextProperty("backgroundColor", "#F6F6F6"); - ctxt->setContextProperty("cellColor", "#FFFFFF"); - ctxt->setContextProperty("selectedColor", "#FFFFFF"); - ctxt->setContextProperty("selectedBorderColor", "#007AFF"); - ctxt->setContextProperty("borderColor", "#DBDBDB"); - ctxt->setContextProperty("titleColor", "#121212"); - ctxt->setContextProperty("textColor", "#636363"); - ctxt->setContextProperty("showDropShadow", QVariant(false)); - // fonts settings - ctxt->setContextProperty("fontSize", 11); - ctxt->setContextProperty("fontFamily", QApplication::font().family()); - ctxt->setContextProperty("fontSpacing", 0.5); - - // info - copy/pasted from info_comics_view TODO create helpers for setting the UI config - ctxt->setContextProperty("infoBackgroundColor", "#FFFFFF"); - ctxt->setContextProperty("topShadow", QUrl()); - ctxt->setContextProperty("infoShadow", "info-shadow-light.png"); - ctxt->setContextProperty("infoIndicator", "info-indicator-light.png"); - - ctxt->setContextProperty("infoTextColor", "#404040"); - ctxt->setContextProperty("infoTitleColor", "#2E2E2E"); - - ctxt->setContextProperty("ratingUnselectedColor", "#DEDEDE"); - ctxt->setContextProperty("ratingSelectedColor", "#2B2B2B"); - - ctxt->setContextProperty("favUncheckedColor", "#DEDEDE"); - ctxt->setContextProperty("favCheckedColor", "#E84852"); - - ctxt->setContextProperty("readTickUncheckedColor", "#DEDEDE"); - ctxt->setContextProperty("readTickCheckedColor", "#E84852"); - - ctxt->setContextProperty("currentComicBackgroundColor", "#88FFFFFF"); - } else { - ctxt->setContextProperty("backgroundColor", "#2A2A2A"); - ctxt->setContextProperty("cellColor", "#212121"); - ctxt->setContextProperty("selectedColor", "#121212"); - ctxt->setContextProperty("selectedBorderColor", "#FFCC00"); - ctxt->setContextProperty("borderColor", "#121212"); - ctxt->setContextProperty("titleColor", "#FFFFFF"); - ctxt->setContextProperty("textColor", "#A8A8A8"); - ctxt->setContextProperty("showDropShadow", QVariant(true)); - // fonts settings - 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); - - // info - copy/pasted from info_comics_view TODO create helpers for setting the UI config - ctxt->setContextProperty("infoBackgroundColor", "#2E2E2E"); - ctxt->setContextProperty("topShadow", "info-top-shadow.png"); - ctxt->setContextProperty("infoShadow", "info-shadow.png"); - ctxt->setContextProperty("infoIndicator", "info-indicator.png"); - - ctxt->setContextProperty("infoTextColor", "#B0B0B0"); - ctxt->setContextProperty("infoTitleColor", "#FFFFFF"); - - ctxt->setContextProperty("ratingUnselectedColor", "#1C1C1C"); - ctxt->setContextProperty("ratingSelectedColor", "#FFFFFF"); - - ctxt->setContextProperty("favUncheckedColor", "#1C1C1C"); - ctxt->setContextProperty("favCheckedColor", "#E84852"); - - ctxt->setContextProperty("readTickUncheckedColor", "#1C1C1C"); - ctxt->setContextProperty("readTickCheckedColor", "#E84852"); - - ctxt->setContextProperty("currentComicBackgroundColor", "#88000000"); - } + // fonts settings (not theme-dependent) + 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); ctxt->setContextProperty("backgroundImage", QUrl()); ctxt->setContextProperty("backgroundBlurOpacity", 0.0); @@ -144,11 +75,13 @@ GridComicsView::GridComicsView(QWidget *parent) QQmlProperty(infoContainer, "width").write(settings->value(COMICS_GRID_INFO_WIDTH, 350)); showInfoAction = new QAction(tr("Show info"), this); - showInfoAction->setIcon(QIcon(":/images/comics_view_toolbar/show_comic_info.svg")); showInfoAction->setCheckable(true); showInfoAction->setChecked(showInfo); connect(showInfoAction, &QAction::toggled, this, &GridComicsView::showInfo); + // Apply theme colors (must be after showInfoAction is created) + initTheme(this); + setShowMarks(true); // TODO save this in settings auto l = new QVBoxLayout; @@ -175,14 +108,16 @@ void GridComicsView::createCoverSizeSliderWidget() coverSizeSlider->setOrientation(Qt::Horizontal); coverSizeSlider->setRange(YACREADER_MIN_GRID_ZOOM_WIDTH, YACREADER_MAX_GRID_ZOOM_WIDTH); + const auto &comicsToolbar = theme.comicsViewToolbar; + auto horizontalLayout = new QHBoxLayout(); - QLabel *smallLabel = new QLabel(); - smallLabel->setPixmap(hdpiPixmap(":/images/comics_view_toolbar/small_size_grid_zoom.svg", QSize(18, 18))); - horizontalLayout->addWidget(smallLabel); + smallZoomLabel = new QLabel(); + smallZoomLabel->setPixmap(comicsToolbar.smallGridZoomIcon.pixmap(18, 18)); + horizontalLayout->addWidget(smallZoomLabel); horizontalLayout->addWidget(coverSizeSlider, 0, Qt::AlignVCenter); - QLabel *bigLabel = new QLabel(); - bigLabel->setPixmap(hdpiPixmap(":/images/comics_view_toolbar/big_size_grid_zoom.svg", QSize(18, 18))); - horizontalLayout->addWidget(bigLabel); + bigZoomLabel = new QLabel(); + bigZoomLabel->setPixmap(comicsToolbar.bigGridZoomIcon.pixmap(18, 18)); + horizontalLayout->addWidget(bigZoomLabel); horizontalLayout->addSpacing(10); horizontalLayout->setContentsMargins(0, 0, 0, 0); @@ -283,13 +218,10 @@ void GridComicsView::updateBackgroundConfig() ctxt->setContextProperty("backgroundBlurVisible", QVariant(false)); } -#ifdef Y_MAC_UI - ctxt->setContextProperty("cellColor", useBackgroundImage ? "#99FFFFFF" : "#FFFFFF"); - ctxt->setContextProperty("selectedColor", "#FFFFFF"); -#else - ctxt->setContextProperty("cellColor", useBackgroundImage ? "#99212121" : "#212121"); - ctxt->setContextProperty("selectedColor", "#121212"); -#endif + // Use theme colors for cell and selected colors + const auto &qv = theme.qmlView; + ctxt->setContextProperty("cellColor", useBackgroundImage ? qv.cellColorWithBackground : qv.cellColor); + ctxt->setContextProperty("selectedColor", qv.selectedColor); } void GridComicsView::showInfo() @@ -552,6 +484,55 @@ void GridComicsView::selectedItem(int index) emit selected(index); } +void GridComicsView::applyTheme(const Theme &theme) +{ + QQmlContext *ctxt = view->rootContext(); + const auto &qv = theme.qmlView; + + // Grid colors + ctxt->setContextProperty("backgroundColor", qv.backgroundColor); + ctxt->setContextProperty("cellColor", qv.cellColor); + ctxt->setContextProperty("selectedColor", qv.selectedColor); + ctxt->setContextProperty("selectedBorderColor", qv.selectedBorderColor); + ctxt->setContextProperty("borderColor", qv.borderColor); + ctxt->setContextProperty("titleColor", qv.titleColor); + ctxt->setContextProperty("textColor", qv.textColor); + ctxt->setContextProperty("showDropShadow", QVariant(qv.showDropShadow)); + + // Info panel colors + ctxt->setContextProperty("infoBackgroundColor", qv.infoBackgroundColor); + ctxt->setContextProperty("topShadow", qv.topShadow.isEmpty() ? QUrl() : QUrl(qv.topShadow)); + ctxt->setContextProperty("infoShadow", qv.infoShadow); + ctxt->setContextProperty("infoIndicator", qv.infoIndicator); + ctxt->setContextProperty("infoTextColor", qv.infoTextColor); + ctxt->setContextProperty("infoTitleColor", qv.infoTitleColor); + + // Rating and favorite colors + ctxt->setContextProperty("ratingUnselectedColor", qv.ratingUnselectedColor); + ctxt->setContextProperty("ratingSelectedColor", qv.ratingSelectedColor); + ctxt->setContextProperty("favUncheckedColor", qv.favUncheckedColor); + ctxt->setContextProperty("favCheckedColor", qv.favCheckedColor); + ctxt->setContextProperty("readTickUncheckedColor", qv.readTickUncheckedColor); + ctxt->setContextProperty("readTickCheckedColor", qv.readTickCheckedColor); + + // Current comic banner + ctxt->setContextProperty("currentComicBackgroundColor", qv.currentComicBackgroundColor); + + // Update background config to apply theme cell colors + updateBackgroundConfig(); + + // Update show info action icon + showInfoAction->setIcon(theme.comicsViewToolbar.showComicInfoIcon); + + // Update zoom slider icons (if they exist - created in setToolBar) + if (smallZoomLabel) { + smallZoomLabel->setPixmap(theme.comicsViewToolbar.smallGridZoomIcon.pixmap(18, 18)); + } + if (bigZoomLabel) { + bigZoomLabel->setPixmap(theme.comicsViewToolbar.bigGridZoomIcon.pixmap(18, 18)); + } +} + void GridComicsView::setShowMarks(bool show) { QQmlContext *ctxt = view->rootContext(); diff --git a/YACReaderLibrary/grid_comics_view.h b/YACReaderLibrary/grid_comics_view.h index 50d3c03c5..6ba587fdd 100644 --- a/YACReaderLibrary/grid_comics_view.h +++ b/YACReaderLibrary/grid_comics_view.h @@ -2,6 +2,7 @@ #define GRID_COMICS_VIEW_H #include "comics_view.h" +#include "themable.h" #include @@ -32,11 +33,14 @@ const unsigned int YACREADER_MIN_COVER_WIDTH = YACREADER_MIN_GRID_ZOOM_WIDTH; const unsigned int YACREADER_MIN_ITEM_HEIGHT = YACREADER_MAX_COVER_HEIGHT + 51; // 51 is the height of the bottom rectangle used for title and other info const unsigned int YACREADER_MIN_ITEM_WIDTH = YACREADER_MIN_COVER_WIDTH; -class GridComicsView : public ComicsView +class GridComicsView : public ComicsView, protected Themable { Q_OBJECT public: explicit GridComicsView(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; ~GridComicsView() override; void setToolBar(QToolBar *toolBar) override; void setModel(ComicModel *model) override; @@ -114,6 +118,10 @@ protected slots: bool dummy; void closeEvent(QCloseEvent *event) override; void createCoverSizeSliderWidget(); + + // Zoom slider labels (for theming) + QLabel *smallZoomLabel; + QLabel *bigZoomLabel; }; #endif // GRID_COMICS_VIEW_H diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index 175162087..d0749b7f5 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -1,7 +1,7 @@ - ../images/accept_shortcut.svg - ../images/clear_shortcut.svg + ../images/shortcuts/accept_shortcut.svg + ../images/shortcuts/clear_shortcut.svg ../images/comic_vine/downArrow.svg ../images/comic_vine/nextPage.svg ../images/comic_vine/previousPage.svg @@ -28,30 +28,41 @@ ../images/comics_view_toolbar/setNormal.svg ../images/comics_view_toolbar/showRecentIndicator.svg ../images/defaultCover.png - ../images/edit.png - ../images/empty_current_readings.png - ../images/empty_favorites.png - ../images/empty_label.png - ../images/exportComicsInfo.png - ../images/exportLibrary.png + ../images/library_dialogs/edit.svg + ../images/empty_container/empty_current_readings.svg + ../images/empty_container/empty_favorites.svg + ../images/empty_container/empty_folder.svg + ../images/empty_container/empty_label.svg + ../images/empty_container/empty_reading_list.svg + ../images/library_dialogs/exportComicsInfo.svg + ../images/library_dialogs/exportLibrary.svg ../images/f_overlayed.png ../images/f_overlayed_retina.png - ../images/find_folder.png + ../images/find_folder.svg ../images/flow1.png ../images/flow2.png ../images/flow3.png ../images/flow4.png ../images/flow5.png ../images/glowLine.png - ../images/loadCustomCover.svg - ../images/hiddenCovers.png + ../images/metadata_dialog/loadCustomCover.svg + ../images/import/coversToggle.svg ../images/icon-new.svg ../images/iconLibrary.png - ../images/importBottomCoversDecoration.png - ../images/importComicsInfo.png - ../images/importingIcon.png - ../images/importLibrary.png - ../images/importTopCoversDecoration.png + ../images/import/importBottomCoversDecoration.svg + ../images/library_dialogs/importComicsInfo.svg + ../images/import/importingIcon.svg + ../images/library_dialogs/importLibrary.svg + ../images/import/importTopCoversDecoration.svg + ../images/main_toolbar/back.svg + ../images/main_toolbar/forward.svg + ../images/main_toolbar/settings.svg + ../images/main_toolbar/server.svg + ../images/main_toolbar/help.svg + ../images/main_toolbar/fullscreen.svg + ../images/main_toolbar/flow.svg + ../images/main_toolbar/grid.svg + ../images/main_toolbar/info.svg ../images/main_toolbar/divider.svg ../images/menus_icons/editIcon.svg ../images/menus_icons/exportComicsInfoIcon.svg @@ -62,18 +73,18 @@ ../images/menus_icons/updateLibraryIcon.svg ../images/menus_icons/open_containing_folder.svg ../images/menus_icons/update_current_folder.svg - ../images/new.png - ../images/nextCoverPage.png - ../images/noLibrariesIcon.png + ../images/library_dialogs/new.svg + ../images/metadata_dialog/nextCoverPage.svg + ../images/noLibrariesIcon.svg ../images/noLibrariesLine.png ../images/notCover.png - ../images/openLibrary.png - ../images/previousCoverPage.png + ../images/library_dialogs/openLibrary.svg + ../images/metadata_dialog/previousCoverPage.svg ../images/readingRibbon.png ../images/readRibbon.png - ../images/resetCover.svg - ../images/searching_icon.png - ../images/serverConfigBackground.png + ../images/metadata_dialog/resetCover.svg + ../images/search_result.svg + ../images/serverConfigBackground.svg ../images/shortcuts/shortcuts_group_comics.svg ../images/shortcuts/shortcuts_group_folders.svg ../images/shortcuts/shortcuts_group_general.svg @@ -82,7 +93,16 @@ ../images/shortcuts/shortcuts_group_page.svg ../images/shortcuts/shortcuts_group_reading.svg ../images/shortcuts/shortcuts_group_visualization.svg - ../images/shownCovers.png + ../images/sidebar/libraryIcon.svg + ../images/sidebar/setRoot.svg + ../images/sidebar/expand.svg + ../images/sidebar/colapse.svg + ../images/sidebar/newLibraryIcon.svg + ../images/sidebar/openLibraryIcon.svg + ../images/sidebar/addNew_sidebar.svg + ../images/sidebar/delete_sidebar.svg + ../images/sidebar/addLabelIcon.svg + ../images/sidebar/renameListIcon.svg ../images/sidebar/branch-closed.svg ../images/sidebar/branch-open.svg ../images/sidebar/collapsed_branch_osx.png @@ -91,28 +111,20 @@ ../images/sidebar/expanded_branch_selected.png ../images/sidebar/folder.svg ../images/sidebar/folder_finished.svg + ../images/sidebar/folder_read_overlay.svg ../images/sidebar/libraryIconSelected.svg ../images/sidebar/libraryOptions.svg - ../images/updatingIcon.png + ../images/import/updatingIcon.svg ../images/custom_dialog/custom_close_button.svg ../images/whats_new/whatsnew_header.svg ../images/lists/default_0.svg ../images/lists/default_1.svg ../images/lists/default_2.svg - - ../images/lists/label_blue.svg - ../images/lists/label_cyan.svg - ../images/lists/label_dark.svg - ../images/lists/label_green.svg - ../images/lists/label_light.svg - ../images/lists/label_orange.svg - ../images/lists/label_pink.svg - ../images/lists/label_purple.svg - ../images/lists/label_red.svg - ../images/lists/label_violet.svg - ../images/lists/label_white.svg - ../images/lists/label_yellow.svg + ../images/lists/label_template.svg ../images/lists/list.svg + + ../images/clearSearchNew.svg + ../images/iconSearchNew.svg diff --git a/YACReaderLibrary/images_osx.qrc b/YACReaderLibrary/images_osx.qrc index 15a289e59..a26df5b0f 100644 --- a/YACReaderLibrary/images_osx.qrc +++ b/YACReaderLibrary/images_osx.qrc @@ -1,30 +1,5 @@ - ../images/folder_finished_macosx.png - ../images/empty_folder_osx.png - ../images/empty_search_osx.png - ../images/empty_reading_list_osx.png - ../images/sidebar/libraryIcon_osx.png - ../images/sidebar/setRoot_osx.png - ../images/sidebar/expand_osx.png - ../images/sidebar/colapse_osx.png - ../images/sidebar/newLibraryIcon_osx.png - ../images/sidebar/openLibraryIcon_osx.png - ../images/sidebar/addNew_sidebar_osx.png - ../images/sidebar/delete_sidebar_osx.png - ../images/sidebar/addLabelIcon_osx.png - ../images/sidebar/renameListIcon_osx.png - ../images/sidebar/setRoot_osx@2x.png - ../images/sidebar/expand_osx@2x.png - ../images/sidebar/colapse_osx@2x.png - ../images/sidebar/newLibraryIcon_osx@2x.png - ../images/sidebar/openLibraryIcon_osx@2x.png - ../images/sidebar/addNew_sidebar_osx@2x.png - ../images/sidebar/delete_sidebar_osx@2x.png - ../images/sidebar/addLabelIcon_osx@2x.png - ../images/sidebar/renameListIcon_osx@2x.png - ../images/viewer_toolbar/close_osx.png - ../images/viewer_toolbar/close_osx@2x.png macostrayicon.svg diff --git a/YACReaderLibrary/images_win.qrc b/YACReaderLibrary/images_win.qrc index 3fa00b2fe..9eb496efc 100644 --- a/YACReaderLibrary/images_win.qrc +++ b/YACReaderLibrary/images_win.qrc @@ -1,31 +1,5 @@ - ../images/main_toolbar/back.svg - ../images/main_toolbar/back_disabled.png - ../images/main_toolbar/forward.svg - ../images/main_toolbar/forward_disabled.png - ../images/main_toolbar/settings.svg - ../images/main_toolbar/server.svg - ../images/main_toolbar/help.svg - ../images/main_toolbar/fullscreen.svg - ../images/main_toolbar/flow.svg - ../images/main_toolbar/grid.svg - ../images/main_toolbar/info.svg - ../images/sidebar/libraryIcon.svg - ../images/sidebar/setRoot.svg - ../images/sidebar/expand.svg - ../images/sidebar/colapse.svg - ../images/sidebar/newLibraryIcon.svg - ../images/sidebar/openLibraryIcon.svg - ../images/sidebar/addNew_sidebar.svg - ../images/sidebar/delete_sidebar.svg - ../images/sidebar/addLabelIcon.svg - ../images/sidebar/renameListIcon.svg - ../images/empty_folder.png - ../images/empty_search.png - ../images/iconSearchNew.svg - ../images/clearSearchNew.svg - ../images/empty_reading_list.png ../images/viewer_toolbar/close.svg icon.ico diff --git a/YACReaderLibrary/import_comics_info_dialog.cpp b/YACReaderLibrary/import_comics_info_dialog.cpp index 2ed5fd569..3018c5721 100644 --- a/YACReaderLibrary/import_comics_info_dialog.cpp +++ b/YACReaderLibrary/import_comics_info_dialog.cpp @@ -25,7 +25,7 @@ ImportComicsInfoDialog::ImportComicsInfoDialog(QWidget *parent) connect(cancel, &QAbstractButton::clicked, this, &ImportComicsInfoDialog::close); // connect(cancel,SIGNAL(clicked()),this,SIGNAL(rejected())); - find = new QPushButton(QIcon(":/images/find_folder.png"), ""); + find = new QPushButton(""); connect(find, &QAbstractButton::clicked, this, &ImportComicsInfoDialog::findPath); auto libraryLayout = new QHBoxLayout; @@ -54,15 +54,21 @@ ImportComicsInfoDialog::ImportComicsInfoDialog(QWidget *parent) mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/importComicsInfo.png"); - imgLabel->setPixmap(p); + imgLabel = new QLabel(this); imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); setLayout(imgMainLayout); setModal(true); + + initTheme(this); +} + +void ImportComicsInfoDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.importComicsInfoIcon); + find->setIcon(theme.dialogIcons.findFolderIcon); } ImportComicsInfoDialog::~ImportComicsInfoDialog() diff --git a/YACReaderLibrary/import_comics_info_dialog.h b/YACReaderLibrary/import_comics_info_dialog.h index 01ea022f1..37d7d8e91 100644 --- a/YACReaderLibrary/import_comics_info_dialog.h +++ b/YACReaderLibrary/import_comics_info_dialog.h @@ -1,6 +1,8 @@ #ifndef IMPORT_COMICS_INFO_DIALOG_H #define IMPORT_COMICS_INFO_DIALOG_H +#include "themable.h" + #include #include #include @@ -19,7 +21,7 @@ class Importer : public QThread void run() override; }; -class ImportComicsInfoDialog : public QDialog +class ImportComicsInfoDialog : public QDialog, protected Themable { Q_OBJECT @@ -28,7 +30,11 @@ class ImportComicsInfoDialog : public QDialog ~ImportComicsInfoDialog(); QString dest; +protected: + void applyTheme(const Theme &theme) override; + private: + QLabel *imgLabel; QLabel *nameLabel; QLabel *textLabel; QLabel *destLabel; diff --git a/YACReaderLibrary/import_library_dialog.cpp b/YACReaderLibrary/import_library_dialog.cpp index 2a065bd61..aad7b8231 100644 --- a/YACReaderLibrary/import_library_dialog.cpp +++ b/YACReaderLibrary/import_library_dialog.cpp @@ -35,10 +35,10 @@ void ImportLibraryDialog::setupUI() connect(cancel, &QAbstractButton::clicked, this, &ImportLibraryDialog::close); // connect(cancel,SIGNAL(clicked()),this,SIGNAL(rejected())); - find = new QPushButton(QIcon(":/images/find_folder.png"), ""); + find = new QPushButton(""); connect(find, &QAbstractButton::clicked, this, &ImportLibraryDialog::findPath); - findDest = new QPushButton(QIcon(":/images/find_folder.png"), ""); + findDest = new QPushButton(""); connect(findDest, &QAbstractButton::clicked, this, &ImportLibraryDialog::findDestination); auto content = new QGridLayout; @@ -75,9 +75,7 @@ void ImportLibraryDialog::setupUI() mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/importLibrary.png"); - imgLabel->setPixmap(p); + imgLabel = new QLabel(this); imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); @@ -85,6 +83,15 @@ void ImportLibraryDialog::setupUI() setModal(true); setWindowTitle(tr("Extract a catalog")); + + initTheme(this); +} + +void ImportLibraryDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.importLibraryIcon); + find->setIcon(theme.dialogIcons.findFolderIcon); + findDest->setIcon(theme.dialogIcons.findFolderIcon); } void ImportLibraryDialog::open(const YACReaderLibraries &libs) { diff --git a/YACReaderLibrary/import_library_dialog.h b/YACReaderLibrary/import_library_dialog.h index 632ea5474..de1cceed4 100644 --- a/YACReaderLibrary/import_library_dialog.h +++ b/YACReaderLibrary/import_library_dialog.h @@ -1,6 +1,7 @@ #ifndef IMPORT_LIBRARY_DIALOG_H #define IMPORT_LIBRARY_DIALOG_H #include "yacreader_libraries.h" +#include "themable.h" #include #include @@ -9,13 +10,17 @@ #include #include -class ImportLibraryDialog : public QDialog +class ImportLibraryDialog : public QDialog, protected Themable { Q_OBJECT public: ImportLibraryDialog(QWidget *parent = nullptr); +protected: + void applyTheme(const Theme &theme) override; + private: + QLabel *imgLabel; QLabel *nameLabel; QLabel *textLabel; QLabel *destLabel; diff --git a/YACReaderLibrary/import_widget.cpp b/YACReaderLibrary/import_widget.cpp index 7d721b48e..f899353fd 100644 --- a/YACReaderLibrary/import_widget.cpp +++ b/YACReaderLibrary/import_widget.cpp @@ -85,28 +85,17 @@ ImportWidget::ImportWidget(QWidget *parent) : QWidget(parent) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - - QPalette p(palette()); - p.setColor(QPalette::Window, QColor(250, 250, 250)); setAutoFillBackground(true); - setPalette(p); - QPixmap icon(":/images/importingIcon.png"); iconLabel = new QLabel(); - iconLabel->setPixmap(icon); - - /*QPixmap line(":/images/noLibrariesLine.png"); - QLabel * lineLabel = new QLabel(); - lineLabel->setPixmap(line);*/ auto activityIndicator = new YACReaderActivityIndicatorWidget(); - text = new QLabel(); //""+tr("Importing comics")+""); - text->setStyleSheet("QLabel {font-size:25px;font-weight:bold;}"); - textDescription = new QLabel(); //""+tr("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")+""); + text = new QLabel(); + textDescription = new QLabel(); textDescription->setWordWrap(true); textDescription->setMaximumWidth(330); - currentComicLabel = new QLabel("..."); + currentComicLabel = new QLabel("..."); coversViewContainer = new QWidget(this); auto coversViewLayout = new QVBoxLayout; @@ -115,11 +104,9 @@ ImportWidget::ImportWidget(QWidget *parent) coversViewContainer->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Maximum); coversView = new QGraphicsView(); - // coversView->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); coversView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); coversView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); coversView->setMaximumHeight(300); - coversView->setStyleSheet("QGraphicsView {background-color: #E6E6E6;border:none;}"); coversScene = new QGraphicsScene(); coversView->setAlignment(Qt::AlignLeft); @@ -130,16 +117,10 @@ ImportWidget::ImportWidget(QWidget *parent) scrollAnimation = new QPropertyAnimation(coversView->horizontalScrollBar(), "value"); - QLabel *topDecorator = new QLabel(); - QLabel *bottomDecorator = new QLabel(); - QPixmap top(":/images/importTopCoversDecoration.png"); - QPixmap bottom(":/images/importBottomCoversDecoration.png"); - topDecorator->setPixmap(top); - bottomDecorator->setPixmap(bottom); + topDecorator = new QLabel(); + bottomDecorator = new QLabel(); topDecorator->setScaledContents(true); bottomDecorator->setScaledContents(true); - topDecorator->setFixedHeight(top.height()); - bottomDecorator->setFixedHeight(bottom.height()); coversViewLayout->addWidget(topDecorator, 0); coversViewLayout->addWidget(coversView, 1); @@ -187,12 +168,13 @@ ImportWidget::ImportWidget(QWidget *parent) layout->addLayout(buttonLayout, 0); layout->addSpacing(10); layout->addStretch(); - coversLabel = new QLabel("" + tr("Some of the comics being added...") + ""); + coversLabel = new QLabel(tr("Some of the comics being added...")); hideButton = new QToolButton(this); hideButton->setFixedSize(25, 18); - hideButton->setStyleSheet("QToolButton {background: url(\":/images/shownCovers.png\"); border:none;}" - " QToolButton:checked {background:url(\":/images/hiddenCovers.png\"); border:none;}"); + hideButton->setStyleSheet("QToolButton { border: none; padding: 0px; }" + "QToolButton:pressed { border: none; padding: 0px; }" + "QToolButton:checked { border: none; padding: 0px; }"); hideButton->setCheckable(true); connect(hideButton, &QAbstractButton::toggled, this, &ImportWidget::showCovers); @@ -210,6 +192,8 @@ ImportWidget::ImportWidget(QWidget *parent) updatingCovers = false; elapsedTimer = new QElapsedTimer(); elapsedTimer->start(); + + initTheme(this); } void ImportWidget::newComic(const QString &path, const QString &coverPath) @@ -217,7 +201,7 @@ void ImportWidget::newComic(const QString &path, const QString &coverPath) if (!this->isVisible()) return; - currentComicLabel->setText("" + path + ""); + currentComicLabel->setText(path); if (((elapsedTimer->elapsed() >= 1100) || ((previousWidth < coversView->width()) && (elapsedTimer->elapsed() >= 500))) && scrollAnimation->state() != QAbstractAnimation::Running) // todo elapsed time { @@ -323,16 +307,16 @@ void ImportWidget::clear() updatingCovers = false; - currentComicLabel->setText("..."); + currentComicLabel->setText("..."); this->i = 0; } void ImportWidget::setImportLook() { - iconLabel->setPixmap(QPixmap(":/images/importingIcon.png")); - text->setText("" + tr("Importing comics") + ""); - textDescription->setText("" + tr("

YACReaderLibrary is now creating a new library.

Create a library could take several minutes. You can stop the process and update the library later for completing the task.

") + "
"); + iconLabel->setPixmap(theme.importWidget.importingIcon); + text->setText(tr("Importing comics")); + textDescription->setText(tr("

YACReaderLibrary is now creating a new library.

Create a library could take several minutes. You can stop the process and update the library later for completing the task.

")); stopButton->setVisible(true); coversLabel->setVisible(true); @@ -342,9 +326,9 @@ void ImportWidget::setImportLook() void ImportWidget::setUpdateLook() { - iconLabel->setPixmap(QPixmap(":/images/updatingIcon.png")); - text->setText("" + tr("Updating the library") + ""); - textDescription->setText("" + tr("

The current library is being updated. For faster updates, please, update your libraries frequently.

You can stop the process and continue updating this library later.

") + "
"); + iconLabel->setPixmap(theme.importWidget.updatingIcon); + text->setText(tr("Updating the library")); + textDescription->setText(tr("

The current library is being updated. For faster updates, please, update your libraries frequently.

You can stop the process and continue updating this library later.

")); stopButton->setVisible(true); coversLabel->setVisible(true); @@ -354,9 +338,9 @@ void ImportWidget::setUpdateLook() void ImportWidget::setUpgradeLook() { - iconLabel->setPixmap(QPixmap(":/images/updatingIcon.png")); - text->setText("" + tr("Upgrading the library") + ""); - textDescription->setText("" + tr("

The current library is being upgraded, please wait.

") + "
"); + iconLabel->setPixmap(theme.importWidget.updatingIcon); + text->setText(tr("Upgrading the library")); + textDescription->setText(tr("

The current library is being upgraded, please wait.

")); stopButton->setVisible(false); coversLabel->setVisible(false); @@ -366,9 +350,9 @@ void ImportWidget::setUpgradeLook() void ImportWidget::setXMLScanLook() { - iconLabel->setPixmap(QPixmap(":/images/updatingIcon.png")); - text->setText("" + tr("Scanning the library") + ""); - textDescription->setText("" + tr("

Current library is being scanned for legacy XML metadata information.

This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.

") + "
"); + iconLabel->setPixmap(theme.importWidget.updatingIcon); + text->setText(tr("Scanning the library")); + textDescription->setText(tr("

Current library is being scanned for legacy XML metadata information.

This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.

")); stopButton->setVisible(true); coversLabel->setVisible(false); @@ -392,3 +376,53 @@ void ImportWidget::resizeEvent(QResizeEvent *event) QWidget::resizeEvent(event); } + +void ImportWidget::applyTheme(const Theme &theme) +{ + const auto &importTheme = theme.importWidget; + + // Covers toggle button + hideButton->setIcon(importTheme.coversToggleIcon); + hideButton->setIconSize(hideButton->size()); + + // Background + QPalette p(palette()); + p.setColor(QPalette::Window, importTheme.backgroundColor); + setPalette(p); + + // Covers view background + coversView->setStyleSheet(QString("QGraphicsView {background-color: %1; border:none;}") + .arg(importTheme.coversViewBackgroundColor.name())); + + // Covers decorations + topDecorator->setPixmap(importTheme.topCoversDecoration); + topDecorator->setFixedHeight(importTheme.topCoversDecoration.height()); + bottomDecorator->setPixmap(importTheme.bottomCoversDecoration); + bottomDecorator->setFixedHeight(importTheme.bottomCoversDecoration.height()); + + // Apply text colors + updateTextColors(); +} + +void ImportWidget::updateTextColors() +{ + const auto &importTheme = theme.importWidget; + + // Title text + text->setStyleSheet(importTheme.titleLabelQSS); + + // Description text + QPalette descPalette = textDescription->palette(); + descPalette.setColor(QPalette::WindowText, importTheme.descriptionTextColor); + textDescription->setPalette(descPalette); + + // Current comic label + QPalette comicPalette = currentComicLabel->palette(); + comicPalette.setColor(QPalette::WindowText, importTheme.currentComicTextColor); + currentComicLabel->setPalette(comicPalette); + + // Covers label + QPalette coversLabelPalette = coversLabel->palette(); + coversLabelPalette.setColor(QPalette::WindowText, importTheme.coversLabelColor); + coversLabel->setPalette(coversLabelPalette); +} diff --git a/YACReaderLibrary/import_widget.h b/YACReaderLibrary/import_widget.h index 21d4c7555..833660629 100644 --- a/YACReaderLibrary/import_widget.h +++ b/YACReaderLibrary/import_widget.h @@ -3,12 +3,17 @@ #include -class ImportWidget : public QWidget +#include "themable.h" + +class ImportWidget : public QWidget, protected Themable { Q_OBJECT public: explicit ImportWidget(QWidget *parent = 0); +protected: + void applyTheme(const Theme &theme) override; + signals: void stop(); public slots: @@ -41,8 +46,11 @@ public slots: quint64 i; QToolButton *hideButton; + QLabel *topDecorator; + QLabel *bottomDecorator; void resizeEvent(QResizeEvent *event) override; + void updateTextColors(); }; #endif // IMPORT_WIDGET_H diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp index 0bd687641..e81ec1400 100644 --- a/YACReaderLibrary/info_comics_view.cpp +++ b/YACReaderLibrary/info_comics_view.cpp @@ -1,6 +1,7 @@ #include "info_comics_view.h" #include "yacreader_global.h" +#include "theme_manager.h" #include #include @@ -22,52 +23,8 @@ InfoComicsView::InfoComicsView(QWidget *parent) QQmlContext *ctxt = view->rootContext(); - LibraryUITheme theme; -#ifdef Y_MAC_UI - theme = Light; -#else - theme = Dark; -#endif - - if (theme == Light) { - ctxt->setContextProperty("infoBackgroundColor", "#FFFFFF"); - ctxt->setContextProperty("topShadow", QUrl()); - ctxt->setContextProperty("infoShadow", "info-shadow-light.png"); - ctxt->setContextProperty("infoIndicator", "info-indicator-light.png"); - - ctxt->setContextProperty("infoTextColor", "#404040"); - ctxt->setContextProperty("infoTitleColor", "#2E2E2E"); - - ctxt->setContextProperty("ratingUnselectedColor", "#DEDEDE"); - ctxt->setContextProperty("ratingSelectedColor", "#2B2B2B"); - - ctxt->setContextProperty("favUncheckedColor", "#DEDEDE"); - ctxt->setContextProperty("favCheckedColor", "#E84852"); - - ctxt->setContextProperty("readTickUncheckedColor", "#DEDEDE"); - ctxt->setContextProperty("readTickCheckedColor", "#E84852"); - - ctxt->setContextProperty("showDropShadow", QVariant(false)); - } else { - ctxt->setContextProperty("infoBackgroundColor", "#2E2E2E"); - ctxt->setContextProperty("topShadow", "info-top-shadow.png"); - ctxt->setContextProperty("infoShadow", "info-shadow.png"); - ctxt->setContextProperty("infoIndicator", "info-indicator.png"); - - ctxt->setContextProperty("infoTextColor", "#B0B0B0"); - ctxt->setContextProperty("infoTitleColor", "#FFFFFF"); - - ctxt->setContextProperty("ratingUnselectedColor", "#1C1C1C"); - ctxt->setContextProperty("ratingSelectedColor", "#FFFFFF"); - - ctxt->setContextProperty("favUncheckedColor", "#1C1C1C"); - ctxt->setContextProperty("favCheckedColor", "#E84852"); - - ctxt->setContextProperty("readTickUncheckedColor", "#1C1C1C"); - ctxt->setContextProperty("readTickCheckedColor", "#E84852"); - - ctxt->setContextProperty("showDropShadow", QVariant(true)); - } + // Apply theme colors + initTheme(this); ctxt->setContextProperty("backgroundImage", QUrl()); ctxt->setContextProperty("comicsList", new ComicModel()); @@ -263,3 +220,28 @@ void InfoComicsView::selectedItem(int index) { emit selected(index); } + +void InfoComicsView::applyTheme(const Theme &theme) +{ + QQmlContext *ctxt = view->rootContext(); + const auto &qv = theme.qmlView; + + // Info panel colors + ctxt->setContextProperty("infoBackgroundColor", qv.infoBackgroundColor); + ctxt->setContextProperty("topShadow", qv.topShadow.isEmpty() ? QUrl() : QUrl(qv.topShadow)); + ctxt->setContextProperty("infoShadow", qv.infoShadow); + ctxt->setContextProperty("infoIndicator", qv.infoIndicator); + ctxt->setContextProperty("infoTextColor", qv.infoTextColor); + ctxt->setContextProperty("infoTitleColor", qv.infoTitleColor); + + // Rating and favorite colors + ctxt->setContextProperty("ratingUnselectedColor", qv.ratingUnselectedColor); + ctxt->setContextProperty("ratingSelectedColor", qv.ratingSelectedColor); + ctxt->setContextProperty("favUncheckedColor", qv.favUncheckedColor); + ctxt->setContextProperty("favCheckedColor", qv.favCheckedColor); + ctxt->setContextProperty("readTickUncheckedColor", qv.readTickUncheckedColor); + ctxt->setContextProperty("readTickCheckedColor", qv.readTickCheckedColor); + + ctxt->setContextProperty("showDropShadow", QVariant(qv.showDropShadow)); +} + diff --git a/YACReaderLibrary/info_comics_view.h b/YACReaderLibrary/info_comics_view.h index 3cc925c86..596b60c43 100644 --- a/YACReaderLibrary/info_comics_view.h +++ b/YACReaderLibrary/info_comics_view.h @@ -2,17 +2,22 @@ #define INFOCOMICSVIEW_H #include "comics_view.h" +#include +#include "themable.h" class QQuickView; class YACReaderComicsSelectionHelper; class YACReaderComicInfoHelper; -class InfoComicsView : public ComicsView +class InfoComicsView : public ComicsView, protected Themable { Q_OBJECT public: explicit InfoComicsView(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; ~InfoComicsView() override; void setToolBar(QToolBar *toolBar) override; void setModel(ComicModel *model) override; diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 2ae2f521c..031eac89a 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -54,7 +54,6 @@ #include "comic_vine_dialog.h" #include "api_key_dialog.h" -// #include "yacreader_social_dialog.h" #include "comics_view.h" @@ -85,6 +84,8 @@ #include "cover_utils.h" +#include "theme_manager.h" + #include "QsLog.h" #include "yacreader_http_server.h" @@ -233,25 +234,28 @@ void LibraryWindow::setupUI() showMaximized(); trayIconController = new TrayIconController(settings, this); + + initTheme(this); +} + +void LibraryWindow::applyTheme(const Theme &theme) +{ + editInfoToolBar->setStyleSheet(theme.comicsViewToolbar.toolbarQSS); + mainSplitter->setStyleSheet(theme.contentSplitter.horizontalSplitterQSS); + + // Update main toolbar and comics view toolbar icons + actions.updateTheme(theme); } void LibraryWindow::doLayout() { // LAYOUT ELEMENTS------------------------------------------------------------ - auto sHorizontal = new QSplitter(Qt::Horizontal); // spliter principal -#ifdef Y_MAC_UI - sHorizontal->setStyleSheet("QSplitter::handle{image:none;background-color:#B8B8B8;} QSplitter::handle:vertical {height:1px;}"); -#else - sHorizontal->setStyleSheet("QSplitter::handle:vertical {height:4px;}"); -#endif + mainSplitter = new QSplitter(Qt::Horizontal); // spliter principal + auto sHorizontal = mainSplitter; // Keep local alias for existing code // TOOLBARS------------------------------------------------------------------- //--------------------------------------------------------------------------- editInfoToolBar = new QToolBar(); - editInfoToolBar->setStyleSheet(R"( - QToolBar { border: none; } - QToolButton:checked { background-color: #cccccc; } - )"); #ifdef Y_MAC_UI libraryToolBar = new YACReaderMacOSXToolbar(this); @@ -1402,12 +1406,14 @@ void LibraryWindow::showGridFoldersContextMenu(QPoint point, Folder folder) { QMenu menu; + const auto &menuIcons = theme.menuIcons; + auto openContainingFolderAction = new QAction(); openContainingFolderAction->setText(tr("Open folder...")); - openContainingFolderAction->setIcon(QIcon(":/images/menus_icons/open_containing_folder.svg")); + openContainingFolderAction->setIcon(menuIcons.openContainingFolderIcon); auto updateFolderAction = new QAction(tr("Update folder"), this); - updateFolderAction->setIcon(QIcon(":/images/menus_icons/update_current_folder.svg")); + updateFolderAction->setIcon(menuIcons.updateCurrentFolderIcon); auto rescanLibraryForXMLInfoAction = new QAction(tr("Rescan library for XML info"), this); @@ -1563,7 +1569,7 @@ void LibraryWindow::showContinueReadingContextMenu(QPoint point, ComicDB comic) auto setAsUnReadAction = new QAction(); setAsUnReadAction->setText(tr("Set as unread")); - setAsUnReadAction->setIcon(QIcon(":/images/comics_view_toolbar/setUnread.svg")); + setAsUnReadAction->setIcon(theme.comicsViewToolbar.setAsUnreadIcon); menu.addAction(setAsUnReadAction); @@ -2642,19 +2648,6 @@ void LibraryWindow::showFoldersContextMenu(const QPoint &point) menu.exec(foldersView->mapToGlobal(point)); } -/* -void LibraryWindow::showSocial() -{ - socialDialog->move(this->mapToGlobal(QPoint(width()-socialDialog->width()-10, centralWidget()->pos().y()+10))); - - QModelIndexList indexList = getSelectedComics(); - - ComicDB comic = dmCV->getComic(indexList.at(0)); - - socialDialog->setComic(comic,currentPath()); - socialDialog->setHidden(false); -}*/ - void LibraryWindow::libraryAlreadyExists(const QString &name) { QMessageBox::information(this, tr("Library name already exists"), tr("There is another library with the name '%1'.").arg(name)); diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index c200a8b85..091ef2757 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -16,6 +16,8 @@ #include "comic_query_result_processor.h" #include "folder_query_result_processor.h" +#include "themable.h" + #include "comic_model.h" #include "comic_db.h" #include "folder.h" @@ -94,13 +96,14 @@ class XMLInfoLibraryScanner; using namespace YACReader; -class LibraryWindow : public QMainWindow +class LibraryWindow : public QMainWindow, protected Themable { friend class YACReaderNavigationController; Q_OBJECT public: YACReaderSideBar *sideBar; + QSplitter *mainSplitter; CreateLibraryDialog *createLibraryDialog; ExportLibraryDialog *exportLibraryDialog; @@ -115,7 +118,6 @@ class LibraryWindow : public QMainWindow PropertiesDialog *propertiesDialog; ComicVineDialog *comicVineDialog; EditShortcutsDialog *editShortcutsDialog; - // YACReaderSocialDialog * socialDialog; bool fullscreen; bool importedCovers; // if true, the library is read only (not updates,open comic or properties) bool fromMaximized; @@ -215,6 +217,7 @@ class LibraryWindow : public QMainWindow protected: virtual void closeEvent(QCloseEvent *event) override; + void applyTheme(const Theme &theme) override; public: LibraryWindow(); @@ -290,7 +293,6 @@ public slots: void deleteComics(); void deleteComicsFromDisk(); void deleteComicsFromList(); - // void showSocial(); void showFoldersContextMenu(const QPoint &point); void showGridFoldersContextMenu(QPoint point, Folder folder); void showContinueReadingContextMenu(QPoint point, ComicDB comic); diff --git a/YACReaderLibrary/library_window_actions.cpp b/YACReaderLibrary/library_window_actions.cpp index 011321e64..cebf7b51f 100644 --- a/YACReaderLibrary/library_window_actions.cpp +++ b/YACReaderLibrary/library_window_actions.cpp @@ -12,6 +12,7 @@ #include "server_config_dialog.h" #include "yacreader_folders_view.h" #include "yacreader_options_dialog.h" +#include "theme_manager.h" #include #include @@ -25,76 +26,59 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti auto tr = [](const char *text) { return QObject::tr(text); }; backAction = new QAction(window); - QIcon icoBackButton; - icoBackButton.addFile(addExtensionToIconPath(":/images/main_toolbar/back"), QSize(), QIcon::Normal); - // icoBackButton.addPixmap(QPixmap(":/images/main_toolbar/back_disabled.png"), QIcon::Disabled); backAction->setData(BACK_ACTION_YL); backAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(BACK_ACTION_YL)); - backAction->setIcon(icoBackButton); backAction->setDisabled(true); forwardAction = new QAction(window); - QIcon icoFordwardButton; - icoFordwardButton.addFile(addExtensionToIconPath(":/images/main_toolbar/forward"), QSize(), QIcon::Normal); - // icoFordwardButton.addPixmap(QPixmap(":/images/main_toolbar/forward_disabled.png"), QIcon::Disabled); forwardAction->setData(FORWARD_ACTION_YL); forwardAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FORWARD_ACTION_YL)); - forwardAction->setIcon(icoFordwardButton); forwardAction->setDisabled(true); createLibraryAction = new QAction(window); createLibraryAction->setToolTip(tr("Create a new library")); createLibraryAction->setData(CREATE_LIBRARY_ACTION_YL); createLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(CREATE_LIBRARY_ACTION_YL)); - createLibraryAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/newLibraryIcon"))); openLibraryAction = new QAction(window); openLibraryAction->setToolTip(tr("Open an existing library")); openLibraryAction->setData(OPEN_LIBRARY_ACTION_YL); openLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_LIBRARY_ACTION_YL)); - openLibraryAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/openLibraryIcon"))); exportComicsInfoAction = new QAction(tr("Export comics info"), window); exportComicsInfoAction->setToolTip(tr("Export comics info")); exportComicsInfoAction->setData(EXPORT_COMICS_INFO_ACTION_YL); exportComicsInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EXPORT_COMICS_INFO_ACTION_YL)); - exportComicsInfoAction->setIcon(QIcon(":/images/menus_icons/exportComicsInfoIcon.svg")); importComicsInfoAction = new QAction(tr("Import comics info"), window); importComicsInfoAction->setToolTip(tr("Import comics info")); importComicsInfoAction->setData(IMPORT_COMICS_INFO_ACTION_YL); importComicsInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(IMPORT_COMICS_INFO_ACTION_YL)); - importComicsInfoAction->setIcon(QIcon(":/images/menus_icons/importComicsInfoIcon.svg")); exportLibraryAction = new QAction(tr("Pack covers"), window); exportLibraryAction->setToolTip(tr("Pack the covers of the selected library")); exportLibraryAction->setData(EXPORT_LIBRARY_ACTION_YL); exportLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EXPORT_LIBRARY_ACTION_YL)); - exportLibraryAction->setIcon(QIcon(":/images/menus_icons/exportLibraryIcon.svg")); importLibraryAction = new QAction(tr("Unpack covers"), window); importLibraryAction->setToolTip(tr("Unpack a catalog")); importLibraryAction->setData(IMPORT_LIBRARY_ACTION_YL); importLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(IMPORT_LIBRARY_ACTION_YL)); - importLibraryAction->setIcon(QIcon(":/images/menus_icons/importLibraryIcon.svg")); updateLibraryAction = new QAction(tr("Update library"), window); updateLibraryAction->setToolTip(tr("Update current library")); updateLibraryAction->setData(UPDATE_LIBRARY_ACTION_YL); updateLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(UPDATE_LIBRARY_ACTION_YL)); - updateLibraryAction->setIcon(QIcon(":/images/menus_icons/updateLibraryIcon.svg")); renameLibraryAction = new QAction(tr("Rename library"), window); renameLibraryAction->setToolTip(tr("Rename current library")); renameLibraryAction->setData(RENAME_LIBRARY_ACTION_YL); renameLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RENAME_LIBRARY_ACTION_YL)); - renameLibraryAction->setIcon(QIcon(":/images/menus_icons/editIcon.svg")); removeLibraryAction = new QAction(tr("Remove library"), window); removeLibraryAction->setToolTip(tr("Remove current library from your collection")); removeLibraryAction->setData(REMOVE_LIBRARY_ACTION_YL); removeLibraryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(REMOVE_LIBRARY_ACTION_YL)); - removeLibraryAction->setIcon(QIcon(":/images/menus_icons/removeLibraryIcon.svg")); rescanLibraryForXMLInfoAction = new QAction(tr("Rescan library for XML info"), window); rescanLibraryForXMLInfoAction->setToolTip(tr("Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files.")); @@ -110,7 +94,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti openComicAction->setToolTip(tr("Open current comic on YACReader")); openComicAction->setData(OPEN_COMIC_ACTION_YL); openComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_COMIC_ACTION_YL)); - openComicAction->setIcon(QIcon(":/images/comics_view_toolbar/openInYACReader.svg")); saveCoversToAction = new QAction(tr("Save selected covers to..."), window); saveCoversToAction->setToolTip(tr("Save covers of the selected comics as JPG files")); @@ -121,25 +104,21 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti setAsReadAction->setToolTip(tr("Set comic as read")); setAsReadAction->setData(SET_AS_READ_ACTION_YL); setAsReadAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_READ_ACTION_YL)); - setAsReadAction->setIcon(QIcon(":/images/comics_view_toolbar/setReadButton.svg")); setAsNonReadAction = new QAction(tr("Set as unread"), window); setAsNonReadAction->setToolTip(tr("Set comic as unread")); setAsNonReadAction->setData(SET_AS_NON_READ_ACTION_YL); setAsNonReadAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_NON_READ_ACTION_YL)); - setAsNonReadAction->setIcon(QIcon(":/images/comics_view_toolbar/setUnread.svg")); setMangaAction = new QAction(tr("manga"), window); setMangaAction->setToolTip(tr("Set issue as manga")); setMangaAction->setData(SET_AS_MANGA_ACTION_YL); setMangaAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_MANGA_ACTION_YL)); - setMangaAction->setIcon(QIcon(":/images/comics_view_toolbar/setManga.svg")); setNormalAction = new QAction(tr("comic"), window); setNormalAction->setToolTip(tr("Set issue as normal")); setNormalAction->setData(SET_AS_NORMAL_ACTION_YL); setNormalAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_AS_NORMAL_ACTION_YL)); - setNormalAction->setIcon(QIcon(":/images/comics_view_toolbar/setNormal.svg")); setWesternMangaAction = new QAction(tr("western manga"), window); setWesternMangaAction->setToolTip(tr("Set issue as western manga")); @@ -163,7 +142,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti showHideMarksAction->setData(SHOW_HIDE_MARKS_ACTION_YL); showHideMarksAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_HIDE_MARKS_ACTION_YL)); showHideMarksAction->setCheckable(true); - showHideMarksAction->setIcon(QIcon(":/images/comics_view_toolbar/showMarks.svg")); showHideMarksAction->setChecked(true); toogleShowRecentIndicatorAction = new QAction(tr("Show/Hide recent indicator"), window); @@ -171,7 +149,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti toogleShowRecentIndicatorAction->setData(SHOW_HIDE_RECENT_INDICATOR_ACTION_YL); toogleShowRecentIndicatorAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_HIDE_RECENT_INDICATOR_ACTION_YL)); toogleShowRecentIndicatorAction->setCheckable(true); - toogleShowRecentIndicatorAction->setIcon(QIcon(":/images/comics_view_toolbar/showRecentIndicator.svg")); toogleShowRecentIndicatorAction->setChecked(settings->value(DISPLAY_RECENTLY_INDICATOR, true).toBool()); #ifndef Q_OS_MACOS @@ -179,79 +156,52 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti toggleFullScreenAction->setToolTip(tr("Fullscreen mode on/off")); toggleFullScreenAction->setData(TOGGLE_FULL_SCREEN_ACTION_YL); toggleFullScreenAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(TOGGLE_FULL_SCREEN_ACTION_YL)); - QIcon icoFullscreenButton; - icoFullscreenButton.addFile(addExtensionToIconPath(":/images/main_toolbar/fullscreen"), QSize(), QIcon::Normal); - toggleFullScreenAction->setIcon(icoFullscreenButton); #endif helpAboutAction = new QAction(window); helpAboutAction->setToolTip(tr("Help, About YACReader")); helpAboutAction->setData(HELP_ABOUT_ACTION_YL); helpAboutAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HELP_ABOUT_ACTION_YL)); - QIcon icoHelpButton; - icoHelpButton.addFile(addExtensionToIconPath(":/images/main_toolbar/help"), QSize(), QIcon::Normal); - helpAboutAction->setIcon(icoHelpButton); addFolderAction = new QAction(tr("Add new folder"), window); addFolderAction->setData(ADD_FOLDER_ACTION_YL); addFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADD_FOLDER_ACTION_YL)); addFolderAction->setToolTip(tr("Add new folder to the current library")); - addFolderAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/addNew_sidebar"))); deleteFolderAction = new QAction(tr("Delete folder"), window); deleteFolderAction->setData(REMOVE_FOLDER_ACTION_YL); deleteFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(REMOVE_FOLDER_ACTION_YL)); deleteFolderAction->setToolTip(tr("Delete current folder from disk")); - deleteFolderAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/delete_sidebar"))); setRootIndexAction = new QAction(window); setRootIndexAction->setData(SET_ROOT_INDEX_ACTION_YL); setRootIndexAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_ROOT_INDEX_ACTION_YL)); setRootIndexAction->setToolTip(tr("Select root node")); - setRootIndexAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/setRoot"))); expandAllNodesAction = new QAction(window); expandAllNodesAction->setToolTip(tr("Expand all nodes")); expandAllNodesAction->setData(EXPAND_ALL_NODES_ACTION_YL); expandAllNodesAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EXPAND_ALL_NODES_ACTION_YL)); - expandAllNodesAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/expand"))); colapseAllNodesAction = new QAction(window); colapseAllNodesAction->setToolTip(tr("Collapse all nodes")); colapseAllNodesAction->setData(COLAPSE_ALL_NODES_ACTION_YL); colapseAllNodesAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(COLAPSE_ALL_NODES_ACTION_YL)); - colapseAllNodesAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/colapse"))); optionsAction = new QAction(window); optionsAction->setToolTip(tr("Show options dialog")); optionsAction->setData(OPTIONS_ACTION_YL); optionsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPTIONS_ACTION_YL)); - QIcon icoSettingsButton; - icoSettingsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/settings"), QSize(), QIcon::Normal); - optionsAction->setIcon(icoSettingsButton); serverConfigAction = new QAction(window); serverConfigAction->setToolTip(tr("Show comics server options dialog")); serverConfigAction->setData(SERVER_CONFIG_ACTION_YL); serverConfigAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SERVER_CONFIG_ACTION_YL)); - QIcon icoServerButton; - icoServerButton.addFile(addExtensionToIconPath(":/images/main_toolbar/server"), QSize(), QIcon::Normal); - serverConfigAction->setIcon(icoServerButton); toggleComicsViewAction = new QAction(tr("Change between comics views"), window); toggleComicsViewAction->setToolTip(tr("Change between comics views")); - QIcon icoViewsButton; - - if (!settings->contains(COMICS_VIEW_STATUS) || settings->value(COMICS_VIEW_STATUS) == Flow) - icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/grid"), QSize(), QIcon::Normal); - else if (settings->value(COMICS_VIEW_STATUS) == Grid) - icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/info"), QSize(), QIcon::Normal); - else - icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/flow"), QSize(), QIcon::Normal); toggleComicsViewAction->setData(TOGGLE_COMICS_VIEW_ACTION_YL); toggleComicsViewAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(TOGGLE_COMICS_VIEW_ACTION_YL)); - toggleComicsViewAction->setIcon(icoViewsButton); - // socialAction = new QAction(this); //---- @@ -259,7 +209,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti openContainingFolderAction->setText(tr("Open folder...")); openContainingFolderAction->setData(OPEN_CONTAINING_FOLDER_ACTION_YL); openContainingFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_CONTAINING_FOLDER_ACTION_YL)); - openContainingFolderAction->setIcon(QIcon(":/images/menus_icons/open_containing_folder.svg")); setFolderAsNotCompletedAction = new QAction(window); setFolderAsNotCompletedAction->setText(tr("Set as uncompleted")); @@ -322,7 +271,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti openContainingFolderComicAction->setText(tr("Open containing folder...")); openContainingFolderComicAction->setData(OPEN_CONTAINING_FOLDER_COMIC_ACTION_YL); openContainingFolderComicAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_CONTAINING_FOLDER_COMIC_ACTION_YL)); - openContainingFolderComicAction->setIcon(QIcon(":/images/menus_icons/open_containing_folder.svg")); resetComicRatingAction = new QAction(window); resetComicRatingAction->setText(tr("Reset comic rating")); @@ -334,19 +282,16 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti selectAllComicsAction->setText(tr("Select all comics")); selectAllComicsAction->setData(SELECT_ALL_COMICS_ACTION_YL); selectAllComicsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SELECT_ALL_COMICS_ACTION_YL)); - selectAllComicsAction->setIcon(QIcon(":/images/comics_view_toolbar/selectAll.svg")); editSelectedComicsAction = new QAction(window); editSelectedComicsAction->setText(tr("Edit")); editSelectedComicsAction->setData(EDIT_SELECTED_COMICS_ACTION_YL); editSelectedComicsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(EDIT_SELECTED_COMICS_ACTION_YL)); - editSelectedComicsAction->setIcon(QIcon(":/images/comics_view_toolbar/editComic.svg")); asignOrderAction = new QAction(window); asignOrderAction->setText(tr("Assign current order to comics")); asignOrderAction->setData(ASIGN_ORDER_ACTION_YL); asignOrderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ASIGN_ORDER_ACTION_YL)); - asignOrderAction->setIcon(QIcon(":/images/comics_view_toolbar/asignNumber.svg")); forceCoverExtractedAction = new QAction(window); forceCoverExtractedAction->setText(tr("Update cover")); @@ -358,7 +303,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti deleteComicsAction->setText(tr("Delete selected comics")); deleteComicsAction->setData(DELETE_COMICS_ACTION_YL); deleteComicsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(DELETE_COMICS_ACTION_YL)); - deleteComicsAction->setIcon(QIcon(":/images/comics_view_toolbar/trash.svg")); deleteMetadataAction = new QAction(window); deleteMetadataAction->setText(tr("Delete metadata from selected comics")); @@ -369,7 +313,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti getInfoAction->setData(GET_INFO_ACTION_YL); getInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(GET_INFO_ACTION_YL)); getInfoAction->setText(tr("Download tags from Comic Vine")); - getInfoAction->setIcon(QIcon(":/images/comics_view_toolbar/getInfo.svg")); //------------------------------------------------------------------------- focusSearchLineAction = new QAction(tr("Focus search line"), window); @@ -390,19 +333,17 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti window->addAction(showEditShortcutsAction); quitAction = new QAction(tr("&Quit"), window); - quitAction->setIcon(QIcon(":/images/viewer_toolbar/close.svg")); + // quitAction->setIcon(QIcon(":/images/viewer_toolbar/close.svg")); quitAction->setData(QUIT_ACTION_YL); quitAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(QUIT_ACTION_YL)); // TODO: is `quitAction->setMenuRole(QAction::QuitRole);` useful on macOS? window->addAction(quitAction); updateFolderAction = new QAction(tr("Update folder"), window); - updateFolderAction->setIcon(QIcon(":/images/menus_icons/update_current_folder.svg")); updateCurrentFolderAction = new QAction(tr("Update current folder"), window); updateCurrentFolderAction->setData(UPDATE_CURRENT_FOLDER_ACTION_YL); updateCurrentFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(UPDATE_CURRENT_FOLDER_ACTION_YL)); - updateCurrentFolderAction->setIcon(QIcon(":/images/menus_icons/update_current_folder.svg")); rescanXMLFromCurrentFolderAction = new QAction(tr("Scan legacy XML metadata"), window); rescanXMLFromCurrentFolderAction->setData(SCAN_XML_FROM_CURRENT_FOLDER_ACTION_YL); @@ -412,25 +353,21 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti addReadingListAction->setData(ADD_READING_LIST_ACTION_YL); addReadingListAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADD_READING_LIST_ACTION_YL)); addReadingListAction->setToolTip(tr("Add a new reading list to the current library")); - addReadingListAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/addNew_sidebar"))); deleteReadingListAction = new QAction(tr("Remove reading list"), window); deleteReadingListAction->setData(REMOVE_READING_LIST_ACTION_YL); deleteReadingListAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(REMOVE_READING_LIST_ACTION_YL)); deleteReadingListAction->setToolTip(tr("Remove current reading list from the library")); - deleteReadingListAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/delete_sidebar"))); addLabelAction = new QAction(tr("Add new label"), window); addLabelAction->setData(ADD_LABEL_ACTION_YL); addLabelAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADD_LABEL_ACTION_YL)); addLabelAction->setToolTip(tr("Add a new label to this library")); - addLabelAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/addLabelIcon"))); renameListAction = new QAction(tr("Rename selected list"), window); renameListAction->setData(RENAME_LIST_ACTION_YL); renameListAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RENAME_LIST_ACTION_YL)); renameListAction->setToolTip(tr("Rename any selected labels or lists")); - renameListAction->setIcon(QIcon(addExtensionToIconPath(":/images/sidebar/renameListIcon"))); //-- addToMenuAction = new QAction(tr("Add to..."), window); @@ -439,7 +376,6 @@ void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *setti addToFavoritesAction->setData(ADD_TO_FAVORITES_ACTION_YL); addToFavoritesAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADD_TO_FAVORITES_ACTION_YL)); addToFavoritesAction->setToolTip(tr("Add selected comics to favorites list")); - addToFavoritesAction->setIcon(QIcon(":/images/lists/default_1.svg")); // global actions window->addAction(openComicAction); // this fixes opening comics in fullscreen mode using the keyboard shortcut @@ -609,11 +545,23 @@ void LibraryWindowActions::createConnections( void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editShortcutsDialog) { + // Set up icon mapping for theme changes + QMap> iconMapping; + iconMapping["Comics"] = [](const Theme &t) { return t.shortcutsIcons.comicsIcon; }; + iconMapping["Folders"] = [](const Theme &t) { return t.shortcutsIcons.foldersIcon; }; + iconMapping["Lists"] = [](const Theme &t) { return t.shortcutsIcons.foldersIcon; }; // TODO change icon + iconMapping["General"] = [](const Theme &t) { return t.shortcutsIcons.generalIcon; }; + iconMapping["Libraries"] = [](const Theme &t) { return t.shortcutsIcons.librariesIcon; }; + iconMapping["Visualization"] = [](const Theme &t) { return t.shortcutsIcons.visualizationIcon; }; + editShortcutsDialog->setGroupIconMapping(iconMapping); QList allActions; QList tmpList; - editShortcutsDialog->addActionsGroup("Comics", QIcon(":/images/shortcuts/shortcuts_group_comics.svg"), + // Get current theme for initial icons + const auto &theme = ThemeManager::instance().getCurrentTheme(); + + editShortcutsDialog->addActionsGroup("Comics", theme.shortcutsIcons.comicsIcon, tmpList = QList() << openComicAction << saveCoversToAction @@ -632,7 +580,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho allActions << tmpList; - editShortcutsDialog->addActionsGroup("Folders", QIcon(":/images/shortcuts/shortcuts_group_folders.svg"), + editShortcutsDialog->addActionsGroup("Folders", theme.shortcutsIcons.foldersIcon, tmpList = QList() << addFolderAction << deleteFolderAction @@ -652,7 +600,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho << deleteCustomFolderCoverAction); allActions << tmpList; - editShortcutsDialog->addActionsGroup("Lists", QIcon(":/images/shortcuts/shortcuts_group_folders.svg"), // TODO change icon + editShortcutsDialog->addActionsGroup("Lists", theme.shortcutsIcons.foldersIcon, // TODO change icon tmpList = QList() << addReadingListAction << deleteReadingListAction @@ -660,7 +608,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho << renameListAction); allActions << tmpList; - editShortcutsDialog->addActionsGroup("General", QIcon(":/images/shortcuts/shortcuts_group_general.svg"), + editShortcutsDialog->addActionsGroup("General", theme.shortcutsIcons.generalIcon, tmpList = QList() << backAction << forwardAction @@ -674,7 +622,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho allActions << tmpList; - editShortcutsDialog->addActionsGroup("Libraries", QIcon(":/images/shortcuts/shortcuts_group_libraries.svg"), + editShortcutsDialog->addActionsGroup("Libraries", theme.shortcutsIcons.librariesIcon, tmpList = QList() << createLibraryAction << openLibraryAction @@ -690,7 +638,7 @@ void LibraryWindowActions::setUpShortcutsManagement(EditShortcutsDialog *editSho allActions << tmpList; - editShortcutsDialog->addActionsGroup("Visualization", QIcon(":/images/shortcuts/shortcuts_group_visualization.svg"), + editShortcutsDialog->addActionsGroup("Visualization", theme.shortcutsIcons.visualizationIcon, tmpList = QList() << showHideMarksAction << toogleShowRecentIndicatorAction @@ -774,3 +722,67 @@ void LibraryWindowActions::disableAllActions() disableLibrariesActions(true); disableFoldersActions(true); } + +void LibraryWindowActions::updateTheme(const Theme &theme) +{ + const auto &mainToolbar = theme.mainToolbar; + const auto &comicsToolbar = theme.comicsViewToolbar; + const auto &readingListIcons = theme.readingListIcons; + const auto &menuIcons = theme.menuIcons; + + // Update sidebar action icons + const auto &sidebarIcons = theme.sidebarIcons; + createLibraryAction->setIcon(sidebarIcons.newLibraryIcon); + openLibraryAction->setIcon(sidebarIcons.openLibraryIcon); + addFolderAction->setIcon(sidebarIcons.addNewIcon); + deleteFolderAction->setIcon(sidebarIcons.deleteIcon); + setRootIndexAction->setIcon(sidebarIcons.setRootIcon); + expandAllNodesAction->setIcon(sidebarIcons.expandIcon); + colapseAllNodesAction->setIcon(sidebarIcons.colapseIcon); + addReadingListAction->setIcon(sidebarIcons.addNewIcon); + deleteReadingListAction->setIcon(sidebarIcons.deleteIcon); + addLabelAction->setIcon(sidebarIcons.addLabelIcon); + renameListAction->setIcon(sidebarIcons.renameListIcon); + + // Main toolbar icons + backAction->setIcon(mainToolbar.backIcon); + forwardAction->setIcon(mainToolbar.forwardIcon); + helpAboutAction->setIcon(mainToolbar.helpIcon); + optionsAction->setIcon(mainToolbar.settingsIcon); + serverConfigAction->setIcon(mainToolbar.serverIcon); +#ifndef Q_OS_MACOS + toggleFullScreenAction->setIcon(mainToolbar.fullscreenIcon); +#endif + + // Comics view toolbar icons + openComicAction->setIcon(comicsToolbar.openInYACReaderIcon); + setAsReadAction->setIcon(comicsToolbar.setAsReadIcon); + setAsNonReadAction->setIcon(comicsToolbar.setAsUnreadIcon); + setMangaAction->setIcon(comicsToolbar.setAsMangaIcon); + setNormalAction->setIcon(comicsToolbar.setAsNormalIcon); + showHideMarksAction->setIcon(comicsToolbar.showMarksIcon); + toogleShowRecentIndicatorAction->setIcon(comicsToolbar.showRecentIndicatorIcon); + selectAllComicsAction->setIcon(comicsToolbar.selectAllIcon); + editSelectedComicsAction->setIcon(comicsToolbar.editComicIcon); + asignOrderAction->setIcon(comicsToolbar.assignNumberIcon); + deleteComicsAction->setIcon(comicsToolbar.deleteIcon); + getInfoAction->setIcon(comicsToolbar.getInfoIcon); + + // Reading list icons + addToFavoritesAction->setIcon(readingListIcons.favoritesIcon); + + // Menu icons (context menus) + exportComicsInfoAction->setIcon(menuIcons.exportComicsInfoIcon); + importComicsInfoAction->setIcon(menuIcons.importComicsInfoIcon); + exportLibraryAction->setIcon(menuIcons.exportLibraryIcon); + importLibraryAction->setIcon(menuIcons.importLibraryIcon); + updateLibraryAction->setIcon(menuIcons.updateLibraryIcon); + renameLibraryAction->setIcon(menuIcons.renameLibraryIcon); + removeLibraryAction->setIcon(menuIcons.removeLibraryIcon); + openContainingFolderAction->setIcon(menuIcons.openContainingFolderIcon); + openContainingFolderComicAction->setIcon(menuIcons.openContainingFolderIcon); + updateFolderAction->setIcon(menuIcons.updateCurrentFolderIcon); + updateCurrentFolderAction->setIcon(menuIcons.updateCurrentFolderIcon); + + quitAction->setIcon(menuIcons.quitIcon); +} diff --git a/YACReaderLibrary/library_window_actions.h b/YACReaderLibrary/library_window_actions.h index 304942363..583595a42 100644 --- a/YACReaderLibrary/library_window_actions.h +++ b/YACReaderLibrary/library_window_actions.h @@ -16,6 +16,7 @@ class YACReaderFoldersView; class YACReaderOptionsDialog; class ServerConfigDialog; class RecentVisibilityCoordinator; +struct Theme; class LibraryWindowActions { @@ -48,7 +49,6 @@ class LibraryWindowActions QAction *optionsAction; QAction *serverConfigAction; QAction *toggleComicsViewAction; - // QAction * socialAction; // tree actions QAction *addFolderAction; @@ -139,6 +139,7 @@ class LibraryWindowActions void disableFoldersActions(bool disabled); void disableAllActions(); void setUpShortcutsManagement(EditShortcutsDialog *editShortcutsDialog); + void updateTheme(const Theme &theme); }; #endif // LIBRARY_WINDOW_ACTIONS_H diff --git a/YACReaderLibrary/no_libraries_widget.cpp b/YACReaderLibrary/no_libraries_widget.cpp index c0e05441c..7603db7fb 100644 --- a/YACReaderLibrary/no_libraries_widget.cpp +++ b/YACReaderLibrary/no_libraries_widget.cpp @@ -9,23 +9,17 @@ NoLibrariesWidget::NoLibrariesWidget(QWidget *parent) : QWidget(parent) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - - QPalette p(palette()); - p.setColor(QPalette::Window, QColor(250, 250, 250)); setAutoFillBackground(true); - setPalette(p); - QPixmap icon(":/images/noLibrariesIcon.png"); - QLabel *iconLabel = new QLabel(); - iconLabel->setPixmap(icon); + iconLabel = new QLabel(); QPixmap line(":/images/noLibrariesLine.png"); QLabel *lineLabel = new QLabel(); lineLabel->setPixmap(line); - QLabel *text = new QLabel("" + tr("You don't have any libraries yet") + ""); + text = new QLabel(tr("You don't have any libraries yet")); text->setStyleSheet("QLabel {font-size:25px;font-weight:bold;}"); - QLabel *textDescription = new QLabel("" + tr("

You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.

Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.

") + "
"); + textDescription = new QLabel(tr("

You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.

Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.

")); textDescription->setWordWrap(true); textDescription->setMaximumWidth(330); @@ -75,4 +69,25 @@ NoLibrariesWidget::NoLibrariesWidget(QWidget *parent) connect(createButton, &QAbstractButton::clicked, this, &NoLibrariesWidget::createNewLibrary); connect(addButton, &QAbstractButton::clicked, this, &NoLibrariesWidget::addExistingLibrary); + + initTheme(this); +} + +void NoLibrariesWidget::applyTheme(const Theme &theme) +{ + auto emptyTheme = theme.emptyContainer; + + QPalette p(palette()); + p.setColor(QPalette::Window, emptyTheme.backgroundColor); + setPalette(p); + + QPalette textPalette = text->palette(); + textPalette.setColor(QPalette::WindowText, emptyTheme.textColor); + text->setPalette(textPalette); + + QPalette descPalette = textDescription->palette(); + descPalette.setColor(QPalette::WindowText, emptyTheme.descriptionTextColor); + textDescription->setPalette(descPalette); + + iconLabel->setPixmap(emptyTheme.noLibrariesIcon); } diff --git a/YACReaderLibrary/no_libraries_widget.h b/YACReaderLibrary/no_libraries_widget.h index ee1a7b82d..9ccfb751b 100644 --- a/YACReaderLibrary/no_libraries_widget.h +++ b/YACReaderLibrary/no_libraries_widget.h @@ -3,7 +3,11 @@ #include -class NoLibrariesWidget : public QWidget +#include "themable.h" + +class QLabel; + +class NoLibrariesWidget : public QWidget, protected Themable { Q_OBJECT public: @@ -13,6 +17,14 @@ class NoLibrariesWidget : public QWidget void createNewLibrary(); void addExistingLibrary(); public slots: + +protected: + void applyTheme(const Theme &theme) override; + +private: + QLabel *iconLabel; + QLabel *text; + QLabel *textDescription; }; #endif // NO_LIBRARIES_WIDGET_H diff --git a/YACReaderLibrary/no_search_results_widget.cpp b/YACReaderLibrary/no_search_results_widget.cpp index bda1096c8..e1238d8ff 100644 --- a/YACReaderLibrary/no_search_results_widget.cpp +++ b/YACReaderLibrary/no_search_results_widget.cpp @@ -1,53 +1,19 @@ #include "no_search_results_widget.h" -#include "yacreader_global.h" - -#include -#include -#include - NoSearchResultsWidget::NoSearchResultsWidget(QWidget *parent) - : QWidget(parent) + : EmptyContainerInfo(parent) { -#ifdef Y_MAC_UI - backgroundColor = "#FFFFFF"; -#else - backgroundColor = "#2A2A2A"; -#endif - - auto layout = new QVBoxLayout; - - iconLabel = new QLabel(); - iconLabel->setPixmap(QPixmap(":/images/empty_search.png")); - iconLabel->setAlignment(Qt::AlignCenter); + setUpDefaultLayout(true); - titleLabel = new QLabel("No results"); - titleLabel->setAlignment(Qt::AlignCenter); - -#ifdef Y_MAC_UI - titleLabel->setStyleSheet("QLabel {color:#888888; font-size:24px;font-family:Arial;font-weight:bold;}"); -#else - titleLabel->setStyleSheet("QLabel {color:#CCCCCC; font-size:24px;font-family:Arial;font-weight:bold;}"); -#endif - - layout->addSpacing(100); - layout->addWidget(iconLabel); - layout->addSpacing(30); - layout->addWidget(titleLabel); - layout->addStretch(); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); + setPixmap(theme.emptyContainer.noSearchResultsIcon); + setText(tr("No results")); setContentsMargins(0, 0, 0, 0); - - setStyleSheet(QString("QWidget {background:%1}").arg(backgroundColor)); - setSizePolicy(QSizePolicy ::Expanding, QSizePolicy ::Expanding); - setLayout(layout); } -void NoSearchResultsWidget::paintEvent(QPaintEvent *) +void NoSearchResultsWidget::applyTheme(const Theme &theme) { - QPainter painter(this); - painter.fillRect(0, 0, width(), height(), QColor(backgroundColor)); + EmptyContainerInfo::applyTheme(theme); + setPixmap(theme.emptyContainer.noSearchResultsIcon); } diff --git a/YACReaderLibrary/no_search_results_widget.h b/YACReaderLibrary/no_search_results_widget.h index 57939af73..48df514ac 100644 --- a/YACReaderLibrary/no_search_results_widget.h +++ b/YACReaderLibrary/no_search_results_widget.h @@ -1,25 +1,16 @@ #ifndef NO_SEARCH_RESULTS_WIDGET_H #define NO_SEARCH_RESULTS_WIDGET_H -#include +#include "empty_container_info.h" -class QLabel; - -class NoSearchResultsWidget : public QWidget +class NoSearchResultsWidget : public EmptyContainerInfo { Q_OBJECT public: explicit NoSearchResultsWidget(QWidget *parent = nullptr); -signals: - -public slots: - protected: - QLabel *iconLabel; - QLabel *titleLabel; - void paintEvent(QPaintEvent *) override; - QString backgroundColor; + void applyTheme(const Theme &theme) override; }; #endif // NO_SEARCH_RESULTS_WIDGET_H diff --git a/YACReaderLibrary/properties_dialog.cpp b/YACReaderLibrary/properties_dialog.cpp index 55b66c9d6..435e0d6dc 100644 --- a/YACReaderLibrary/properties_dialog.cpp +++ b/YACReaderLibrary/properties_dialog.cpp @@ -106,21 +106,21 @@ void PropertiesDialog::createCoverBox() coverPageEdit = new YACReaderFieldEdit(); showPreviousCoverPageButton = new QToolButton(); - showPreviousCoverPageButton->setIcon(QIcon(":/images/previousCoverPage.png")); + showPreviousCoverPageButton->setIcon(QIcon(":/images/metadata_dialog/previousCoverPage.svg")); showPreviousCoverPageButton->setToolTip(tr("Load previous page as cover")); showPreviousCoverPageButton->setStyleSheet("QToolButton {border:none;}"); showNextCoverPageButton = new QToolButton(); - showNextCoverPageButton->setIcon(QIcon(":/images/nextCoverPage.png")); + showNextCoverPageButton->setIcon(QIcon(":/images/metadata_dialog/nextCoverPage.svg")); showNextCoverPageButton->setToolTip(tr("Load next page as cover")); showNextCoverPageButton->setStyleSheet("QToolButton {border:none;}"); resetCoverButton = new QToolButton(); - resetCoverButton->setIcon(QIcon(":/images/resetCover.svg")); + resetCoverButton->setIcon(QIcon(":/images/metadata_dialog/resetCover.svg")); resetCoverButton->setToolTip(tr("Reset cover to the default image")); resetCoverButton->setStyleSheet("QToolButton {border:none;}"); loadCustomCoverImageButton = new QToolButton(); - loadCustomCoverImageButton->setIcon(QIcon(":/images/loadCustomCover.svg")); + loadCustomCoverImageButton->setIcon(QIcon(":/images/metadata_dialog/loadCustomCover.svg")); loadCustomCoverImageButton->setToolTip(tr("Load custom cover image")); loadCustomCoverImageButton->setStyleSheet("QToolButton {border:none;}"); diff --git a/YACReaderLibrary/rename_library_dialog.cpp b/YACReaderLibrary/rename_library_dialog.cpp index b249a22c9..724dfd342 100644 --- a/YACReaderLibrary/rename_library_dialog.cpp +++ b/YACReaderLibrary/rename_library_dialog.cpp @@ -39,9 +39,7 @@ void RenameLibraryDialog::setupUI() mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - QLabel *imgLabel = new QLabel(this); - QPixmap p(":/images/edit.png"); - imgLabel->setPixmap(p); + imgLabel = new QLabel(this); imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); @@ -49,6 +47,13 @@ void RenameLibraryDialog::setupUI() setModal(true); setWindowTitle(tr("Rename current library")); + + initTheme(this); +} + +void RenameLibraryDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.editIcon); } void RenameLibraryDialog::rename() diff --git a/YACReaderLibrary/rename_library_dialog.h b/YACReaderLibrary/rename_library_dialog.h index 385614153..c8145c598 100644 --- a/YACReaderLibrary/rename_library_dialog.h +++ b/YACReaderLibrary/rename_library_dialog.h @@ -1,18 +1,24 @@ #ifndef __RENAME_LIBRARY_DIALOG_H #define __RENAME_LIBRARY_DIALOG_H +#include "themable.h" + #include #include #include #include -class RenameLibraryDialog : public QDialog +class RenameLibraryDialog : public QDialog, protected Themable { Q_OBJECT public: RenameLibraryDialog(QWidget *parent = nullptr); +protected: + void applyTheme(const Theme &theme) override; + private: + QLabel *imgLabel; QLabel *newNameLabel; QLineEdit *newNameEdit; QPushButton *accept; diff --git a/YACReaderLibrary/server_config_dialog.cpp b/YACReaderLibrary/server_config_dialog.cpp index eacd28c1a..9352db740 100644 --- a/YACReaderLibrary/server_config_dialog.cpp +++ b/YACReaderLibrary/server_config_dialog.cpp @@ -11,42 +11,45 @@ #include "ip_config_helper.h" #include "qrcodegen.hpp" +#include "theme_manager.h" extern YACReaderHttpServer *httpServer; ServerConfigDialog::ServerConfigDialog(QWidget *parent) : QDialog(parent) { + // Background decoration (SVG on left side) + backgroundDecoration = new QLabel(this); + backgroundDecoration->move(0, 0); + backgroundDecoration->setFixedSize(329, 595); + backgroundDecoration->setScaledContents(true); + accept = new QPushButton(tr("set port"), this); + qrCode = new QLabel(this); qrCode->move(64, 112); qrCode->setFixedSize(200, 200); qrCode->setScaledContents(true); - QLabel *title1 = new QLabel(tr("Server connectivity information"), this); - title1->move(332, 61); - title1->setStyleSheet("QLabel {color:#474747; font-size:30px; font-family: Arial;}"); + titleLabel = new QLabel(tr("Server connectivity information"), this); + titleLabel->move(332, 61); - QLabel *qrMessage = new QLabel(tr("Scan it!"), this); - qrMessage->move(135, 388); // 373,627); - qrMessage->setStyleSheet("QLabel {color:#A3A3A3; font-size:18px; font-family: Arial;}"); - qrMessage->setWordWrap(true); - qrMessage->setFixedWidth(200); + qrMessageLabel = new QLabel(tr("Scan it!"), this); + qrMessageLabel->move(135, 388); + qrMessageLabel->setWordWrap(true); + qrMessageLabel->setFixedWidth(200); - QLabel *propaganda = new QLabel(tr("YACReader is available for iOS and Android devices.
Discover it for iOS or Android."), this); - propaganda->move(332, 505); - propaganda->setStyleSheet("QLabel {color:#4D4D4D; font-size:13px; font-family: Arial; font-style: italic;}"); - propaganda->setOpenExternalLinks(true); + propagandaLabel = new QLabel(tr("YACReader is available for iOS and Android devices.
Discover it for iOS or Android."), this); + propagandaLabel->move(332, 505); + propagandaLabel->setOpenExternalLinks(true); // FORM--------------------------------------------------------------------- - QLabel *ipLabel = new QLabel(tr("Choose an IP address"), this); + ipLabel = new QLabel(tr("Choose an IP address"), this); ipLabel->move(332, 117); - ipLabel->setStyleSheet("QLabel {color:#575757; font-size:18px; font-family: Arial;}"); - QLabel *portLabel = new QLabel(tr("Port"), this); + portLabel = new QLabel(tr("Port"), this); portLabel->move(332, 211); - portLabel->setStyleSheet("QLabel {color:#575757; font-size:18px; font-family: Arial;}"); ip = new QComboBox(this); connect(ip, &QComboBox::currentTextChanged, this, &ServerConfigDialog::regenerateQR); @@ -78,15 +81,8 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent) check = new QCheckBox(this); check->move(332, 314); check->setText(tr("enable the server")); - check->setStyleSheet("QCheckBox {color:#262626; font-size:13px; font-family: Arial;}"); - - QPalette palette; - QImage image(":/images/serverConfigBackground.png"); - palette.setBrush(this->backgroundRole(), QBrush(image)); - setPalette(palette); - - this->setFixedSize(image.size()); + this->setFixedSize(770, 595); QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); settings->beginGroup("libraryConfig"); @@ -105,6 +101,28 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent) settings->endGroup(); connect(check, &QCheckBox::stateChanged, this, &ServerConfigDialog::enableServer); + + // Initialize theme + initTheme(this); +} + +void ServerConfigDialog::applyTheme(const Theme &theme) +{ + // Apply pre-built QSS from theme + setStyleSheet(theme.serverConfigDialog.dialogQSS); + titleLabel->setStyleSheet(theme.serverConfigDialog.titleLabelQSS); + qrMessageLabel->setStyleSheet(theme.serverConfigDialog.qrMessageLabelQSS); + propagandaLabel->setStyleSheet(theme.serverConfigDialog.propagandaLabelQSS); + ipLabel->setStyleSheet(theme.serverConfigDialog.labelQSS); + portLabel->setStyleSheet(theme.serverConfigDialog.labelQSS); + check->setStyleSheet(theme.serverConfigDialog.checkBoxQSS); + + // Set background decoration (SVG on left) + backgroundDecoration->setPixmap(theme.serverConfigDialog.backgroundDecoration); + backgroundDecoration->lower(); // Send to back so other widgets appear on top + + // Regenerate QR code with new theme colors + generateQR(); } void ServerConfigDialog::showEvent(QShowEvent *event) @@ -156,16 +174,22 @@ void ServerConfigDialog::generateQR(const QString &serverAddress) { qrCode->clear(); + auto backgroundColor = theme.serverConfigDialog.qrBackgroundColor; + auto foregroundColor = theme.serverConfigDialog.qrForegroundColor; + qrcodegen::QrCode code = qrcodegen::QrCode::encodeText( serverAddress.toLocal8Bit(), qrcodegen::QrCode::Ecc::LOW); - QBitmap image(code.getSize(), code.getSize()); - image.fill(); - QPainter painter; - painter.begin(&image); - for (int x = 0; x < code.getSize(); x++) { - for (int y = 0; y < code.getSize(); y++) { + int qrSize = code.getSize(); + QPixmap qrPixmap(qrSize, qrSize); + qrPixmap.fill(backgroundColor); + + QPainter painter(&qrPixmap); + painter.setPen(foregroundColor); + painter.setBrush(foregroundColor); + for (int x = 0; x < qrSize; x++) { + for (int y = 0; y < qrSize; y++) { if (code.getModule(x, y)) { painter.drawPoint(x, y); } @@ -173,14 +197,11 @@ void ServerConfigDialog::generateQR(const QString &serverAddress) } painter.end(); - image = image.scaled(qrCode->size() * devicePixelRatioF()); - - QPixmap pMask(image.size()); - pMask.fill(QColor(66, 66, 66)); - pMask.setMask(image.createMaskFromColor(Qt::white)); - pMask.setDevicePixelRatio(devicePixelRatioF()); + // Scale to label size + qrPixmap = qrPixmap.scaled(qrCode->size() * devicePixelRatioF(), Qt::KeepAspectRatio, Qt::FastTransformation); + qrPixmap.setDevicePixelRatio(devicePixelRatioF()); - qrCode->setPixmap(pMask); + qrCode->setPixmap(qrPixmap); } void ServerConfigDialog::regenerateQR(const QString &ip) diff --git a/YACReaderLibrary/server_config_dialog.h b/YACReaderLibrary/server_config_dialog.h index 7d0e9cfab..e882e573e 100644 --- a/YACReaderLibrary/server_config_dialog.h +++ b/YACReaderLibrary/server_config_dialog.h @@ -8,13 +8,18 @@ #include #include -class ServerConfigDialog : public QDialog +#include "themable.h" + +class ServerConfigDialog : public QDialog, protected Themable { Q_OBJECT public: ServerConfigDialog(QWidget *parent = 0); void showEvent(QShowEvent *event) override; +protected: + void applyTheme(const Theme &theme) override; + private: QComboBox *ip; QLineEdit *port; @@ -24,6 +29,14 @@ class ServerConfigDialog : public QDialog QPushButton *close; QPushButton *accept; QLabel *qrCode; + + // Labels for themable styling + QLabel *titleLabel; + QLabel *qrMessageLabel; + QLabel *propagandaLabel; + QLabel *ipLabel; + QLabel *portLabel; + QLabel *backgroundDecoration; public slots: void generateQR(); diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index ed8b7a1c0..bf3b7a1dc 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -5,6 +5,7 @@ #include "yacreader_icon.h" #include "help_about_dialog_theme.h" +#include "whats_new_dialog_theme.h" struct ComicVineThemeTemplates { QString defaultLabelQSS = "QLabel {color:%1; font-size:12px;font-family:Arial;}"; @@ -95,6 +96,339 @@ struct ComicFlowColors { QColor textColor; }; +struct TableViewThemeTemplates { + QString tableViewQSS = "QTableView {alternate-background-color: %1; background-color: %2; outline: 0px; border: none;}" + "QTableCornerButton::section {background-color:%3; border:none; border-bottom:1px solid %4; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %5, stop: 1 %4);}" + "QTableView::item {outline: 0px; border-bottom: 1px solid %6; border-top: 1px solid %7; padding-bottom:1px; color:%8;}" + "QTableView::item:selected {outline: 0px; border-bottom: 1px solid %9; border-top: 1px solid %9; padding-bottom:1px; background-color: %9; color: %10; }" + "QHeaderView::section:horizontal {background-color:%3; border-bottom:1px solid %4; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %5, stop: 1 %4); border-left:none; border-top:none; padding:4px; color:%11;}" + "QHeaderView::section:vertical {border-bottom: 1px solid %6; border-top: 1px solid %7;}"; +}; + +struct TableViewTheme { + QString tableViewQSS; + QColor starRatingColor; + QColor starRatingSelectedColor; +}; + +struct EmptyContainerThemeTemplates { + QString titleLabelQSS = "QLabel {color:%1; font-size:24px;font-family:Arial;font-weight:bold;}"; +}; + +struct EmptyContainerTheme { + QColor backgroundColor; + QString titleLabelQSS; + + // For NoLibrariesWidget + QColor textColor; + QColor descriptionTextColor; + QPixmap noLibrariesIcon; + + // Search-related icons (themed from search_result.svg) + QPixmap searchingIcon; // For ClassicComicsView searching state + QPixmap noSearchResultsIcon; // For NoSearchResultsWidget empty state + + // Empty container icons (themed from SVGs) + QPixmap emptyFolderIcon; + QPixmap emptyFavoritesIcon; + QPixmap emptyCurrentReadingsIcon; + QPixmap emptyReadingListIcon; + QMap emptyLabelIcons; // Keyed by YACReader::LabelColors enum value +}; + +struct SidebarThemeTemplates { + // Non-macOS splitter template: %1 = background color, %2 = height + QString styledSplitterQSS = "QSplitter::handle { image: none; background-color: %1; }" + "QSplitter::handle:vertical { height: %2px;}"; + + // macOS splitter template: %1 = height, %2 = background color + QString nativeSplitterQSS = "QSplitter::handle:vertical { height: %1px; background-color: %2;}"; +}; + +struct SidebarTheme { + QColor backgroundColor; + QColor separatorColor; + QColor sectionSeparatorColor; // Horizontal separators between sidebar sections + QString splitterQSS; + + // When true, section title strings are uppercased after translation + bool uppercaseLabels; + + // Title bar colors + QColor titleTextColor; + QColor titleDropShadowColor; + QColor busyIndicatorColor; +}; + +struct ImportWidgetThemeTemplates { + QString titleLabelQSS = "QLabel {color:%1; font-size:25px;font-weight:bold;}"; +}; + +struct ImportWidgetTheme { + QColor backgroundColor; + QString titleLabelQSS; + QColor descriptionTextColor; + QColor currentComicTextColor; + QColor coversViewBackgroundColor; + QColor coversLabelColor; + + QPixmap topCoversDecoration; + QPixmap bottomCoversDecoration; + QPixmap importingIcon; + QPixmap updatingIcon; + QIcon coversToggleIcon; +}; + +struct TreeViewThemeTemplates { + // Styled tree view template with custom scroll bars + // %1 = text color, %2 = selection/hover background, %3 = scroll background, %4 = scroll handle, %5 = selected text color + QString styledTreeViewQSS = "QTreeView {background-color:transparent; border: none; color:%1; outline:0; show-decoration-selected: 0;}" + "QTreeView::item:selected {background-color: %2; color:%5; font:bold;}" + "QTreeView::item:hover {background-color:%2; color:%5; font:bold;}" + "QTreeView::branch:selected {background-color:%2;}" + "QScrollBar:vertical { border: none; background: %3; width: 7px; margin: 0 3px 0 0; }" + "QScrollBar::handle:vertical { background: %4; width: 7px; min-height: 20px; }" + "QScrollBar::add-line:vertical { border: none; background: %3; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::sub-line:vertical { border: none; background: %3; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" + "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" + "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none; }" + "QTreeView::branch:has-children:!has-siblings:closed,QTreeView::branch:closed:has-children:has-siblings {border-image: none;image: url('%6');}" + "QTreeView::branch:has-children:selected:!has-siblings:closed,QTreeView::branch:closed:selected:has-children:has-siblings {border-image: none;image: url('%6');}" + "QTreeView::branch:open:has-children:!has-siblings,QTreeView::branch:open:has-children:has-siblings {border-image: none;image: url('%7');}" + "QTreeView::branch:open:has-children:selected:!has-siblings,QTreeView::branch:open:has-children:selected:has-siblings {border-image: none;image: url('%7');}"; + + // Native tree view template (uses system scroll bars) - for macOS + QString nativeTreeViewQSS = "QTreeView {background-color:transparent; border: none;}" + "QTreeView::item:selected {background-color:%1; border-top: 1px solid %1; border-left:none;border-right:none;border-bottom:1px solid %1;}" + "QTreeView::branch:selected {background-color:%1; border-top: 1px solid %1; border-left:none;border-right:none;border-bottom:1px solid %1;}" + "QTreeView::branch:open:selected:has-children {image: url(':/images/sidebar/expanded_branch_osx.png');}" + "QTreeView::branch:closed:selected:has-children {image: url(':/images/sidebar/collapsed_branch_osx.png');}"; +}; + +struct TreeViewTheme { + QString treeViewQSS; + QColor folderIndicatorColor; // For incomplete folders and recently updated folders +}; + +// QML view theme colors (used by GridComicsView, FolderContentView, InfoComicsView) +struct QmlViewTheme { + // Grid colors + QColor backgroundColor; + QColor cellColor; + QColor cellColorWithBackground; + QColor selectedColor; + QColor selectedBorderColor; + QColor borderColor; + QColor titleColor; + QColor textColor; + bool showDropShadow; + + // Info panel colors + QColor infoBackgroundColor; + QString topShadow; // Image filename + QString infoShadow; // Image filename + QString infoIndicator; // Image filename + QColor infoTextColor; + QColor infoTitleColor; + + // Rating and favorite colors + QColor ratingUnselectedColor; + QColor ratingSelectedColor; + QColor favUncheckedColor; + QColor favCheckedColor; + QColor readTickUncheckedColor; + QColor readTickCheckedColor; + + // Current comic banner + QColor currentComicBackgroundColor; + + // Continue reading section (FolderContentView) + QColor continueReadingBackgroundColor; + QColor continueReadingColor; +}; + +struct MainToolbarThemeTemplates { + // Toolbar QSS: %1 = background color + QString toolbarQSS = "QToolButton {border:none;}"; + + // Folder name label QSS: %1 = text color + QString folderNameLabelQSS = "QLabel {color:%1; font-size:22px; font-weight:bold;}"; +}; + +struct ContentSplitterThemeTemplates { + QString horizontalSplitterQSS = "QSplitter::handle { image: none; background-color: %1; height: %2px; }"; + QString verticalSplitterQSS = "QSplitter::handle { image: none; background-color: %1; height: %2px; }"; +}; + +struct ComicsViewToolbarThemeTemplates { + QString toolbarQSS = R"( + QToolBar { border: none; } + QToolButton:checked { background-color: %1; } + )"; +}; + +struct SearchLineEditThemeTemplates { + // %1 = text color, %2 = background color, %3 = padding-left, %4 = padding-right + QString lineEditQSS = "QLineEdit {color: %1; border:none; border-radius: 4px; background-color:%2; padding-left: %3px; padding-right: %4px; padding-bottom: 1px; margin-right: 9px;} "; + QString searchLabelQSS = "QLabel { border: none; padding: 0px; }"; + QString clearButtonQSS = "QToolButton { border: none; padding: 0px; }"; +}; + +struct ContentSplitterTheme { + QString horizontalSplitterQSS; // For Qt::Horizontal splitters (vertical handle bar) + QString verticalSplitterQSS; // For Qt::Vertical splitters (horizontal handle bar) +}; + +struct SidebarIconsTheme { + // When true, use QFileIconProvider for folder icons and overlay folderReadOverlay for finished folders + // When false, use the themed folderIcon and folderFinishedIcon SVGs + bool useSystemFolderIcons; + QPixmap folderReadOverlay; // Tick overlay drawn on system folder icons when useSystemFolderIcons is true + + // Folder icons (for FolderModel, ReadingListItem) + QIcon folderIcon; + QIcon folderFinishedIcon; + + // Library icon (for YACReaderLibraryItemWidget - unselected state) + QIcon libraryIcon; + + // Action icons (for LibraryWindowActions - toolbar buttons) + QIcon newLibraryIcon; + QIcon openLibraryIcon; + QIcon addNewIcon; + QIcon deleteIcon; + QIcon setRootIcon; + QIcon expandIcon; + QIcon colapseIcon; + QIcon addLabelIcon; + QIcon renameListIcon; + + // Branch icons (for TreeView QSS) + QString branchClosedIconPath; + QString branchOpenIconPath; +}; + +struct LibraryItemTheme { + QColor textColor; + QColor selectedTextColor; + QColor selectedBackgroundColor; + QIcon libraryIconSelected; // Library icon when selected + QIcon libraryOptionsIcon; // Options icon (shown only when selected) +}; + +struct SearchLineEditTheme { + QString lineEditQSS; + QString searchLabelQSS; + QString clearButtonQSS; + QPixmap searchIcon; + QPixmap clearIcon; +}; + +struct ReadingListIconsTheme { + // Label icons by color name (red, orange, yellow, green, cyan, blue, violet, purple, pink, white, light, dark) + QMap labelIcons; + + // Special list icons (Reading, Favorites, Currently Reading) + QIcon readingListIcon; // default_0 - bookmark + QIcon favoritesIcon; // default_1 - heart + QIcon currentlyReadingIcon; // default_2 - circle with star + + // Reading list icon + QIcon listIcon; +}; + +struct DialogIconsTheme { + QPixmap newLibraryIcon; + QPixmap openLibraryIcon; + QPixmap editIcon; + QPixmap exportComicsInfoIcon; + QPixmap importComicsInfoIcon; + QPixmap exportLibraryIcon; + QPixmap importLibraryIcon; + QIcon findFolderIcon; +}; + +struct MenuIconsTheme { + // Library context menu + QIcon exportComicsInfoIcon; + QIcon importComicsInfoIcon; + QIcon exportLibraryIcon; + QIcon importLibraryIcon; + QIcon updateLibraryIcon; + QIcon renameLibraryIcon; // editIcon + QIcon removeLibraryIcon; + + // Folder/Comic context menu + QIcon openContainingFolderIcon; + QIcon updateCurrentFolderIcon; + + // App + QIcon quitIcon; +}; + +struct ShortcutsIconsTheme { + QIcon comicsIcon; + QIcon foldersIcon; + QIcon generalIcon; + QIcon librariesIcon; + QIcon visualizationIcon; +}; + +struct ServerConfigDialogTheme { + QString dialogQSS; + QString titleLabelQSS; + QString qrMessageLabelQSS; + QString propagandaLabelQSS; + QString labelQSS; + QString checkBoxQSS; + QColor qrBackgroundColor; + QColor qrForegroundColor; + QPixmap backgroundDecoration; +}; + +struct ComicsViewToolbarTheme { + QString toolbarQSS; + + QIcon openInYACReaderIcon; + QIcon setAsReadIcon; + QIcon setAsUnreadIcon; + QIcon showComicInfoIcon; + QIcon setAsNormalIcon; + QIcon setAsMangaIcon; + QIcon editComicIcon; + QIcon getInfoIcon; + QIcon assignNumberIcon; + QIcon selectAllIcon; + QIcon deleteIcon; + QIcon hideComicFlowIcon; + QIcon showMarksIcon; + QIcon showRecentIndicatorIcon; + QIcon bigGridZoomIcon; + QIcon smallGridZoomIcon; +}; + +struct MainToolbarTheme { + QColor backgroundColor; + QColor folderNameColor; + QPixmap dividerPixmap; + + // Icons (contain both Normal and Disabled states) + QIcon backIcon; + QIcon forwardIcon; + QIcon settingsIcon; + QIcon serverIcon; + QIcon helpIcon; + QIcon gridIcon; + QIcon flowIcon; + QIcon infoIcon; + QIcon fullscreenIcon; + + // QSS + QString toolbarQSS; + QString folderNameLabelQSS; +}; + struct ComicVineTheme { QString defaultLabelQSS; QString titleLabelQSS; @@ -129,9 +463,29 @@ struct ComicVineTheme { }; struct Theme { + QColor defaultContentBackgroundColor; + ComicFlowColors comicFlow; ComicVineTheme comicVine; HelpAboutDialogTheme helpAboutDialog; + WhatsNewDialogTheme whatsNewDialog; + EmptyContainerTheme emptyContainer; + SidebarTheme sidebar; + SidebarIconsTheme sidebarIcons; + LibraryItemTheme libraryItem; + ImportWidgetTheme importWidget; + ServerConfigDialogTheme serverConfigDialog; + TreeViewTheme treeView; + TableViewTheme tableView; + QmlViewTheme qmlView; + MainToolbarTheme mainToolbar; + ContentSplitterTheme contentSplitter; + ComicsViewToolbarTheme comicsViewToolbar; + SearchLineEditTheme searchLineEdit; + ReadingListIconsTheme readingListIcons; + DialogIconsTheme dialogIcons; + MenuIconsTheme menuIcons; + ShortcutsIconsTheme shortcutsIcons; }; #endif // THEME_H diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index bdd589f4a..5f7c49691 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -1,6 +1,9 @@ #include "theme_factory.h" +#include + #include "icon_utils.h" +#include "yacreader_global.h" struct ComicVineParams { ComicVineThemeTemplates t; @@ -49,18 +52,273 @@ struct ComicVineParams { QColor rowIconColor; }; +struct EmptyContainerParams { + EmptyContainerThemeTemplates t; + + QColor backgroundColor; + QColor titleTextColor; + + // For NoLibrariesWidget + QColor textColor; + QColor descriptionTextColor; + + QColor searchIconColor; // Color for search-related icons (replaces #f0f in search_result.svg) +}; + +struct SidebarParams { + SidebarThemeTemplates t; + bool useStyledSplitter; // true for non-macOS, false for macOS + + QColor backgroundColor; + QColor separatorColor; + QColor sectionSeparatorColor; // Horizontal separators between sidebar sections + + // Splitter parameters + QColor splitterBackgroundColor; + int splitterHeight; + + bool uppercaseLabels; + + // Title bar colors + QColor titleTextColor; + QColor titleDropShadowColor; + QColor busyIndicatorColor; +}; + +struct ImportWidgetParams { + ImportWidgetThemeTemplates t; + + QColor backgroundColor; + QColor titleTextColor; + QColor descriptionTextColor; + QColor currentComicTextColor; + QColor coversViewBackgroundColor; + QColor coversLabelColor; + QColor coversDecorationBgColor; + QColor coversDecorationShadowColor; + QColor modeIconColor; + QColor iconColor; + QColor iconCheckedColor; +}; + +struct TreeViewParams { + TreeViewThemeTemplates t; + bool useStyledTemplate; // true for non-macOS themes, false for macOS themes + + // For styled template: %1=text, %2=selection bg, %3=scroll bg, %4=scroll handle, %5=selected text + QColor textColor; + QColor selectionBackgroundColor; + QColor scrollBackgroundColor; + QColor scrollHandleColor; + QColor selectedTextColor; + + // For native (macOS) template: %1=selection color + QColor nativeSelectionColor; + + QColor folderIndicatorColor; +}; + +struct TableViewParams { + TableViewThemeTemplates t; + + QColor alternateBackgroundColor; + QColor backgroundColor; + QColor cornerButtonBackgroundColor; + QColor cornerButtonBorderColor; + QColor cornerButtonGradientColor; + QColor itemBorderBottomColor; + QColor itemBorderTopColor; + QColor itemTextColor; + QColor selectedColor; + QColor selectedTextColor; + QColor headerTextColor; + + QColor starRatingColor; + QColor starRatingSelectedColor; +}; + +struct QmlViewParams { + // Grid colors + QColor backgroundColor; + QColor cellColor; + QColor cellColorWithBackground; + QColor selectedColor; + QColor selectedBorderColor; + QColor borderColor; + QColor titleColor; + QColor textColor; + bool showDropShadow; + + // Info panel colors + QColor infoBackgroundColor; + QString topShadow; // Image filename + QString infoShadow; // Image filename + QString infoIndicator; // Image filename + QColor infoTextColor; + QColor infoTitleColor; + + // Rating and favorite colors + QColor ratingUnselectedColor; + QColor ratingSelectedColor; + QColor favUncheckedColor; + QColor favCheckedColor; + QColor readTickUncheckedColor; + QColor readTickCheckedColor; + + // Current comic banner + QColor currentComicBackgroundColor; + + // Continue reading section (FolderContentView) + QColor continueReadingBackgroundColor; + QColor continueReadingColor; +}; + +struct MainToolbarParams { + MainToolbarThemeTemplates t; + + QColor backgroundColor; + QColor folderNameColor; + QColor dividerColor; + QColor iconColor; + QColor iconDisabledColor; +}; + +struct ContentSplitterParams { + ContentSplitterThemeTemplates t; + + QColor handleColor; + int horizontalHandleHeight; // for vertical splitter (horizontal handle) + int verticalHandleWidth; // for horizontal splitter (vertical handle) +}; + +struct SidebarIconsParams { + // Icon colors - #f0f placeholder gets replaced with these + QColor iconColor; // Main icon color (replaces #f0f) + QColor shadowColor; // Shadow color (replaces #0ff) + QColor extraColor; // Extra info like ticks (replaces #ff0) + + // When true, use QFileIconProvider for folder icons and overlay a tick for finished folders + bool useSystemFolderIcons; + QColor folderReadOverlayColor; // Color for the tick overlay (replaces #f0f in folder_read_overlay.svg) +}; + +struct ServerConfigDialogThemeTemplates { + QString dialogQSS = "ServerConfigDialog { background-color: %1; }"; + QString titleLabelQSS = "QLabel { color: %1; font-size: 30px; font-family: Arial; }"; + QString qrMessageLabelQSS = "QLabel { color: %1; font-size: 18px; font-family: Arial; }"; + QString propagandaLabelQSS = "QLabel { color: %1; font-size: 13px; font-family: Arial; font-style: italic; }"; + QString labelQSS = "QLabel { color: %1; font-size: 18px; font-family: Arial; }"; + QString checkBoxQSS = "QCheckBox { color: %1; font-size: 13px; font-family: Arial; }"; +}; + +struct LibraryItemParams { + QColor textColor; + QColor selectedTextColor; + QColor selectedBackgroundColor; + QColor libraryIconSelectedColor; // Color for the library icon when selected + QColor libraryOptionsIconColor; // Color for the options icon (shown only when selected) +}; + +struct ComicsViewToolbarParams { + ComicsViewToolbarThemeTemplates t; + + QColor checkedBackgroundColor; + QColor iconColor; // Main icon color (replaces #f0f) +}; + +struct SearchLineEditParams { + SearchLineEditThemeTemplates t; + + QColor textColor; + QColor backgroundColor; + QColor iconColor; // Main icon color (replaces #f0f) +}; + +struct ReadingListIconsParams { + QMap labelColors; // Label colors by name (e.g., "red" -> #f67a7b) + QColor labelShadowColor; // Shadow color for labels (replaces #0ff) + + // Special list icon colors + QColor readingListMainColor; // default_0 main color (replaces #f0f) + QColor favoritesMainColor; // default_1 main color (replaces #f0f) + QColor currentlyReadingMainColor; // default_2 main color (replaces #f0f) + QColor currentlyReadingOuterColor; // default_2 outer circle (replaces #ff0) + QColor specialListShadowColor; // Shadow color for special lists (replaces #0ff) + + // List icon colors + QColor listMainColor; // main color (replaces #f0f) + QColor listShadowColor; // shadow color (replaces #0ff) + QColor listDetailColor; // detail/checkbox color (replaces #ff0) +}; + +struct DialogIconsParams { + QColor iconColor; // Main icon color (replaces #f0f) +}; + +struct MenuIconsParams { + QColor iconColor; // Main icon color (replaces #f0f) +}; + +struct ShortcutsIconsParams { + QColor iconColor; // Main icon color (replaces #f0f) +}; + +struct ServerConfigDialogParams { + ServerConfigDialogThemeTemplates t; + QColor backgroundColor; + QColor titleTextColor; + QColor qrMessageTextColor; + QColor propagandaTextColor; + QColor labelTextColor; + QColor checkBoxTextColor; + QColor qrBackgroundColor; + QColor qrForegroundColor; + QColor decorationColor; +}; + +struct WhatsNewDialogParams { + QColor backgroundColor; + QColor headerTextColor; + QColor versionTextColor; + QColor contentTextColor; + QColor linkColor; + QColor closeButtonColor; + QColor headerDecorationColor; +}; + struct ThemeParams { QString themeName; + QColor defaultContentBackgroundColor; ComicFlowColors comicFlowColors; ComicVineParams comicVineParams; HelpAboutDialogTheme helpAboutDialogParams; + EmptyContainerParams emptyContainerParams; + SidebarParams sidebarParams; + SidebarIconsParams sidebarIconsParams; + LibraryItemParams libraryItemParams; + ImportWidgetParams importWidgetParams; + ServerConfigDialogParams serverConfigDialogParams; + MainToolbarParams mainToolbarParams; + ContentSplitterParams contentSplitterParams; + TreeViewParams treeViewParams; + TableViewParams tableViewParams; + QmlViewParams qmlViewParams; + ComicsViewToolbarParams comicsViewToolbarParams; + SearchLineEditParams searchLineEditParams; + ReadingListIconsParams readingListIconsParams; + DialogIconsParams dialogIconsParams; + MenuIconsParams menuIconsParams; + ShortcutsIconsParams shortcutsIconsParams; + WhatsNewDialogParams whatsNewDialogParams; }; Theme makeTheme(const ThemeParams ¶ms) { Theme theme; + theme.defaultContentBackgroundColor = params.defaultContentBackgroundColor; + // Comic Flow const auto &cf = params.comicFlowColors; theme.comicFlow.backgroundColor = cf.backgroundColor; @@ -91,19 +349,19 @@ Theme makeTheme(const ThemeParams ¶ms) theme.comicVine.scraperScrollLabelScrollAreaQSS = t.scraperScrollLabelScrollAreaQSS.arg(cv.contentBackgroundColor.name(), cv.tableScrollHandleColor.name(), cv.tableScrollBackgroundColor.name()); theme.comicVine.scraperTableViewQSS = t.scraperTableViewQSS - .arg(cv.tableHeaderTextColor.name()) - .arg(cv.tableAltBackgroundColor.name()) - .arg(cv.tableBackgroundColor.name()) - .arg(cv.tableSelectedColor.name()) - .arg(cv.tableHeaderBackgroundColor.name()) - .arg(cv.tableHeaderBorderColor.name()) - .arg(cv.tableHeaderTextColor.name()) - .arg(cv.tableSectionBorderDark.name()) - .arg(cv.tableSectionBorderLight.name()) - .arg(cv.tableScrollHandleColor.name()) - .arg(cv.tableScrollBackgroundColor.name()) - .arg(recolor(":/images/comic_vine/downArrow.svg", cv.downArrowColor)) - .arg(recolor(":/images/comic_vine/upArrow.svg", cv.upArrowColor)); + .arg(cv.tableHeaderTextColor.name(), + cv.tableAltBackgroundColor.name(), + cv.tableBackgroundColor.name(), + cv.tableSelectedColor.name(), + cv.tableHeaderBackgroundColor.name(), + cv.tableHeaderBorderColor.name(), + cv.tableHeaderTextColor.name(), + cv.tableSectionBorderDark.name(), + cv.tableSectionBorderLight.name(), + cv.tableScrollHandleColor.name(), + cv.tableScrollBackgroundColor.name(), + recolor(":/images/comic_vine/downArrow.svg", cv.downArrowColor), + recolor(":/images/comic_vine/upArrow.svg", cv.upArrowColor)); theme.comicVine.dialogQSS = t.dialogQSS.arg(cv.dialogBackgroundColor.name()); theme.comicVine.dialogButtonsQSS = t.dialogButtonsQSS.arg(cv.buttonBorderColor.name(), cv.buttonBackgroundColor.name(), cv.buttonTextColor.name()); @@ -120,6 +378,455 @@ Theme makeTheme(const ThemeParams ¶ms) theme.helpAboutDialog = params.helpAboutDialogParams; // end HelpAboutDialog + // WhatsNewDialog + const auto &wn = params.whatsNewDialogParams; + theme.whatsNewDialog.backgroundColor = wn.backgroundColor; + theme.whatsNewDialog.headerTextColor = wn.headerTextColor; + theme.whatsNewDialog.versionTextColor = wn.versionTextColor; + theme.whatsNewDialog.contentTextColor = wn.contentTextColor; + theme.whatsNewDialog.linkColor = wn.linkColor; + theme.whatsNewDialog.closeButtonIcon = QPixmap(recoloredSvgToThemeFile(":/images/custom_dialog/custom_close_button.svg", wn.closeButtonColor, params.themeName)); + theme.whatsNewDialog.headerDecoration = QPixmap(recoloredSvgToThemeFile(":/images/whats_new/whatsnew_header.svg", wn.headerDecorationColor, params.themeName)); + // end WhatsNewDialog + + // EmptyContainer + const auto &ec = params.emptyContainerParams; + const auto &ect = ec.t; + + theme.emptyContainer.backgroundColor = ec.backgroundColor; + theme.emptyContainer.titleLabelQSS = ect.titleLabelQSS.arg(ec.titleTextColor.name()); + theme.emptyContainer.textColor = ec.textColor; + theme.emptyContainer.descriptionTextColor = ec.descriptionTextColor; + theme.emptyContainer.noLibrariesIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/noLibrariesIcon.svg", ec.searchIconColor, params.themeName), 165, 160, qApp->devicePixelRatio()); + { + const qreal dpr = qApp->devicePixelRatio(); + theme.emptyContainer.searchingIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/search_result.svg", ec.searchIconColor, params.themeName, { .suffix = "_searching" }), 97, dpr); + theme.emptyContainer.noSearchResultsIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/search_result.svg", ec.searchIconColor, params.themeName, { .suffix = "_no_results" }), 239, dpr); + + theme.emptyContainer.emptyFolderIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_folder.svg", ec.searchIconColor, params.themeName), 319, 243, dpr); + theme.emptyContainer.emptyFavoritesIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_favorites.svg", QColor(0xe84853), params.themeName), 238, 223, dpr); + theme.emptyContainer.emptyCurrentReadingsIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_current_readings.svg", ec.searchIconColor, params.themeName), 167, 214, dpr); + theme.emptyContainer.emptyReadingListIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_reading_list.svg", ec.searchIconColor, params.themeName), 248, 187, dpr); + + // Generate empty label icons for each label color + const auto &rli = params.readingListIconsParams; + for (int c = YACReader::YRed; c <= YACReader::YDark; ++c) { + auto labelColor = static_cast(c); + auto colorName = YACReader::colorToName(labelColor); + auto it = rli.labelColors.find(colorName); + if (it != rli.labelColors.end()) { + theme.emptyContainer.emptyLabelIcons[c] = renderSvgToPixmap( + recoloredSvgToThemeFile(":/images/empty_container/empty_label.svg", it.value(), params.themeName, { .suffix = "_" + colorName }), 243, 243, dpr); + } + } + } + // end EmptyContainer + + // Sidebar + const auto &sb = params.sidebarParams; + theme.sidebar.backgroundColor = sb.backgroundColor; + theme.sidebar.separatorColor = sb.separatorColor; + theme.sidebar.sectionSeparatorColor = sb.sectionSeparatorColor; + if (sb.useStyledSplitter) { + theme.sidebar.splitterQSS = sb.t.styledSplitterQSS + .arg(sb.splitterBackgroundColor.name()) + .arg(sb.splitterHeight); + } else { + theme.sidebar.splitterQSS = sb.t.nativeSplitterQSS + .arg(sb.splitterHeight) + .arg(sb.splitterBackgroundColor.name()); + } + theme.sidebar.uppercaseLabels = sb.uppercaseLabels; + theme.sidebar.titleTextColor = sb.titleTextColor; + theme.sidebar.titleDropShadowColor = sb.titleDropShadowColor; + theme.sidebar.busyIndicatorColor = sb.busyIndicatorColor; + // end Sidebar + + // ImportWidget + const auto &iw = params.importWidgetParams; + const auto &iwt = iw.t; + theme.importWidget.backgroundColor = iw.backgroundColor; + theme.importWidget.titleLabelQSS = iwt.titleLabelQSS.arg(iw.titleTextColor.name()); + theme.importWidget.descriptionTextColor = iw.descriptionTextColor; + theme.importWidget.currentComicTextColor = iw.currentComicTextColor; + theme.importWidget.coversViewBackgroundColor = iw.coversViewBackgroundColor; + theme.importWidget.coversLabelColor = iw.coversLabelColor; + theme.importWidget.topCoversDecoration = QPixmap(recoloredSvgToThemeFile(":/images/import/importTopCoversDecoration.svg", iw.coversDecorationBgColor, iw.coversDecorationShadowColor, params.themeName)); + theme.importWidget.bottomCoversDecoration = QPixmap(recoloredSvgToThemeFile(":/images/import/importBottomCoversDecoration.svg", iw.coversDecorationBgColor, iw.coversDecorationShadowColor, params.themeName)); + theme.importWidget.importingIcon = QPixmap(recoloredSvgToThemeFile(":/images/import/importingIcon.svg", iw.modeIconColor, params.themeName)); + theme.importWidget.updatingIcon = QPixmap(recoloredSvgToThemeFile(":/images/import/updatingIcon.svg", iw.modeIconColor, params.themeName)); + { + QIcon coversToggle; + const QString normalPath = recoloredSvgToThemeFile(":/images/import/coversToggle.svg", iw.iconColor, params.themeName); + const QString checkedPath = recoloredSvgToThemeFile(":/images/import/coversToggle.svg", iw.iconCheckedColor, params.themeName, { .suffix = "_checked" }); + coversToggle.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); + coversToggle.addFile(checkedPath, QSize(), QIcon::Normal, QIcon::On); + theme.importWidget.coversToggleIcon = coversToggle; + } + // end ImportWidget + + // TableView + const auto &tav = params.tableViewParams; + const auto &tavt = tav.t; + theme.tableView.tableViewQSS = tavt.tableViewQSS + .arg(tav.alternateBackgroundColor.name(), + tav.backgroundColor.name(), + tav.cornerButtonBackgroundColor.name(), + tav.cornerButtonBorderColor.name(), + tav.cornerButtonGradientColor.name(), + tav.itemBorderBottomColor.name(), + tav.itemBorderTopColor.name(), + tav.itemTextColor.name(), + tav.selectedColor.name(), + tav.selectedTextColor.name(), + tav.headerTextColor.name()); + theme.tableView.starRatingColor = tav.starRatingColor; + theme.tableView.starRatingSelectedColor = tav.starRatingSelectedColor; + // end TableView + + // QmlView + const auto &qv = params.qmlViewParams; + theme.qmlView.backgroundColor = qv.backgroundColor; + theme.qmlView.cellColor = qv.cellColor; + theme.qmlView.cellColorWithBackground = qv.cellColorWithBackground; + theme.qmlView.selectedColor = qv.selectedColor; + theme.qmlView.selectedBorderColor = qv.selectedBorderColor; + theme.qmlView.borderColor = qv.borderColor; + theme.qmlView.titleColor = qv.titleColor; + theme.qmlView.textColor = qv.textColor; + theme.qmlView.showDropShadow = qv.showDropShadow; + theme.qmlView.infoBackgroundColor = qv.infoBackgroundColor; + theme.qmlView.topShadow = qv.topShadow; + theme.qmlView.infoShadow = qv.infoShadow; + theme.qmlView.infoIndicator = qv.infoIndicator; + theme.qmlView.infoTextColor = qv.infoTextColor; + theme.qmlView.infoTitleColor = qv.infoTitleColor; + theme.qmlView.ratingUnselectedColor = qv.ratingUnselectedColor; + theme.qmlView.ratingSelectedColor = qv.ratingSelectedColor; + theme.qmlView.favUncheckedColor = qv.favUncheckedColor; + theme.qmlView.favCheckedColor = qv.favCheckedColor; + theme.qmlView.readTickUncheckedColor = qv.readTickUncheckedColor; + theme.qmlView.readTickCheckedColor = qv.readTickCheckedColor; + theme.qmlView.currentComicBackgroundColor = qv.currentComicBackgroundColor; + theme.qmlView.continueReadingBackgroundColor = qv.continueReadingBackgroundColor; + theme.qmlView.continueReadingColor = qv.continueReadingColor; + // end QmlView + + // MainToolbar + const auto &mt = params.mainToolbarParams; + theme.mainToolbar.backgroundColor = mt.backgroundColor; + theme.mainToolbar.folderNameColor = mt.folderNameColor; + theme.mainToolbar.toolbarQSS = mt.t.toolbarQSS; + theme.mainToolbar.folderNameLabelQSS = mt.t.folderNameLabelQSS.arg(mt.folderNameColor.name()); + + // Build divider pixmap with gradient (HiDPI aware) + { + const qreal dpr = qApp->devicePixelRatio(); + const int width = 1; + const int height = 34; + + QPixmap pixmap(width * dpr, height * dpr); + pixmap.setDevicePixelRatio(dpr); + pixmap.fill(Qt::transparent); + + QPainter painter(&pixmap); + painter.setRenderHint(QPainter::Antialiasing); + + QLinearGradient gradient(0, 0, 0, height); + QColor transparentColor = mt.dividerColor; + transparentColor.setAlpha(0); + + gradient.setColorAt(0.0, transparentColor); + gradient.setColorAt(0.5, mt.dividerColor); + gradient.setColorAt(1.0, transparentColor); + + painter.setPen(QPen(QBrush(gradient), 1)); + painter.drawLine(0, 0, 0, height); + + theme.mainToolbar.dividerPixmap = pixmap; + } + + // Build icons with Normal and Disabled states + auto makeToolbarIcon = [&](const QString &basePath) { + QIcon icon; + const QString normalPath = recoloredSvgToThemeFile(basePath, mt.iconColor, params.themeName); + const QString disabledPath = recoloredSvgToThemeFile(basePath, mt.iconDisabledColor, params.themeName, { .suffix = "_disabled" }); + icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(disabledPath, QSize(), QIcon::Disabled, QIcon::Off); + return icon; + }; + + theme.mainToolbar.backIcon = makeToolbarIcon(":/images/main_toolbar/back.svg"); + theme.mainToolbar.forwardIcon = makeToolbarIcon(":/images/main_toolbar/forward.svg"); + theme.mainToolbar.settingsIcon = makeToolbarIcon(":/images/main_toolbar/settings.svg"); + theme.mainToolbar.serverIcon = makeToolbarIcon(":/images/main_toolbar/server.svg"); + theme.mainToolbar.helpIcon = makeToolbarIcon(":/images/main_toolbar/help.svg"); + theme.mainToolbar.gridIcon = makeToolbarIcon(":/images/main_toolbar/grid.svg"); + theme.mainToolbar.flowIcon = makeToolbarIcon(":/images/main_toolbar/flow.svg"); + theme.mainToolbar.infoIcon = makeToolbarIcon(":/images/main_toolbar/info.svg"); + theme.mainToolbar.fullscreenIcon = makeToolbarIcon(":/images/main_toolbar/fullscreen.svg"); + // end MainToolbar + + // SidebarIcons + const auto &si = params.sidebarIconsParams; + + // Helper to create icons with shadow (two-color: #f0f main, #0ff shadow) + // Adds both Normal and Selected modes to prevent Qt from applying a selection tint + auto makeSidebarIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, si.iconColor, si.shadowColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + return icon; + }; + + // Helper for icons with extra color (three-color: #f0f main, #0ff shadow, #ff0 extra) + auto makeSidebarIconWithExtra = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, si.iconColor, si.shadowColor, si.extraColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + return icon; + }; + + // Helper for single-color icons (only #f0f main) + auto makeSingleColorIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, si.iconColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + return icon; + }; + + // System folder icons flag and overlay + theme.sidebarIcons.useSystemFolderIcons = si.useSystemFolderIcons; + if (si.useSystemFolderIcons) { + const QString overlayPath = recoloredSvgToThemeFile(":/images/sidebar/folder_read_overlay.svg", si.folderReadOverlayColor, params.themeName); + theme.sidebarIcons.folderReadOverlay = QPixmap(overlayPath); + } + + // Folder icons + theme.sidebarIcons.folderIcon = makeSidebarIcon(":/images/sidebar/folder.svg"); + theme.sidebarIcons.folderFinishedIcon = makeSidebarIconWithExtra(":/images/sidebar/folder_finished.svg"); + + // Library icon (unselected state uses sidebar colors) + theme.sidebarIcons.libraryIcon = makeSidebarIcon(":/images/sidebar/libraryIcon.svg"); + + // Action icons + theme.sidebarIcons.newLibraryIcon = makeSidebarIcon(":/images/sidebar/newLibraryIcon.svg"); + theme.sidebarIcons.openLibraryIcon = makeSidebarIcon(":/images/sidebar/openLibraryIcon.svg"); + theme.sidebarIcons.addNewIcon = makeSidebarIcon(":/images/sidebar/addNew_sidebar.svg"); + theme.sidebarIcons.deleteIcon = makeSidebarIcon(":/images/sidebar/delete_sidebar.svg"); + theme.sidebarIcons.setRootIcon = makeSidebarIcon(":/images/sidebar/setRoot.svg"); + theme.sidebarIcons.expandIcon = makeSidebarIcon(":/images/sidebar/expand.svg"); + theme.sidebarIcons.colapseIcon = makeSidebarIcon(":/images/sidebar/colapse.svg"); + theme.sidebarIcons.addLabelIcon = makeSidebarIcon(":/images/sidebar/addLabelIcon.svg"); + theme.sidebarIcons.renameListIcon = makeSidebarIcon(":/images/sidebar/renameListIcon.svg"); + + // Branch icons (paths for QSS) + theme.sidebarIcons.branchClosedIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-closed.svg", si.iconColor, params.themeName); + theme.sidebarIcons.branchOpenIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", si.iconColor, params.themeName); + // end SidebarIcons + + // LibraryItem + const auto &li = params.libraryItemParams; + theme.libraryItem.textColor = li.textColor; + theme.libraryItem.selectedTextColor = li.selectedTextColor; + theme.libraryItem.selectedBackgroundColor = li.selectedBackgroundColor; + + // Library icon when selected (uses its own color to contrast with selected background) + const QString libraryIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/libraryIconSelected.svg", li.libraryIconSelectedColor, params.themeName); + theme.libraryItem.libraryIconSelected = QIcon(libraryIconSelectedPath); + + // Library options icon (shown only when selected, uses its own color) + const QString libraryOptionsPath = recoloredSvgToThemeFile(":/images/sidebar/libraryOptions.svg", li.libraryOptionsIconColor, params.themeName); + theme.libraryItem.libraryOptionsIcon = QIcon(libraryOptionsPath); + // end LibraryItem + + // TreeView (must come after SidebarIcons for branch icon paths) + const auto &tv = params.treeViewParams; + if (tv.useStyledTemplate) { + theme.treeView.treeViewQSS = tv.t.styledTreeViewQSS + .arg(tv.textColor.name(), + tv.selectionBackgroundColor.name(), + tv.scrollBackgroundColor.name(), + tv.scrollHandleColor.name(), + tv.selectedTextColor.name(), + theme.sidebarIcons.branchClosedIconPath, + theme.sidebarIcons.branchOpenIconPath); + } else { + theme.treeView.treeViewQSS = tv.t.nativeTreeViewQSS.arg(tv.nativeSelectionColor.name()); + } + theme.treeView.folderIndicatorColor = tv.folderIndicatorColor; + // end TreeView + + // ContentSplitter + const auto &cs = params.contentSplitterParams; + theme.contentSplitter.horizontalSplitterQSS = cs.t.horizontalSplitterQSS + .arg(cs.handleColor.name()) + .arg(cs.verticalHandleWidth); + theme.contentSplitter.verticalSplitterQSS = cs.t.verticalSplitterQSS + .arg(cs.handleColor.name()) + .arg(cs.horizontalHandleHeight); + // end ContentSplitter + + // ComicsViewToolbar + const auto &cvt = params.comicsViewToolbarParams; + + // Helper to create single-color icons for comics view toolbar + auto makeComicsViewIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, cvt.iconColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + return icon; + }; + + theme.comicsViewToolbar.toolbarQSS = cvt.t.toolbarQSS.arg(cvt.checkedBackgroundColor.name()); + theme.comicsViewToolbar.openInYACReaderIcon = makeComicsViewIcon(":/images/comics_view_toolbar/openInYACReader.svg"); + theme.comicsViewToolbar.setAsReadIcon = makeComicsViewIcon(":/images/comics_view_toolbar/setReadButton.svg"); + theme.comicsViewToolbar.setAsUnreadIcon = makeComicsViewIcon(":/images/comics_view_toolbar/setUnread.svg"); + theme.comicsViewToolbar.showComicInfoIcon = makeComicsViewIcon(":/images/comics_view_toolbar/show_comic_info.svg"); + theme.comicsViewToolbar.setAsNormalIcon = makeComicsViewIcon(":/images/comics_view_toolbar/setNormal.svg"); + theme.comicsViewToolbar.setAsMangaIcon = makeComicsViewIcon(":/images/comics_view_toolbar/setManga.svg"); + theme.comicsViewToolbar.editComicIcon = makeComicsViewIcon(":/images/comics_view_toolbar/editComic.svg"); + theme.comicsViewToolbar.getInfoIcon = makeComicsViewIcon(":/images/comics_view_toolbar/getInfo.svg"); + theme.comicsViewToolbar.assignNumberIcon = makeComicsViewIcon(":/images/comics_view_toolbar/asignNumber.svg"); + theme.comicsViewToolbar.selectAllIcon = makeComicsViewIcon(":/images/comics_view_toolbar/selectAll.svg"); + theme.comicsViewToolbar.deleteIcon = makeComicsViewIcon(":/images/comics_view_toolbar/trash.svg"); + theme.comicsViewToolbar.hideComicFlowIcon = makeComicsViewIcon(":/images/comics_view_toolbar/hideComicFlow.svg"); + theme.comicsViewToolbar.showMarksIcon = makeComicsViewIcon(":/images/comics_view_toolbar/showMarks.svg"); + theme.comicsViewToolbar.showRecentIndicatorIcon = makeComicsViewIcon(":/images/comics_view_toolbar/showRecentIndicator.svg"); + theme.comicsViewToolbar.bigGridZoomIcon = makeComicsViewIcon(":/images/comics_view_toolbar/big_size_grid_zoom.svg"); + theme.comicsViewToolbar.smallGridZoomIcon = makeComicsViewIcon(":/images/comics_view_toolbar/small_size_grid_zoom.svg"); + // end ComicsViewToolbar + + // SearchLineEdit + const auto &sle = params.searchLineEditParams; + + theme.searchLineEdit.lineEditQSS = sle.t.lineEditQSS + .arg(sle.textColor.name(), + sle.backgroundColor.name()); + theme.searchLineEdit.searchLabelQSS = sle.t.searchLabelQSS; + theme.searchLineEdit.clearButtonQSS = sle.t.clearButtonQSS; + + const qreal dpr = qApp->devicePixelRatio(); + theme.searchLineEdit.searchIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/iconSearchNew.svg", sle.iconColor, params.themeName), 15, dpr); + theme.searchLineEdit.clearIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/clearSearchNew.svg", sle.iconColor, params.themeName), 12, dpr); + // end SearchLineEdit + + // ReadingListIcons + const auto &rli = params.readingListIconsParams; + + // Helper to create label icons from template (uses color name to generate label_.svg files) + auto makeLabelIcon = [&](const QString &colorName, const QColor &mainColor) { + const QString path = recoloredSvgToThemeFile(":/images/lists/label_template.svg", mainColor, rli.labelShadowColor, params.themeName, { .fileName = "label_" + colorName }); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + return icon; + }; + + for (auto it = rli.labelColors.constBegin(); it != rli.labelColors.constEnd(); ++it) { + theme.readingListIcons.labelIcons[it.key()] = makeLabelIcon(it.key(), it.value()); + } + + // Special list icons + auto makeSpecialIcon = [&](const QString &basePath, const QColor &mainColor) { + const QString path = recoloredSvgToThemeFile(basePath, mainColor, rli.specialListShadowColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + return icon; + }; + + theme.readingListIcons.readingListIcon = makeSpecialIcon(":/images/lists/default_0.svg", rli.readingListMainColor); + theme.readingListIcons.favoritesIcon = makeSpecialIcon(":/images/lists/default_1.svg", rli.favoritesMainColor); + + // Currently reading has 3 colors + { + const QString path = recoloredSvgToThemeFile(":/images/lists/default_2.svg", rli.currentlyReadingMainColor, rli.specialListShadowColor, rli.currentlyReadingOuterColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + theme.readingListIcons.currentlyReadingIcon = icon; + } + + // List icon (3 colors) + { + const QString path = recoloredSvgToThemeFile(":/images/lists/list.svg", rli.listMainColor, rli.listShadowColor, rli.listDetailColor, params.themeName); + QIcon icon; + icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + theme.readingListIcons.listIcon = icon; + } + // end ReadingListIcons + + // MenuIcons + const auto &mi = params.menuIconsParams; + auto makeMenuIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, mi.iconColor, params.themeName); + return QIcon(path); + }; + + theme.menuIcons.exportComicsInfoIcon = makeMenuIcon(":/images/menus_icons/exportComicsInfoIcon.svg"); + theme.menuIcons.importComicsInfoIcon = makeMenuIcon(":/images/menus_icons/importComicsInfoIcon.svg"); + theme.menuIcons.exportLibraryIcon = makeMenuIcon(":/images/menus_icons/exportLibraryIcon.svg"); + theme.menuIcons.importLibraryIcon = makeMenuIcon(":/images/menus_icons/importLibraryIcon.svg"); + theme.menuIcons.updateLibraryIcon = makeMenuIcon(":/images/menus_icons/updateLibraryIcon.svg"); + theme.menuIcons.renameLibraryIcon = makeMenuIcon(":/images/menus_icons/editIcon.svg"); + theme.menuIcons.removeLibraryIcon = makeMenuIcon(":/images/menus_icons/removeLibraryIcon.svg"); + theme.menuIcons.openContainingFolderIcon = makeMenuIcon(":/images/menus_icons/open_containing_folder.svg"); + theme.menuIcons.updateCurrentFolderIcon = makeMenuIcon(":/images/menus_icons/update_current_folder.svg"); + theme.menuIcons.quitIcon = makeMenuIcon(":/images/viewer_toolbar/close.svg"); + // end MenuIcons + + // DialogIcons + const auto &di = params.dialogIconsParams; + auto makeDialogIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, di.iconColor, params.themeName); + return QPixmap(path); + }; + theme.dialogIcons.newLibraryIcon = makeDialogIcon(":/images/library_dialogs/new.svg"); + theme.dialogIcons.openLibraryIcon = makeDialogIcon(":/images/library_dialogs/openLibrary.svg"); + theme.dialogIcons.editIcon = makeDialogIcon(":/images/library_dialogs/edit.svg"); + theme.dialogIcons.exportComicsInfoIcon = makeDialogIcon(":/images/library_dialogs/exportComicsInfo.svg"); + theme.dialogIcons.importComicsInfoIcon = makeDialogIcon(":/images/library_dialogs/importComicsInfo.svg"); + theme.dialogIcons.exportLibraryIcon = makeDialogIcon(":/images/library_dialogs/exportLibrary.svg"); + theme.dialogIcons.importLibraryIcon = makeDialogIcon(":/images/library_dialogs/importLibrary.svg"); + { + const QString path = recoloredSvgToThemeFile(":/images/find_folder.svg", di.iconColor, params.themeName); + const qreal dpr = qApp->devicePixelRatio(); + theme.dialogIcons.findFolderIcon = QIcon(renderSvgToPixmap(path, 13, 13, dpr)); + } + // end DialogIcons + + // ShortcutsIcons + const auto &sci = params.shortcutsIconsParams; + auto makeShortcutsIcon = [&](const QString &basePath) { + const QString path = recoloredSvgToThemeFile(basePath, sci.iconColor, params.themeName); + return QIcon(path); + }; + + theme.shortcutsIcons.comicsIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_comics.svg"); + theme.shortcutsIcons.foldersIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_folders.svg"); + theme.shortcutsIcons.generalIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_general.svg"); + theme.shortcutsIcons.librariesIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_libraries.svg"); + theme.shortcutsIcons.visualizationIcon = makeShortcutsIcon(":/images/shortcuts/shortcuts_group_visualization.svg"); + // end ShortcutsIcons + + // ServerConfigDialog + const auto &scd = params.serverConfigDialogParams; + theme.serverConfigDialog.dialogQSS = scd.t.dialogQSS.arg(scd.backgroundColor.name()); + theme.serverConfigDialog.titleLabelQSS = scd.t.titleLabelQSS.arg(scd.titleTextColor.name()); + theme.serverConfigDialog.qrMessageLabelQSS = scd.t.qrMessageLabelQSS.arg(scd.qrMessageTextColor.name()); + theme.serverConfigDialog.propagandaLabelQSS = scd.t.propagandaLabelQSS.arg(scd.propagandaTextColor.name()); + theme.serverConfigDialog.labelQSS = scd.t.labelQSS.arg(scd.labelTextColor.name()); + theme.serverConfigDialog.checkBoxQSS = scd.t.checkBoxQSS.arg(scd.checkBoxTextColor.name()); + theme.serverConfigDialog.qrBackgroundColor = scd.qrBackgroundColor; + theme.serverConfigDialog.qrForegroundColor = scd.qrForegroundColor; + theme.serverConfigDialog.backgroundDecoration = QPixmap(recoloredSvgToThemeFile(":/images/serverConfigBackground.svg", scd.decorationColor, params.themeName)); + return theme; } @@ -129,6 +836,7 @@ ThemeParams darkThemeParams(); Theme makeTheme(ThemeId themeId) { + switch (themeId) { case ThemeId::Classic: return makeTheme(classicThemeParams()); @@ -145,6 +853,7 @@ ThemeParams classicThemeParams() { ThemeParams params; params.themeName = "classic"; + params.defaultContentBackgroundColor = QColor(0x2A2A2A); ComicFlowColors cf; cf.backgroundColor = Qt::black; @@ -176,7 +885,7 @@ ThemeParams classicThemeParams() cv.buttonTextColor = Qt::white; cv.buttonBorderColor = QColor(0x242424); - cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.png"; + cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.svg"; cv.radioUncheckedColor = QColor(0xE5E5E5); cv.radioCheckedPath = ":/images/comic_vine/radioChecked.svg"; @@ -202,6 +911,196 @@ ThemeParams classicThemeParams() params.helpAboutDialogParams.headingColor = QColor(0x302f2d); params.helpAboutDialogParams.linkColor = QColor(0xC19441); + WhatsNewDialogParams wnp; + wnp.backgroundColor = QColor(0x2A2A2A); + wnp.headerTextColor = QColor(0xE0E0E0); + wnp.versionTextColor = QColor(0x858585); + wnp.contentTextColor = QColor(0xE0E0E0); + wnp.linkColor = QColor(0xE8B800); + wnp.closeButtonColor = QColor(0xDDDDDD); + wnp.headerDecorationColor = QColor(0xE8B800); + params.whatsNewDialogParams = wnp; + + EmptyContainerParams ec; + ec.backgroundColor = QColor(0x2A2A2A); + ec.titleTextColor = QColor(0xCCCCCC); + ec.textColor = QColor(0xCCCCCC); + ec.descriptionTextColor = QColor(0xAAAAAA); + ec.searchIconColor = QColor(0x4C4C4C); + ec.t = EmptyContainerThemeTemplates(); + params.emptyContainerParams = ec; + + SidebarParams sb; + sb.useStyledSplitter = true; + sb.backgroundColor = QColor(0x454545); + sb.separatorColor = QColor(0xBDBFBF); + sb.sectionSeparatorColor = QColor(0x575757); + sb.splitterBackgroundColor = QColor(0x454545); + sb.splitterHeight = 39; + sb.uppercaseLabels = true; + sb.titleTextColor = QColor(0xBDBFBF); + sb.titleDropShadowColor = Qt::black; + sb.busyIndicatorColor = Qt::white; + params.sidebarParams = sb; + + ImportWidgetParams iw; + iw.backgroundColor = QColor(0x2A2A2A); + iw.titleTextColor = QColor(0xCCCCCC); + iw.descriptionTextColor = QColor(0xAAAAAA); + iw.currentComicTextColor = QColor(0xAAAAAA); + iw.coversViewBackgroundColor = QColor(0x3A3A3A); + iw.coversLabelColor = QColor(0xAAAAAA); + iw.coversDecorationBgColor = QColor(0x3A3A3A); + iw.coversDecorationShadowColor = QColor(0x1A1A1A); + iw.modeIconColor = QColor(0x4A4A4A); + iw.iconColor = QColor(0xCCCCCC); + iw.iconCheckedColor = QColor(0xAAAAAA); + params.importWidgetParams = iw; + + TreeViewParams tv; + tv.useStyledTemplate = true; + tv.textColor = QColor(0xDDDFDF); + tv.selectionBackgroundColor = QColor(0x2E2E2E); + tv.scrollBackgroundColor = QColor(0x404040); + tv.scrollHandleColor = QColor(0xDDDDDD); + tv.selectedTextColor = Qt::white; + tv.folderIndicatorColor = QColor(237, 197, 24); + params.treeViewParams = tv; + + TableViewParams tav; + tav.alternateBackgroundColor = QColor(0xF2F2F2); + tav.backgroundColor = QColor(0xFAFAFA); + tav.cornerButtonBackgroundColor = QColor(0xF5F5F5); + tav.cornerButtonBorderColor = QColor(0xB8BDC4); + tav.cornerButtonGradientColor = QColor(0xD1D1D1); + tav.itemBorderBottomColor = QColor(0xDFDFDF); + tav.itemBorderTopColor = QColor(0xFEFEFE); + tav.itemTextColor = QColor(0x252626); + tav.selectedColor = QColor(0xD4D4D4); + tav.selectedTextColor = QColor(0x252626); + tav.headerTextColor = QColor(0x313232); + tav.starRatingColor = QColor(0xE9BE0F); + tav.starRatingSelectedColor = QColor(0xFFFFFF); + tav.t = TableViewThemeTemplates(); + params.tableViewParams = tav; + + QmlViewParams qv; + qv.backgroundColor = QColor(0x2A2A2A); + qv.cellColor = QColor(0x212121); + qv.cellColorWithBackground = QColor(0x21, 0x21, 0x21, 0x99); + qv.selectedColor = QColor(0x121212); + qv.selectedBorderColor = QColor(0xFFCC00); + qv.borderColor = QColor(0x121212); + qv.titleColor = QColor(0xFFFFFF); + qv.textColor = QColor(0xA8A8A8); + qv.showDropShadow = true; + qv.infoBackgroundColor = QColor(0x2E2E2E); + qv.topShadow = "info-top-shadow.png"; + qv.infoShadow = "info-shadow.png"; + qv.infoIndicator = "info-indicator.png"; + qv.infoTextColor = QColor(0xB0B0B0); + qv.infoTitleColor = QColor(0xFFFFFF); + qv.ratingUnselectedColor = QColor(0x1C1C1C); + qv.ratingSelectedColor = QColor(0xFFFFFF); + qv.favUncheckedColor = QColor(0x1C1C1C); + qv.favCheckedColor = QColor(0xE84852); + qv.readTickUncheckedColor = QColor(0x1C1C1C); + qv.readTickCheckedColor = QColor(0xE84852); + qv.currentComicBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); + qv.continueReadingBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); + qv.continueReadingColor = QColor(0xFFFFFF); + params.qmlViewParams = qv; + + MainToolbarParams mt; + mt.backgroundColor = QColor(0xF0F0F0); + mt.folderNameColor = QColor(0x404040); + mt.dividerColor = QColor(0xB8BDC4); + mt.iconColor = QColor(0x404040); + mt.iconDisabledColor = QColor(0xB0B0B0); + params.mainToolbarParams = mt; + + ContentSplitterParams cs; + cs.handleColor = QColor(0xB8B8B8); + cs.horizontalHandleHeight = 4; + cs.verticalHandleWidth = 4; + params.contentSplitterParams = cs; + + SidebarIconsParams si; + si.iconColor = QColor(0xE0E0E0); + si.shadowColor = QColor(0xFF000000); + si.extraColor = QColor(0x464646); + si.useSystemFolderIcons = false; + params.sidebarIconsParams = si; + + LibraryItemParams li; + li.textColor = QColor(0xDDDFDF); + li.selectedTextColor = Qt::white; + li.selectedBackgroundColor = QColor(0x2E2E2E); + li.libraryIconSelectedColor = Qt::white; + li.libraryOptionsIconColor = Qt::white; + params.libraryItemParams = li; + + ComicsViewToolbarParams cvt; + cvt.checkedBackgroundColor = QColor(0xCCCCCC); + cvt.iconColor = QColor(0x404040); + params.comicsViewToolbarParams = cvt; + + SearchLineEditParams sle; + sle.textColor = QColor(0xABABAB); + sle.backgroundColor = QColor(0x404040); + sle.iconColor = QColor(0xF7F7F7); + params.searchLineEditParams = sle; + + ReadingListIconsParams rli; + rli.labelColors = { + { "red", QColor(0xf67a7b) }, + { "orange", QColor(0xf5c240) }, + { "yellow", QColor(0xf2e446) }, + { "green", QColor(0xade738) }, + { "cyan", QColor(0xa0fddb) }, + { "blue", QColor(0x82c7ff) }, + { "violet", QColor(0x8f95ff) }, + { "purple", QColor(0xd692fc) }, + { "pink", QColor(0xfd9cda) }, + { "white", QColor(0xfcfcfc) }, + { "light", QColor(0xcbcbcb) }, + { "dark", QColor(0xb7b7b7) } + }; + rli.labelShadowColor = Qt::black; + rli.readingListMainColor = QColor(0xe7e7e7); + rli.favoritesMainColor = QColor(0xe15055); + rli.currentlyReadingMainColor = QColor(0xffcc00); + rli.currentlyReadingOuterColor = Qt::black; + rli.specialListShadowColor = Qt::black; + rli.listMainColor = QColor(0xe7e7e7); + rli.listShadowColor = Qt::black; + rli.listDetailColor = QColor(0x464646); + params.readingListIconsParams = rli; + + MenuIconsParams mi; + mi.iconColor = QColor(0xF7F7F7); + params.menuIconsParams = mi; + + DialogIconsParams dip; + dip.iconColor = mi.iconColor; + params.dialogIconsParams = dip; + + ShortcutsIconsParams sci; + sci.iconColor = QColor(0xF7F7F7); + params.shortcutsIconsParams = sci; + + ServerConfigDialogParams scd; + scd.backgroundColor = QColor(0x2A2A2A); + scd.titleTextColor = QColor(0x474747); + scd.qrMessageTextColor = QColor(0xA3A3A3); + scd.propagandaTextColor = QColor(0x4D4D4D); + scd.labelTextColor = QColor(0x575757); + scd.checkBoxTextColor = QColor(0x262626); + scd.qrBackgroundColor = QColor(0x2A2A2A); + scd.qrForegroundColor = Qt::white; + scd.decorationColor = QColor(0xF7F7F7); + params.serverConfigDialogParams = scd; + return params; } @@ -209,6 +1108,7 @@ ThemeParams lightThemeParams() { ThemeParams params; params.themeName = "light"; + params.defaultContentBackgroundColor = QColor(0xFFFFFF); ComicFlowColors cf; cf.backgroundColor = Qt::white; @@ -266,6 +1166,196 @@ ThemeParams lightThemeParams() params.helpAboutDialogParams.headingColor = QColor(0x302f2d); params.helpAboutDialogParams.linkColor = QColor(0xC19441); + WhatsNewDialogParams wnp; + wnp.backgroundColor = QColor(0xFFFFFF); + wnp.headerTextColor = QColor(0x0A0A0A); + wnp.versionTextColor = QColor(0x858585); + wnp.contentTextColor = QColor(0x0A0A0A); + wnp.linkColor = QColor(0xE8B800); + wnp.closeButtonColor = QColor(0x444444); + wnp.headerDecorationColor = QColor(0xE8B800); + params.whatsNewDialogParams = wnp; + + EmptyContainerParams ec; + ec.backgroundColor = QColor(0xFFFFFF); + ec.titleTextColor = QColor(0x888888); + ec.textColor = QColor(0x495252); + ec.descriptionTextColor = QColor(0x565959); + ec.searchIconColor = QColor(0xCCCCCC); + ec.t = EmptyContainerThemeTemplates(); + params.emptyContainerParams = ec; + + SidebarParams sb; + sb.useStyledSplitter = true; + sb.backgroundColor = QColor(0xF1F1F1); + sb.separatorColor = QColor(0x808080); + sb.sectionSeparatorColor = QColor(0xD0D0D0); + sb.splitterBackgroundColor = QColor(0xF1F1F1); + sb.splitterHeight = 39; + sb.uppercaseLabels = true; + sb.titleTextColor = QColor(0x808080); + sb.titleDropShadowColor = QColor(0xFFFFFF); + sb.busyIndicatorColor = QColor(0x808080); + params.sidebarParams = sb; + + ImportWidgetParams iw; + iw.backgroundColor = QColor(0xFAFAFA); + iw.titleTextColor = QColor(0x495252); + iw.descriptionTextColor = QColor(0x565959); + iw.currentComicTextColor = QColor(0x565959); + iw.coversViewBackgroundColor = QColor(0xE6E6E6); + iw.coversLabelColor = QColor(0x565959); + iw.coversDecorationBgColor = QColor(0xE6E6E6); + iw.coversDecorationShadowColor = QColor(0xA1A1A1); + iw.modeIconColor = QColor(0xE6E6E6); + iw.iconColor = QColor(0x495252); + iw.iconCheckedColor = QColor(0x565959); + params.importWidgetParams = iw; + + TreeViewParams tv; + tv.useStyledTemplate = true; + tv.textColor = Qt::black; + tv.selectionBackgroundColor = QColor(0xD0D0D0); + tv.scrollBackgroundColor = QColor(0xE0E0E0); + tv.scrollHandleColor = QColor(0x888888); + tv.selectedTextColor = QColor(0x1A1A1A); + tv.folderIndicatorColor = QColor(85, 95, 127); + params.treeViewParams = tv; + + TableViewParams tav; + tav.alternateBackgroundColor = QColor(0xF2F2F2); + tav.backgroundColor = QColor(0xFAFAFA); + tav.cornerButtonBackgroundColor = QColor(0xF5F5F5); + tav.cornerButtonBorderColor = QColor(0xB8BDC4); + tav.cornerButtonGradientColor = QColor(0xD1D1D1); + tav.itemBorderBottomColor = QColor(0xDFDFDF); + tav.itemBorderTopColor = QColor(0xFEFEFE); + tav.itemTextColor = QColor(0x252626); + tav.selectedColor = QColor(0x3875D7); + tav.selectedTextColor = QColor(0xFFFFFF); + tav.headerTextColor = QColor(0x313232); + tav.starRatingColor = QColor(0xE9BE0F); + tav.starRatingSelectedColor = QColor(0xFFFFFF); + tav.t = TableViewThemeTemplates(); + params.tableViewParams = tav; + + QmlViewParams qv; + qv.backgroundColor = QColor(0xF6F6F6); + qv.cellColor = QColor(0xFFFFFF); + qv.cellColorWithBackground = QColor(0xFF, 0xFF, 0xFF, 0x99); + qv.selectedColor = QColor(0xFFFFFF); + qv.selectedBorderColor = QColor(0xFFCC00); + qv.borderColor = QColor(0xDBDBDB); + qv.titleColor = QColor(0x121212); + qv.textColor = QColor(0x636363); + qv.showDropShadow = true; + qv.infoBackgroundColor = QColor(0xFFFFFF); + qv.topShadow = ""; + qv.infoShadow = "info-shadow-light.png"; + qv.infoIndicator = "info-indicator-light.png"; + qv.infoTextColor = QColor(0x404040); + qv.infoTitleColor = QColor(0x2E2E2E); + qv.ratingUnselectedColor = QColor(0xDEDEDE); + qv.ratingSelectedColor = QColor(0x2B2B2B); + qv.favUncheckedColor = QColor(0xDEDEDE); + qv.favCheckedColor = QColor(0xE84852); + qv.readTickUncheckedColor = QColor(0xDEDEDE); + qv.readTickCheckedColor = QColor(0xE84852); + qv.currentComicBackgroundColor = QColor(0xFF, 0xFF, 0xFF, 0x88); + qv.continueReadingBackgroundColor = QColor(0xE8E8E8); + qv.continueReadingColor = QColor::fromRgb(0x000000); + params.qmlViewParams = qv; + + MainToolbarParams mt; + mt.backgroundColor = QColor(0xF0F0F0); + mt.folderNameColor = QColor(0x404040); + mt.dividerColor = QColor(0xB8BDC4); + mt.iconColor = QColor(0x404040); + mt.iconDisabledColor = QColor(0xB0B0B0); + params.mainToolbarParams = mt; + + ContentSplitterParams cs; + cs.handleColor = QColor(0xB8B8B8); + cs.horizontalHandleHeight = 4; + cs.verticalHandleWidth = 4; + params.contentSplitterParams = cs; + + SidebarIconsParams si; + si.iconColor = QColor(0x606060); + si.shadowColor = QColor(0xFFFFFF); + si.extraColor = QColor(0xFFFFFF); + si.useSystemFolderIcons = false; + params.sidebarIconsParams = si; + + LibraryItemParams li; + li.textColor = QColor(0x404040); + li.selectedTextColor = QColor(0x1A1A1A); + li.selectedBackgroundColor = QColor(0xD0D0D0); + li.libraryIconSelectedColor = QColor(0x404040); + li.libraryOptionsIconColor = QColor(0x404040); + params.libraryItemParams = li; + + ComicsViewToolbarParams cvt; + cvt.checkedBackgroundColor = QColor(0xCCCCCC); + cvt.iconColor = QColor(0x404040); + params.comicsViewToolbarParams = cvt; + + SearchLineEditParams sle; + sle.textColor = QColor(0x606060); + sle.backgroundColor = QColor(0xE0E0E0); + sle.iconColor = QColor(0x808080); + params.searchLineEditParams = sle; + + ReadingListIconsParams rli; + rli.labelColors = { + { "red", QColor(0xf67a7b) }, + { "orange", QColor(0xf5c240) }, + { "yellow", QColor(0xf2e446) }, + { "green", QColor(0xade738) }, + { "cyan", QColor(0xa0fddb) }, + { "blue", QColor(0x82c7ff) }, + { "violet", QColor(0x8f95ff) }, + { "purple", QColor(0xd692fc) }, + { "pink", QColor(0xfd9cda) }, + { "white", QColor(0xfcfcfc) }, + { "light", QColor(0xcbcbcb) }, + { "dark", QColor(0xb7b7b7) } + }; + rli.labelShadowColor = QColor(0xa0a0a0); + rli.readingListMainColor = QColor(0x808080); + rli.favoritesMainColor = QColor(0xe15055); + rli.currentlyReadingMainColor = QColor(0xffcc00); + rli.currentlyReadingOuterColor = Qt::black; + rli.specialListShadowColor = QColor(0xa0a0a0); + rli.listMainColor = QColor(0x808080); + rli.listShadowColor = QColor(0xc0c0c0); + rli.listDetailColor = QColor(0xFFFFFF); + params.readingListIconsParams = rli; + + MenuIconsParams mi; + mi.iconColor = QColor(0x606060); + params.menuIconsParams = mi; + + DialogIconsParams dip; + dip.iconColor = mi.iconColor; + params.dialogIconsParams = dip; + + ShortcutsIconsParams sci; + sci.iconColor = QColor(0x606060); + params.shortcutsIconsParams = sci; + + ServerConfigDialogParams scd; + scd.backgroundColor = QColor(0xFFFFFF); + scd.titleTextColor = QColor(0x474747); + scd.qrMessageTextColor = QColor(0xA3A3A3); + scd.propagandaTextColor = QColor(0x4D4D4D); + scd.labelTextColor = QColor(0x575757); + scd.checkBoxTextColor = QColor(0x262626); + scd.qrBackgroundColor = Qt::white; + scd.qrForegroundColor = QColor(0x606060); + scd.decorationColor = QColor(0x606060); + params.serverConfigDialogParams = scd; + return params; } @@ -273,6 +1363,7 @@ ThemeParams darkThemeParams() { ThemeParams params; params.themeName = "dark"; + params.defaultContentBackgroundColor = QColor(0x2A2A2A); ComicFlowColors cf; cf.backgroundColor = QColor(0x111111); @@ -304,7 +1395,7 @@ ThemeParams darkThemeParams() cv.buttonTextColor = Qt::white; cv.buttonBorderColor = QColor(0x242424); - cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.png"; + cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.svg"; cv.radioUncheckedColor = QColor(0xE5E5E5); cv.radioCheckedPath = ":/images/comic_vine/radioChecked.svg"; @@ -330,5 +1421,195 @@ ThemeParams darkThemeParams() params.helpAboutDialogParams.headingColor = QColor(0xE0E0E0); params.helpAboutDialogParams.linkColor = QColor(0xD4A84B); + WhatsNewDialogParams wnp; + wnp.backgroundColor = QColor(0x2A2A2A); + wnp.headerTextColor = QColor(0xE0E0E0); + wnp.versionTextColor = QColor(0x858585); + wnp.contentTextColor = QColor(0xE0E0E0); + wnp.linkColor = QColor(0xE8B800); + wnp.closeButtonColor = QColor(0xDDDDDD); + wnp.headerDecorationColor = QColor(0xE8B800); + params.whatsNewDialogParams = wnp; + + EmptyContainerParams ec; + ec.backgroundColor = QColor(0x2A2A2A); + ec.titleTextColor = QColor(0xCCCCCC); + ec.textColor = QColor(0xCCCCCC); + ec.descriptionTextColor = QColor(0xAAAAAA); + ec.searchIconColor = QColor(0x4C4C4C); + ec.t = EmptyContainerThemeTemplates(); + params.emptyContainerParams = ec; + + SidebarParams sb; + sb.useStyledSplitter = true; + sb.backgroundColor = QColor(0x454545); + sb.separatorColor = QColor(0xBDBFBF); + sb.sectionSeparatorColor = QColor(0x575757); + sb.splitterBackgroundColor = QColor(0x454545); + sb.splitterHeight = 39; + sb.uppercaseLabels = true; + sb.titleTextColor = QColor(0xBDBFBF); + sb.titleDropShadowColor = Qt::black; + sb.busyIndicatorColor = Qt::white; + params.sidebarParams = sb; + + ImportWidgetParams iw; + iw.backgroundColor = QColor(0x2A2A2A); + iw.titleTextColor = QColor(0xCCCCCC); + iw.descriptionTextColor = QColor(0xAAAAAA); + iw.currentComicTextColor = QColor(0xAAAAAA); + iw.coversViewBackgroundColor = QColor(0x3A3A3A); + iw.coversLabelColor = QColor(0xAAAAAA); + iw.coversDecorationBgColor = QColor(0x3A3A3A); + iw.coversDecorationShadowColor = QColor(0x1A1A1A); + iw.modeIconColor = QColor(0x4A4A4A); + iw.iconColor = QColor(0xCCCCCC); + iw.iconCheckedColor = QColor(0xAAAAAA); + params.importWidgetParams = iw; + + TreeViewParams tv; + tv.useStyledTemplate = true; + tv.textColor = QColor(0xDDDFDF); + tv.selectionBackgroundColor = QColor(0x2E2E2E); + tv.scrollBackgroundColor = QColor(0x404040); + tv.scrollHandleColor = QColor(0xDDDDDD); + tv.selectedTextColor = Qt::white; + tv.folderIndicatorColor = QColor(237, 197, 24); + params.treeViewParams = tv; + + TableViewParams tav; + tav.alternateBackgroundColor = QColor(0x2E2E2E); + tav.backgroundColor = QColor(0x2A2A2A); + tav.cornerButtonBackgroundColor = QColor(0x2A2A2A); + tav.cornerButtonBorderColor = QColor(0x1F1F1F); + tav.cornerButtonGradientColor = QColor(0x252525); + tav.itemBorderBottomColor = QColor(0x1F1F1F); + tav.itemBorderTopColor = QColor(0x353535); + tav.itemTextColor = QColor(0xDDDDDD); + tav.selectedColor = QColor(0x555555); + tav.selectedTextColor = QColor(0xFFFFFF); + tav.headerTextColor = QColor(0xDDDDDD); + tav.starRatingColor = QColor(0xE9BE0F); + tav.starRatingSelectedColor = QColor(0xFFFFFF); + tav.t = TableViewThemeTemplates(); + params.tableViewParams = tav; + + QmlViewParams qv; + qv.backgroundColor = QColor(0x2A2A2A); + qv.cellColor = QColor(0x212121); + qv.cellColorWithBackground = QColor(0x21, 0x21, 0x21, 0x99); + qv.selectedColor = QColor(0x121212); + qv.selectedBorderColor = QColor(0xFFCC00); + qv.borderColor = QColor(0x121212); + qv.titleColor = QColor(0xFFFFFF); + qv.textColor = QColor(0xA8A8A8); + qv.showDropShadow = true; + qv.infoBackgroundColor = QColor(0x2E2E2E); + qv.topShadow = "info-top-shadow.png"; + qv.infoShadow = "info-shadow.png"; + qv.infoIndicator = "info-indicator.png"; + qv.infoTextColor = QColor(0xB0B0B0); + qv.infoTitleColor = QColor(0xFFFFFF); + qv.ratingUnselectedColor = QColor(0x1C1C1C); + qv.ratingSelectedColor = QColor(0xFFFFFF); + qv.favUncheckedColor = QColor(0x1C1C1C); + qv.favCheckedColor = QColor(0xE84852); + qv.readTickUncheckedColor = QColor(0x1C1C1C); + qv.readTickCheckedColor = QColor(0xE84852); + qv.currentComicBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); + qv.continueReadingBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); + qv.continueReadingColor = QColor(0xFFFFFF); + params.qmlViewParams = qv; + + MainToolbarParams mt; + mt.backgroundColor = QColor(0x2A2A2A); + mt.folderNameColor = QColor(0xDDDDDD); + mt.dividerColor = QColor(0x555555); + mt.iconColor = QColor(0xDDDDDD); + mt.iconDisabledColor = QColor(0x666666); + params.mainToolbarParams = mt; + + ContentSplitterParams cs; + cs.handleColor = QColor(0x1F1F1F); + cs.horizontalHandleHeight = 4; + cs.verticalHandleWidth = 4; + params.contentSplitterParams = cs; + + SidebarIconsParams si; + si.iconColor = QColor(0xE0E0E0); + si.shadowColor = QColor(0xFF000000); + si.extraColor = QColor(0x222222); + si.useSystemFolderIcons = false; + params.sidebarIconsParams = si; + + LibraryItemParams li; + li.textColor = QColor(0xDDDFDF); + li.selectedTextColor = Qt::white; + li.selectedBackgroundColor = QColor(0x2E2E2E); + li.libraryIconSelectedColor = Qt::white; + li.libraryOptionsIconColor = Qt::white; + params.libraryItemParams = li; + + ComicsViewToolbarParams cvt; + cvt.checkedBackgroundColor = QColor(0x555555); + cvt.iconColor = QColor(0xDDDDDD); + params.comicsViewToolbarParams = cvt; + + SearchLineEditParams sle; + sle.textColor = QColor(0xABABAB); + sle.backgroundColor = QColor(0x404040); + sle.iconColor = QColor(0xF7F7F7); + params.searchLineEditParams = sle; + + ReadingListIconsParams rli; + rli.labelColors = { + { "red", QColor(0xf67a7b) }, + { "orange", QColor(0xf5c240) }, + { "yellow", QColor(0xf2e446) }, + { "green", QColor(0xade738) }, + { "cyan", QColor(0xa0fddb) }, + { "blue", QColor(0x82c7ff) }, + { "violet", QColor(0x8f95ff) }, + { "purple", QColor(0xd692fc) }, + { "pink", QColor(0xfd9cda) }, + { "white", QColor(0xfcfcfc) }, + { "light", QColor(0xcbcbcb) }, + { "dark", QColor(0xb7b7b7) } + }; + rli.labelShadowColor = Qt::black; + rli.readingListMainColor = QColor(0xe7e7e7); + rli.favoritesMainColor = QColor(0xe15055); + rli.currentlyReadingMainColor = QColor(0xffcc00); + rli.currentlyReadingOuterColor = Qt::black; + rli.specialListShadowColor = Qt::black; + rli.listMainColor = QColor(0xe7e7e7); + rli.listShadowColor = Qt::black; + rli.listDetailColor = QColor(0x464646); + params.readingListIconsParams = rli; + + MenuIconsParams mi; + mi.iconColor = QColor(0xF7F7F7); + params.menuIconsParams = mi; + + DialogIconsParams dip; + dip.iconColor = mi.iconColor; + params.dialogIconsParams = dip; + + ShortcutsIconsParams sci; + sci.iconColor = QColor(0xF7F7F7); + params.shortcutsIconsParams = sci; + + ServerConfigDialogParams scd; + scd.backgroundColor = QColor(0x2A2A2A); + scd.titleTextColor = QColor(0xD0D0D0); + scd.qrMessageTextColor = QColor(0xA3A3A3); + scd.propagandaTextColor = QColor(0xB0B0B0); + scd.labelTextColor = QColor(0xC0C0C0); + scd.checkBoxTextColor = QColor(0xDDDDDD); + scd.qrBackgroundColor = QColor(0x2A2A2A); + scd.qrForegroundColor = Qt::white; + scd.decorationColor = QColor(0xF7F7F7); + params.serverConfigDialogParams = scd; + return params; } diff --git a/YACReaderLibrary/yacreader_content_views_manager.cpp b/YACReaderLibrary/yacreader_content_views_manager.cpp index e2597cb1e..b36f33d65 100644 --- a/YACReaderLibrary/yacreader_content_views_manager.cpp +++ b/YACReaderLibrary/yacreader_content_views_manager.cpp @@ -10,6 +10,7 @@ #include "empty_label_widget.h" #include "empty_special_list.h" #include "empty_reading_list_widget.h" +#include "empty_folder_widget.h" #include "no_search_results_widget.h" #include "yacreader_sidebar.h" @@ -17,6 +18,7 @@ //-- #include "yacreader_search_line_edit.h" #include "options_dialog.h" +#include "theme_manager.h" YACReaderContentViewsManager::YACReaderContentViewsManager(QSettings *settings, LibraryWindow *parent) : QObject(parent), libraryWindow(parent), classicComicsView(nullptr), gridComicsView(nullptr), infoComicsView(nullptr) @@ -50,6 +52,7 @@ YACReaderContentViewsManager::YACReaderContentViewsManager(QSettings *settings, comicsViewStack->addWidget(emptyLabelWidget = new EmptyLabelWidget()); comicsViewStack->addWidget(emptySpecialList = new EmptySpecialListWidget()); comicsViewStack->addWidget(emptyReadingList = new EmptyReadingListWidget()); + comicsViewStack->addWidget(emptyFolderWidget = new EmptyFolderWidget()); comicsViewStack->addWidget(noSearchResultsWidget = new NoSearchResultsWidget()); comicsViewStack->addWidget(comicsView); @@ -60,6 +63,8 @@ YACReaderContentViewsManager::YACReaderContentViewsManager(QSettings *settings, connect(folderContentView, &FolderContentView::copyComicsToCurrentFolder, libraryWindow, &LibraryWindow::copyAndImportComicsToCurrentFolder); connect(folderContentView, &FolderContentView::moveComicsToCurrentFolder, libraryWindow, &LibraryWindow::moveAndImportComicsToCurrentFolder); connect(libraryWindow->optionsDialog, &YACReaderOptionsDialog::optionsChanged, folderContentView, &FolderContentView::updateSettings); + + initTheme(this); } QWidget *YACReaderContentViewsManager::containerWidget() @@ -152,6 +157,11 @@ void YACReaderContentViewsManager::showEmptyReadingListWidget() comicsViewStack->setCurrentWidget(emptyReadingList); } +void YACReaderContentViewsManager::showEmptyFolderWidget() +{ + comicsViewStack->setCurrentWidget(emptyFolderWidget); +} + void YACReaderContentViewsManager::showNoSearchResultsView() { comicsViewStack->setCurrentWidget(noSearchResultsWidget); @@ -235,10 +245,11 @@ void YACReaderContentViewsManager::showComicsViewTransition() void YACReaderContentViewsManager::_toggleComicsView() { + const auto &mainToolbar = theme.mainToolbar; + switch (comicsViewStatus) { case Flow: { - QIcon icoViewsButton; - icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/info"), QSize(), QIcon::Normal); + QIcon icoViewsButton = mainToolbar.infoIcon; libraryWindow->actions.toggleComicsViewAction->setIcon(icoViewsButton); #ifdef Y_MAC_UI libraryWindow->libraryToolBar->updateViewSelectorIcon(icoViewsButton); @@ -255,8 +266,7 @@ void YACReaderContentViewsManager::_toggleComicsView() } case Grid: { - QIcon icoViewsButton; - icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/flow"), QSize(), QIcon::Normal); + QIcon icoViewsButton = mainToolbar.flowIcon; libraryWindow->actions.toggleComicsViewAction->setIcon(icoViewsButton); #ifdef Y_MAC_UI libraryWindow->libraryToolBar->updateViewSelectorIcon(icoViewsButton); @@ -271,8 +281,7 @@ void YACReaderContentViewsManager::_toggleComicsView() } case Info: { - QIcon icoViewsButton; - icoViewsButton.addFile(addExtensionToIconPath(":/images/main_toolbar/grid"), QSize(), QIcon::Normal); + QIcon icoViewsButton = mainToolbar.gridIcon; libraryWindow->actions.toggleComicsViewAction->setIcon(icoViewsButton); #ifdef Y_MAC_UI libraryWindow->libraryToolBar->updateViewSelectorIcon(icoViewsButton); @@ -292,3 +301,28 @@ void YACReaderContentViewsManager::_toggleComicsView() if (comicsViewStack->currentWidget() == comicsViewTransition) showComicsView(); } + +void YACReaderContentViewsManager::applyTheme(const Theme &theme) +{ + const auto &mainToolbar = theme.mainToolbar; + + // Update the toggle button icon based on current view status + // The icon shows what the NEXT view will be when clicked + QIcon icon; + switch (comicsViewStatus) { + case Flow: + icon = mainToolbar.gridIcon; + break; + case Grid: + icon = mainToolbar.infoIcon; + break; + case Info: + icon = mainToolbar.flowIcon; + break; + } + + libraryWindow->actions.toggleComicsViewAction->setIcon(icon); +#ifdef Y_MAC_UI + libraryWindow->libraryToolBar->updateViewSelectorIcon(icon); +#endif +} diff --git a/YACReaderLibrary/yacreader_content_views_manager.h b/YACReaderLibrary/yacreader_content_views_manager.h index 67119a0bf..8ef45fd17 100644 --- a/YACReaderLibrary/yacreader_content_views_manager.h +++ b/YACReaderLibrary/yacreader_content_views_manager.h @@ -4,6 +4,7 @@ #include #include "yacreader_global_gui.h" +#include "themable.h" class LibraryWindow; @@ -16,11 +17,12 @@ class FolderContentView; class EmptyLabelWidget; class EmptySpecialListWidget; class EmptyReadingListWidget; +class EmptyFolderWidget; class NoSearchResultsWidget; using namespace YACReader; -class YACReaderContentViewsManager : public QObject +class YACReaderContentViewsManager : public QObject, protected Themable { Q_OBJECT public: @@ -36,6 +38,7 @@ class YACReaderContentViewsManager : public QObject EmptyLabelWidget *emptyLabelWidget; EmptySpecialListWidget *emptySpecialList; EmptyReadingListWidget *emptyReadingList; + EmptyFolderWidget *emptyFolderWidget; NoSearchResultsWidget *noSearchResultsWidget; @@ -56,6 +59,8 @@ class YACReaderContentViewsManager : public QObject GridComicsView *gridComicsView; InfoComicsView *infoComicsView; + void applyTheme(const Theme &theme) override; + signals: public slots: @@ -67,6 +72,7 @@ public slots: void showEmptyLabelView(); void showEmptySpecialList(); void showEmptyReadingListWidget(); + void showEmptyFolderWidget(); void showNoSearchResultsView(); protected slots: diff --git a/YACReaderLibrary/yacreader_folders_view.cpp b/YACReaderLibrary/yacreader_folders_view.cpp index c042a6e60..57f6f5b84 100644 --- a/YACReaderLibrary/yacreader_folders_view.cpp +++ b/YACReaderLibrary/yacreader_folders_view.cpp @@ -1,6 +1,7 @@ #include "yacreader_folders_view.h" #include "yacreader_global.h" +#include "yacreader_treeview.h" #include "folder_item.h" #include "folder_model.h" @@ -80,13 +81,15 @@ YACReaderFoldersViewItemDeletegate::YACReaderFoldersViewItemDeletegate(QObject * void YACReaderFoldersViewItemDeletegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { + // Get indicator color from parent tree view + QColor indicatorColor(237, 197, 24); // Default fallback + if (auto treeView = qobject_cast(parent())) { + indicatorColor = treeView->folderIndicatorColor(); + } + if (!index.data(FolderModel::CompletedRole).toBool()) { painter->save(); -#ifdef Y_MAC_UI - painter->setBrush(QBrush(QColor(85, 95, 127))); -#else - painter->setBrush(QBrush(QColor(237, 197, 24))); -#endif + painter->setBrush(QBrush(indicatorColor)); painter->setPen(QPen(QBrush(), 0)); painter->drawRect(0, option.rect.y(), 2, option.rect.height()); painter->restore(); @@ -105,11 +108,7 @@ void YACReaderFoldersViewItemDeletegate::paint(QPainter *painter, const QStyleOp if (now - added < daysInSeconds || now - updated < daysInSeconds) { painter->save(); painter->setRenderHint(QPainter::Antialiasing); -#ifdef Y_MAC_UI - painter->setBrush(QBrush(QColor(85, 95, 127))); -#else - painter->setBrush(QBrush(QColor(237, 197, 24))); -#endif + painter->setBrush(QBrush(indicatorColor)); painter->setPen(QPen(QBrush(), 0)); painter->drawEllipse(option.rect.x() + 13, option.rect.y() + 2, 7, 7); painter->restore(); diff --git a/YACReaderLibrary/yacreader_main_toolbar.cpp b/YACReaderLibrary/yacreader_main_toolbar.cpp index c879ef6f5..93a76a10b 100644 --- a/YACReaderLibrary/yacreader_main_toolbar.cpp +++ b/YACReaderLibrary/yacreader_main_toolbar.cpp @@ -14,8 +14,6 @@ YACReaderMainToolBar::YACReaderMainToolBar(QWidget *parent) mainLayout = new QHBoxLayout; currentFolder = new QLabel(this); - // currentFolder->setAlignment(Qt::AlignCenter); - currentFolder->setStyleSheet(" QLabel {color:#404040; font-size:22px; font-weight:bold;}"); QFont f = currentFolder->font(); f.setStyleStrategy(QFont::PreferAntialias); @@ -76,6 +74,8 @@ YACReaderMainToolBar::YACReaderMainToolBar(QWidget *parent) setLayout(mainLayout); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + initTheme(this); } QSize YACReaderMainToolBar::sizeHint() const @@ -95,7 +95,7 @@ void YACReaderMainToolBar::paintEvent(QPaintEvent *event) Q_UNUSED(event); QPainter painter(this); - painter.fillRect(0, 0, width(), height(), QColor("#F0F0F0")); + painter.fillRect(0, 0, width(), height(), theme.mainToolbar.backgroundColor); } void YACReaderMainToolBar::resizeEvent(QResizeEvent *event) @@ -116,9 +116,9 @@ void YACReaderMainToolBar::resizeEvent(QResizeEvent *event) void YACReaderMainToolBar::addDivider() { - QPixmap img(":/images/main_toolbar/divider.svg"); QLabel *divider = new QLabel(); - divider->setPixmap(img); + divider->setPixmap(theme.mainToolbar.dividerPixmap); + dividers.append(divider); mainLayout->addSpacing(5); mainLayout->addWidget(divider, 0, Qt::AlignVCenter); @@ -149,3 +149,34 @@ void YACReaderMainToolBar::setCurrentFolderName(const QString &name) currentFolder->adjustSize(); currentFolder->move((width() - currentFolder->width()) / 2, (height() - currentFolder->height()) / 2); } + +void YACReaderMainToolBar::applyTheme(const Theme &theme) +{ + const auto &mt = theme.mainToolbar; + + currentFolder->setStyleSheet(mt.folderNameLabelQSS); + + // Update dividers + for (QLabel *divider : dividers) { + divider->setPixmap(mt.dividerPixmap); + } + + // Update action icons via the button's default action + // (buttons get their icons from their default actions when setDefaultAction is called) + if (auto action = backButton->defaultAction()) + action->setIcon(mt.backIcon); + if (auto action = forwardButton->defaultAction()) + action->setIcon(mt.forwardIcon); + if (auto action = settingsButton->defaultAction()) + action->setIcon(mt.settingsIcon); + if (auto action = serverButton->defaultAction()) + action->setIcon(mt.serverIcon); + if (auto action = helpButton->defaultAction()) + action->setIcon(mt.helpIcon); + if (auto action = fullscreenButton->defaultAction()) + action->setIcon(mt.fullscreenIcon); + + // toggleComicsViewButton icon is handled by YACReaderContentViewsManager::applyTheme() + + update(); // Repaint with new background color +} diff --git a/YACReaderLibrary/yacreader_main_toolbar.h b/YACReaderLibrary/yacreader_main_toolbar.h index d010782a8..06d490431 100644 --- a/YACReaderLibrary/yacreader_main_toolbar.h +++ b/YACReaderLibrary/yacreader_main_toolbar.h @@ -3,6 +3,8 @@ #include +#include "themable.h" + class QToolButton; class QLabel; class QResizeEvent; @@ -10,7 +12,7 @@ class QPaintEvent; class QHBoxLayout; // TODO create methods for adding actions, separators and sctreches dynimically -class YACReaderMainToolBar : public QWidget +class YACReaderMainToolBar : public QWidget, protected Themable { Q_OBJECT public: @@ -40,8 +42,13 @@ public slots: QLabel *currentFolder; QString currentFolderName; + QList dividers; + void addDivider(); void addWideDivider(); + +protected: + void applyTheme(const Theme &theme) override; }; #endif // YACREADER_MAIN_TOOLBAR_H diff --git a/YACReaderLibrary/yacreader_navigation_controller.cpp b/YACReaderLibrary/yacreader_navigation_controller.cpp index 9e477fe67..43ab4bee0 100644 --- a/YACReaderLibrary/yacreader_navigation_controller.cpp +++ b/YACReaderLibrary/yacreader_navigation_controller.cpp @@ -64,11 +64,15 @@ void YACReaderNavigationController::loadFolderInfo(const QModelIndex &modelIndex contentViewsManager->comicsView->setModel(libraryWindow->comicsModel); contentViewsManager->showComicsView(); libraryWindow->disableComicsActions(false); - } else { - // showEmptyFolder + } else if (libraryWindow->foldersModel->rowCount(modelIndex) > 0 || !modelIndex.isValid()) { + // folder has subfolders (or is root), show folder content view loadEmptyFolderInfo(modelIndex); contentViewsManager->showFolderContentView(); libraryWindow->disableComicsActions(true); + } else { + // folder has no comics and no subfolders + contentViewsManager->showEmptyFolderWidget(); + libraryWindow->disableComicsActions(true); } // libraryWindow->updateFoldersViewConextMenu(modelIndex); @@ -122,16 +126,13 @@ void YACReaderNavigationController::loadSpecialListInfo(const QModelIndex &model // setup empty special list widget switch (type) { case ReadingListModel::TypeSpecialList::Favorites: - contentViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_favorites.png")); - contentViewsManager->emptySpecialList->setText(tr("No favorites")); + contentViewsManager->emptySpecialList->showFavorites(); break; case ReadingListModel::TypeSpecialList::Reading: - contentViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_current_readings.png")); - contentViewsManager->emptySpecialList->setText(tr("You are not reading anything yet, come on!!")); + contentViewsManager->emptySpecialList->showReading(); break; case ReadingListModel::TypeSpecialList::Recent: - contentViewsManager->emptySpecialList->setPixmap(QPixmap()); - contentViewsManager->emptySpecialList->setText(tr("There are no recent comics!")); + contentViewsManager->emptySpecialList->showRecent(); break; } diff --git a/YACReaderLibrary/yacreaderlibrary_de.ts b/YACReaderLibrary/yacreaderlibrary_de.ts index bf043d2f4..abc2bc5a0 100644 --- a/YACReaderLibrary/yacreaderlibrary_de.ts +++ b/YACReaderLibrary/yacreaderlibrary_de.ts @@ -2815,19 +2815,6 @@ um die Leistung zu verbessern Schließen - - YACReaderDeletingProgress - - - cancel - Abbrechen - - - - Please wait, deleting in progress... - Bitte warten, Löschvorgang läuft... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_en.ts b/YACReaderLibrary/yacreaderlibrary_en.ts index 2540f02e7..0d9528dc1 100644 --- a/YACReaderLibrary/yacreaderlibrary_en.ts +++ b/YACReaderLibrary/yacreaderlibrary_en.ts @@ -2549,19 +2549,6 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - - YACReaderDeletingProgress - - - Please wait, deleting in progress... - - - - - cancel - - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_es.ts b/YACReaderLibrary/yacreaderlibrary_es.ts index c2309aa65..643c55b0d 100644 --- a/YACReaderLibrary/yacreaderlibrary_es.ts +++ b/YACReaderLibrary/yacreaderlibrary_es.ts @@ -2822,19 +2822,6 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Cerrar - - YACReaderDeletingProgress - - - cancel - cancelar - - - - Please wait, deleting in progress... - Borrando, por favor espera... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_fr.ts b/YACReaderLibrary/yacreaderlibrary_fr.ts index abf9377fd..5212a1457 100644 --- a/YACReaderLibrary/yacreaderlibrary_fr.ts +++ b/YACReaderLibrary/yacreaderlibrary_fr.ts @@ -2726,19 +2726,6 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - - YACReaderDeletingProgress - - - cancel - Annuler - - - - Please wait, deleting in progress... - Attendez, suppression en cours... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_it.ts b/YACReaderLibrary/yacreaderlibrary_it.ts index ed29a7c7c..8f32caea7 100644 --- a/YACReaderLibrary/yacreaderlibrary_it.ts +++ b/YACReaderLibrary/yacreaderlibrary_it.ts @@ -2803,19 +2803,6 @@ Migliora le prestazioni! - - YACReaderDeletingProgress - - - cancel - Cancella - - - - Please wait, deleting in progress... - Aspetta, cancellazione in corso... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_nl.ts b/YACReaderLibrary/yacreaderlibrary_nl.ts index e53185efa..c81d99609 100644 --- a/YACReaderLibrary/yacreaderlibrary_nl.ts +++ b/YACReaderLibrary/yacreaderlibrary_nl.ts @@ -2666,19 +2666,6 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - - YACReaderDeletingProgress - - - cancel - annuleren - - - - Please wait, deleting in progress... - Even geduld, verwijderen ... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_pt.ts b/YACReaderLibrary/yacreaderlibrary_pt.ts index f116002c4..add794dd7 100644 --- a/YACReaderLibrary/yacreaderlibrary_pt.ts +++ b/YACReaderLibrary/yacreaderlibrary_pt.ts @@ -2598,19 +2598,6 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - - YACReaderDeletingProgress - - - Please wait, deleting in progress... - - - - - cancel - - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_ru.ts b/YACReaderLibrary/yacreaderlibrary_ru.ts index d99a7977b..306c4972a 100644 --- a/YACReaderLibrary/yacreaderlibrary_ru.ts +++ b/YACReaderLibrary/yacreaderlibrary_ru.ts @@ -2779,19 +2779,6 @@ to improve the performance - - YACReaderDeletingProgress - - - cancel - отменить - - - - Please wait, deleting in progress... - Пожалуйста подождите, удаление в процессе... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_source.ts b/YACReaderLibrary/yacreaderlibrary_source.ts index 87e652144..17e29eea2 100644 --- a/YACReaderLibrary/yacreaderlibrary_source.ts +++ b/YACReaderLibrary/yacreaderlibrary_source.ts @@ -2003,19 +2003,6 @@ to improve the performance - - YACReaderDeletingProgress - - - Please wait, deleting in progress... - - - - - cancel - - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_tr.ts b/YACReaderLibrary/yacreaderlibrary_tr.ts index 2f3463669..04e56a168 100644 --- a/YACReaderLibrary/yacreaderlibrary_tr.ts +++ b/YACReaderLibrary/yacreaderlibrary_tr.ts @@ -2817,19 +2817,6 @@ performansı iyileştirmek için Kapat - - YACReaderDeletingProgress - - - cancel - vazgeç - - - - Please wait, deleting in progress... - Lütfen bekleyin, silme işlemi yapılıyor... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_zh_CN.ts b/YACReaderLibrary/yacreaderlibrary_zh_CN.ts index 0b3755536..dcf002484 100644 --- a/YACReaderLibrary/yacreaderlibrary_zh_CN.ts +++ b/YACReaderLibrary/yacreaderlibrary_zh_CN.ts @@ -2862,19 +2862,6 @@ to improve the performance 关闭 - - YACReaderDeletingProgress - - - cancel - 取消 - - - - Please wait, deleting in progress... - 请稍候,正在删除... - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_zh_HK.ts b/YACReaderLibrary/yacreaderlibrary_zh_HK.ts index 8c1f52aa5..32a397dc5 100644 --- a/YACReaderLibrary/yacreaderlibrary_zh_HK.ts +++ b/YACReaderLibrary/yacreaderlibrary_zh_HK.ts @@ -2827,19 +2827,6 @@ to improve the performance 關閉 - - YACReaderDeletingProgress - - - Please wait, deleting in progress... - 請稍候,正在刪除... - - - - cancel - 取消 - - YACReaderFieldEdit diff --git a/YACReaderLibrary/yacreaderlibrary_zh_TW.ts b/YACReaderLibrary/yacreaderlibrary_zh_TW.ts index f7042bb62..1b66465eb 100644 --- a/YACReaderLibrary/yacreaderlibrary_zh_TW.ts +++ b/YACReaderLibrary/yacreaderlibrary_zh_TW.ts @@ -2827,19 +2827,6 @@ to improve the performance 關閉 - - YACReaderDeletingProgress - - - Please wait, deleting in progress... - 請稍候,正在刪除... - - - - cancel - 取消 - - YACReaderFieldEdit diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index 8ef969ead..93bd88a73 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -1270,9 +1270,8 @@ void YACReaderFlow3D::setTextColor(const QColor &color) { textColor = color; - QPalette palette = indexLabel->palette(); - palette.setColor(QPalette::WindowText, textColor); - indexLabel->setPalette(palette); + auto styleSheet = QString("QLabel { color: %1; }").arg(textColor.name()); + indexLabel->setStyleSheet(styleSheet); update(); } @@ -1424,9 +1423,8 @@ void YACReaderFlow3D::updateIndexLabelStyle() QFont font("Arial", newFontSize); indexLabel->setFont(font); - QPalette palette = indexLabel->palette(); - palette.setColor(QPalette::WindowText, textColor); - indexLabel->setPalette(palette); + auto styleSheet = QString("QLabel { color: %1; }").arg(textColor.name()); + indexLabel->setStyleSheet(styleSheet); indexLabel->move(10, 10); indexLabel->adjustSize(); @@ -1435,9 +1433,7 @@ void YACReaderFlow3D::updateIndexLabelStyle() #if defined(YACREADER_RHI_PERF) if (perfLabel) { perfLabel->setFont(font); - QPalette p = perfLabel->palette(); - p.setColor(QPalette::WindowText, textColor); - perfLabel->setPalette(p); + perfLabel->setStyleSheet(styleSheet); perfLabel->move(10, 10 + indexLabel->height() + 4); perfLabel->adjustSize(); } diff --git a/common/themes/icon_utils.cpp b/common/themes/icon_utils.cpp index bfa0fead9..f0ca5f9d6 100644 --- a/common/themes/icon_utils.cpp +++ b/common/themes/icon_utils.cpp @@ -1,7 +1,28 @@ #include "icon_utils.h" +#include + #include "yacreader_global.h" +QPixmap renderSvgToPixmap(const QString &svgPath, int logicalSize, qreal devicePixelRatio) +{ + return renderSvgToPixmap(svgPath, logicalSize, logicalSize, devicePixelRatio); +} + +QPixmap renderSvgToPixmap(const QString &svgPath, int logicalWidth, int logicalHeight, qreal devicePixelRatio) +{ + const int pixelWidth = qRound(logicalWidth * devicePixelRatio); + const int pixelHeight = qRound(logicalHeight * devicePixelRatio); + QPixmap pixmap(pixelWidth, pixelHeight); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + QSvgRenderer renderer(svgPath); + renderer.render(&painter); + painter.end(); + pixmap.setDevicePixelRatio(devicePixelRatio); + return pixmap; +} + QString readSvg(const QString &resourcePath) { QFile in(resourcePath); diff --git a/common/themes/icon_utils.h b/common/themes/icon_utils.h index 8575590dd..48b4462cc 100644 --- a/common/themes/icon_utils.h +++ b/common/themes/icon_utils.h @@ -3,6 +3,11 @@ #include +// Render an SVG file to a QPixmap at a specific logical size with HiDPI support. +// Uses QSvgRenderer to rasterize directly at the target resolution (no upscaling). +QPixmap renderSvgToPixmap(const QString &svgPath, int logicalSize, qreal devicePixelRatio); +QPixmap renderSvgToPixmap(const QString &svgPath, int logicalWidth, int logicalHeight, qreal devicePixelRatio); + struct RecolorOptions { QString suffix; QString fileName; diff --git a/common/themes/shared/whats_new_dialog_theme.h b/common/themes/shared/whats_new_dialog_theme.h new file mode 100644 index 000000000..cd8829572 --- /dev/null +++ b/common/themes/shared/whats_new_dialog_theme.h @@ -0,0 +1,17 @@ +#ifndef WHATS_NEW_DIALOG_THEME_H +#define WHATS_NEW_DIALOG_THEME_H + +#include +#include + +struct WhatsNewDialogTheme { + QColor backgroundColor; + QColor headerTextColor; + QColor versionTextColor; + QColor contentTextColor; + QColor linkColor; + QPixmap closeButtonIcon; + QPixmap headerDecoration; +}; + +#endif // WHATS_NEW_DIALOG_THEME_H diff --git a/common/themes/theme_manager.cpp b/common/themes/theme_manager.cpp index 4bfabb21f..081a7147d 100644 --- a/common/themes/theme_manager.cpp +++ b/common/themes/theme_manager.cpp @@ -6,6 +6,8 @@ #include #include +// TODO: add API to force color scheme //styleHints->setColorScheme(Qt::ColorScheme::Dark); + ThemeManager::ThemeManager() { } diff --git a/common/themes/themes_common.pri b/common/themes/themes_common.pri index bed4ed5cd..f246882c9 100644 --- a/common/themes/themes_common.pri +++ b/common/themes/themes_common.pri @@ -8,6 +8,7 @@ HEADERS += \ $$PWD/themable.h \ $$PWD/yacreader_icon.h \ $$PWD/shared/help_about_dialog_theme.h \ + $$PWD/shared/whats_new_dialog_theme.h \ SOURCES += \ diff --git a/common/yacreader_global_gui.cpp b/common/yacreader_global_gui.cpp index abf4be555..f80f1aff9 100644 --- a/common/yacreader_global_gui.cpp +++ b/common/yacreader_global_gui.cpp @@ -53,22 +53,6 @@ QList YACReader::mimeDataToComicsIds(const QMimeData *data) return comicIds; } -// TODO some SVG assets are missing in macos (WIP) -// we need two sets of icons, one for the toolbar and one for the context menu because of this bug (QTBUG-96553): https://bugreports.qt.io/browse/QTBUG-96553 - -QString YACReader::addExtensionToIconPath(const QString &path) -{ -#ifdef YACREADER_LIBRARY -#ifdef Q_OS_MACOS // TODO_Y_MAC_UI - return path + ".png"; -#else - return path + ".svg"; -#endif -#else - return path + ".svg"; -#endif -} - QString YACReader::addExtensionToIconPathInToolbar(const QString &path) { return path + "_18x18.svg"; diff --git a/common/yacreader_global_gui.h b/common/yacreader_global_gui.h index 84f8e64c4..7f25ad993 100644 --- a/common/yacreader_global_gui.h +++ b/common/yacreader_global_gui.h @@ -110,7 +110,6 @@ QAction *createSeparator(); QIcon noHighlightedIcon(const QString &path); void colorize(QImage &img, const QColor &col); QList mimeDataToComicsIds(const QMimeData *data); -QString addExtensionToIconPath(const QString &path); QString addExtensionToIconPathInToolbar(const QString &path); QAction *actionWithCustomIcon(const QIcon &icon, QAction *action); QPixmap hdpiPixmap(const QString &file, QSize size); diff --git a/custom_widgets/custom_widgets_yacreaderlibrary.pri b/custom_widgets/custom_widgets_yacreaderlibrary.pri index 3341bd40c..e9f61afd0 100644 --- a/custom_widgets/custom_widgets_yacreaderlibrary.pri +++ b/custom_widgets/custom_widgets_yacreaderlibrary.pri @@ -13,7 +13,6 @@ HEADERS += \ $$PWD/yacreader_spin_slider_widget.h \ $$PWD/yacreader_tool_bar_stretch.h \ $$PWD/yacreader_titled_toolbar.h \ - $$PWD/yacreader_deleting_progress.h \ $$PWD/yacreader_table_view.h \ $$PWD/yacreader_sidebar.h \ $$PWD/yacreader_library_list_widget.h \ @@ -38,7 +37,6 @@ SOURCES += \ $$PWD/yacreader_spin_slider_widget.cpp \ $$PWD/yacreader_tool_bar_stretch.cpp \ $$PWD/yacreader_titled_toolbar.cpp \ - $$PWD/yacreader_deleting_progress.cpp \ $$PWD/yacreader_table_view.cpp \ $$PWD/yacreader_sidebar.cpp \ $$PWD/yacreader_library_list_widget.cpp \ diff --git a/custom_widgets/rounded_corners_dialog.cpp b/custom_widgets/rounded_corners_dialog.cpp index 5210b6f79..2529b6d71 100644 --- a/custom_widgets/rounded_corners_dialog.cpp +++ b/custom_widgets/rounded_corners_dialog.cpp @@ -9,6 +9,12 @@ YACReader::RoundedCornersDialog::RoundedCornersDialog(QWidget *parent) setAttribute(Qt::WA_TranslucentBackground); } +void YACReader::RoundedCornersDialog::setBackgroundColor(const QColor &color) +{ + m_backgroundColor = color; + update(); +} + void YACReader::RoundedCornersDialog::paintEvent(QPaintEvent *) { qreal radius = 14.0; // desired radius in absolute pixels @@ -26,7 +32,7 @@ void YACReader::RoundedCornersDialog::paintEvent(QPaintEvent *) // Set the brush from palette role. // p.setBrush(palette().brush(backgroundRole())); - p.setBrush(QBrush(QColor(255, 255, 255))); // TODO: the rest of the colors are hardcoded + p.setBrush(QBrush(m_backgroundColor)); // Got radius? Otherwise draw a quicker rect. if (radius > 0.0) p.drawRoundedRect(rect, radius, radius, Qt::AbsoluteSize); diff --git a/custom_widgets/rounded_corners_dialog.h b/custom_widgets/rounded_corners_dialog.h index 04679fb82..3e5c3ce10 100644 --- a/custom_widgets/rounded_corners_dialog.h +++ b/custom_widgets/rounded_corners_dialog.h @@ -1,6 +1,7 @@ #ifndef ROUNDEDCORNERSDIALOG_H #define ROUNDEDCORNERSDIALOG_H +#include #include namespace YACReader { @@ -12,6 +13,10 @@ class RoundedCornersDialog : public QDialog protected: void paintEvent(QPaintEvent *) override; + void setBackgroundColor(const QColor &color); + +private: + QColor m_backgroundColor { 255, 255, 255 }; }; } diff --git a/custom_widgets/whats_new_dialog.cpp b/custom_widgets/whats_new_dialog.cpp index 4f0e1dccc..6f9689d94 100644 --- a/custom_widgets/whats_new_dialog.cpp +++ b/custom_widgets/whats_new_dialog.cpp @@ -22,114 +22,121 @@ YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent) content->setStyleSheet("background-color:transparent;" "border:none;"); - auto headerImageLabel = new QLabel(); - QPixmap headerImage(":/images/whats_new/whatsnew_header.svg"); - headerImageLabel->setPixmap(headerImage); - headerImageLabel->setFixedSize(headerImage.size()); + headerImageLabel = new QLabel(); - auto headerLabel = new QLabel(); + headerLabel = new QLabel(); headerLabel->setText("What's New in\nYACReader"); QFont headerLabelFont("Arial", 34, QFont::ExtraBold); headerLabel->setFont(headerLabelFont); headerLabel->setAlignment(Qt::AlignCenter); - headerLabel->setStyleSheet("padding: 18px 0 0 0;" - "background-color:transparent;" - "color:#0A0A0A;"); - auto versionLabel = new QLabel(); + versionLabel = new QLabel(); versionLabel->setText(VERSION); QFont versionLabelFont("Arial", 12, QFont::Normal); versionLabel->setFont(versionLabelFont); versionLabel->setAlignment(Qt::AlignCenter); - versionLabel->setStyleSheet("padding:0 0 0 0;" - "background-color:transparent;" - "color:#858585;"); - - auto text = new QLabel(); - text->setText("This version brings exciting new features, improved functionality, enhanced customization options, bug fixes, and performance improvements across all apps:
" - "
" - "YACReader
" - " • Don't use scroll animations on macOS by default, where hdpi scroll is most likely to be used
" - " • New toolbar on macOS
" - " • New mouse modes to turn pages - you can setup the app to use the left/right buttons to turn pages directly or click on the left/right part of the screen to turn pages
" - " • Fix current page/time label content when the content is too long. (new in 9.16.3)
" - "
" - "YACReaderLibrary
" - " • Improve flexibility of the open comic in third party app setting so more complex commands can be used, e.g. `open -a \"/Applications/My Reader.app\" \"{comic_file_path}\"`
" - " • Fix setting the comic rating in the table view
" - " • Log libraries validation when the app starts
" - " • New toolbar on macOS
" - " • New setting in Comic Vine scraper to force exact volume matches
" - " • Better default search query in the Comic Vine scraper
" - " • Improved navigation in Comic Vine scraper, including keeping the current query around to make edits and refined searches easier
" - " • Add support for custom covers for any folder using the context menu
" - " • The edit cover buttons now support looping through pages, going forward from the last returns to the first, and going backward from the first jumps to the last
" - " • Add support for custom covers for comics using the edit metadata dialog, you can use a pick file button or drag&drop an image into the cover view in the dialog
" - " • Covers can be set in bulk for various comics at once
" - " • New button to reset to the default cover of a comic
" - " • Support for storing the new image filters from iOS and Android apps
" - " • Fixed cover loading in Comic Vine scraper (new in 9.16.1)
" - " • Added a customizable User Agent string to use it with Comic Vine. It can be set in YACReaderLibrary.ini in the [ComicVine] section using the COMIC_VINE_USER_AGENT key (new in 9.16.2)
" - " • Prevent crash when opening the folders context menu if a folder is not selected. (new in 9.16.2)
" - " • Fix crash when using the `Set type` menu on libraries. (new in 9.16.2)
" - " • Fix table view last section stretch. Before it was only working randomly. (new in 9.16.3)
" - " • Fix empty table view caused by wront state being saved. You'll need to reconfigure the table view headers to your liking after this udpate. (new in 9.16.3)
" - "
" - "YACReaderLibraryServer
" - " • Log libraries validation when the app starts
" - "
" - "All apps
" - " • PDF support has been updated in all Windows apps
" - "
" - "I hope you enjoy the new update. Please, if you like YACReader consider to become a patron in Patreon " - "or donate some money using Pay-Pal and help keeping the project alive. " - "Remember that there is an iOS version available in the Apple App Store, " - "and there is a brand new app for Android that you can get on the Google Play Store."); + + textLabel = new QLabel(); + htmlTemplate = "This version brings exciting new features, improved functionality, enhanced customization options, bug fixes, and performance improvements across all apps:
" + "
" + "YACReader
" + " • Don't use scroll animations on macOS by default, where hdpi scroll is most likely to be used
" + " • New toolbar on macOS
" + " • New mouse modes to turn pages - you can setup the app to use the left/right buttons to turn pages directly or click on the left/right part of the screen to turn pages
" + " • Fix current page/time label content when the content is too long. (new in 9.16.3)
" + "
" + "YACReaderLibrary
" + " • Improve flexibility of the open comic in third party app setting so more complex commands can be used, e.g. `open -a \"/Applications/My Reader.app\" \"{comic_file_path}\"`
" + " • Fix setting the comic rating in the table view
" + " • Log libraries validation when the app starts
" + " • New toolbar on macOS
" + " • New setting in Comic Vine scraper to force exact volume matches
" + " • Better default search query in the Comic Vine scraper
" + " • Improved navigation in Comic Vine scraper, including keeping the current query around to make edits and refined searches easier
" + " • Add support for custom covers for any folder using the context menu
" + " • The edit cover buttons now support looping through pages, going forward from the last returns to the first, and going backward from the first jumps to the last
" + " • Add support for custom covers for comics using the edit metadata dialog, you can use a pick file button or drag&drop an image into the cover view in the dialog
" + " • Covers can be set in bulk for various comics at once
" + " • New button to reset to the default cover of a comic
" + " • Support for storing the new image filters from iOS and Android apps
" + " • Fixed cover loading in Comic Vine scraper (new in 9.16.1)
" + " • Added a customizable User Agent string to use it with Comic Vine. It can be set in YACReaderLibrary.ini in the [ComicVine] section using the COMIC_VINE_USER_AGENT key (new in 9.16.2)
" + " • Prevent crash when opening the folders context menu if a folder is not selected. (new in 9.16.2)
" + " • Fix crash when using the `Set type` menu on libraries. (new in 9.16.2)
" + " • Fix table view last section stretch. Before it was only working randomly. (new in 9.16.3)
" + " • Fix empty table view caused by wront state being saved. You'll need to reconfigure the table view headers to your liking after this udpate. (new in 9.16.3)
" + "
" + "YACReaderLibraryServer
" + " • Log libraries validation when the app starts
" + "
" + "All apps
" + " • PDF support has been updated in all Windows apps
" + "
" + "I hope you enjoy the new update. Please, if you like YACReader consider to become a patron in Patreon " + "or donate some money using Pay-Pal and help keeping the project alive. " + "Remember that there is an iOS version available in the Apple App Store, " + "and there is a brand new app for Android that you can get on the Google Play Store."; QFont textLabelFont("Arial", 15, QFont::Light); - text->setFont(textLabelFont); - text->setStyleSheet("padding:51px;" - "background-color:transparent;" - "color:#0A0A0A;"); - text->setWordWrap(true); - text->setOpenExternalLinks(true); + textLabel->setFont(textLabelFont); + textLabel->setWordWrap(true); + textLabel->setOpenExternalLinks(true); contentLayout->addItem(new QSpacerItem(0, 50), 0, 0); contentLayout->addWidget(headerImageLabel, 1, 0, Qt::AlignTop | Qt::AlignHCenter); contentLayout->addWidget(headerLabel, 1, 0, Qt::AlignTop | Qt::AlignHCenter); contentLayout->addWidget(versionLabel, 2, 0, Qt::AlignTop | Qt::AlignHCenter); - contentLayout->addWidget(text, 3, 0, Qt::AlignTop); + contentLayout->addWidget(textLabel, 3, 0, Qt::AlignTop); contentLayout->setRowStretch(3, 1); content->setLayout(contentLayout); mainLayout->addWidget(scrollArea); - // containerLayout->addWidget(content); scrollArea->setWidget(content); scrollArea->setWidgetResizable(true); this->setLayout(mainLayout); - auto closeButton = new QPushButton(this); + closeButton = new QPushButton(this); closeButton->setFlat(true); closeButton->setStyleSheet("background-color:transparent;"); - auto closeIcon = QPixmap(":/images/custom_dialog/custom_close_button.svg"); - if (!closeIcon.isNull()) { - closeButton->setIcon(QPixmap(":/images/custom_dialog/custom_close_button.svg")); - closeButton->setIconSize(QSize(44, 44)); - closeButton->setFixedSize(44, 44); - closeButton->move(656, 20); - } else { - closeButton->setText(tr("Close")); - auto font = closeButton->font(); - font.setPointSize(16); - closeButton->setFont(font); - closeButton->move(616, 20); - } + closeButton->setIconSize(QSize(44, 44)); + closeButton->setFixedSize(44, 44); + closeButton->move(656, 20); scrollArea->setFixedSize(720, 640); setFixedSize(720, 640); setModal(true); connect(closeButton, &QPushButton::clicked, this, &QDialog::close); + + initTheme(this); +} + +void YACReader::WhatsNewDialog::applyTheme(const Theme &theme) +{ + auto whatsNewTheme = theme.whatsNewDialog; + + setBackgroundColor(whatsNewTheme.backgroundColor); + + headerImageLabel->setPixmap(whatsNewTheme.headerDecoration); + headerImageLabel->setFixedSize(whatsNewTheme.headerDecoration.size()); + + headerLabel->setStyleSheet(QString("padding: 18px 0 0 0;" + "background-color:transparent;" + "color:%1;") + .arg(whatsNewTheme.headerTextColor.name())); + + versionLabel->setStyleSheet(QString("padding:0 0 0 0;" + "background-color:transparent;" + "color:%1;") + .arg(whatsNewTheme.versionTextColor.name())); + + textLabel->setStyleSheet(QString("padding:51px;" + "background-color:transparent;" + "color:%1;") + .arg(whatsNewTheme.contentTextColor.name())); + textLabel->setText(htmlTemplate.arg(whatsNewTheme.linkColor.name())); + + closeButton->setIcon(whatsNewTheme.closeButtonIcon); } diff --git a/custom_widgets/whats_new_dialog.h b/custom_widgets/whats_new_dialog.h index 8ec3722b8..a580b668b 100644 --- a/custom_widgets/whats_new_dialog.h +++ b/custom_widgets/whats_new_dialog.h @@ -2,15 +2,29 @@ #define WHATSNEWDIALOG_H #include "rounded_corners_dialog.h" -#include +#include "themable.h" + +class QLabel; +class QPushButton; namespace YACReader { -class WhatsNewDialog : public RoundedCornersDialog +class WhatsNewDialog : public RoundedCornersDialog, protected Themable { Q_OBJECT public: explicit WhatsNewDialog(QWidget *parent = nullptr); + +protected: + void applyTheme(const Theme &theme) override; + +private: + QLabel *headerImageLabel; + QLabel *headerLabel; + QLabel *versionLabel; + QLabel *textLabel; + QPushButton *closeButton; + QString htmlTemplate; }; } diff --git a/custom_widgets/yacreader_deleting_progress.cpp b/custom_widgets/yacreader_deleting_progress.cpp deleted file mode 100644 index fc54476b9..000000000 --- a/custom_widgets/yacreader_deleting_progress.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include "yacreader_deleting_progress.h" - -#include -#include -#include -#include -#include -#include - -YACReaderDeletingProgress::YACReaderDeletingProgress(QWidget *parent) - : QWidget(parent) -{ - QVBoxLayout *contentLayout = new QVBoxLayout(this); - - QLabel *iconLabel = new QLabel(); - QPixmap icon(":/images/deleting_progress/icon.png"); - iconLabel->setPixmap(icon); - iconLabel->setStyleSheet("QLabel {padding:0px; margin:0px;}"); - - textMessage = new QLabel(tr("Please wait, deleting in progress...")); - - textMessage->setStyleSheet("QLabel {color:#ABABAB; padding:0 0 0 0px; margin:0px; font-size:18px; font-weight:bold;}"); - - QProgressBar *progressBar = new QProgressBar(); - - progressBar->setTextVisible(false); - progressBar->setFixedHeight(6); - progressBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - progressBar->setRange(0, 10); - progressBar->setValue(5); - progressBar->setStyleSheet( - "QProgressBar { border: none; border-radius: 3px; background: #ABABAB; margin:0; margin-left:16; margin-right:16px;}" - "QProgressBar::chunk {background-color: #FFC745; border: none; border-radius: 3px;}"); - - QPushButton *button = new QPushButton(tr("cancel")); - - button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - - contentLayout->addSpacing(16); - contentLayout->addWidget(iconLabel, 0, Qt::AlignHCenter); - contentLayout->addSpacing(11); - contentLayout->addWidget(textMessage, 0, Qt::AlignHCenter); - contentLayout->addSpacing(13); - contentLayout->addWidget(progressBar); - contentLayout->addSpacing(13); - contentLayout->addWidget(button, 0, Qt::AlignHCenter); - contentLayout->addSpacing(18); - - contentLayout->setContentsMargins(0, 0, 0, 0); - - setLayout(contentLayout); - - setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - - resize(sizeHint()); -} - -void YACReaderDeletingProgress::paintEvent(QPaintEvent *event) -{ - int borderTop, borderRight, borderBottom, borderLeft; - - QPixmap pL(":/images/deleting_progress/imgTopLeft.png"); - QPixmap pM(":/images/deleting_progress/imgTopMiddle.png"); - QPixmap pR(":/images/deleting_progress/imgTopRight.png"); - - QPixmap pLM(":/images/deleting_progress/imgLeftMiddle.png"); - - QPixmap pRM(":/images/deleting_progress/imgRightMiddle.png"); - - QPixmap pBL(":/images/deleting_progress/imgBottomLeft.png"); - QPixmap pBM(":/images/deleting_progress/imgBottomMiddle.png"); - QPixmap pBR(":/images/deleting_progress/imgBottomRight.png"); - - borderTop = pL.height(); - borderRight = pRM.width(); - borderBottom = pBM.height(); - borderLeft = pLM.width(); - - int width = this->width() - borderRight - borderLeft; - int height = this->height() - borderTop - borderBottom; - - QPainter painter(this); - - // corners - painter.drawPixmap(0, 0, pL); - painter.drawPixmap(this->width() - borderRight, 0, pR); - painter.drawPixmap(0, this->height() - pBL.height(), pBL); - painter.drawPixmap(this->width() - pBR.width(), this->height() - borderBottom, pBR); - - // middle - painter.drawPixmap(borderRight, 0, width, borderTop, pM); - painter.drawPixmap(0, borderTop, borderLeft, height, pLM); - painter.drawPixmap(width + borderLeft, borderTop, borderRight, height, pRM); - painter.drawPixmap(pBR.width(), height + borderTop, this->width() - pBR.width() - pBL.width(), pBR.height(), pBM); - - // center - painter.fillRect(borderLeft, borderTop, width, height, QColor("#FAFAFA")); - - QWidget::paintEvent(event); -} - -QSize YACReaderDeletingProgress::sizeHint() const -{ - return QSize(textMessage->sizeHint().width() + 120, 185); -} diff --git a/custom_widgets/yacreader_deleting_progress.h b/custom_widgets/yacreader_deleting_progress.h deleted file mode 100644 index b1e7cc025..000000000 --- a/custom_widgets/yacreader_deleting_progress.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef YACREADER_DELETING_PROGRESS_H -#define YACREADER_DELETING_PROGRESS_H - -#include - -class QLabel; - -class YACReaderDeletingProgress : public QWidget -{ - Q_OBJECT -public: - explicit YACReaderDeletingProgress(QWidget *parent = 0); - QSize sizeHint() const; -signals: - -public slots: - -protected: - void paintEvent(QPaintEvent *); - -private: - QLabel *textMessage; -}; - -#endif // YACREADER_DELETING_PROGRESS_H diff --git a/custom_widgets/yacreader_library_item_widget.cpp b/custom_widgets/yacreader_library_item_widget.cpp index f7cbec8e5..295714f9c 100644 --- a/custom_widgets/yacreader_library_item_widget.cpp +++ b/custom_widgets/yacreader_library_item_widget.cpp @@ -19,20 +19,15 @@ YACReaderLibraryItemWidget::YACReaderLibraryItemWidget(QString n /*ame*/, QStrin // installEventFilter(this); - QPixmap iconPixmap = hdpiPixmap(addExtensionToIconPath(":/images/sidebar/libraryIcon"), QSize(16, 16)); icon = new QLabel(this); - icon->setPixmap(iconPixmap); nameLabel = new QLabel(name, this); options = new QToolButton(this); - QPixmap iconOptionsPixmap = hdpiPixmap(":/images/sidebar/libraryOptions.svg", QSize(8, 8)); - iconOptionsPixmap.setDevicePixelRatio(devicePixelRatioF()); - QLabel *helperLabel = new QLabel(options); - helperLabel->move(4, 3); - helperLabel->setFixedSize(14, 14); - helperLabel->setPixmap(iconOptionsPixmap); + optionsIconLabel = new QLabel(options); + optionsIconLabel->move(4, 3); + optionsIconLabel->setFixedSize(14, 14); options->setHidden(true); options->setIconSize(QSize(18, 18)); @@ -57,10 +52,6 @@ YACReaderLibraryItemWidget::YACReaderLibraryItemWidget(QString n /*ame*/, QStrin mainLayout->addWidget(down);*/ setLayout(mainLayout); -#ifndef Y_MAC_UI - QString styleSheet = "background-color:transparent; color:#DDDFDF;"; - setStyleSheet(styleSheet); -#endif QString iconStyleSheet = "QLabel {padding:0 0 0 24px; margin:0px}"; icon->setStyleSheet(iconStyleSheet); @@ -70,6 +61,35 @@ YACReaderLibraryItemWidget::YACReaderLibraryItemWidget(QString n /*ame*/, QStrin setMinimumHeight(20); setAttribute(Qt::WA_StyledBackground, true); + + initTheme(this); +} + +void YACReaderLibraryItemWidget::applyTheme(const Theme &theme) +{ + const auto &icons = theme.sidebarIcons; + const auto &li = theme.libraryItem; + + // Update icon based on current selection state + QIcon iconToUse = isSelected ? li.libraryIconSelected : icons.libraryIcon; + icon->setPixmap(iconToUse.pixmap(16, 16)); + + // Update options icon (uses libraryItem theme since it's only shown when selected) + QPixmap optionsPixmap = li.libraryOptionsIcon.pixmap(8, 8); + optionsPixmap.setDevicePixelRatio(devicePixelRatioF()); + optionsIconLabel->setPixmap(optionsPixmap); + + // Update widget styling based on selection state + if (isSelected) { + QString styleSheet = QString("color: %1; background-color: %2; font-weight:bold;") + .arg(li.selectedTextColor.name()) + .arg(li.selectedBackgroundColor.name()); + setStyleSheet(styleSheet); + } else { + QString styleSheet = QString("background-color:transparent; color: %1;") + .arg(li.textColor.name()); + setStyleSheet(styleSheet); + } } void YACReaderLibraryItemWidget::showUpDownButtons(bool show) @@ -117,17 +137,11 @@ bool YACReaderLibraryItemWidget::eventFilter(QObject *object, QEvent *event){ void YACReaderLibraryItemWidget::deselect() { - -#ifdef Y_MAC_UI - QString styleSheet = "background-color:transparent;"; - setStyleSheet(styleSheet); -#else - QString styleSheet = "background-color:transparent; color:#DDDFDF;"; + QString styleSheet = QString("background-color:transparent; color: %1;") + .arg(theme.libraryItem.textColor.name()); setStyleSheet(styleSheet); -#endif - QPixmap iconPixmap = hdpiPixmap(addExtensionToIconPath(":/images/sidebar/libraryIcon"), QSize(16, 16)); - icon->setPixmap(iconPixmap); + icon->setPixmap(theme.sidebarIcons.libraryIcon.pixmap(16, 16)); /*up->setHidden(true); down->setHidden(true);*/ @@ -138,18 +152,15 @@ void YACReaderLibraryItemWidget::deselect() void YACReaderLibraryItemWidget::select() { -#ifdef Y_MAC_UI - // QString styleSheet ="color: white; background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6BAFE4, stop: 1 #3984D2); border-top: 2px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #5EA3DF, stop: 1 #73B8EA); border-left:none;border-right:none;border-bottom:1px solid #3577C2;"; - QString styleSheet = "color: white; background-color:#91c4f4; border-bottom:1px solid #91c4f4;"; -#else - QString styleSheet = "color: white; background-color:#2E2E2E; font-weight:bold;"; -#endif + const auto &li = theme.libraryItem; + QString styleSheet = QString("color: %1; background-color: %2; font-weight:bold;") + .arg(li.selectedTextColor.name()) + .arg(li.selectedBackgroundColor.name()); setStyleSheet(styleSheet); options->setHidden(false); - QPixmap iconPixmap = hdpiPixmap(":/images/sidebar/libraryIconSelected.svg", QSize(16, 16)); - icon->setPixmap(iconPixmap); + icon->setPixmap(theme.libraryItem.libraryIconSelected.pixmap(16, 16)); isSelected = true; } diff --git a/custom_widgets/yacreader_library_item_widget.h b/custom_widgets/yacreader_library_item_widget.h index d2af6d107..33462b566 100644 --- a/custom_widgets/yacreader_library_item_widget.h +++ b/custom_widgets/yacreader_library_item_widget.h @@ -2,13 +2,16 @@ #define YACREADER_LIBRARY_ITEM_WIDGET_H #include +#include + +#include "themable.h" class QLabel; class QToolButton; class QMouseEvent; class QEvent; -class YACReaderLibraryItemWidget : public QWidget +class YACReaderLibraryItemWidget : public QWidget, protected Themable { Q_OBJECT @@ -32,12 +35,16 @@ public slots: private: QLabel *icon; QLabel *nameLabel; + QLabel *optionsIconLabel; QToolButton *options; QToolButton *up; QToolButton *down; bool isSelected; + +protected: + void applyTheme(const Theme &theme) override; }; #endif // YACREADER_LIBRARY_ITEM_WIDGET_H diff --git a/custom_widgets/yacreader_macosx_toolbar.h b/custom_widgets/yacreader_macosx_toolbar.h index 18cdccb51..f07de90cc 100644 --- a/custom_widgets/yacreader_macosx_toolbar.h +++ b/custom_widgets/yacreader_macosx_toolbar.h @@ -1,92 +1,6 @@ #ifndef YACREADER_MACOSX_TOOLBAR_H #define YACREADER_MACOSX_TOOLBAR_H -#include -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -#include -#include -#include - -#include "yacreader_global.h" - -// Wrapper for NSTextField -class YACReaderMacOSXSearchLineEdit : public QObject -{ - Q_OBJECT -public: - YACReaderMacOSXSearchLineEdit(); - void setFocus(Qt::FocusReason reason); - void *getNSTextField(); - -public slots: - QString text(); - void clear(); - void clearText(); // no signal emited - void setDisabled(bool disabled); - void setEnabled(bool enabled); - -private: - void *nstextfield; - -signals: - // convenience signal for YACReaderLibrary search edit - void filterChanged(QString); -}; - -class MacToolBarItemWrapper : public QObject -{ - Q_OBJECT -public: - MacToolBarItemWrapper(QAction *action, QMacToolBarItem *toolbaritem); - -public slots: - void actionToggled(bool toogled); - -private: - QAction *action; - QMacToolBarItem *toolbaritem; - - void updateIcon(bool checked); -}; - -class YACReaderMacOSXToolbar : public QMacToolBar -{ - Q_OBJECT -public: - explicit YACReaderMacOSXToolbar(QObject *parent = 0); - void addAction(QAction *action); - void addDropDownItem(const QList &actions, const QAction *defaultAction = 0); - void addSpace(int size); // size in points - void addSeparator(); - void addStretch(); - void addWidget(QWidget *widget); - void show(); - void hide(); - QMap actions; - - // hacks everywhere - // convenience method for YACReaderLibrary search edit - YACReaderMacOSXSearchLineEdit *addSearchEdit(); - // convenience method for showing the fit to width slider in MacOSX - QAction *addFitToWidthSlider(QAction *attachToAction); - - // convenience method for switching the icon of the view selector - void updateViewSelectorIcon(const QIcon &icon); - - void attachToWindow(QMainWindow *window); - -signals: - -public slots: - -protected: - NSToolbar *nativeToolBar; - void *delegate; - bool yosemite; - QMacToolBarItem *viewSelector; -}; -#else - #ifdef YACREADER_LIBRARY #include "yacreader_main_toolbar.h" @@ -149,6 +63,4 @@ public slots: #endif -#endif - #endif // YACREADER_MACOSX_TOOLBAR_H diff --git a/custom_widgets/yacreader_macosx_toolbar.mm b/custom_widgets/yacreader_macosx_toolbar.mm index e2d074505..487bc90ff 100644 --- a/custom_widgets/yacreader_macosx_toolbar.mm +++ b/custom_widgets/yacreader_macosx_toolbar.mm @@ -1,403 +1,8 @@ #include "yacreader_macosx_toolbar.h" #include "QtWidgets/qmainwindow.h" -#include #include -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -#include -#include -#include -#include -#include - -#import -#import -#import - -#import "shortcuts_manager.h" - -//---------------------------- -// A custom items separator for NSToolbar -@interface CustomSeparator : NSView - -@end - -@implementation CustomSeparator - -- (void)drawRect:(NSRect)rect -{ - [[NSColor colorWithDeviceRed:0.5 green:0.5 blue:0.5 alpha:1] setFill]; - NSRectFill(rect); - [super drawRect:rect]; -} - -@end - -//---------------------------- -// Toolbar delegate, needed for allow disabled/enabled items -@interface MyToolbarDelegate : NSObject { -@public - YACReaderMacOSXToolbar *mytoolbar; -} - -- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdent willBeInsertedIntoToolbar:(BOOL)willBeInserted; -- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar; -- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar; -//- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar; -- (IBAction)itemClicked:(id)sender; -- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem; -@end - -@implementation MyToolbarDelegate - -- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar -{ - Q_UNUSED(toolbar); - - NSMutableArray *array = [[NSMutableArray alloc] init]; - - QList items = mytoolbar->items(); - foreach (const QMacToolBarItem *item, items) { - [array addObject:item->nativeToolBarItem().itemIdentifier]; - } - return array; -} - -- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar -{ - Q_UNUSED(toolbar); - - NSMutableArray *array = [[NSMutableArray alloc] init]; - - QList items = mytoolbar->items(); - foreach (const QMacToolBarItem *item, items) { - [array addObject:item->nativeToolBarItem().itemIdentifier]; - } - return array; -} - -/* -- (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar -{ - Q_UNUSED(toolbar); - - NSMutableArray *array = [[NSMutableArray alloc] init]; - - QList items = mytoolbar->items(); - foreach (const QMacToolBarItem * item, items) { - [array addObject : item->nativeToolBarItem().itemIdentifier]; - } - return array; - //NSMutableArray *array = toolbarPrivate->getItemIdentifiers(toolbarPrivate->items, true); - //[array addObjectsFromArray:toolbarPrivate->getItemIdentifiers(toolbarPrivate->allowedItems, true)]; - //return array; -}*/ - -- (IBAction)itemClicked:(id)sender -{ - if ([sender respondsToSelector:@selector(itemIdentifier)]) { - NSToolbarItem *item = reinterpret_cast(sender); - - QString identifier = QString::fromNSString([item itemIdentifier]); - QMacToolBarItem *toolButton = reinterpret_cast(identifier.toULongLong()); - Q_EMIT toolButton->activated(); - } -} - -- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)willBeInserted -{ - Q_UNUSED(toolbar); - Q_UNUSED(willBeInserted); - QList items = mytoolbar->items(); - - foreach (const QMacToolBarItem *item, items) { - NSToolbarItem *toolbarItem = item->nativeToolBarItem(); - if ([toolbarItem.itemIdentifier isEqual:itemIdentifier]) { - - [toolbarItem setTarget:self]; - [toolbarItem setAction:@selector(itemClicked:)]; - - return toolbarItem; - } - } - return nil; -} - -- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem -{ - QString identifier = QString::fromNSString(theItem.itemIdentifier); - - if (mytoolbar->actions.contains(identifier)) { - return mytoolbar->actions.value(identifier)->isEnabled(); - } else - return NO; -} -@end - -//---------------------------- -// detect changes in native text field -// TODO implement validation and auto completion -@interface MyTextFieldDelegate : NSObject { -@public - YACReaderMacOSXSearchLineEdit *mylineedit; -} -@end - -@implementation MyTextFieldDelegate - -- (void)controlTextDidChange:(NSNotification *)notification -{ - NSTextField *textField = [notification object]; - NSLog(@"%@", [textField stringValue]); - Q_EMIT mylineedit->filterChanged(QString::fromNSString([textField stringValue])); -} - -@end -//---------------------------- - -YACReaderMacOSXToolbar::YACReaderMacOSXToolbar(QObject *parent) - : viewSelector(0) -{ - // setup native toolbar - nativeToolBar = nativeToolbar(); - [nativeToolBar setDisplayMode:NSToolbarDisplayModeIconOnly]; - [nativeToolBar setAllowsUserCustomization:NO]; - - delegate = [[MyToolbarDelegate alloc] init]; - ((MyToolbarDelegate *)delegate)->mytoolbar = this; - [nativeToolBar setDelegate:(MyToolbarDelegate *)delegate]; - -#ifdef YACREADER_LIBRARY - NSWindow *nswindow = (NSWindow *)qApp->platformNativeInterface()->nativeResourceForWindow("nswindow", ((QMainWindow *)parent)->windowHandle()); - if ([nswindow respondsToSelector:@selector(setTitleVisibility:)]) { - yosemite = true; - // TODO yosemite new constants are not found in compilation time - [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 - } else { - [nativeToolBar setSizeMode:NSToolbarSizeModeSmall]; - yosemite = false; - } -#else - yosemite = false; - [nativeToolBar setAutosavesConfiguration:YES]; // TODO this doesn't work - [nativeToolBar setSizeMode:NSToolbarSizeModeSmall]; -#endif -} - -void YACReaderMacOSXToolbar::addAction(QAction *action) -{ - QMacToolBarItem *toolBarItem = addItem(action->icon(), action->text()); - if (action->data().toString() == TOGGLE_COMICS_VIEW_ACTION_YL) - viewSelector = toolBarItem; - connect(toolBarItem, &QMacToolBarItem::activated, action, [=] { emit action->triggered(); }); - - NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem(); - actions.insert(QString::fromNSString(nativeItem.itemIdentifier), action); - - MacToolBarItemWrapper *wrapper = new MacToolBarItemWrapper(action, toolBarItem); - // wrapper->actionToogled(true); -} - -void YACReaderMacOSXToolbar::addDropDownItem(const QList &actions, const QAction *defaultAction) -{ - // TODO -} - -void YACReaderMacOSXToolbar::addSpace(int size) -{ - QMacToolBarItem *toolBarItem = addItem(QIcon(), ""); - NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem(); - - static const NSRect frameRect = { { 0.0, 0.0 }, { CGFloat(size), 16.0 } }; - NSView *view = [[NSView alloc] initWithFrame:frameRect]; - - [nativeItem setView:view]; -} - -// reimplemented for convenience -void YACReaderMacOSXToolbar::addSeparator() -{ - // QMacToolBar::addSeparator(); - - QMacToolBarItem *toolBarItem = addItem(QIcon(), ""); - NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem(); - - static const NSRect frameRect = { { 0.0, 0.0 }, { 1, 16.0 } }; - CustomSeparator *view = [[CustomSeparator alloc] initWithFrame:frameRect]; - - [nativeItem setView:view]; -} - -void YACReaderMacOSXToolbar::addStretch() -{ - QMacToolBarItem *toolBarItem = addItem(QIcon(), ""); - toolBarItem->setStandardItem(QMacToolBarItem::FlexibleSpace); -} - -void YACReaderMacOSXToolbar::addWidget(QWidget *widget) -{ - // TODO fix it - /* QMacNativeWidget *nativeWidget = new QMacNativeWidget(); - QVBoxLayout *layout = new QVBoxLayout(); - layout->addWidget(widget); - nativeWidget->setLayout(layout); - - - NSView *nativeWidgetView = reinterpret_cast(nativeWidget->winId()); - QMacToolBarItem *toolBarItem = addItem(QIcon(),""); - NSToolbarItem * nativeItem = toolBarItem->nativeToolBarItem(); - [nativeItem setView:nativeWidgetView];*/ -} - -void YACReaderMacOSXToolbar::show() -{ - [nativeToolBar setVisible:YES]; -} - -void YACReaderMacOSXToolbar::hide() -{ - [nativeToolBar setVisible:NO]; -} - -YACReaderMacOSXSearchLineEdit *YACReaderMacOSXToolbar::addSearchEdit() -{ - QMacToolBarItem *toolBarItem = addItem(QIcon(), ""); - NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem(); - - YACReaderMacOSXSearchLineEdit *searchEdit = new YACReaderMacOSXSearchLineEdit(); - - if (yosemite) - [nativeItem setView:(NSTextField *)searchEdit->getNSTextField()]; - else { - static const NSRect searchEditFrameRect = { { 0.0, 0.0 }, { 165, 26.0 } }; - NSView *view = [[NSView alloc] initWithFrame:searchEditFrameRect]; - [view addSubview:((NSTextField *)searchEdit->getNSTextField())]; - [nativeItem setView:view]; - } - - return searchEdit; -} - -// deprecated -QAction *YACReaderMacOSXToolbar::addFitToWidthSlider(QAction *attachToAction) -{ - QMacToolBarItem *toolBarItem = addItem(QIcon(":/images/viewer_toolbar/toWidthSlider.png"), "fit to width slider"); - - NSToolbarItem *nativeItem = toolBarItem->nativeToolBarItem(); - actions.insert(QString::fromNSString(nativeItem.itemIdentifier), attachToAction); - - QAction *action = new QAction("", attachToAction->parent()); - - connect(toolBarItem, &QMacToolBarItem::activated, action, [=] { emit action->triggered(); }); - - return action; -} - -void YACReaderMacOSXToolbar::updateViewSelectorIcon(const QIcon &icon) -{ - if (viewSelector) - viewSelector->setIcon(icon); -} - -void YACReaderMacOSXToolbar::attachToWindow(QMainWindow *window) -{ - QMacToolBar::attachToWindow(window->windowHandle()); -} - -YACReaderMacOSXSearchLineEdit::YACReaderMacOSXSearchLineEdit() - : QObject() -{ - NSRect searchEditFrameRect = { { 0.0, -3.0 }, { 165, 32.0 } }; - // NSTextField * searchEdit = [[NSTextField alloc] initWithFrame:searchEditFrameRect]; - - NSTextField *searchEdit = [[NSSearchField alloc] initWithFrame:searchEditFrameRect]; - //[searchEdit setBezelStyle:NSTextFieldRoundedBezel]; - - [[searchEdit cell] setPlaceholderString:@"type to search"]; - - MyTextFieldDelegate *delegate = [[MyTextFieldDelegate alloc] init]; - delegate->mylineedit = this; - [searchEdit setDelegate:delegate]; - - nstextfield = searchEdit; -} - -void YACReaderMacOSXSearchLineEdit::setFocus(Qt::FocusReason reason) -{ - Q_UNUSED(reason) - - [((NSTextField *)nstextfield) becomeFirstResponder]; -} - -void *YACReaderMacOSXSearchLineEdit::getNSTextField() -{ - return nstextfield; -} - -QString YACReaderMacOSXSearchLineEdit::text() -{ - return QString::fromNSString([((NSTextField *)nstextfield) stringValue]); -} - -void YACReaderMacOSXSearchLineEdit::clear() -{ - [((NSTextField *)nstextfield) setStringValue:@""]; - emit filterChanged(""); -} - -void YACReaderMacOSXSearchLineEdit::clearText() -{ - // TODO be sure that this will not generate any event.... - [((NSTextField *)nstextfield) setStringValue:@""]; -} - -void YACReaderMacOSXSearchLineEdit::setDisabled(bool disabled) -{ - [((NSTextField *)nstextfield) setEnabled:!disabled]; -} - -void YACReaderMacOSXSearchLineEdit::setEnabled(bool enabled) -{ - [((NSTextField *)nstextfield) setEnabled:enabled]; -} - -MacToolBarItemWrapper::MacToolBarItemWrapper(QAction *action, QMacToolBarItem *toolbaritem) - : action(action), toolbaritem(toolbaritem) -{ - if (action->isCheckable()) { - connect(action, &QAction::toggled, this, &MacToolBarItemWrapper::actionToggled); - connect(toolbaritem, &QMacToolBarItem::activated, action, &QAction::toggle); - updateIcon(action->isChecked()); - } -} - -void MacToolBarItemWrapper::actionToggled(bool toogled) -{ - updateIcon(toogled); -} - -void MacToolBarItemWrapper::updateIcon(bool enabled) -{ - if (enabled) { - QIcon icon = action->icon(); - QPixmap tempPixmap = icon.pixmap(QSize(24, 24)); - QPainter painter; - painter.begin(&tempPixmap); - painter.fillRect(QRect(3, 21, 18, 1), QColor("#3F3F3F")); - painter.fillRect(QRect(3, 22, 18, 1), QColor("#6E6E6E")); - painter.fillRect(QRect(3, 23, 18, 1), QColor("#EEEEEE")); - painter.end(); - - toolbaritem->setIcon(QIcon(tempPixmap)); - } else - toolbaritem->setIcon(action->icon()); -} -#else - #import #import #import @@ -462,9 +67,17 @@ void bindActionToNSToolbarItem(QAction *action, NSToolbarItem *toolbarItem, cons toolbarItem.toolTip = tooltip.isEmpty() ? @"" : [NSString stringWithUTF8String:tooltip.toUtf8().constData()]; QIcon icon = action->icon(); + if (icon.isNull()) { + return; + } __auto_type image = QIconToNSImage(icon, { 24, 24 }, iconColor); + if (image.size.width == 0 || image.size.height == 0) { + [image release]; + return; + } + if (action->isChecked()) { NSSize size = image.size; NSImage *decoratedImage = [[NSImage alloc] initWithSize:size]; @@ -950,5 +563,3 @@ - (BOOL)validateToolbarItem:(NSToolbarItem *)item } #endif - -#endif diff --git a/custom_widgets/yacreader_search_line_edit.cpp b/custom_widgets/yacreader_search_line_edit.cpp index e1e105b8f..7c2b08f26 100644 --- a/custom_widgets/yacreader_search_line_edit.cpp +++ b/custom_widgets/yacreader_search_line_edit.cpp @@ -1,81 +1,50 @@ #include "yacreader_search_line_edit.h" -#include "yacreader_global.h" -#include "yacreader_global_gui.h" - #include #include #include -#include "QsLog.h" - YACReaderSearchLineEdit::YACReaderSearchLineEdit(QWidget *parent) - : QLineEdit(parent) + : QLineEdit(parent), paddingLeft(0), paddingRight(0) { clearButton = new QToolButton(this); searchLabel = new QLabel(this); -#ifdef Y_MAC_UI - QPixmap clearIcon; - QPixmap searchIcon; - - clearIcon.setDevicePixelRatio(devicePixelRatioF()); - searchIcon.setDevicePixelRatio(devicePixelRatioF()); - - if (devicePixelRatioF() > 1) { - if (!clearIcon.load(":/images/clearSearch@2x.png")) { - clearIcon.load(":/images/clearSearch.png"); - } - if (!searchIcon.load(":/images/iconSearch@2x.png")) { - searchIcon.load(":/images/iconSearch.png"); - } - } else { - clearIcon.load(":/images/clearSearch.png"); - searchIcon.load(":/images/iconSearch.png"); - } -#else - QPixmap clearIcon = YACReader::hdpiPixmap(":/images/clearSearch.svg", QSize(15, 15)); - QPixmap searchIcon = YACReader::hdpiPixmap(":/images/iconSearch.svg", QSize(15, 15)); -#endif - - searchLabel->setStyleSheet("QLabel { border: none; padding: 0px; }"); - searchLabel->setPixmap(searchIcon); - - clearButton->setIcon(QIcon(clearIcon)); - -#ifdef Y_MAC_UI - clearButton->setIconSize(QSize(14, 14)); -#else clearButton->setIconSize(QSize(12, 12)); -#endif clearButton->setCursor(Qt::ArrowCursor); - clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }"); clearButton->hide(); connect(clearButton, &QAbstractButton::clicked, this, &QLineEdit::clear); connect(this, &QLineEdit::textChanged, this, &YACReaderSearchLineEdit::updateCloseButton); + int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); -#ifdef Y_MAC_UI - setStyleSheet(QString("QLineEdit {border-top:1px solid #9F9F9F; border-bottom:1px solid #ACACAC; border-right:1px solid #ACACAC; border-left:1px solid #ACACAC; border-radius: 4px; background-color:#EEEEEE; padding-left: %1px; padding-right: %2px; padding-bottom: 1px; margin-bottom: 1px;} ").arg(searchLabel->sizeHint().width() + frameWidth + 6).arg(clearButton->sizeHint().width() + frameWidth + 2)); -#else - setStyleSheet(QString("QLineEdit {color: #ABABAB; border:none; border-radius: 4px; background-color:#404040; padding-left: %1px; padding-right: %2px; padding-bottom: 1px; margin-right: 9px;} ").arg(searchLabel->sizeHint().width() + frameWidth + 6 + 5).arg(clearButton->sizeHint().width() + frameWidth + 2)); -#endif + paddingLeft = 15 + frameWidth + 6 + 5; + paddingRight = 12 + frameWidth + 10; + QSize msz = minimumSizeHint(); setMinimumSize(qMax(msz.width(), clearButton->sizeHint().height() + frameWidth * 2 + 2), qMax(msz.height(), clearButton->sizeHint().height() + frameWidth * 2 + 2)); -#ifdef Y_MAC_UI - setMaximumWidth(212); - setFixedHeight(26); -#else setMaximumWidth(255); setFixedHeight(26); -#endif - setAttribute(Qt::WA_MacShowFocusRect, false); setPlaceholderText(tr("type to search")); connect(this, &QLineEdit::textChanged, this, &YACReaderSearchLineEdit::processText); + + initTheme(this); +} + +void YACReaderSearchLineEdit::applyTheme(const Theme &theme) +{ + const auto &searchTheme = theme.searchLineEdit; + + setStyleSheet(searchTheme.lineEditQSS.arg(paddingLeft).arg(paddingRight)); + searchLabel->setStyleSheet(searchTheme.searchLabelQSS); + clearButton->setStyleSheet(searchTheme.clearButtonQSS); + + searchLabel->setPixmap(searchTheme.searchIcon); + clearButton->setIcon(QIcon(searchTheme.clearIcon)); } void YACReaderSearchLineEdit::clearText() @@ -92,15 +61,6 @@ const QString YACReaderSearchLineEdit::text() void YACReaderSearchLineEdit::resizeEvent(QResizeEvent *) { -#ifdef Y_MAC_UI - QSize sz = clearButton->sizeHint(); - int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - clearButton->move(rect().right() - frameWidth - sz.width(), - (rect().bottom() + 1 - sz.height()) / 2); - - QSize szl = searchLabel->sizeHint(); - searchLabel->move(6, (rect().bottom() + 1 - szl.height()) / 2); -#else QSize sz = clearButton->sizeHint(); int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); int marginRight = style()->pixelMetric(QStyle::PM_LayoutRightMargin); @@ -109,7 +69,6 @@ void YACReaderSearchLineEdit::resizeEvent(QResizeEvent *) QSize szl = searchLabel->sizeHint(); searchLabel->move(8, (rect().bottom() + 2 - szl.height()) / 2); -#endif } void YACReaderSearchLineEdit::updateCloseButton(const QString &text) diff --git a/custom_widgets/yacreader_search_line_edit.h b/custom_widgets/yacreader_search_line_edit.h index fdedef1d0..3f901dc65 100644 --- a/custom_widgets/yacreader_search_line_edit.h +++ b/custom_widgets/yacreader_search_line_edit.h @@ -5,11 +5,12 @@ #include #include "yacreader_global.h" +#include "themable.h" class QToolButton; class QLabel; -class YACReaderSearchLineEdit : public QLineEdit +class YACReaderSearchLineEdit : public QLineEdit, protected Themable { Q_OBJECT @@ -20,6 +21,7 @@ class YACReaderSearchLineEdit : public QLineEdit protected: void resizeEvent(QResizeEvent *); + void applyTheme(const Theme &theme) override; signals: void filterChanged(QString); @@ -31,6 +33,9 @@ private slots: private: QToolButton *clearButton; QLabel *searchLabel; + + int paddingLeft; + int paddingRight; }; #endif // YACREADER_SEARCH_LINE_EDIT_H diff --git a/custom_widgets/yacreader_sidebar.cpp b/custom_widgets/yacreader_sidebar.cpp index 13f72dc56..bac2364ce 100644 --- a/custom_widgets/yacreader_sidebar.cpp +++ b/custom_widgets/yacreader_sidebar.cpp @@ -25,28 +25,14 @@ YACReaderSideBar::YACReaderSideBar(QWidget *parent) readingListsView = new YACReaderReadingListsView; selectedLibrary = new YACReaderLibraryListWidget; -#ifdef Y_MAC_UI - librariesTitle = new YACReaderTitledToolBar(tr("Libraries")); - foldersTitle = new YACReaderTitledToolBar(tr("Folders")); - readingListsTitle = new YACReaderTitledToolBar(tr("Reading Lists")); -#else - librariesTitle = new YACReaderTitledToolBar(tr("LIBRARIES")); - foldersTitle = new YACReaderTitledToolBar(tr("FOLDERS")); - readingListsTitle = new YACReaderTitledToolBar(tr("READING LISTS")); -#endif + // Titles will be set from theme in applyTheme + librariesTitle = new YACReaderTitledToolBar(""); + foldersTitle = new YACReaderTitledToolBar(""); + readingListsTitle = new YACReaderTitledToolBar(""); splitter = new QSplitter(this); splitter->setOrientation(Qt::Vertical); -#ifndef Y_MAC_UI - splitter->setStyleSheet("QSplitter::handle { " - " image: none; background-color = black; " - " }" - "QSplitter::handle:vertical { height: 39px;}"); -#else - splitter->setStyleSheet("QSplitter::handle:vertical { height: 26px; background-color: transparent;}"); -#endif - selectedLibrary->setContextMenuPolicy(Qt::ActionsContextMenu); selectedLibrary->setAttribute(Qt::WA_MacShowFocusRect, false); selectedLibrary->setFocusPolicy(Qt::NoFocus); @@ -57,24 +43,18 @@ YACReaderSideBar::YACReaderSideBar(QWidget *parent) l->setContentsMargins(0, 0, 0, 0); // LIBRARIES------------------------------------------------------- -#ifndef Y_MAC_UI l->addSpacing(5); -#endif l->addWidget(librariesTitle); -#ifndef Y_MAC_UI l->addSpacing(4); - l->addWidget(new YACReaderSideBarSeparator(this)); + auto sep1 = new YACReaderSideBarSeparator(this); + separators.append(sep1); + l->addWidget(sep1); l->addSpacing(3); -#endif l->addWidget(selectedLibrary); -#ifndef Y_MAC_UI l->addSpacing(11); -#else - l->addSpacing(6); -#endif // END LIBRARIES--------------------------------------------------- @@ -84,23 +64,18 @@ YACReaderSideBar::YACReaderSideBar(QWidget *parent) foldersLayout->setContentsMargins(0, 0, 0, 0); foldersLayout->setSpacing(0); -#ifndef Y_MAC_UI - // foldersLayout->addSpacing(6); - - // foldersLayout->addSpacing(5); - foldersLayout->addWidget(new YACReaderSideBarSeparator(this)); + auto sep2 = new YACReaderSideBarSeparator(this); + separators.append(sep2); + foldersLayout->addWidget(sep2); foldersLayout->addSpacing(4); -#else - // foldersLayout->addSpacing(6); -#endif foldersLayout->addWidget(foldersTitle); -#ifndef Y_MAC_UI foldersLayout->addSpacing(4); - foldersLayout->addWidget(new YACReaderSideBarSeparator(this)); + auto sep3 = new YACReaderSideBarSeparator(this); + separators.append(sep3); + foldersLayout->addWidget(sep3); foldersLayout->addSpacing(4); -#endif foldersLayout->addWidget(foldersView); foldersLayout->addSpacing(6); @@ -116,28 +91,21 @@ YACReaderSideBar::YACReaderSideBar(QWidget *parent) readingListsHeaderLayout->setContentsMargins(0, 0, 0, 0); readingListsHeaderLayout->setSpacing(0); -#ifndef Y_MAC_UI - // readingListsHeaderLayout->addSpacing(6); - - // readingListsHeaderLayout->addSpacing(5); - readingListsHeaderLayout->addWidget(new YACReaderSideBarSeparator(this)); + auto sep4 = new YACReaderSideBarSeparator(this); + separators.append(sep4); + readingListsHeaderLayout->addWidget(sep4); readingListsHeaderLayout->addSpacing(4); -#else - // readingListsHeaderLayout->addSpacing(6); -#endif readingListsHeaderLayout->addWidget(readingListsTitle); -#ifndef Y_MAC_UI readingListsHeaderLayout->addSpacing(4); - readingListsHeaderLayout->addWidget(new YACReaderSideBarSeparator(this)); + auto sep5 = new YACReaderSideBarSeparator(this); + separators.append(sep5); + readingListsHeaderLayout->addWidget(sep5); readingListsHeaderLayout->addSpacing(4); -#endif - // readingListsLayout->addWidget(readingListsView); readingListsHeaderLayout->addStretch(); QSplitterHandle *handle = splitter->handle(1); - // handle->setCursor(QCursor(Qt::ArrowCursor)); handle->setLayout(readingListsHeaderLayout); // END READING LISTS------------------------------------------------ @@ -148,30 +116,16 @@ YACReaderSideBar::YACReaderSideBar(QWidget *parent) if (settings->contains(SIDEBAR_SPLITTER_STATUS)) splitter->restoreState(settings->value(SIDEBAR_SPLITTER_STATUS).toByteArray()); + + initTheme(this); } void YACReaderSideBar::paintEvent(QPaintEvent *event) { Q_UNUSED(event) -#ifdef Y_MAC_UI - QPainter painter(this); - - painter.fillRect(0, 0, width(), height(), QColor("#F1F1F1")); -#else QPainter painter(this); - - painter.fillRect(0, 0, width(), height(), QColor("#454545")); - // QWidget::paintEvent(event); -#endif - - // QPixmap shadow(":/images/side_bar/shadow.png"); - // painter.drawPixmap(width()-shadow.width(),0,shadow.width(),height(),shadow); - - // painter.setRenderHint(QPainter::Antialiasing); - // painter.drawLine(rect().topLeft(), rect().bottomRight()); - - // QWidget::paintEvent(event); + painter.fillRect(0, 0, width(), height(), theme.sidebar.backgroundColor); } void YACReaderSideBar::closeEvent(QCloseEvent *event) @@ -186,17 +140,40 @@ QSize YACReaderSideBar::sizeHint() const return QSize(275, 200); } +void YACReaderSideBar::applyTheme(const Theme &theme) +{ + splitter->setStyleSheet(theme.sidebar.splitterQSS); + + // Titles are per-instance, toolbars handle their own colors via Themable + auto applyCase = [&](const QString &s) { return theme.sidebar.uppercaseLabels ? s.toUpper() : s; }; + librariesTitle->setTitle(applyCase(QObject::tr("Libraries"))); + foldersTitle->setTitle(applyCase(QObject::tr("Folders"))); + readingListsTitle->setTitle(applyCase(QObject::tr("Reading Lists"))); + + for (auto separator : separators) { + separator->setColor(theme.sidebar.sectionSeparatorColor); + } + + update(); // Trigger repaint for background color +} + YACReaderSideBarSeparator::YACReaderSideBarSeparator(QWidget *parent) - : QWidget(parent) + : QWidget(parent), separatorColor(QColor("#575757")) { setFixedHeight(1); } +void YACReaderSideBarSeparator::setColor(const QColor &color) +{ + separatorColor = color; + update(); +} + void YACReaderSideBarSeparator::paintEvent(QPaintEvent *event) { Q_UNUSED(event) QPainter painter(this); - painter.fillRect(5, 0, width() - 10, height(), QColor("#575757")); + painter.fillRect(5, 0, width() - 10, height(), separatorColor); } diff --git a/custom_widgets/yacreader_sidebar.h b/custom_widgets/yacreader_sidebar.h index e04405b64..ca511b782 100644 --- a/custom_widgets/yacreader_sidebar.h +++ b/custom_widgets/yacreader_sidebar.h @@ -3,6 +3,8 @@ #include +#include "themable.h" + class YACReaderFoldersView; class YACReaderLibraryListWidget; class YACReaderSearchLineEdit; @@ -14,12 +16,16 @@ class YACReaderSideBarSeparator : public QWidget { public: explicit YACReaderSideBarSeparator(QWidget *parent = 0); + void setColor(const QColor &color); protected: void paintEvent(QPaintEvent *event); + +private: + QColor separatorColor; }; -class YACReaderSideBar : public QWidget +class YACReaderSideBar : public QWidget, protected Themable { Q_OBJECT public: @@ -40,8 +46,11 @@ public slots: protected: void paintEvent(QPaintEvent *); void closeEvent(QCloseEvent *event); + void applyTheme(const Theme &theme) override; + QSettings *settings; QSplitter *splitter; + QList separators; }; #endif // YACREADER_SIDEBAR_H diff --git a/custom_widgets/yacreader_table_view.cpp b/custom_widgets/yacreader_table_view.cpp index 7e291e89d..7c8b2507c 100644 --- a/custom_widgets/yacreader_table_view.cpp +++ b/custom_widgets/yacreader_table_view.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -19,26 +18,11 @@ #include "comic_model.h" YACReaderTableView::YACReaderTableView(QWidget *parent) - : QTableView(parent), showDelete(false), editing(false), myeditor(0) + : QTableView(parent), editing(false), myeditor(0) { setAlternatingRowColors(true); verticalHeader()->setAlternatingRowColors(true); - setStyleSheet("QTableView {alternate-background-color: #F2F2F2;background-color: #FAFAFA; outline: 0px;}" // border: 1px solid #999999; border-right:none; border-bottom:none;}" - "QTableCornerButton::section {background-color:#F5F5F5; border:none; border-bottom:1px solid #B8BDC4; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #D1D1D1, stop: 1 #B8BDC4);}" - "QTableView::item {outline: 0px; border-bottom: 1px solid #DFDFDF;border-top: 1px solid #FEFEFE; padding-bottom:1px; color:#252626;}" - "QTableView {border-top:1px solid #B8B8B8;border-bottom:none;border-left:1px solid #B8B8B8;border-right:none;}" -#ifdef Y_MAC_UI - "QTableView {border-top:1px solid #B8B8B8;border-bottom:none;border-left:none;border-right:none;}" - "QTableView::item:selected {outline: 0px; border-bottom: 1px solid #3875D7;border-top: 1px solid #3875D7; padding-bottom:1px; background-color: #3875D7; color: #FFFFFF; }" -#else - "QTableView::item:selected {outline: 0px; border-bottom: 1px solid #D4D4D4;border-top: 1px solid #D4D4D4; padding-bottom:1px; background-color: #D4D4D4; }" -#endif - "QHeaderView::section:horizontal {background-color:#F5F5F5; border-bottom:1px solid #B8BDC4; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #D1D1D1, stop: 1 #B8BDC4); border-left:none; border-top:none; padding:4px; color:#313232;}" - "QHeaderView::section:vertical {border-bottom: 1px solid #DFDFDF;border-top: 1px solid #FEFEFE;}" - //"QTableView::item:hover {border-bottom: 1px solid #A3A3A3;border-top: 1px solid #A3A3A3; padding-bottom:1px; background-color: #A3A3A3; color: #FFFFFF; }" - ""); - // comicView->setItemDelegate(new YACReaderComicViewDelegate()); setContextMenuPolicy(Qt::ActionsContextMenu); setShowGrid(false); @@ -72,16 +56,19 @@ YACReaderTableView::YACReaderTableView(QWidget *parent) setEditTriggers(QAbstractItemView::NoEditTriggers); setMouseTracking(true); - /*deletingProgress = new YACReaderDeletingProgress(this); - - showDeletingProgressAnimation = new QPropertyAnimation(deletingProgress,"pos"); - showDeletingProgressAnimation->setDuration(150);*/ // drag: if the default drag is enabled there is no way for setting a custom image // TODO report bug/suggestion // setDragEnabled(true); // setDragDropMode(QAbstractItemView::DragDrop); setAcceptDrops(true); + + initTheme(this); +} + +void YACReaderTableView::applyTheme(const Theme &theme) +{ + setStyleSheet(theme.tableView.tableViewQSS); } void YACReaderTableView::mouseMoveEvent(QMouseEvent *event) @@ -204,36 +191,8 @@ void YACReaderTableView::commitData(QWidget *editor) emit comicRated(((StarEditor *)editor)->starRating().starCount(), currentIndexEditing); } -void YACReaderTableView::showDeleteProgress() -{ - /*showDelete = true; - - showDeletingProgressAnimation->setStartValue(deletingProgress->pos()); - showDeletingProgressAnimation->setEndValue(QPoint((width()-deletingProgress->width())/2 ,1)); - showDeletingProgressAnimation->start();*/ -} - -void YACReaderTableView::hideDeleteProgress() -{ - /*showDelete = false; - - if(showDeletingProgressAnimation->state()==QPropertyAnimation::Running) - showDeletingProgressAnimation->stop(); - - showDeletingProgressAnimation->setStartValue(deletingProgress->pos()); - showDeletingProgressAnimation->setEndValue(QPoint((width()-deletingProgress->width())/2 ,-deletingProgress->height())); - showDeletingProgressAnimation->start();*/ -} - void YACReaderTableView::resizeEvent(QResizeEvent *event) { - /*event->size(); - - if(showDelete) - deletingProgress->move((event->size().width()-deletingProgress->width())/2 ,1); - else - deletingProgress->move((event->size().width()-deletingProgress->width())/2 ,-deletingProgress->height());*/ - QTableView::resizeEvent(event); } @@ -247,15 +206,23 @@ void YACReaderRatingDelegate::paint(QPainter *painter, const QStyleOptionViewIte StarRating starRating(rating); + // Get colors from parent table view + QColor ratingColor(0xE9BE0F); + QColor ratingSelectedColor(Qt::white); + if (auto tableView = qobject_cast(parent())) { + ratingColor = tableView->starRatingColor(); + ratingSelectedColor = tableView->starRatingSelectedColor(); + } + QStyledItemDelegate::paint(painter, option, index); if (!(option.state & QStyle::State_Editing)) { if (option.state & QStyle::State_Selected) starRating.paintSelected(painter, option.rect, option.palette, - StarRating::ReadOnly); + StarRating::ReadOnly, ratingSelectedColor); else starRating.paint(painter, option.rect, option.palette, - StarRating::ReadOnly); + StarRating::ReadOnly, ratingColor); } } @@ -344,6 +311,12 @@ QSize StarRating::sizeHint() const void StarRating::paint(QPainter *painter, const QRect &rect, const QPalette &palette, EditMode mode) const +{ + paint(painter, rect, palette, mode, QColor("#e9be0f")); +} + +void StarRating::paint(QPainter *painter, const QRect &rect, + const QPalette &palette, EditMode mode, QColor color) const { Q_UNUSED(palette) painter->save(); @@ -351,12 +324,8 @@ void StarRating::paint(QPainter *painter, const QRect &rect, painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(Qt::NoPen); - // if (mode == Editable) { - // painter->setBrush(palette.highlight()); - // } else { - QBrush brush(QColor("#e9be0f")); + QBrush brush(color); painter->setBrush(brush); - //} int yOffset = (rect.height() - PaintingScaleFactor) / 2; painter->translate(rect.x(), rect.y() + yOffset); @@ -366,7 +335,7 @@ void StarRating::paint(QPainter *painter, const QRect &rect, if (i < myStarCount) { painter->drawPolygon(starPolygon, Qt::WindingFill); } else if (mode == Editable) { - painter->drawEllipse(QPointF(0.5, 0.5), 0.08, 0.08); //(diamondPolygon, Qt::WindingFill); + painter->drawEllipse(QPointF(0.5, 0.5), 0.08, 0.08); } painter->translate(1.0, 0.0); } diff --git a/custom_widgets/yacreader_table_view.h b/custom_widgets/yacreader_table_view.h index 183797c7c..7c17e34fa 100644 --- a/custom_widgets/yacreader_table_view.h +++ b/custom_widgets/yacreader_table_view.h @@ -4,21 +4,24 @@ #include #include -class YACReaderDeletingProgress; +#include "themable.h" + class QResizeEvent; -class QPropertyAnimation; -class YACReaderTableView : public QTableView +class YACReaderTableView : public QTableView, protected Themable { Q_OBJECT public: explicit YACReaderTableView(QWidget *parent = 0); + QColor starRatingColor() const { return theme.tableView.starRatingColor; } + QColor starRatingSelectedColor() const { return theme.tableView.starRatingSelectedColor; } + +protected: + void applyTheme(const Theme &theme) override; signals: void comicRated(int, QModelIndex); public slots: - void showDeleteProgress(); - void hideDeleteProgress(); void closeRatingEditor(); protected slots: @@ -26,10 +29,6 @@ protected slots: virtual void commitData(QWidget *editor); private: - YACReaderDeletingProgress *deletingProgress; - bool showDelete; - QPropertyAnimation *showDeletingProgressAnimation; - void resizeEvent(QResizeEvent *event); void mouseMoveEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event); @@ -84,6 +83,8 @@ class StarRating void paint(QPainter *painter, const QRect &rect, const QPalette &palette, EditMode mode) const; + void paint(QPainter *painter, const QRect &rect, + const QPalette &palette, EditMode mode, QColor color) const; void paintSelected(QPainter *painter, const QRect &rect, const QPalette &palette, EditMode mode, QColor color) const; void paintSelected(QPainter *painter, const QRect &rect, diff --git a/custom_widgets/yacreader_titled_toolbar.cpp b/custom_widgets/yacreader_titled_toolbar.cpp index 51a955d5f..0265bc46e 100644 --- a/custom_widgets/yacreader_titled_toolbar.cpp +++ b/custom_widgets/yacreader_titled_toolbar.cpp @@ -43,9 +43,7 @@ void DropShadowLabel::paintEvent(QPaintEvent *event) QPainter painter(this); painter.setFont(font()); -#ifndef Y_MAC_UI drawTextEffect(&painter, QPoint(contentsMargins().left(), 1)); -#endif drawText(&painter, QPoint(contentsMargins().left(), 0)); } @@ -73,23 +71,10 @@ YACReaderTitledToolBar::YACReaderTitledToolBar(const QString &title, QWidget *pa busyIndicator = new BusyIndicator(this, 12); connect(busyIndicator, &BusyIndicator::clicked, this, &YACReaderTitledToolBar::cancelOperationRequested); busyIndicator->setIndicatorStyle(BusyIndicator::StyleArc); -#ifdef Y_MAC_UI - busyIndicator->setColor(QColor("#808080")); -#else - busyIndicator->setColor(Qt::white); -#endif busyIndicator->setHidden(true); nameLabel->setText(title); -#ifdef Y_MAC_UI QString nameLabelStyleSheet = "QLabel {padding:0 0 0 10px; margin:0px; font-size:11px; font-weight:bold;}"; - nameLabel->setColor(QColor("#808080")); - // nameLabel->setDropShadowColor(QColor("#F9FAFB")); -#else - QString nameLabelStyleSheet = "QLabel {padding:0 0 0 10px; margin:0px; font-size:11px; font-weight:bold;}"; - nameLabel->setColor(QColor("#BDBFBF")); - nameLabel->setDropShadowColor(QColor("#000000")); -#endif nameLabel->setStyleSheet(nameLabelStyleSheet); mainLayout->addWidget(nameLabel); @@ -101,32 +86,21 @@ YACReaderTitledToolBar::YACReaderTitledToolBar(const QString &title, QWidget *pa setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); setMinimumHeight(25); + + initTheme(this); } void YACReaderTitledToolBar::addAction(QAction *action) { QHBoxLayout *mainLayout = dynamic_cast(layout()); -// fix for QToolButton and retina support in OSX -#ifdef Q_OS_MACOS // TODO_Y_MAC_UI - QPushButton *pb = new QPushButton(this); - pb->setCursor(QCursor(Qt::ArrowCursor)); - pb->setIcon(action->icon()); - pb->addAction(action); - - connect(pb, &QPushButton::clicked, action, &QAction::triggered); - - mainLayout->addWidget(pb); -#else 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->setStyleSheet("QToolButton:hover {background-color:#C5C5C5;}"); mainLayout->addWidget(tb); -#endif } void YACReaderTitledToolBar::addSpacing(int spacing) @@ -142,11 +116,8 @@ void YACReaderTitledToolBar::addSepartor() QWidget *w = new QWidget(this); w->setFixedSize(1, 14); -#ifdef Y_MAC_UI - w->setStyleSheet("QWidget {background-color:#AFAFAF;}"); -#else - w->setStyleSheet("QWidget {background-color:#6F6F6F;}"); -#endif + w->setStyleSheet(QString("QWidget {background-color:%1;}").arg(theme.sidebar.separatorColor.name())); + separators.append(w); mainLayout->addSpacing(10); mainLayout->addWidget(w); @@ -162,3 +133,24 @@ void YACReaderTitledToolBar::hideBusyIndicator() { busyIndicator->setHidden(true); } + +void YACReaderTitledToolBar::setTitle(const QString &title) +{ + nameLabel->setText(title); +} + +void YACReaderTitledToolBar::applyTheme(const Theme &theme) +{ + auto sidebarTheme = theme.sidebar; + + nameLabel->setColor(sidebarTheme.titleTextColor); + nameLabel->setDropShadowColor(sidebarTheme.titleDropShadowColor); + nameLabel->update(); + + busyIndicator->setColor(sidebarTheme.busyIndicatorColor); + + QString qss = QString("QWidget {background-color:%1;}").arg(sidebarTheme.separatorColor.name()); + for (auto separator : separators) { + separator->setStyleSheet(qss); + } +} diff --git a/custom_widgets/yacreader_titled_toolbar.h b/custom_widgets/yacreader_titled_toolbar.h index de1386aaa..6856394a0 100644 --- a/custom_widgets/yacreader_titled_toolbar.h +++ b/custom_widgets/yacreader_titled_toolbar.h @@ -7,6 +7,8 @@ #include #include +#include "themable.h" + class QIcon; class BusyIndicator; @@ -27,7 +29,7 @@ class DropShadowLabel : public QLabel void drawTextEffect(QPainter *painter, QPoint offset); }; -class YACReaderTitledToolBar : public QWidget +class YACReaderTitledToolBar : public QWidget, protected Themable { Q_OBJECT public: @@ -42,10 +44,15 @@ public slots: void addSepartor(); void showBusyIndicator(); void hideBusyIndicator(); + void setTitle(const QString &title); + +protected: + void applyTheme(const Theme &theme) override; private: DropShadowLabel *nameLabel; BusyIndicator *busyIndicator; + QList separators; }; #endif // YACREADER_TITLED_TOOLBAR_H diff --git a/custom_widgets/yacreader_treeview.cpp b/custom_widgets/yacreader_treeview.cpp index 2a9799f29..4a07424ea 100644 --- a/custom_widgets/yacreader_treeview.cpp +++ b/custom_widgets/yacreader_treeview.cpp @@ -9,10 +9,6 @@ YACReaderTreeView::YACReaderTreeView(QWidget *parent) setDragDropMode(QAbstractItemView::DropOnly); setItemsExpandable(true); - // setDragEnabled(true); - /*viewport()->setAcceptDrops(true); - setDropIndicatorShown(true);*/ - setContextMenuPolicy(Qt::CustomContextMenu); header()->hide(); @@ -20,38 +16,12 @@ YACReaderTreeView::YACReaderTreeView(QWidget *parent) setSelectionBehavior(QAbstractItemView::SelectRows); setAttribute(Qt::WA_MacShowFocusRect, false); -#ifdef Y_MAC_UI - - setStyleSheet("QTreeView {background-color:transparent; border: none;}" - "QTreeView::item:selected {background-color:#91c4f4; border-top: 1px solid #91c4f4; border-left:none;border-right:none;border-bottom:1px solid #91c4f4;}" - "QTreeView::branch:selected {background-color:#91c4f4; border-top: 1px solid #91c4f4; border-left:none;border-right:none;border-bottom:1px solid #91c4f4;}" - "QTreeView::branch:open:selected:has-children {image: url(':/images/sidebar/expanded_branch_osx.png');}" - "QTreeView::branch:closed:selected:has-children {image: url(':/images/sidebar/collapsed_branch_osx.png');}" - - ); - -#else - setStyleSheet("QTreeView {background-color:transparent; border: none; color:#DDDFDF; outline:0; show-decoration-selected: 0;}" - "QTreeView::item:selected {background-color: #2E2E2E; color:white; font:bold;}" - "QTreeView::item:hover {background-color:#2E2E2E; color:white; font:bold;}" - "QTreeView::branch:selected {background-color:#2E2E2E;}" - - "QScrollBar:vertical { border: none; background: #404040; width: 7px; margin: 0 3px 0 0; }" - "QScrollBar::handle:vertical { background: #DDDDDD; width: 7px; min-height: 20px; }" - "QScrollBar::add-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" - - "QScrollBar::sub-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" - "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" - - "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none; }" - - "QTreeView::branch:has-children:!has-siblings:closed,QTreeView::branch:closed:has-children:has-siblings {border-image: none;image: url(':/images/sidebar/branch-closed.svg');}" - "QTreeView::branch:has-children:selected:!has-siblings:closed,QTreeView::branch:closed:selected:has-children:has-siblings {border-image: none;image: url(':/images/sidebar/collapsed_branch_selected.png');}" + initTheme(this); +} - "QTreeView::branch:open:has-children:!has-siblings,QTreeView::branch:open:has-children:has-siblings {border-image: none;image: url(':/images/sidebar/branch-open.svg');}" - "QTreeView::branch:open:has-children:selected:!has-siblings,QTreeView::branch:open:has-children:selected:has-siblings {border-image: none;image: url(':/images/sidebar/expanded_branch_selected.png');}"); -#endif +void YACReaderTreeView::applyTheme(const Theme &theme) +{ + setStyleSheet(theme.treeView.treeViewQSS); } void YACReaderTreeView::mousePressEvent(QMouseEvent *event) diff --git a/custom_widgets/yacreader_treeview.h b/custom_widgets/yacreader_treeview.h index 380af038e..78b0154f4 100644 --- a/custom_widgets/yacreader_treeview.h +++ b/custom_widgets/yacreader_treeview.h @@ -3,11 +3,16 @@ #include -class YACReaderTreeView : public QTreeView +#include "themable.h" + +class YACReaderTreeView : public QTreeView, protected Themable { Q_OBJECT public: explicit YACReaderTreeView(QWidget *parent = 0); + QColor folderIndicatorColor() const { return theme.treeView.folderIndicatorColor; } + +private: void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; signals: @@ -24,6 +29,7 @@ protected slots: void dropEvent(QDropEvent *event) override; void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) override; + void applyTheme(const Theme &theme) override; // fix for drop auto expand QTimer expandTimer; diff --git a/images/clearSearch.png b/images/clearSearch.png deleted file mode 100644 index f895c564f3994676cb8f0aa2863705a714306d73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa&H|6fVg?3oArNM~bhqvgQ1F(g zi(`n!#JQ99@-`a?w922TRf;l?Y?wCfnrhC0j2r>0J4VdhOBT9%x_W+Dv-zooV^_u0 z+I{cq=Dz*Sr=R^+)Pa2gV?cK$lL5nvUPJ%)(hk|WbE_G||6J>K>@{>|VBICpurlh< zO^ZIA_YaLlT^mbd?Q4Xkjqew|)N}|9bD!U)h}3IBnEmb9q|G z#T6Mr2~mqwhTbSvuz* rL!QN_-l)zpm3@{S(~IZJ9FTrFr_{eu_sJQcFBv>t{an^LB{Ts5#gKHz diff --git a/images/clearSearch@2x.png b/images/clearSearch@2x.png deleted file mode 100644 index 738fc2e779945ad9870168fec9f14402c6579b5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 538 zcmV+#0_FXQP)}3K*MvuHfABFUdI(lS< z3HA(SV+?`~2`Zm_X-Mz5q=fdDP6>(6pG(*GK|OZcq}(>E}PTogza{VZntY3%2j^L za~Ev6T;g~<`hZVKlB^>wRbGh$aa4@7BFt*g2mz6UTEJ*DGS6GBRu!0N5akMSDd^#F zFd$iSUjZiS6c7I06={nJ%6>B&nT<4bWC}_n?Pph2OpwK5VOHqKIJ61^ec9;C-Vo5V zCuUAv4Yo|`S2!L!BFd7+IUe+Sy`ZCFq_W2&!)WNc*i~(kBr#VhSJzVCLIq~`IAm&R z*70u~DMHFdj*Ah4nOAq{iEARts#)>iPjnWk4W>RbT>y39sSD~HqW*tOEI|Km5O% diff --git a/images/clearSearchNew.svg b/images/clearSearchNew.svg index 9f29aec38..a5d0bb46d 100644 --- a/images/clearSearchNew.svg +++ b/images/clearSearchNew.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/comics_view_toolbar/asignNumber.svg b/images/comics_view_toolbar/asignNumber.svg index 3342ffaec..0b658fe6b 100644 --- a/images/comics_view_toolbar/asignNumber.svg +++ b/images/comics_view_toolbar/asignNumber.svg @@ -1 +1,15 @@ - \ No newline at end of file + + + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/big_size_grid_zoom.svg b/images/comics_view_toolbar/big_size_grid_zoom.svg index 52cef716f..0717f0535 100644 --- a/images/comics_view_toolbar/big_size_grid_zoom.svg +++ b/images/comics_view_toolbar/big_size_grid_zoom.svg @@ -1 +1,15 @@ - \ No newline at end of file + + + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/editComic.svg b/images/comics_view_toolbar/editComic.svg index 8da5f200a..6eafb7fe4 100644 --- a/images/comics_view_toolbar/editComic.svg +++ b/images/comics_view_toolbar/editComic.svg @@ -1 +1,14 @@ - + + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/getInfo.svg b/images/comics_view_toolbar/getInfo.svg index 5ebd74e7d..a9884473c 100644 --- a/images/comics_view_toolbar/getInfo.svg +++ b/images/comics_view_toolbar/getInfo.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/hideComicFlow.svg b/images/comics_view_toolbar/hideComicFlow.svg index 01652ba40..e4fbb55ce 100644 --- a/images/comics_view_toolbar/hideComicFlow.svg +++ b/images/comics_view_toolbar/hideComicFlow.svg @@ -1 +1,12 @@ - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/openInYACReader.svg b/images/comics_view_toolbar/openInYACReader.svg index 91c4d420c..ae8e4c5c9 100644 --- a/images/comics_view_toolbar/openInYACReader.svg +++ b/images/comics_view_toolbar/openInYACReader.svg @@ -1 +1,12 @@ - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/selectAll.svg b/images/comics_view_toolbar/selectAll.svg index d61862a95..148b6b48b 100644 --- a/images/comics_view_toolbar/selectAll.svg +++ b/images/comics_view_toolbar/selectAll.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/setManga.svg b/images/comics_view_toolbar/setManga.svg index f9be7e9a7..72c3e3683 100644 --- a/images/comics_view_toolbar/setManga.svg +++ b/images/comics_view_toolbar/setManga.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/setNormal.svg b/images/comics_view_toolbar/setNormal.svg index 7e8c385c0..4c12dd774 100644 --- a/images/comics_view_toolbar/setNormal.svg +++ b/images/comics_view_toolbar/setNormal.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/setReadButton.svg b/images/comics_view_toolbar/setReadButton.svg index 89f400578..e44d0cdea 100644 --- a/images/comics_view_toolbar/setReadButton.svg +++ b/images/comics_view_toolbar/setReadButton.svg @@ -1 +1,12 @@ - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/setUnread.svg b/images/comics_view_toolbar/setUnread.svg index fbc97ea08..bba657781 100644 --- a/images/comics_view_toolbar/setUnread.svg +++ b/images/comics_view_toolbar/setUnread.svg @@ -1 +1,12 @@ - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/showMarks.svg b/images/comics_view_toolbar/showMarks.svg index 63205d921..470e92bee 100644 --- a/images/comics_view_toolbar/showMarks.svg +++ b/images/comics_view_toolbar/showMarks.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/showRecentIndicator.svg b/images/comics_view_toolbar/showRecentIndicator.svg index 5f12b064a..0d82d6c99 100644 --- a/images/comics_view_toolbar/showRecentIndicator.svg +++ b/images/comics_view_toolbar/showRecentIndicator.svg @@ -1,11 +1,12 @@ - + + - + \ No newline at end of file diff --git a/images/comics_view_toolbar/show_comic_info.svg b/images/comics_view_toolbar/show_comic_info.svg index 3e0da8bc0..22b596bd6 100644 --- a/images/comics_view_toolbar/show_comic_info.svg +++ b/images/comics_view_toolbar/show_comic_info.svg @@ -1 +1,15 @@ - \ No newline at end of file + + + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/small_size_grid_zoom.svg b/images/comics_view_toolbar/small_size_grid_zoom.svg index 44d20c85f..eb4d48a7f 100644 --- a/images/comics_view_toolbar/small_size_grid_zoom.svg +++ b/images/comics_view_toolbar/small_size_grid_zoom.svg @@ -1 +1,17 @@ - \ No newline at end of file + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/comics_view_toolbar/trash.svg b/images/comics_view_toolbar/trash.svg index 4767dab72..f28dcd02b 100644 --- a/images/comics_view_toolbar/trash.svg +++ b/images/comics_view_toolbar/trash.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/custom_dialog/custom_close_button.svg b/images/custom_dialog/custom_close_button.svg index 1a6ad742c..7bb61f316 100644 --- a/images/custom_dialog/custom_close_button.svg +++ b/images/custom_dialog/custom_close_button.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/deleting_progress/icon.png b/images/deleting_progress/icon.png deleted file mode 100644 index 707741906f2235b0596ed4d0834e4ddbb32604e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 292 zcmeAS@N?(olHy`uVBq!ia0vp^@<6P|!3HERbR04SQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JijH}@IEGZ*N=i{+S`)W-7o*2f=8a5(r|cO%9=UMg0-F<; zWapM0^BPMoc${GLagmsG-a)QIeMv(rhcnBB8%+-PYYqr|DQtbeFs3Q+h)Y-ahe)3u z8`o*U(gse=S+)Y!7cSmoc91z?!XRes@HYB9kUlJHu%OVcNLPMmgW%eVKmOU=jY}0C zXEaG~t#M%B)?6uUX+A;APU_9#Y5h@lSwB}iMKElqU9?y}>nVRm&VA;ZY3!FSF!C>W fc9_wjfssKY(D>+`*$N3jA2E2k`njxgN@xNAg8glm diff --git a/images/deleting_progress/imgBottomLeft.png b/images/deleting_progress/imgBottomLeft.png deleted file mode 100644 index 9c2f77ecc83c8348b154f07eb78a51a49ece64cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xc6+)whE&{2N&o_uBsm4M+CM)&PLAJS_xE_~%!aOi%pc_y z{*}GHwstm81%vREf80mr-@bLL%us;QVb+g^8>P?B&1EmNWR7H(7RY8OJk-q2Kkspo zF;Bytzg!*p7M7M@?P`C0QB{1tfoUU)z-`9DcaM&C_bbdk)3Z$C$-4Lj6Br+UeSO{j z*52yx%!!GKetdjf$`cQA73mo} bG%zx7&#m+PGIY%u6{1-oD!M|6H_V+Po~-c70G$JIEGZ*O8W8j_4Rr+HiZNJ4F^=x6h5*ZdBn_Nz;Gvy Vb@BqYzyP3122WQ%mvv4FO#mxRCOQBB diff --git a/images/deleting_progress/imgBottomRight.png b/images/deleting_progress/imgBottomRight.png deleted file mode 100644 index c33e6aee07866d4192953dac5e867384d662c4bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X4tcsbhE&{2`tkMk_4=3}H#evAOG-$bX`I2{AvsgxLqqlV zcd^Vt_Zxobcl3uBy1O4&Q~1i+@t@&iJzI?5jh)5M6;}xVc-WQ{{NusF=I0J8T@&r`Tb@k8U}fi7AzZCsS>JibOnJ978H@C8Z=JBrqk#DO_XZFkoPq$zZ!m>`WC8U}fi7AzZCsS>JibOnJ978H@B_$*zY+y^OQ%GatFkoQHW$@ja+3yFGXYh3O Kb6Mw<&;$U^Z5>kp diff --git a/images/deleting_progress/imgTopLeft.png b/images/deleting_progress/imgTopLeft.png deleted file mode 100644 index ea44e3547a932a883503e428033782f20dbedaae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^%s|YDSr z1<%~X^wgl##FWaylc_d9MY5hQjv*Ddl2Q^9Ca@%FDojgb6WZVSLtUVlfklErxSh#= U{f&=nfC?ErUHx3vIVCg!0Q(Lhf&c&j diff --git a/images/deleting_progress/imgTopMiddle.png b/images/deleting_progress/imgTopMiddle.png deleted file mode 100644 index a4ad99048a7a4a69fbed2294f1c6a89cbfc0d11c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^j6lr9!2~459xE0ADajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MZ%sgjv*Ddl5Xs;w?91FJfDGyhe7BcE0gtV_a8uM22WQ% Jmvv4FO#sS-9*O_} diff --git a/images/deleting_progress/imgTopRight.png b/images/deleting_progress/imgTopRight.png deleted file mode 100644 index c528653e38eae91236c34f0c78b3bde7a6337a73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^%s|YDSr z1<%~X^wgl##FWaylc_d9MY5hQjv*DdlF||qJ}@WADWoMZJ~DUsBhg{c#3I2UdWBhO T`!@OcK!psRu6{1-oD!M<{pBGE diff --git a/images/edit.png b/images/edit.png deleted file mode 100644 index 7ac38c8c321a73b199cb867942f63012b5f1fbd9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1063 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m`{4TIEGZ*dNbEH@3w=0n`(a76f36w1JVII9q%li;{Qb1 z<>e(y&Dcmw#}ektv6pt1%v5w>Y!eJr+i7imx>DX@jSgo-)ceF8f1=lgwFo$ID1wP2 zuGjvs{JNR9eXB|NrWkp?c4ej?&HoinyG=`vw0k;*f$`Hpd)3t}923Or$~XlS?EkD0 zQfT1)aZ|;C!TQ5yj|PTq4_13OFnoKk+N*)V?BQz928ObSt3l!q)u%HszB%l##mF>; z(S9ZihXH?`>e+nNAD${Zm>z%OXbGDof9h`8CfhGl+qn{!2-QqYTYe{Z3ecEystLjd zMF-SRznyvZV6VyVOJ?khYZklzzU_5s+uQTo@4vkF+HUgnt&djKPI=m0Qmy~@zazuk z*u7PnLJ9}I{Qct!wEgk}eK#hS8GQAELL0;l`2T6{t~0-I>E1!v-HlcsbiFRf%I`=M zUci3;(zAps2NhX5*zY&7Ebiw~I-qq@^RA4LkCl#0!~8cj`C^NF)*=h0KhO}e5!Gn){&A62BZO)Dhuvpp zDQ7%zJXM{U*RcNq*9G4MjkDhyXX>pDXZrr(d04|`n{CeLPj8OmY>*FZxTL~Rr@}bP zynea@;|Jl;1|c9{hw&HVgPqECVyX;vPq+$R?lhYQ6lG&v!4+F$Q@s)aWv*@i7E@ zG1NTe3UGf{-^X$wzJVbaXoDK#ESJ}YZcGpK*D&==WcV@h^E+v0paT{kvf{P%s8pVB z+pO!)x?<|J%oRcm_Zu0Sg(lQ6nVfpP&AR+PW9M}KHZ6znd%F+bUBA!P>tw!TibKN* zcZSB;1lARey$lD+bR3v-?lYAnH!yGDgyb|(cGEQZ&mzHKWzsq&SL06~Fy}LPy85}S Ib4q9e0I%!2?*IS* diff --git a/images/empty_container/empty_current_readings.svg b/images/empty_container/empty_current_readings.svg new file mode 100644 index 000000000..ceaabeb52 --- /dev/null +++ b/images/empty_container/empty_current_readings.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/empty_container/empty_favorites.svg b/images/empty_container/empty_favorites.svg new file mode 100644 index 000000000..8ca30b6e0 --- /dev/null +++ b/images/empty_container/empty_favorites.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/empty_container/empty_folder.svg b/images/empty_container/empty_folder.svg new file mode 100644 index 000000000..39a5b9dd2 --- /dev/null +++ b/images/empty_container/empty_folder.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/empty_container/empty_label.svg b/images/empty_container/empty_label.svg new file mode 100644 index 000000000..3d5d6d00a --- /dev/null +++ b/images/empty_container/empty_label.svg @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/images/empty_container/empty_reading_list.svg b/images/empty_container/empty_reading_list.svg new file mode 100644 index 000000000..9419898c4 --- /dev/null +++ b/images/empty_container/empty_reading_list.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/images/empty_current_readings.png b/images/empty_current_readings.png deleted file mode 100644 index 776fb0c3e8ba0207ffb8325d8f0f7ec776f32be8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1550 zcmcJPdr;C@6vuh^C{UVFr&aS&wqdjm;Tu#G99eZ!EU8(`N4cw_?wTfOktnE9?oRg7 ze5FVaVZtD`rOd)jw3q1uMq+9q*+U7lhbW2C?$7#br@wd3+wvwam zVXiO`2xK1{6O{;L0kAYHY=B*weX0sbE_6~7osyqL-=AKX2_k0X|CG5lHZPr;nV6ZL z!PwWA83qDbOJbvl+YgLRKdp{;i*{x|%RCLq265iF>T%S+ zd&xDejOJ5xt_h)^RbZhHX5W3#If%i(o6i23M^L7fFHHG~|0vfaYu|(8>{E>Mk6WBO zo=?yCralN6&&^z18uWd5|4x6&;<*2$==nJ-v*l+0!4COMI0Z!?VJw*j7W#a* zMV2lUD@Xo*@DDw#HtE)F|H*GQSyRBDyLsta{qE+oS5(rV80> zXqL|szFi`|kqnhHoCZeL)xUQ?fd+B>aSiOA#(;rp@lB;SmX&1H>AWIqsFdr%E0}@M zG{e10Frl>+u49T8R2VRaRzJ}ubDxDzm0>`fSr(?|K<*4XZLzM~<(I_rPH;dO9*&jA zIS_4)Hi{e#A4Y>t4d?cpF;echyfwVSG0#%CUPF!?+#{plG7?8>a#auo5qK`%8%Gj) z+t7kE$dUxYynN>)^y?BaLH5L5J-vp(NgXsvrwz z(Z8SG`NZiWdc`XrQ~W%az1p9&$$FCc8WYSG3nTe48+1NdX7zfN7eA)+xeQ%Y)8);B zWACB%UKvmSh*Tk|yrR39Z$7@UGa?k}2O+e4-cIt#!d_e>3tbH1jl`cU?CBKpLoNFD zOMrrI=~}1Vt3j#~xD+8V)S!_P>!v$SDBET@ro{G!(67O3$fY}Fg6_cUi%8)gRU4_! zfSsw|NX7Evg#<%X`e=ry2QXkh)$H$~dcluDJqxh7cxH$BN(;)yg?^UUHpc1u$Wjjeca6|{`O{m!~)daIIOVasEq<2ULFej<7s_Dj=di#B#^9b^;2>y<4(SI z>)=b3;Vg$Ey%#?6d4H+o*1XvmoDh3*G<=aX{WJ&CJFwmoizOKaFr|=V;K|^ zR<(FtodXL})t>GU`uNjkLDg(oLPK@02+BsAtPbwpFJ#ekST+3 zhz{kp)DqbiHJ4I0nj&;gzv+*2Ua!yde!o7S=W~Dld8jToDwS#`LSj6zgzqpbyYWfIaYOme9X8Z4Gvu?61 zznd?)awlff-E&NlR03Z@pg?0jh$Zxi>YmT%2h`G*kM2^1J@8V7MsTbGO1z!nD>i?% z>g>V!$7=Rue{a-qi?~|fnQ}1omi$1{Ze9*(hW;S#7G}icV&Ov}aFUqxkjua(Tu5O= z?)DG8kaIWG&Him3DL_0|LPpr4Tdeo`?kL>vIo#srE$^YdTYdLh)vIpHXJbDsmk{L$e;ae&}YPR!tAo_(-xlZ79|G(qS9!d%|NByrwhP$5#V` zXg&J)$DJKZ3XheGrOw9RmdZS(%x!arg?bm_75$rLE!4K4#8kFo5I;;7W{HhvL~Uum zx3R{=>AzI1G<@34C^sYF=fCNOt}iC(Q3kKS&b44iuGC*YS~u%m#ef=SxJactsR<^V z97w+GJ@>L9y!iFu^}9-JPR_B~dvDzr#uwP&PBkNZk~9Z2O(TJd@{J*JN``HmRp389+J!{e^7a?>e(b*3p|~b zP_~v7L7s+Jnq(dLL70lpXwGoQ*(==srwG2@an<#y#2?rUMzh|TzGx#F_(#UXLqS}K z$zh$AK23yo#6sH%Q_7tyS?a99W$hi60-FaKVfahKp3S^dJr?icC%x);*GdwL5Z~{l zT<1m4l}GjX1ainUMr7qe{*hs@x>`@33^;w0f(*W(hrx055AcT7>|$79TQbgM>_SC` zyFpOlUxrb*3y5cfzE@;oj(5H;RL!9)kl^N@?1;*W0@6{PSr~u%NPAn{`1J&&HrsG& z?(LbY-x6CJKA5YRw-{9XINhg~=}bv)9c~?@FGA}#bjOHyOdBc%X-$$lhqtWwP{YLQ z<8NZy#{%s*F?)*k0Bxdo{W%rJeXxL?z~~D*93T$?o-*ZjRRH&H?1G>)GHB* zDhtAF7GJRz?0-dz4|+Z8<;PRcl>QkOAP8k{a7Vtf%rkc-3O59Gjb%s?bqk&>VG&!x zG(-rD6T^F!o7oHX#WB6YACnz1Ljw`g8nLBDI=ptZ?uG&pCw#|E;KUO z)<_i?;7e?F#II{3YQg2%NbdR9T0;1fT^1KhnC>_Z9`GuxY;ow~C!F1p#aY`WvN`Bja;`o%>( zg9cTV8<6t-+D{v3_w`6HQ!4`%a$-wFdzG%qR|BmE)kE5uX1x@G&)R_z?S|Y*;_1R8 zYruTxg!LA&o2s7)LvbY)t5z1v90u}I^kV)ep(w*N2D?%CdVT}qhaj(wR~!WFity|` zV}IMx()~sYF9Em4pAje-RORukZFHu&=JZ#P_xTXl4UcQo8i-jXUMh_lUGCSPNB2j+DHp7A?)wDJP`jq0 z#^NEIVVj9~rrcJ-*U{KJDU2;UO1F+~?Yjd19x$1S_qC&MF9X+B67V-U{VeqksAqBCo|fnA`*L2M#f@Uk(mZq`=r=2?pwFLr+;EL`-)nE@e98!d8pE(dxExapG`Y^ zbjSY0*8F~!Z+Q~)Z3$Kgd6n*II%(VmKEm_tMJyv%H0$q^+a`SG<3-K8)Un9=+J2T6 zvfzwWoOmqfg5d0t1=g_0KZ=nbg=wE;uicLCq zUAyAtAe01zu+vz^yx(M+2X8=2awi5LpY@SGW!757DuAcfH;sb;oV3*6jKs8@^) zy-;XxR`XGuE2a`Jd6JKEn@$?!T8dqKL@1*5X|_}%*eJ9*V7&=mkgH*7R=CULkL=8Ja@%`wOqm0J+41KyPGI@_XWJm?mX$3?|8u*F0)&7*? zc|owVv+G8wt+>PUOz$v@FCKaXk^!zd2ZDug{u}X67qGW=vT3mLPyRn?(^Jy` diff --git a/images/empty_folder.png b/images/empty_folder.png deleted file mode 100644 index fa3b13cde0239492769d94f53bf767b651edaf75..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2515 zcmb7GdpHwp8{dYQr1FxIOnFCAbdW>FBw7wjuM%N1iX37QIgFtb5#C;Eyg8&^Bp*VW z(+oL_Eklbk?~p^W18uXDZ{PR*^BvynyRQEE-Ov4duHWyz@9X~KdG4P(i`b&9r3?T7 zwm6=#cLM-`aM^iPX_E}uqU}^!*cIjA8Fd~T7!~6e82~tW1?wN6>lo&DHNY*v?@C-m ze*g>s07pC8pS%z|@$EC&Yxl=p?SB1db5v0sPN?SC8o(wo)N$oC{RB4 z^0R7_Gcl5ImaAcJcpf@`3<3VCa2qo$emKRCTf?v*;Ov`830DJ6X{?66AkztF-+Sw| zPd2zqeACO1bq2-XZ^XOIuda6nmV6a%>0Lnzj}DhiuHK9~-G%*K2XbDi+)R8cFl0*`pO}v^NWfk@fyP+uRFO9L7;l81 zr#|YJDPHsiOZ}9Wvx;x;R`-+^O{$pAIV!@qiw6m2nhFnmAiwIvnkgp5?c#c*Lk0MH zlaF*L@Tq%_@07u6D8;~hf9Uk6<`R!?1OLEyu9|8FtjZU2$1a6y3ETXY^LSiqJtp5q z<6I5wd#`bJab$s$PJUr2pO5e^eA9(Rua0VVWNgOZw>4k9$3~&S>bPBsHbF4_y4@e; z#}l_2CruS9^@L0}Q`Hw;~U9eFk2d;@*Jr&O1FrAefg@ zTC?YnKA+zP47X^u)1eU;rz`l^P+H!+FBMp{1^$S&b{cw~&<^E+Cs~NgIlhay#U2uh ze;2ElnYNPNhEo39PhsII&%Rk$E9Sb9B3)D;SHdF3yFq2tWmUc1B7vgE*%NQ0fvr8N3@eM1!Gwl*#sP3EWL7rMKW0%WvBzoa#$rBaW#u9FT4o3HG8foG%|LaylW`JX;n&~0z`WIH<9mDYxhj}~ zCf4K9(I%C)xDY^h_6V>*Nq37p`#toP;1>j-=3q*&w~THESquTAO1zi0IWwF&&kq3$ z<^brATB8^-Y4so1ayyBZX^F`Z2i|q=D0xLowE^$Ln`(4eY~x;L@o2g{1-F6WQ-i*o z=Zl8yL}7qW{#w`1XZGUwD3y+Gm*7VUZ=VrKlaz4PuJzxP`NrzB*;8$HX zwmA@Lyu-?-od&cF2=&V%_F-GXe)cF@Ff0_MN`Xk=|Y~)7^q(Odg0$G*6 zYV`ke|1-ub6lZtlX)7}$Dz7>>PdpV{nfxXO$~4!2V+NV#hmNc-#~1&LsT5fD1}ECA zp@Hsw*1J5!uj|to1Q3H&LR1NgaBY)`J8KuWz6e^fGG>p~d#tV}cun7*d9~I=RE;fJ z{gmV6z`v*n(^qI)r1Sa1I7Qfvr40Oo&9LturmC3yiVF=i$TW3Q>2JH*-rlP0b&Z)Z zHx$e_ngT(gXA=ktzRXaTFb2)mPyA>kzGVuMP?TPR$aTHTbEATir{6BvKadID78EBadRx}8`vl{W zJ6~YpM70A88kr2)Qz^f*cuV!F+n6n}Dm>zdVcgq#d|}cv^|yKQGuj=H_zk!RHA-pH qYV58Bg5}KOp>1f*XfYY20;sS`^*(JHm@WII0URC9+E?3QZv7o7SoZM% diff --git a/images/empty_folder_osx.png b/images/empty_folder_osx.png deleted file mode 100644 index f33e65e045d9e0fd69498d80b1981931db88b976..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2446 zcmb7`c{JNuAI5(YYO9^-&}ll<($TSWsI`6=s#=O_X=w$ew8mCS8kM3tXiIcd>_Uy0 zp_VynD-wztwJ)tT2_d$UjY>rD=FDGn-gnM>PXBrCy`OXM^S#f#=bm#@T`t*6NvKEw z03hXX-u5y82!VqBrr05YGI!;M1!_}&Wuto_6M0**U`_yz`C4)FDV z5YZc80RZCq4z|`;kkjiVjH~MEH|_ITS|S;c90jGMO2F0HRs^Qx;{kXGH9;07UQ1`_ z)K)_lOX7#E*=k`t@M z=F7Ko@UrBYqbU@`r8tnZtOS_VCu%Ga}bf)guLKmKVVe@Tvn{K3?Doa%vmFBj~ZTK_+8M?zOZRXN6 z!cvJ%9`uR3?3oOKm)TBM4$mDo>vM66(Q~G&rVBCSjBUXaJ!&bKa|<3E#7qh~YoJBp z!a7HF=CvXQL5R9ax{W6kx>9WvtLcvFnUvbDUnlS+shx$OzC2v?$|vlW0b1AMZS0Z; zp7;<3QG7;mmD$HwHD*mRlts^mN^D>g(!x9m>0pR^CSpLSHC#By@>Hx7+FX;t(P^$! zmyVys1K#gXXeW)&hlx;^wHcwj8(D29KCW4+fznC80n^l(I=>XKfKr*Pdfn)Zh196t z2r;+_a)>-e$}Io$(Uko7aoud#?u$STz0lpkXgnT78L*r~#P7;#H6z?*TFm@#3|sz+ z8IFbzE!}ELpV1uu)|yp1xEdxnqYPh?oFcfk{pY>mXKcCWG^PuGWpr!#@@>QVqx;)f zjP+Bv2IPpxR_=_vA}sJoS2GUb9Z4_ex_(Hd=}D!Qb{gj&a^Y(?^UuPpROGcLDWUfa z4zo)Afrb9K##3dz0nCB7LW$= zUC7A*Ml-F3JF=~ae6i0eMsXc$9Wvz4Io~|o(e1eU@?qyI&d1I`t*bz(DI!(IxMK?PH6*A9foPTPj5_$GI&w3&O!~&+)W>kp zV^)<^iMgG2kE44yC3G{V@{uf9d{OTCCJ4eF=8mkjf-LA;SVz;5(B5ah&%0$-?gHf^ zTJ7orYAJ-B6b)iS&1(K40So>p0kYWpVJzEOq=@IjkFU;$AqOd4GAo^19vlLg2_Ke3 zd`8=_puA%G4BTW+Xx*Rhh_>Q%KMCuWvEl<={}5RaU_rl1{<-?U%>HfoRo;J3{>lP^ zqF^{t{Jm{ThEsK-3uue-oGy zxNK52luXtsmTuNs5WILf)~@&5ZXvQSUYfHQo7$^akh>qBhbPoQoZFC%L?Woi?25R? z8}$-x9SNX2RK1F=gdVGdP@>j%cjwxm-lkvd!1sc?w`aJsc0DVmS4DG>stHn^#wVLl ze4YuqE)ndh7nhw3r?%*F(rGE zU-VHU+19Lpwf>GsR=%QlF!T-0use+B&-cvP2UKvpcW%mOxSi3EhW>;5Aaf`aD zg!G&c6+)U85r=PYnwx75&>yCrHXdAPK@AWskbOGKpV{44ea?|Zi>)`;=D+`;Z^E*p zIGv$}kkG-mmvDr&gL2E;R=sdRF3T|*iB=P(9w*SC9kY$5@6yTMjw~F}Q6bvPJr~!v zRGnQct4Kh5k*I#|>|X*OYd(6V*qI}|aI}L`aZsoeWR^rKT(c=C<+P!ivWHs#P(Hu_ aP@pO`A@{=|-3vjTzWLs_HllUKDc)*wd diff --git a/images/empty_label.png b/images/empty_label.png deleted file mode 100644 index 4c0857233ee08ff63f57f8f0216b20e05815a82e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2046 zcmZuyX;4#H7Jf-cFeJf2C^T#d-6hD9VhLEoYSPLGGC+$gMg|BH0)l}evM2~iz{U}< zeRd=>|F`%@J@)`oDAP96Cg$S}Z$Sxo{H?&hVQ#C){Ip?19ecwIz-n#c) z`quj}NkdNqf*_KI`ypT8msH;l9I(e$sRw`~C%7F?I2OlENDkviKuk{D$q1?kFDx>` zHzJI4F8L~tZBfXoOrx=oPE$`Pi zp6Z<`*YE53ASGW>thFVE>(AB%C_Xf8RyVd&iWUOL?%DT^u#yzHo7{n(4;-TH&7%4R z{=i<8b8q~;!)3=JUstF8BBcMTe)gu-bWT^SZWian?fssF@#7u!%ktz(> z_`Vi%RjsX4M^jI)D6w(ZgZg7<-CS#4&&Y(do+k}yRvUu2psn@}PK?#Y%f!gL_7Am7 z4%kn`6`$N_qdSqmTN9g>N=tHw>N`=KjyX&Ca(!>FYoD_rqF>C6TlS=fl=R?O{qx~; zqd1;AY`>l^#T$HGx*6ZPn)a^RX?onetUoB?tgB}+SsCs*?DuLlpvz))aK9BYRwR<9 z_nX$VrC2;ZVs*`nusAie>FC-g9es!11=Faz%M9hzwH7CyiBYXr#*`oZLM!d=$3G|R zl~Y5V^qpoMZnAOfZY(A(o{q5@e7rI%_6KT<*4NxVOB2Z*MN!t7 z&a#Pd$7e~kIbrj+v2=v0jv~>KhT*1KI&UpS92{G~yy@nHIV}JUwM~LuhsS-)D9vY>wv~Gp|T=4=mjp4qt0+q7W1(Xsp%dzdj{Ea3ot1C47$Iy93{-V_T)k&;GX97+@N%9^(h%*vE ztnB)nw4D;2@ZG5xNuJd0E7QG*@9))zyczkneO-xYiy*jsy07cq@eE5ZL4fNz?G6d? zwc=?PI-J^_ikA#{n$fOR&h0W_Ulfs;~gi>11CrlyJ*C;rz-|7KYGyh+>JUK^1RBp^!)Us zHu5~mxU`i$hUT0afRig-tNd>TqhTz+;>VCWUe?H7nBnR;IOY6vbQLBMuly9CX!Uwe zNq=8ru}_)yq@#1S;_m{@%j>tNf~leYse%0mvgz}&DYNH(_=|c=o7X~ji@*juS?cl` zy>5>5UH^pff2~%qOhX)el3qL}TksydsCYk^XLk;9yE=JGD^P$}s>Os-EMB}RajGMT zN+v7f#w=b$m#l?Q&<+&kEqB@K?x$!6ZDsR7jy6Pt>5TNBa3`of6#h&wPmJZ8AiM~h zM?M+u)X+iAD3Nm-;t&}L@>$Icf^zy`YD@X7$y)_&mcB3G}XvaB7+^aU}83dz!3uk14FV!K&(PD09XXDz^N#NC=t=_DViK5 z25(1{$Wn}z2>(O)!a}JCdVsubbP=?Q1;~0|47QP>`xLxB+X`Z)?o-Bg%wl8`ZMS0) zP8CapI5G!C0#1*Eayj^PTLch2Rd5yLqN=C~fvO>7hoBvyC>Wan0o+?irHW!$6~#j= zhL3&%VI2=7c>h%b5*Q)47=UdCc;$eRkN%Q4r4$E=-(2l%H2+%+%?q8N*pj~pq%Yhj z%j8$EU^0#nw4M*ZXgv-d%xQ=0`lBn*j}Fle@dZ72qCl5eh$Km1j%pd#GV^O=jwwIS zEezdmbLn}0%s4o7ICqNykG5rgSIL+W9=nk*7^Pg=ks`cKJWKWugB;0csyV4ce@=0ssJD zR9CPegJ-ZfO({`qL<&xQ%0^E>tjpDjh^I%3al?c1)_Zfsa6c z2yxLBj-@^O{gBE~=9ai~MnWA%ck8j}Ks#HN9Z!4-B|$Z-T$@bxrvlXn=Io95Ur%4^ z?$0#N5`8>rP*3Jm3&)lHJ*)ss8X}>^x&@YVG z!F_8TQHtlp+)RB4O41=`Rg%y5O#KhUP#BaC?9=rXZz~~el-C=hy6U4Ld%P;nHQa(_ z&@@G>I&m)5Bc>yS*wNN(4~7n|7}(V?N!WRvc%Hs(-2qciaBC8p$Kh(`qBiG1xX#AI zLloxI5N6eq;Y0tPUSHg!gHI^VP#Km2-%IFsfy_`er}Yvg_haNTA-1@!RW50^|;_8UChiyUD94Ni@a?^epB~et6E|W2o(@*NjqAMC35;- zHYF?*&N&==|CT;qHPp-?yw2UmTe2;Q+}xFPg16?<8+`mlp6Xc^_sN?==I8b*o}igm zJ4Q;lD>pKi0$+vDkH?)^o4p_S>o9r4q5S~c1D^h_?n8h|IC81y*{N~07Vxn}MW#)w z&yj-bL;_W^O5!Vt)>AI@Z?=2TS|XDjniU@?5c9wN)$M!r+n>(ff6a<_oKl(7nh*DR znv}MJ2(0^xiRy|ol7{JDp3us{GVQPNjO=MN=JZ4+Clfu*(}w>Dzm9c`(6PH3Nb`3H zBeYan9fFuQk$I14RQM*?x zZ$@+6n)h-l?nI%xDU#xrKEUsiq8x;&3~?}EW$XIbUNMaiY4Mnk)g_htZst_boQjVt zJFOc$uwW}$EtsLMv_Z3=mS-FE1tYq3oHs2W=SCj&^0BuE6=j592wc<@GUTas7h#CCgF40A)?rXHY;slY$?Vf zT_&LObLA_P1+`Gtiwy;LC@jaU#+`|3WfPFQ_>0lH?il@^h?-CCd!9+z&Z+o%X#M>n z=HCBv`krK`Fz@bVwDRSC`;^pP7S&o|G$;%$47JFp!`&80&F$@Roicmn*HuP&7l%;O z%w?c<&H`w$cPciZ!`(+4n$kBDeDdE{J}!Cw%~Fzby}E0xAdRloaVKazI=HKU?$&|w z4dP>T`L~R6nn&v6H#z5Se2}MS{qB+l@tNOnQwd@yzGGy~DUKE>b8z|(o2`cXSPmV* z%t@`ch)I2r9{R=uWa7QT!T8W$D0W!zQjs9ME!}EuYVrBaVVWf6?I?5S=;?hteR1Tx z%8k;gyj?nPj&cmwI@vW=4FPX8>`E(xFKZ~p%K)vio;yKn6jI8d1*ZL`a{n?70KiGq z%fn-jc(X~CDhJ@}*i@`CoH?F{U(3m`L2e^FIR@YRN4S951QBIX@`O;Cb=vUzajB_L{q(i zzBjj;cP(cJEzalIGHkuF+cQ<&cW5G28@y-a;}+Mge5S9j^XUWVHU8&o0Z2-i%d_#r zQj{0>qhQ(~_q9%b7ISGT1sBZTwz^n~Of(luV?$$p0K+Q<7e{ z3E<7=-142a#q$)M#t|sm?vokG-V0K0Grx~|L%A=eRM!a^`Rj8h-yti$hrk}V=E=g4 zWn{y{mhphK43d1&&cw%D%Er3%o0qxwv!M0f|Kv1Bal?QRLoul(GL;YWF74Xo zeAhoW8l@mLM>~c!A#%G+4(BEI*He2Ri3_d&S(H+4dr#N;~8Ovij`TN@1T3$`pv+OOk7ZdoeO8;W-Hj6o|j)N4?^8;5V kN*Lh#vT@Cz`)!%E0j3@O3_mEli)7hAI=MSm+h4r-H;Fr%kpKVy diff --git a/images/empty_reading_list_osx.png b/images/empty_reading_list_osx.png deleted file mode 100644 index 59667e1f36d5e37dc44af8c4f39e171f2877715f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2346 zcmbVN`8OMA7Y@-R2)ark( z6L&bb9s=UL7SeVMPLK$NJB8W>`h`Y#1^WUnpaZ>qT~c-0RM-CupDq{+o$Mj9Ly! zo6nBh`S1Ab$#iTh-_sXcUjrh-hEFo;*% zS{fF~ELoZ)*4r4}RGkzADNcA$d5rO8L#F)tywKemySC~Oc~RSv>!JLv;?90nChK{{ zGo|}2I#N7ZV=5h2?$@iBSC$yCQe*=2I|3D0wv~e=`a2t{weodWM!A-{S24viZ#~52$p3y(HWe zsBM>JY6ND!o{rA|>-Be(SL64xz@BaQt-|y~Q-6$+N=fQ!D+{-CS?fjsByv;U&i6=O z6cqklIoq&@AGW4q=SwRlf%VRXON|eUInOOM&Mc3trDlGBegIOuRmGwM(AqwI`*Hmb zmBtAQ@$*qDA_+xf$xCie9vE+f%}*d{h)W<{HcJ-r;Z^r403yx<<`vl)?sWQ0+5^6D zM$$qQ;u&0|T>~l%gVuKCas?=jm!!}OxCqPct7!}s3SI`Bs$>})F@FKt1Ejp{w2u@c z%tvY?eL8r^?kRV5#;>L{C)wAU#7IZ?0x6Tmc5vFJpP=B?c;`Rgp1Cs{323m(|wo5_zig>;l_LMvd-)-A>lojK}3|P2j*>tNKAos-i_-{1HQr{ zc!3tS^ykcp)I!G(V$5{TeEiEZ?hw|yOc_}Qt#l8)ZNgMy@*8C<+`HXJ>N1oq*?vJE zvBH(T6ZCUWuRbc~g?788sW;vvvt5AXxU718V_m2Yr4Vy<7FtU8L}oSDZQY%Pl834> zrfx-5Nx&8JZ?9hbuJy~~gs2J7#$2WMq2drkdv5HCSYL0VjYVP1fKq@v`svy4J+Y+h z*IRYo zmVcJh;iLw`sTHIaBY@;?wsq^osK|Fp;xrz4SOCBX3)~1xJoxCXItfx+(rQVT6kQBC zT$6IE$PjUn={J+D>0Ma%ks*r7>I@FpSg>QGO7T@?)YnsC!F}rhb&bI!t8}sGm9wJL zIsOaUDlA%_RXR@|UZ(%gp&%m05&fciJG&;Z73ra`t0zKx@WOtrGKKz-t5e+!;&w8$ zXtmb#Xm$*&D&*RKwm9OpR_BqGkm%_QiIvmK*K7vLx$#LsjK(nvKF-{U@YCSwONJ_M zbCKU12Fp|E0bH)?bYk%(P#T_tP}VTDR?ed>L`qp?C^Ehlg3oGm>dM>FUYS zU}`x0WEasCexPYPy}J{(X28jBTZ!>7b2QYAg#4~Ciy)*~9;a`lk_Bt=94d-^CJ-yv zS|_sL^>-Uk1eKA3HYF_i5i>yo8OECX82#=r8S9&vQ>(SDk&xfei23}UzS(|E_h6KI zwtB(Zt`5;MfbNtW+c29=v1J4y)9dTz>2!nJ(?;*aD`66z?k97Havpw#$1QG3?T>wh zA0B^vbPJqW8LKh}ksI1v5{W@G)L_3ZVNkNm`?t#nT}*aT^a&(_7d+FzXzmQ8JHqMu zJ!FQ*IY&1~-hZib0D$N^Xi(FNt&yZ^`7n3MZRF&wn1*nTh+B&;*@}#uHp}||8@e$` zKwJGEN5=?JLEbCF8$H^cv<$LwuI?*PyoT4o!mv0=m+IX|-p4)d(iEl&w&mZGZ}K!d zzH(QxKfmL_ewwEO?Ro5Zl+k$=^V8|O@Jvcrif{X0x`&ZB$-`Ret;g2bgy5x6YLvWa zPIjyG{5O645B(Mmu_!q8n06$#Vx#t8Re(I<>P}TW>`C2kVkF_PGCt)jTKVJ4BpD&9 zW;aaeew687t;!jT8vALyWd^Fx29gDm<;1SAmxp{mJZ5ct+vDFN#M(p)@L|itPTnky%1?; z_m6Y-j$%fegtQ{R^z<76)b82RJ2-aDRrCiZ-cguNR@3Z(ng8zB&R%%Q5Leule9>sM zw!+_zU-v_ph&zUpTO(E^KlEMZPQ+V2BhDul7un{Ds<{NJ-sEyQ@RCkRSS@f7Z+_@K zjpltl8zkqPsu+kR(qTlN+(if+g^jS`RR2RkP7Wj^` zrk4eG&yl}P;%u;}qEeW9z@!7CxS=)}Nk)2O~nUaW}ov5kyo>G|gybM1g?Q~%DCtxn(vQmczYGt7a44xfN zUmx;#KZ+)XIfr@&>V%6QAu~fZVk5-&k!I#YvTp4Mxz81dp3G{~ofM@C);OgCMR>D4 z_0|FNeH<~o5xI3&%zb9(nyz-yMEOxPW}E^qI7qv&Hl zX1c1o-{14>vyv@oXS(a1s_KvGqCf~msgfqp*Y@`ImV4Xr-_{HNwRgjh%g=3H`?tou zCO7=-)xy_f|2}#D{(VEM120+)(j5<9<-uHpHnb)ldI5YYF9-FQUIJb~{RHZsf8UAZ z(kK3P<-PQT-UQwpV68o@^$nqItZID7EijLP8F*94Qx80>2MNKt49p`B^N9Qzcw+&;l{=0xbe!;I#&=ml83UNXY}WH1-H=r+UBAh>UeJk};pJ(TZ?*+^;A^+1as_>(rS z-RnW|>D;8$CGEPO8o(vs1~njobbf3|W2oH)=J_!#I{*y4xq}bCE#`f ztehG!O2I%}|16#su?4`un;N)T9P{Dl+*3IAB?*8_z}?8pW?4i$ks|fc16%^`$`Vjd zI85sg-dM`%RsbAUDl4o8gMln}tRsY0<_iyVSbDc~_~F{Zz0O>pe((?Dm^`s8x&6Xj z|0SMxxhHjOE2r?Z>3iZRS7MccJ66^zpGK6^9s%t}5T8cmiKVY!5H{c5ncqdyF4Bpz zwTxWY$Z4`*1;QiMU`p1+Km4U#OT%PvNnD0+Z9W-~Zx;>j|5hGP~-F37ogU8+VtG`LwxF9yD^MF_X2!|^$Hkc-&ug$v3wiv`Zl+!%G+$- zIj=7kH#B_zCw}UOQ|ZFx!lIW_G|q4sUByt;uIv!p+UL1eL!-y!wkC36%aPf><+8G6 zN1Y-$&3mJ{&A7G^xTf-8DMGMc%%RWIzn+yNsmsnccu~b>ZhuH-Injd|Uu=I#iiO|A(L8``zD zd#vrS`5bW3hGF!_oj%3#1@}UQ&*#bJygppEH0Ut#gAITiC&1gj53Q*7Hl9}4Y%p9- zvRYtE?0nyG6T5swjXEMY-|bSE~CoXgwPT?zcu18RF_U};(4tMQXK+r zRvuXT+Csf4^}(yPJg=V`dT*csWv%iNCY_}R7H}-gyKZYu9j)tmpBrejG2mwHfu--q z1};U7g_Yr5sFtrOdD1<`gtOOUZws0ldM2XqycWDJ`*G2H1lqzwT!o31wgmbo%!P78 zN$Hw@V!BAwG|evtO6u&mYj_#DoYJbESKI4Ko_mbRqH7-b*g*apoQSO~rgJiosU4ihwn^mWB7JVuQS3`6F5(d=^{LtVH?L47`3JxYj<(#y}o} z;?qf?H+Z$pMx-S?|_wiiu|UO?@nDOY-5UOT{+v8LDotm zVsy4UQ1!h2Ky0mnD#B$Hs|{^=c2vXWM@ly@UiSjqLmP(AVnb71J96(=hXriuZvRgz6VrU6hJVb;?kAN67q}!p#O5r9=5ian@we)pTdi zSjc>anW4mNs}3DD?ow^~3P4dtQxA_k_$S2b*i1t)78=_X=A=8Q9!j*YM(b5uP_v&l?)v31x0j zXnC8PBm=KY;%kL=9AipINx^Ne?Zq04p0^_3MdZElcwcRJ@w_M-&)YU*i|~dXX`Yhr zBIUey8u()$bOmqdNo!6)K-vmzgPnQa&?C+7upOkV&^Fk9&f9gBJMvwG=bfod)_O`_ zS46&xv^7=u%$>I3)fg}!=S8ZD-3I6I))_qU5VBy4b=&Y3z>9!4PR~n&A>fS^-p~s) zK43G*h(g=qUfb{@gb14nn-O6%@FIjQ5;h~0YS_F(Qy>&XRon1x(WVH+2`@s3oEISk zya=It;bnUsLSZy*8(y~OArvXR2qALbrBu=M$cQT71zrTaS-^`BY6;%ZM?ZW?(<37a zZHrfJ!%L`w2%8C;ffoU9NO;FI7y{lP8n+E^aJ79_DMGo~pymoIwjrV%L*_}V@G2d( zSz|j$S;0MTo2>P^cp@yR2iOi$R%jb+m9a&5LwjFxUX+{XopuFp=!F`U($S&_&5zm) zo%6oy3f`$g84<|rL#)$yeJ#b+csmpE}sm`3>c92 zBBgvc^k7x%Y-z(QI>4Mz1~%6@yjKc0Mc#{Yu(_+Q;l=YJJa3Gi*C*7W7i(;}90Y(- zsC-v!E%Z1`)5U=BO}mQ53T^rbvqA~mS|?2PLd52T&M5Pc`6?8=8lG1|=OK25Iu4nK zh0a#gFrHT_?eW?zO(3ycN)J4cFHl;C8HR`g&R8Pa*-=pW48%o5cI%ViC zct=V%T;Y9D%U-uq`uLFwyo#YS-WR1{OQWuG;1&73M;!kGzp{kqJFQX^~;KBG0m zWvz$)BvdiSWlssz^uEtHQ4p=*b;VYmrS5fCfmd_js!$GrP+Zcqm7rrp{iUv`Y5p@9 z3_dUP>MU38^M7~O@iVrG?(n+eai1t&!nZDD{xQ^tl`Aw%B`L7-Q*GBZ&J;66x7g>~ zLigO~?U44lY}j1*i@H#380nOA%oN?Cb7gQZLOYh;ia&p%+(ET_!X9I%=$h9(F7%Ji z3C>2jMnlOHZm8T)yGmy(A$#EN_;6WM;&l&0e`s%w-#IbRXRlejfxHd8HgG8_OsovA zf!tSA8R;~n{17knmO!fIx|?`jE8bV~U*>=F^}45pjU!^!Sm>|wOO4ZDFpwvn_R6P+ z?m9lW%OU^G3*4c5`^Lbfyl`IkmDY!s8#JKg8#3=}A@^heD<5zz3{ZXaVa04-S8e6t zx?%HtyWp9TK7GUb=WM`zW8`wqG{N1-^DZ>#djo?8CZ2?-Q*bRsdU6WFw)REzTKF4> zM*4Tldtj!J(ggR75pd1e{KoLQC(yXitG01nI{=(4xK`4lk+=Ey;q^KybhiuwFyMwt z&5o?JPb={HN$L|r{SLr@+l5Xn?P@DqZg6Sr+E8Q5lX9PFr0BriF_z)3}vQ;-S*ZB@*Q#nlPij%oHpJ&pf%xv`yoEWRvq9{p;Il?eO^V9ub)_%+lvI+=ZSk-6Cre|)WNX<48%Zd4qz>KEpGP$VxWx* z;8L;EV+QzR8ehx`@Ll9KN9^Zn1=^=YoQo`y0Ju~(g4h9`OUeLUrtXcsmwi;&pEbw= z;L?CWqyq5V8_z)=B?9ch0Uq2wlc_m(B~<-V3w(2W9Jl`!U{~FDv`K`|>OQLMS^A+>iAReHi`9PbW#) z8b+h@P?JGlF9mQf_PcZ;#tZkhTg=uCqqH^leSMh0z1~|^wx7aXHZ#4%3n%Su|Lz{t zfAf7k@$>(w?<>C31NW2a;n|{&SH)~Tm|Qpw$+k*481BbweVskPWvX}VN2JdS7Iws{ zX)zml9pBT>L*LJ-YyWy%l&RmbKhTO=OL2wBXUxnYOW&qGh_!Y70oBjJBK)+H>{5E^8-Z#Owshh1+E?oyF_TFSTrK9m zWsa8OOP5Nm;UV0pLwnL@>D&xLXsNieoh`gToF2590W49H_-tjvgVrmz!=VeD8+KF;MrV23du3!Kh z^KrjS9{Z9g!27_vURVvt*MKdIp9+y6z`(m9$h8Mq-m6S*eOk)eZUew7B^!qpO9l$8%_7%2NUO=5Yt+ zc@Y4|3Gl}iRz128<*Z1z6Uy$m0?&(3TpsxUyNd9<2*u@rkLF+Cc@c`o1Is-7{`{Lh z-G$I68Lr47GX#HGtTY0=2-yc%z}>&T4;pw8vJLPY+&?X#0bYdc0(>jDz>APwfbRqs zcoDJ*@V(#yFGBVJUJ6{`MaUMwOM@$7kp@C5${%9)x@foH!b;$ZSRRScit?xRwRxbs z{GIJp_fz9}5!%cP4~yBU8`T=WK6S4nIsIUr&jwzE+JSgpRkXeb`JVs-0Gd$*`W{Q>Bme*a07*qoM6N<$f_>lGr2qf` diff --git a/images/empty_search_osx.png b/images/empty_search_osx.png deleted file mode 100644 index d9b8cee576bf1c4346bc7ef402b762bae9d62114..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4212 zcmV-)5R31LP)JO^grO{GpfQCLqBf^`#^XA1L-`Wbj*1NMWyqi2vm12XUeYyu#+5I@iq zz-wK@e#|T-?mM--p4(G-K@k0x7LvsLc zAJASZxG0>YCcXw@;00PB240{=Kn%Rzpp`oI256&z_=15g;O)S@Dj0~0Nk0d+T7a); zicH~cp{?7u`{MZt9u%J>g`V=HQ%3M=T`MUvtD(}+OjBv<;TIYu2JU(L_5`>|N&50h z`xd3 zd26Wv&qDU=#tkXPPDh zE?TEb)95pt*B)G%61X8I(GHSTS+~Gz1FkH(I3otp9+F)c`ru82;mhE&a z01hjw<&pOhf-BISA9Zq{X>PL$drhTSjb zdI#n}=>Gd(T)2)P+d7V=|H}X!C%`^AuYs28w6~x(c-eI6{3hPCufrI!t`MWm-gm&5 zYi9xOz|uB8)He63N@KRj8eZKP%yX(FZhOoo-a!Fwq|K%69e>O^hE46t0l}@c&h?ra zol@JnsD(XeX2+hll`RMA6sc*xIjwExMdq7zI|JDBuAmYl2VP@ksI=MZhUmANCIhaY zG+Ma=I7ude^B02gHjaOGj`bGZk&o|Zr!GOCb>h0$3{asJ zfF%~Jx70Cl-))`O+I6MQy&`1M3xKa2)W4T*;dS7;k|IqBRrH3Yh3x{4;O@JP^Lj{^ z8)6i_;l7QB^f}}&+i0HG!D_0x?sJ6Dx>%J57;3}pFxaZAO`Z3ouw6~Xd@hP1R>sPT ztF-x}VT0TT z!F`v;>2nZf)(%*;cagu1>Rmb0=73N{yQ+;{8Dy<2GR8J`-pTj1r}&MQOb?*|?kh27u~xng z1+PWDJ0rAE!m)M~3SJB6C1pk_$J!uFm9Nyhp$~ClZWjfW(VTDZhvB_+UW)s~tuYErhyrCzpIRyb(D|8GF z=DeXtn!ge|$XKCcu>YEO=w0rpcM;C}tUg&A8M&^AdKX!%G5DR6zTvePFrel|riwiV zJ9z61?sy1!h{d{Zcnjb~z#FIY(qIU9BZW8g0*&v)4058-v3S%sya*xEX3}Ov+6=r1 z5sReF2&I}fPiP8+f~e{n-Z5>8P@M20gs6EDLcog(pENykqR_GU*f+eSDu}e1v>A92@P>qUPJek(DfBZ!qVz7;!!# zhLDjgVsDt5*XXQLoEK%|ynQn^8uHGt$$$ZMFEXlkLl0K<&XzU2q7%XiWe{_N!~1A( zQPjOChnRaD8eW_i;k+?AuNKsy7i)~$8U%n*sCrjoE%Z3ca)<%p*Pbex8?@;M!U`oE zYlAQ~3Xz+WI-|@}=EqR*S~#zy&S%6G8aQP>D{LM`4dc8P26ElXC}kcjlYI-`&qi%b>Wos0tm7F%JRSGVf0NSztD zLPMm?5>plfRkIOBw{Tf{oZYYtM8kC{m!8{?pFN!sW+a#aqC3Mr zxM7#HwEZw(m@2Ka*C0gUU5+k*x>xMjWv)rO#s`l-h z@m=k(ZJdTMMQ_CCQ(=4V^Fhe?+%#=2^g}%uHjH%2Jz=TPO zkjB6#2Oq_RiLK#vQ2UB1C!L0jZ{mgB5=gUJcOU2V;=WS)sSTj)*m5VJCQ< zxUcA(hZnL0SNhz;y#KA`)MdFx14_Li^S&NxPX@5^0oTI-l}Oed9E4ny(O25+Vb#^D zzOeo|8*slk`8ao$;O^zTD-HV1!JvVQJ0ThrTu+&voPuy*{UJs@{EVrS{vE3WGli5U zxL=%r>n7&+hPS-~%?rETHePB1z{!H^r7W6h%*PL}>Y}iHWDtM>H&khM;iY|gfmesi zuO0O}00Zt2y7u%`TiJ7iOJmoL8e8s^$4nzd2kyjKjVqeBadhmdokl(Xys4w~xhQ@O zVlj;bxci#G)LUEi3a`WTxdZr#l~_@LD}D6j4BRe;YH#gT4%7)>JYH<^yqxUt!XrMu#fuo zDI#!1_g+e{(NI5FC$g`dc0i>7UxAPrxK|2p72(Hs0dN_hlf2fyt7-IE3n>2 z=C&?V=uv>*A?dScFuF9FeW8a3_dLQh*{uVYfjZ6O+}&F)e8HlQLHhqDA!uDVa2c=z z&x&~VUA`@zm%=e3y1@09(Q9@o_I82HL0qE)6?9W`MhzST^8$ z$Zd{T=V}GokD1l9t^h8LgCKT*JIOXcpHp{Zb=eQ?>jWj0wg7XUxNHtJa1aIj0D!Pf_en7z5yo834ShMuGmS@6FK5GIg0^rS1D(-z%7k6X4R@l_|ioGUqJQ&TUp+-(URQ zCaP9|{Bz}NAWaP5((Bblx{w2*U;vN2URir#vRfbfO`%k^_v3`6_bbeFfjh#1==MoprM$1h4daVPGV!y)n0%fzf!{T|}FiKlh6yOrb)aGC1W>WH*- zY(@M>sYZi#zNVjZ0r>c3Ta>9^vCa##*HT<5@?9IKS6lRP4ggEL9Ij>{qtqiogFvR0 z9^k^gq^3RC23+l9>D$x?vBocNP-RY$q4lr~Xq~}{D+zqp`|iS-i39&z|CTvM3J|9S zZDs(=jw=V*!VARdL7N%Cr?NX~NgT0>cpwGcq&{(gr46UR``-@lwmlVy*+sD*$)`b9u824kU00Zw90l+aI>*ey;mqYhYvOwG&8cuAulk-Os0jo74tV|4 z&mF||%0C^w^6k|t^>tIcewNYW%Ae;Qv@zAG0Q~y61M|EHfa3)C=L)M4-G_2kq>mH+ zCI7*B5sJ%!|9z?m=S3(k2mbfuOq>^?cpO;f*^j#~a9)JsaA27sI9>e<;6=zkzyj{^ z%PBt6W`umF&>gt{TR;Q62>Av0O>lu1A-@3s7F^&($S1&S!3AD~`~kcXxWJ2$FMu}& z7kClc4dA+c`&9J1;lftnikRm`XiMp7eSIG2Eg_vtohm*XR9t{{f%Z>yzW{>5Ng-QUm}1<8sWw zXWQW4AQ9W$e>D8zw(u;+K$b5vn#B%JrUSN7%m_Ncg%N&&?n4icI+HX=KLP+>xw<&m z`lZais<26(Gs9-ujw?u1m$eOP-2=3F7urNljkOH^%aGp)re1qsbt02)Wm#eUh~`@Q zLQM!8HO$#LDZ&w4INzG#U^FB>W2qNDahOD~9IMLmSU{ zMJz_|l5pPupe{&zSqip{0rLy8u;P7bw|eUnmKuk2J2wK880U$g$SPg=Qx)?{TaREw zF4}e0N|Q?93?Zv!-2QPmPRR6st&vf;WAlh+Eocw}O^qXqO7XVjh7x^p>L zx}w@{%}jb~5C`5`D7VoO2u6$JLF7X2I9w7A2${8U;&)Mas<1fST5={?3ES$oaxkSh zvZLqiNA!3*#j6FvdA>>pxP$!H>yfgbBC(d8mKlRc$^9P~bMmg29NT)-{0H>4<0nYo zal?XhsS$;vX;vwhwqz)0sV7SOpvpcTHj}6dlb(M70YdqZRzJ6Y3ftZ?4S@e4@cNF< zf}p+!J|;I1LLZa+9@_(uzfedL&FGE-AjL`^VF7b!^K;uPKNBi(K}hhGLiR%16!o!@ z+(>n^`^DC=6*WKq_eJ!X;)YOkspZT%n>vN(46#xhiHBw~~zO~of8X65r%vRynAwblCqy=M=w>sRn^_b0_Xx^_G!&^&iwpHbP zm=s|zEZUopyi$#g%i{`E45W&DD{jno2A}D;&NBZaU(FwvXLCdQ5=5&^oPRfbhuHZk{AP?Yd7hi# z0+oM_!N%|!)^H~+dNF+Uhn9&2KZ=dwF0Cz}>&BVlQ7P=`aH!F{ov6Cudl68V;*cip z;R#WbuW!%RX3SZrjIv*e!B5cbUy1KK;2RPT9eLFKvyyNeuC~xl21vMLnWN1rV{Klo zFHoDqX3EQ021vyXbJp&xXk|w2arO%IIEn9AsEw1}(hA9k{NF5fz&=!l@;cxuk zSFO=p<r(UW0`)%|g0nVI-!1AJGIhrL3!4$s4Ja#7i{VBr%^$Hm z3lCawo`J7V?(`N1IEht`SMxP086M*NH-g0wh0l4X0Y@;z_V}&OlKQ5`o{)xnc3tGFx7-HP%d<64Y=nUn zkCRhl@HlZUnQD)#=k0$AWDunZ3+d)V7vl`|d*O*eALb4HuGds5xL1A(81eDQd=d$j v->Y!y(hEyVNFuSy#hPr$m#6b-5J8mynp>lYI;pL`eZ7E-qo+f&T^R2#2c47A diff --git a/images/exportLibrary.png b/images/exportLibrary.png deleted file mode 100644 index 67d2375733dce22110b2b82230bee7185cb23f2c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1233 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+Sc*Me978H@y_tJ3@V0}9gQ_#*g+{B6l?p|y4y-psAA}_A zX7XV@CYsP^si<|p@@d9WX8B_8fAe#U+6?wV0RBdd1Mj$%l`~JVb!#6F~U;_i-Bhn0V4fIJkcc<5{Qk2V>X`H2+&p zn6jTg)?8mFXZ1BjPld;I;ky}%gt&ihqaaXuv zuZH0VnVR(MS_Y*auRUKUe~xX~DO|Q~@~hHsXQP82wyPZUIu_-s5p?J4T<#BgKbobk z-8r`YD{DlXhC^KPhiKc^_A6F)1-#UH6KLA7@ul> zE%(m0WqNbcNWA5UzHJ)=BR06;>Xka<7tQ@qukSkiH9I%wKl_TKk_T$81?;b~?YvjF zWo3Td_pCVPT;YW0+D}h5PJg-IcGh*L(?$m@tlsS|>#Wq>;?v;mzP`1M<3jnDs03*a z4hEdC0honIhvz&lo4j;#sQJFxkFm>+UE%GCB|ftK$p%a!wJv{_C^Ox$kUM^iYl27B zp6tqB`?V%AN@*YP?)=`9I$@bE?>@G=z(;HEuljR$$1%Rw!477ZPTBCPOgEc6jkA)Q zX?%RBc?g<~RI=()P@kpF*f?P-P&4;Hqxp61V z2)%o{Y|6~u<}XYaBD#0zAK5HWEWJ72l5?SX<-GO6ijN)!xWE0qTC8rNE@Qp%!H%j2 z{|`<#+faF6@`Nh&nGZUB3M_tXo4-`%&RvJeoNgj*`PXa24~9PqsLsjje#N^Wv7LE6 z>!%Z82d`@|mbqMb`XFr9J&l*AoR^s1z3+Wz?sb>KV7DW8tUZ?2nwdK7cXe8GHs`u@ m%IanJ@571&hK372bPq7N3%AeTw9EQ6NZ8ZW&t;ucLK6Vx%ouzC diff --git a/images/find_folder.png b/images/find_folder.png deleted file mode 100644 index f645dfe4f795c633a432c29cb0eddeb2abc8531a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 289 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4uAB#T}@sR2@wC9V-A!TD(=<%vb942~)JNvR5+ zxryniL8*x;m4zo$ZGegnd%8G=RNR^}>9uH+0Z%J4_XWW_3~n0I4_qFp88!a-D&Ci1 zzEb!B?{l&2n&)$>oo3Z|%8Puq>5jU+O*V%AYSH!u*_TavZ_X0oV!ZGuHcUcsy6Fw( zH{mC$*9-Su5PdblX1U6&N{hKcj<-!VKACoeDXYi2?e&sL(Hvq12`A1+U2^}K!~c_I zr~ZV^7mQ}L*BPz5zDBrOa51aod diff --git a/images/folder_finished_macosx.png b/images/folder_finished_macosx.png deleted file mode 100644 index e1dc09ec8a3cfa4736a84117a593f8e3c872f571..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^96-#*!3HG%vEKg;q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6*+jiIEGZ*N=i7un6qfJjDv|X-$@n)Q~3_rnG-@6d#cGr zTD@gZ4k@ztU|7Ybwv!=`b&?)iiYJe|Vl*o=10x&5lPK}*b4lh0fMzjxy85}Sb4q9e E0Na2o*8l(j diff --git a/images/hiddenCovers.png b/images/hiddenCovers.png deleted file mode 100644 index 8689db16a75f17af347b34ab2f6fd958cb3a8c4e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 446 zcmV;v0YUzWP)P000sQ1^@s6t}b<;0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzU`a$lRCwB)Rnd*YFbr)X2IvSKq4$qO zGr@%kjt%aZfa?Un1aK3;P0)Vu4w)17H}8&2eCLqP;u{cCXkPKX27cE&v+QMaIplR?l9 z1Wai-_Ar0Id0dCJm7>0!;sy^68$+ImANGBs@?h3`*mp7fI4X?qjiYk442WVaQkkWn z#Lka6^eMe!y{E_;N$P|{Ddfv>71Fg(d&s608#q2#)&XTqNuiwAnx9Mr<2$CDyOGhW z67ERCz5E#)L&|f1M)V8+e#VJJ@?NThSOV`~T7xX8L6$Ex$OkpZZnV|2TF+|r*4?=Y ok5;5dD{AVYN9&q;wEhGb09-1PYflyc#{d8T07*qoM6N<$f|UKe($ZGXE|^$pbNsgC!2aPx$s2s@-b|a+vT~DC3}NK;y+(2j>VrGQRZk zn_cl{E~9bo?(KUL6lO*;=agK@)HBJyyVo-_GWPn%Pm(*BRv$kd zbdT9MVW!rztj;L{0edfP@|s#y`QqN!b$j(bT2A`swr&bnl ewmf?`UE1SY_~*Mt|EB@{#o+1c=d#Wzp$Pyw%zD`X diff --git a/images/iconSearch@2x.png b/images/iconSearch@2x.png deleted file mode 100644 index 1393f10f5fe38ab68e227816e0afd36006a3a6c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 482 zcmV<80UiE{P)^i@CLE6@7?T4dpa62UY=IhBiO4n> z7||b)0;a(8iP(kpr2>yY#u!_{9Oxzf&>vtdBCBMOLf!+O4Y1bl1E3%9Je`6aK-#X_ ztKbQq6>V+2(a)&|c@dF$C_s~qj4@;2O^S~2{=?DBCoN4 zMrB#nRaHFzcY0J*RkbL~@;l_u^a{J0oPxA?{ai<&!g=1DGau^RI7dayn>oXXbGy!w z8U^{zT8tsK)n3w?n2kXW^U; zbr@Tv9(Ow|+iq-EE6C~#codP~z;?A%8+}?&2=?FCL^AAXj&#)*-hUR;QrqS0-gdwk za~rM5Rm!VeldUy*Yh_VTs#0P929XHsWY=kX2AVXe&X#Hf)@|!tIc>D+?lQE%nkoVK Y1z1?mWQpzy&Hw-a07*qoM6N<$g1MyDga7~l diff --git a/images/iconSearchNew.svg b/images/iconSearchNew.svg index e7fa36836..797143736 100644 --- a/images/iconSearchNew.svg +++ b/images/iconSearchNew.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/import/coversToggle.svg b/images/import/coversToggle.svg new file mode 100644 index 000000000..e7f4195bd --- /dev/null +++ b/images/import/coversToggle.svg @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/images/import/importBottomCoversDecoration.svg b/images/import/importBottomCoversDecoration.svg new file mode 100644 index 000000000..73fd3b749 --- /dev/null +++ b/images/import/importBottomCoversDecoration.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/images/import/importTopCoversDecoration.svg b/images/import/importTopCoversDecoration.svg new file mode 100644 index 000000000..b2ad35f38 --- /dev/null +++ b/images/import/importTopCoversDecoration.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/images/import/importingIcon.svg b/images/import/importingIcon.svg new file mode 100644 index 000000000..a79f3c282 --- /dev/null +++ b/images/import/importingIcon.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/import/updatingIcon.svg b/images/import/updatingIcon.svg new file mode 100644 index 000000000..2d82a53c3 --- /dev/null +++ b/images/import/updatingIcon.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/importBottomCoversDecoration.png b/images/importBottomCoversDecoration.png deleted file mode 100644 index 7508ce1783c1a2649a8b2da2e97188a62cdc9a33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^j6lr6!3HEPq^3H81d4;)ofy`glX(f`u%tWs0tGkr zbN@+X1@buyJR*x382FBWFymBhK53w!WQl7;NpOBzNqJ&XDuZK6ep0G}XKrG8YEWuo zN@d~6R2!fo9Zwg>5Q*^Qif?aj)~m58GzirH`;(aP>)&5%=F7|d=S$4Ex3Bi}fiIt) bdb2UOJrVqv6`HOJ)W_iI>gTe~DWM4f_m4T^ diff --git a/images/importComicsInfo.png b/images/importComicsInfo.png deleted file mode 100644 index 6830bc076df5a98c3cc9b45de063f45b39293bec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1170 zcmV;D1a13?P)kl0sbMljkN&4H!J|~4GRE#!vX-`umHd}EP#W541A*kIQXaT|JQ;)?;nNFBY>i2-yiww zT|O8-w?Y6#=lpF){xdDXT2dvZ!ob%wa`*Fy_2#qyb;EB)9Lb_ufC=zzX99c#0RFJd zGq0yh00l?>N#^zR2%zLqt$Db^w@40d z5Z)JA?*rgRy)RI#H*n|-AyeQ-{Z&xiX>9_0?gIcH0g}MyQ7x+i@Tity0T{MzSODM~ z76AB$1pvNb0f28<03Ow0s!Bz0Khja0Pqb90DQv&gkC-1%g)u% z729ne===V5HkrMWL6021hdKUjbb3H+G9S8%Bl{wM*01mB$mvxaB;Q|ECuvb)#? zw_^)%5`0C1Ebwnr6yC-t1PPMEPd2Ym8>=8Bs1JTr0gxbi-Z=O_Q*We=T_6%f$ z2D%k~u^!f(lSCnbF!)&oK!X2r?cl#H{Ux%_6Bv53j<_axsK1DTH3ua&YP=;#(yd#S z0EQ(H1;3~O1|<*&zqkN~B*@aUSET?3BoGT;1Sejc0?=tA)Oj4T1MB@f=u@ zU&xklWxENp!K>&wj1pgU&ocN*e_dxgJ*aQ#7u&chJ=Lj2`l-`YJfp&9A8K;n%eFuK z!ukt-vpjZAwAi8M-paL6(5H_va1wW*qw zEYF$X+F*W8L+{>=g)eMd7S6PNy_sXX4cTljt_C%9U1#$bTG8@sQT(TKOOlsdT$;|@eQv-ls|V|*kZuUz=RAP7DoKEZwj+dTiWjUYvX&Pxas%B9){g^O8<7LGR+aa)4x?z zVbYf$TOYpsuj0(MVlBgW$$Q0`bH6NIc<}lGf8#x0!{^(A64a|=iW`9@p zT+3R}^XXk`^r;iaU9H$muDRY3{dlKyWBDSr z1<%~X^wgl##FWaylc_d9MQWZdjv*Ddk|K5#C{Et7!{YGE%gZJ6?(I4G;l)Mew)FG! e4jMQ#Ffx2!A$VD|lKmV|2ZN`ppUXO@geCwmMk{9k diff --git a/images/importingIcon.png b/images/importingIcon.png deleted file mode 100644 index a53e768aa73cd187397361cbc34938a80afeb247..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3162 zcmV-g45jmlP)GB~SwV z$pDGn!E*<=1a|-(xC2~*JHRku!aoe|;88;UO#&C zRY0{0Ce}_CP-WUF1z1`mX^>bIj1mb zpyXKsl*<6;GeJXbAdSTKodq~xY5-81hPgW0K_JO%NiAg!zktapNY?AzohGkG?O^T1 zLtUF7div)x#V> z0!-*AzytwIEp-ieY*X7cCo~fTFhKwl1TaA$fC&PaAb<%1m>>|q1OZGCzyyH+CJ11H z044}vf_@&0s%}AzytwI5C~v`044}vf&eB+20?;U2m~-e z08`6{5u|R0B!vj6oAI>o-8SzDTmh5nEbkrFR-pQA1E~qx37X0K4-r)_y=y4hRxV!# zn4EPGl?3w)l5CqSve=r@VVe&vm&;G#^xhgy^vq<_OeJL}%cpxV7_5)y&!0c3Gv`gX z0w&exy}!Tj-QC^wZf|cNORZWZTKBoeruSCGPUCOW;cz%h3R48?XXv1pWwqR_B7s$4 z9oo_I+FX~H5AU^axx^{~#fK~iT?a%G5?RSymwpxJc>rm$%k_6DUN{QJ=g>(nSsUmI z-4%WuAX`7#L? z{v6((>tRL?Ez+>GfJ&jEth#MYsm9H1WcaDwy0Z__NL3)o!qeOir43i%bEDd9CMf}^ zVYmsOx!k*ax~z)bx`Pkt>@paeJl!s_RVqQ*MKfuL=rw5{I_N#WrXviuH{m?Gyu4gx zfr;en*RSsbM4zOcqM?#ns!sn(oBTB?jc*Mp!z1mr2+-p>9Iq}eE>`jy6e(`(fF$)&xm|7W#8?2uKI{nZkvqp%HU!$W`4SNPfFan;F{p zjvDDBDTt#wEdxvh)QZPmZXm=DP}+u)AVphg{_fqo4=Jv95KMvQoBR9wQ6T%5H0l7A z9~(>qB#rLSZ!1y=sjheMa!R0@fEv?GfQ>l~RSLrra=4RJKt$g6U*S9=h2RDzlDBW) zuI}#cCcH!-r<>YHhvd^r8X$4dgFhxkkn)Nuvfr1LvW!bNLiV?F7kZCy6QluoUtf4j4*e@v8~8VWPK`t2kGrWJX(>uy7Bk(LBhFvv#%rbnQ(4F#amgQV8ldhz~`QqSD7!o)5E zn&HJ6#1ojHo$A*}1X8&7BYLoNw59eKaB>-hA2hXqf_6$XbCXkl6%IV9!v%0OnBoj? zR^~E*hDrkx9}1*J&NgM8Qhopa{qtZj7*f#x>FMc{;5y9k4g-lDk`bgixoC2?E9+J# za^Z(3XC<{0G}K|Xl2~iw^WqpFWrv9j!SLjatr_0F@y}g{NFMP)ogAxe**9SZpnj3d zAV6jMpa9hFGq-3bt)n+`xB%S1BwPmn%Q} z6yDw7=6gr3mz*vDcQ8el!3UaoNT2{!IY`>z79h<%wAIC2{QCO(=h@lWOL7^|A-7I- z-DO}I+{bnSxYSH6wDFH-B3KkI2T5zBa4bE6P znc@s@WX| zXgo~OWiaI^1FfCf43yMJ8YJ?`d2snwMdAEhp zO*tG!P5CYEQ#Z%0=VR$IkXcun3{;g1ATHjHJ-PrI3sW@6m*muJ)1vSu7XUp#o@Z{R z&9q!DAFPaSj~`GrNmS%r;uN1LwU~oy^RaNSaX}?n7M80 z`)wZv{w;;hL%B`42rKbsO!-^4hMHVoU!R9|{l~fiO#`aLpES$m0+4;Lvm{&nuXBm( zTwH}r%DxRyRUqX^@I_&%p`9;ef_vFU??7#^lje1A;eIkKiTvqheb4u@ECsZj5EZ(P zhn{wC`a=351}R4;QdsKM)zv6m>%ZacxphtNr7o;!$+(4knzKE+@3oe)M5pPY-^BO3 zkm`-KlP+ju!6f04Uzp2fKtT2WUoqia-yoU&w+R}F7H?_iZSMGOT@*;hkm;1$*6=2O z*ZLvWDSuhrNe7|STKeC#YRv31m^2~Epv;%VE`Ydro81Lq^}EziI?wy2A+fIs<#AN! zlh%h+hsW|n2m6Au)lEG|8C1Cdye!_9DU`B)FU>WsLE0tpyY+vL;MAPyIC3v*cpkTK zZvtskVWp}9k$vlnt6T#fs|3VsbxTiC23jNO1zcLZJ$4j;uD+!q+SKp=xMs9-a$7*E zYRer%D2&xxlz|ma61CF8Tm1H}{ces_8l*DMxBkLSua7X?x!HQIz1zxGI_ehgZTfWI z&-eGO0q0FKMWD>B=Q*Pcyl>&I6DV_-tFr-_Tn1As%AjryRR&UQi;FGX+l(~ZDwBUS zlSd#D806;G^OQxEcX0uD+QMC@^xOKwsglxFgL(p{K@%izh@ za~)t;QVD>EHrG)AfGIyvOI;JM3@To4tGfy}U}`o{>uhxvP?lDTpR273H(+W$P&C6^ z=oy|-%Dwg~+)b4Nx8RA(U|sb*%-&v-q0NEzDh!ug08`v8Xr@XbLpnwo+-SQ=%uoENwofazcv4u_r6NQc-_fC;kqo=Lz2@jc9Sxl$$E0|{XQNbP~j z#W2^F8Ya+APBasMYOXd))pz|A4bd4|AUl62^nU#K z@zC`W^4_%(gG2qrDVb9Yb47}VkuW&aur8O7Z_2PHOPr)CWRz4h@oSm29zgk;vFWM= zDJx49sT#@}ieZ9g@^5hKw9PJHvW7ehB7k)~jbuTU3L+DxLpxhG5a2WmFgL?o&IUvL zN*}`yWEZKjgZumkc?MjNy)_dAvX6$U9OiURA_!y`p!)g`80H|m*iQ23ml;=p3St4I z*Igweg-o$0KP*>}G0g`=`fR0aETk4^2C9&`hom-=p$Qn~02KozwUe&lS8%3%{!dkL z!2k-{$(pb+Pz49EaZ2K{VGSSwC<`hH*Z%|<076?lJ?QU$A^-pY07*qoM6N<$f`D@0 A>Hq)$ diff --git a/images/library_dialogs/edit.svg b/images/library_dialogs/edit.svg new file mode 100644 index 000000000..37f087e96 --- /dev/null +++ b/images/library_dialogs/edit.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/library_dialogs/exportComicsInfo.svg b/images/library_dialogs/exportComicsInfo.svg new file mode 100644 index 000000000..9117d72d5 --- /dev/null +++ b/images/library_dialogs/exportComicsInfo.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/library_dialogs/exportLibrary.svg b/images/library_dialogs/exportLibrary.svg new file mode 100644 index 000000000..b834319cd --- /dev/null +++ b/images/library_dialogs/exportLibrary.svg @@ -0,0 +1,22 @@ + + + + + + + + + + \ No newline at end of file diff --git a/images/library_dialogs/importComicsInfo.svg b/images/library_dialogs/importComicsInfo.svg new file mode 100644 index 000000000..71a8b717f --- /dev/null +++ b/images/library_dialogs/importComicsInfo.svg @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/images/library_dialogs/importLibrary.svg b/images/library_dialogs/importLibrary.svg new file mode 100644 index 000000000..ec5f096b8 --- /dev/null +++ b/images/library_dialogs/importLibrary.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/library_dialogs/new.svg b/images/library_dialogs/new.svg new file mode 100644 index 000000000..a755c5800 --- /dev/null +++ b/images/library_dialogs/new.svg @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/images/library_dialogs/openLibrary.svg b/images/library_dialogs/openLibrary.svg new file mode 100644 index 000000000..1a64f11e6 --- /dev/null +++ b/images/library_dialogs/openLibrary.svg @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/images/lists/default_0.svg b/images/lists/default_0.svg index 1b290d531..75babfca6 100644 --- a/images/lists/default_0.svg +++ b/images/lists/default_0.svg @@ -1 +1,17 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/lists/default_1.svg b/images/lists/default_1.svg index 837ec29c8..c4ddc2840 100644 --- a/images/lists/default_1.svg +++ b/images/lists/default_1.svg @@ -1 +1,17 @@ - \ No newline at end of file + + + + + + + + + \ No newline at end of file diff --git a/images/lists/default_2.svg b/images/lists/default_2.svg index 88ab6868d..eea9ed7e5 100644 --- a/images/lists/default_2.svg +++ b/images/lists/default_2.svg @@ -1,19 +1,28 @@ - + + - - + + - - + + \ No newline at end of file diff --git a/images/lists/label_blue.svg b/images/lists/label_blue.svg deleted file mode 100644 index d735f3bc5..000000000 --- a/images/lists/label_blue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_cyan.svg b/images/lists/label_cyan.svg deleted file mode 100644 index e028467b1..000000000 --- a/images/lists/label_cyan.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_dark.svg b/images/lists/label_dark.svg deleted file mode 100644 index c25fb5219..000000000 --- a/images/lists/label_dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_green.svg b/images/lists/label_green.svg deleted file mode 100644 index 7cbe39424..000000000 --- a/images/lists/label_green.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_light.svg b/images/lists/label_light.svg deleted file mode 100644 index fea8b87f1..000000000 --- a/images/lists/label_light.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_orange.svg b/images/lists/label_orange.svg deleted file mode 100644 index a2838c644..000000000 --- a/images/lists/label_orange.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_pink.svg b/images/lists/label_pink.svg deleted file mode 100644 index c957673d9..000000000 --- a/images/lists/label_pink.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_purple.svg b/images/lists/label_purple.svg deleted file mode 100644 index 85dd2a230..000000000 --- a/images/lists/label_purple.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_red.svg b/images/lists/label_red.svg deleted file mode 100644 index 8ef4a8a85..000000000 --- a/images/lists/label_red.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_template.svg b/images/lists/label_template.svg new file mode 100644 index 000000000..5b13b18f7 --- /dev/null +++ b/images/lists/label_template.svg @@ -0,0 +1,17 @@ + + + + + + + + + \ No newline at end of file diff --git a/images/lists/label_violet.svg b/images/lists/label_violet.svg deleted file mode 100644 index 3400101f1..000000000 --- a/images/lists/label_violet.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_white.svg b/images/lists/label_white.svg deleted file mode 100644 index dfe2ffc84..000000000 --- a/images/lists/label_white.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/label_yellow.svg b/images/lists/label_yellow.svg deleted file mode 100644 index 3d2f0da19..000000000 --- a/images/lists/label_yellow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/lists/list.svg b/images/lists/list.svg index aabef84bc..a24c621b5 100644 --- a/images/lists/list.svg +++ b/images/lists/list.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/lists/original colors.md b/images/lists/original colors.md new file mode 100644 index 000000000..7e5859ed5 --- /dev/null +++ b/images/lists/original colors.md @@ -0,0 +1,24 @@ + +shadow in all icons is represented with #0ff -> original color was #000000 + +all labels have shadow and the icons should be generated from `label_template.svg`, this is the list of actual colors needed per label +label_blue.svg -> #82c7ff +label_cyan.svg -> #a0fddb +label_dark.svg -> #b7b7b7 +label_green.svg -> #ade738 +label_light.svg -> #cbcbcb +label_orange.svg -> #f5c240 +label_pink.svg -> #fd9cda +label_purple.svg -> #d692fc +label_red.svg -> #f67a7b +label_violet.svg -> #8f95ff +label_white.svg -> #fcfcfc +label_yellow.svg -> #f2e446 + +other icons + +default_2.svg -> #f0f -> #ffcc00 #0ff -> #000000 #ff0 -> #33000000 +default_1.svg -> #f0f -> #e15055 #0ff -> #000000 +default_0.svg -> #f0f -> #e7e7e7 #0ff -> #000000 + +list.svg -> #f0f -> #e7e7e7 #0ff -> #000000 #ff0 -> #464646 \ No newline at end of file diff --git a/images/main_toolbar/back.svg b/images/main_toolbar/back.svg index 08a5777f7..f6a4cc94d 100644 --- a/images/main_toolbar/back.svg +++ b/images/main_toolbar/back.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/back_disabled.png b/images/main_toolbar/back_disabled.png deleted file mode 100644 index 9e09b69aa152d3fd9e5230a66baf0d74acdbf1cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+g!3HExhN-duDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9Ma`Zrjv*DdlK%YvZ_m6k;q)|JE{9VMtvtTG4l?|YHcwd0 z$rizpA=Hp{>bTnZCih@Qk&?*O)3rzj105q WJC#~*7nTA#hr!d;&t;ucLK6V-!AULv diff --git a/images/main_toolbar/flow.svg b/images/main_toolbar/flow.svg index afde5c5bd..c84719fc6 100644 --- a/images/main_toolbar/flow.svg +++ b/images/main_toolbar/flow.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/forward.svg b/images/main_toolbar/forward.svg index 50a5f21ab..2a786f996 100644 --- a/images/main_toolbar/forward.svg +++ b/images/main_toolbar/forward.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/forward_disabled.png b/images/main_toolbar/forward_disabled.png deleted file mode 100644 index 1e4b070a9359ffc382f2eebf6eb41f04c945599c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+g!3HExhN-duDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MUy;T978H@ExGWJ*TF!b?crsK101p|>~k7?dk(PqI9%d8 zpwe@I<*TR3$Hl9TtL7_BeIDeIJy$t%t!iFV2iq2jWGj_U!$;p@3Z`?MpBa5=fliBX z&3fKF_XCTUO}VwhVuy-Y_4I;|wVs+Uj@KO2owVcI45NVltOZwPm&6C~)VV1B>8h#N ncR}R0uwTr=sm*s}n0Oc%3bM \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/grid.svg b/images/main_toolbar/grid.svg index 6c6d534de..4787059c1 100644 --- a/images/main_toolbar/grid.svg +++ b/images/main_toolbar/grid.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/help.svg b/images/main_toolbar/help.svg index f0d090536..ce5fc309e 100644 --- a/images/main_toolbar/help.svg +++ b/images/main_toolbar/help.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/info.svg b/images/main_toolbar/info.svg index 4b7510e01..a8e8bb548 100644 --- a/images/main_toolbar/info.svg +++ b/images/main_toolbar/info.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/server.svg b/images/main_toolbar/server.svg index 0bd8cfebd..57c4f2d76 100644 --- a/images/main_toolbar/server.svg +++ b/images/main_toolbar/server.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/main_toolbar/settings.svg b/images/main_toolbar/settings.svg index 4f01a4d0b..d97d6f54e 100644 --- a/images/main_toolbar/settings.svg +++ b/images/main_toolbar/settings.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/menus_icons/editIcon.svg b/images/menus_icons/editIcon.svg index ef898daae..0404a54e8 100644 --- a/images/menus_icons/editIcon.svg +++ b/images/menus_icons/editIcon.svg @@ -1 +1 @@ - + diff --git a/images/menus_icons/exportComicsInfoIcon.svg b/images/menus_icons/exportComicsInfoIcon.svg index 2f2d32a67..ef26e40c2 100644 --- a/images/menus_icons/exportComicsInfoIcon.svg +++ b/images/menus_icons/exportComicsInfoIcon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/menus_icons/exportLibraryIcon.svg b/images/menus_icons/exportLibraryIcon.svg index e36a771cc..677f74d48 100644 --- a/images/menus_icons/exportLibraryIcon.svg +++ b/images/menus_icons/exportLibraryIcon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/menus_icons/importComicsInfoIcon.svg b/images/menus_icons/importComicsInfoIcon.svg index fc2c0dc8d..c5eb625c8 100644 --- a/images/menus_icons/importComicsInfoIcon.svg +++ b/images/menus_icons/importComicsInfoIcon.svg @@ -1 +1 @@ - + diff --git a/images/menus_icons/importLibraryIcon.svg b/images/menus_icons/importLibraryIcon.svg index 752ba386c..b897d65ac 100644 --- a/images/menus_icons/importLibraryIcon.svg +++ b/images/menus_icons/importLibraryIcon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/menus_icons/open_containing_folder.svg b/images/menus_icons/open_containing_folder.svg index 3080991e2..7258b0d2f 100644 --- a/images/menus_icons/open_containing_folder.svg +++ b/images/menus_icons/open_containing_folder.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/menus_icons/removeLibraryIcon.svg b/images/menus_icons/removeLibraryIcon.svg index 51141dd45..6dfb053d4 100644 --- a/images/menus_icons/removeLibraryIcon.svg +++ b/images/menus_icons/removeLibraryIcon.svg @@ -1 +1 @@ - + diff --git a/images/menus_icons/updateLibraryIcon.svg b/images/menus_icons/updateLibraryIcon.svg index 016c9622d..f99b0e605 100644 --- a/images/menus_icons/updateLibraryIcon.svg +++ b/images/menus_icons/updateLibraryIcon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/menus_icons/update_current_folder.svg b/images/menus_icons/update_current_folder.svg index 016c9622d..f99b0e605 100644 --- a/images/menus_icons/update_current_folder.svg +++ b/images/menus_icons/update_current_folder.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/loadCustomCover.svg b/images/metadata_dialog/loadCustomCover.svg similarity index 100% rename from images/loadCustomCover.svg rename to images/metadata_dialog/loadCustomCover.svg diff --git a/images/metadata_dialog/nextCoverPage.svg b/images/metadata_dialog/nextCoverPage.svg new file mode 100644 index 000000000..73be5c01e --- /dev/null +++ b/images/metadata_dialog/nextCoverPage.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/metadata_dialog/previousCoverPage.svg b/images/metadata_dialog/previousCoverPage.svg new file mode 100644 index 000000000..b598c43f5 --- /dev/null +++ b/images/metadata_dialog/previousCoverPage.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/resetCover.svg b/images/metadata_dialog/resetCover.svg similarity index 100% rename from images/resetCover.svg rename to images/metadata_dialog/resetCover.svg diff --git a/images/new.png b/images/new.png deleted file mode 100644 index 7ca9441156fdbd281f776c288f039d3b5823c2b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 454 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+7&AOw978H@y}5msx5*xM3Jffm90rC>VdsB7jg#@5{_9bDw*$HovHZE0`{(|y|LA|>?ay}QhF}IJbi*2& zQoov9nC;ew(-L$Y42%jO#DeLZ884DLrpr1Q9QkisSIk~u)b4pMl3l>*#T>RtC8{wj z@6J9}sf}@{{l<7?t_7cUvYos2loIJ3-M6pK>5DY)Zw+>1IPV;(-SnOBZ{h7}MbbZ{ u4nC6>H_E)H!3HEvS)PI@$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1G)}AhoAr-fhe*FJm&nRHcV90F6CTOsMp+mI5Gf5-q4}Vyb xsELu`1LlYxTZUohbI$YJ_kBIr^|`jsea`(nv8LDbnHcyO0001!!4(}d z%2-IbbLq}do|vyM(3F9fpld@g_r68&bH&f45uCyP7%wbd)n5bh7p^L0{znXlfd5h< zcxpiY4$8*Z6s+xyLxB}xiqft!vI<~j1WZ;@RzXGfB3MpFRvs=R50{mfmX%YLL8!_q zg8y|vDBf^xw^Yq^^#0|GveJOK69_)4aJZkJAIwi4=8d}zmqj2Da2YwcoSZa8LmD4| zB{=&_WAP&YAn2g*t~j(00quTqV@#>t|L*9IA|)DC6C9e- z6lX6TZ&zOo3QI81(ST6iz}(Pos+Z*T6qIz7l$8*d6?NrgWf3|u$||}ta>}v_y7CIz zh<`BtldYVtwyvzqWjRGfd5Wd3yo!#tB0>eBj8KwMR#MW|{m0e-izhf^T~Yt|MN|C# z%U1S(wN=%|p_~ccI16uYuYVX|>h4YO#=Cp_fVIt)z))*6*3H`wFZriEe`l+M!lCb? z-1KnX81P^9RYm^?|NnR1f7`nKe`*G&1Oxv=j{iZHe?$}p{+a%p`jo}LHxCL+*)cfE z*0`yuWd{Io3>oNLvhbh$mc{5}xtrDPjhz)0-r^2O;AS0xnB5dWS`!!<3d*s%op(!` zCL6V{(7o!o)fAq0wRmtd0(3zdGkWv;Ty4e1UEdouoPOMOR>gZ%*PO?1bh5Uq2~RI+ zKG`|a&^Z0pyDZ+IynpA~COP0uMK2$9n?=E54+ximf+=#7COiX;fX~a&t zd8Fl4n<<5osed%_yb3 zFO;_2RuVEVbcozvYddO<(b`p?J5EEQnPcMSpO)AGItIcZMpSOpCRD{vi-CH24{9yI zd{jGrMx*+C_YCqy4!iGyWgfAehxR?vD8yaQzjpyZU+{75H4`(lhf&Qnn@0%?8nfL; zWcia%9|5oRbK}lOrP&1W)$j=&^Mze61n)$fgm?G#_Y2%qR?U@7e?)f94Hq91Dr2*7 zeQdBwCn;=!tP)_3wmL}wn!+9Sz5S@7$h%WOs~y! ze524?1yJr;uFgIxt}t6$+sULth;8R<*#`rJH||ZPd?brz4n3N$%kNWaC>a9J=6>n& zRHOPT9FD{B@K^q3L{^^%Czq=1MJGJX%FSOtZWO|6OXi$`lgoM7G^|k;siG#j9)-BGT z>pR2X?5smMorECQW0v`VFTg8~G?`?2rove%O}dyH^H^U79iaYi93HR8Y8y53S%m%F z+6d!~HVxh_J(ace6xhuXV(z-n-dsRA;8$l)uIy8s>De&D(X5F zI?i431zpVW{U;o1^A;5Wo6`uUYY_~}yKRcfT2!4(q{GS;IH2n#sLO-KH6-MXRn&Dv zetNE0_P`nfQ7$#E9(vMzMq=hkV!Q($p6M%Pk9WVJO%LYoSUazO6>b&DD0~qL{Sa0l ze}U(b_QRfLbXMYEc2b3b%uu$*^ELz1JExc49UMBfz2+o^RkFhNp$q#|fE2f=%2%&^ z2zf=Ge6-w&HTF+9RI{pzi@WcB?dO%AoG+kd+rJc!=7mx%slKh}mbL%JA~KVBy*%@} z)9YGK+^P7YeR#m(4!V4tpdv5?>_3uF)8VD-Bk^?D#IKT>o$NbG)38@q9}nSfkxa$t zT`lo+hdYCsPmUCLzYyM=7hgk@#RYz~wcOj+M3w&jI?RLI6AiO7;kJ;yX=Wz39{-Jh zG?sNCew*r+pI_Y>@iSnS1#(gF(O!!yJtd9HZ}&hu(Rlith{VmF+3UJB-)_fg$xOK3 z_4SqPR=ZjFLZ@*CY_}Fq&~3~odhW%0gyz?~9;=FnF9oD!_LyX=mv#m?I(|vn z`!?~*>*``g_lwzmLIuM1p_;fA3Gcsr+r)g~4&Fi&ITIP(%Cr0XOhS&1eQSDF z*3Gth@wl>3g{~Ut_Pe%dwebL+pZSk9M;-`WU3u@fHA{9}M4&zwcum)D2cDJo24_pr zx%&Fnlvh=mMJAmZej-R4Ufr&~J=Nu$@?GE&L!Dn;P0b_Em_3>BW~$2LkIl`^kiB?I zOUqg!kpWXbPhGU9K@{yuOI=?T^lxCEe(_L+q?+(@(edq7ph0w|qGz&_^Yd`MFiuIC ziFR28y*Tfs=lfUg-D}ctF$MOB>+DJS|4O@1)vz>wnb%#1qf>?VnO)w@b6RabeQHC1 zZK;|Y+a))*>d+;akngt}VVpELqpCKZV)ON*7pHgMCrcYRU!n)&0ke+*ZZskpAf^m! zpd{!Klt%__A9sh`9PR0Ilq{(|F*4#p>pui~OGD5TNvL|S&q=hy(cOx}L!#}lsd6L$ zPJ+%+n-$@V@9l^I7C=AECYAQ#W$49{b2e62p)9<8#u-X8%z1TE;58Dp8N^P3Ygihw zlOU{ei(zbwk-l$iY|QNQ_iBOV(L}yAVcq#Il_7Rl@6u3|sseO-0rYCZ1=u^UXFNf{ z7J!bzAY=xKob_+tyyzGV<2F30=2uqZFYWdrU2;s`e6m35uGCtgOGrb2J#>3cn`iX>r*TJ1AxU;!KEooo#GTE$ zcQ^wiRCZc)kv?OzCdj>Z<+;6L^C6@^=U4(k$ij54t9=fp23l!`=ms5@p zXD^s#0zV=BB^CBfdJvNKqtX=8IF8#=jpkny)2+;I-xZql;3=%AuEw8(+^cLqksJRAM`S-TT0lDnL>4>#*gvp0NFa;~3;L(Qw-Rp{3Vnx2#% z8uL*A#jnll@&yC7`QF{te758cgGtIge;H*bE(J~5=sqvjs9Us43Uo}vj7Mi~JmP-K z9oz3?sQAs@)TQ1Q43n&4NZq^Hbhi-LC%(J!5?I)C5p1~)1R00P>E6WYiptGMQ!NJp zC2uD`ya;(IC^Kk9EpVtbpNg(<*>2Y zUOKk4M^2bPjc5!LxiZa8d0XV~o>f^JF(JMHh-I;xW=oLL7D$li$k_E-PujQ35tfh* z6%_ZgtLIWUZBZY#4}x0j_#Y!EE`Yr`{UDOiXG$*Ta0cBi`?L3MDb&$iO{B^E$us^P znBT*o&742Av3sHyX{Hq0bKyxHB}NMZ=t@TSVu0PH09&PpJzmA{67ZeNIKk1}cY+;N zwmP?nWKsK{vg4);vp5xn42)WoKWZtPv3;vH!uy_q(V5oQ4W%E0hd+hi6(` zI*Ivu#p>mQD2~|vFm~7haa&Vu$noRQ@2AqD!~g=`I^pA*y2=^D>{fA8Vn1txHX-M{ zfItxbETxGij3fw0{?S~SX+)sLL#JAu}WZ34|R$<;iIu~ zODGpjm;AazJ1W-)4L)OI144gQZ{I(y+wlyq3JE6_PC8I)O+zLul~BO`12Zv zSOjMCb^N9-Nb*=C>IbYSZm&I3vx{!wDlM89DIr@O;a9~vX4skPk(j&PHElwokXV+ zj>=%@r|~mUxZWf&ZSXOb%~nE~WctEuGJF5`;nL=i>G!p7aiLTr`*fr{$(=;~Vf_&F zeEWS7w)^R3qVo$QW&dk+yG56z| zS69Jql}D!0&$uEmMbljF(`p|)`yJxMf-EoEbi}FuXGYOOI%$%eo9IKOql#ru6@Ib9# z;c$I@y)N&^Y+|f;=s>o{k;=tj*%L9$JbdbXH;Q+Am_0y2p%+IT~V7$ zXPLY8AgJQwm|!TA-!vvaQP_Mv#obl?@-{F{q`>L;%i@_%!e zDE|l-0>)^8Vv@;k2-DiUkhgQnrJq?onYH*kHoUReFSPp+x_FkzU8PmAAG76i3dx&L zzNtwYj#~$OiRg5e$|{Ry`ISf{5?>ncWB6-2;@2f@{FRDNjhDd@N^sIsC0YmRt7pRjJ^Ks6c8sJ;>$Ou@(31+7{GlP4@3CX~%a^Cl5HHVg zIcn$n)y@RxE~j7i7|i$l*s3g=z7M%O?0q)7PgN7N1bKM;WfE(vk-QPC&uA(SF@)fe z5SGY+m5lUsbztG@1&zJWuBCvg3+FTn=hsos`T6VPfJEP*4w}JD1g9 zmRg+@oAPTU@3#k4Q>PaZh_v_aAjI6Ze>y)OUr5HQsT)3w*GfxE2ad&*F7uYV&NVBs zgdKYY2a~7hF@T7vrO8THec!;q!;#mo75Hc543R(AQGOKm30~XzE^T^77!crSWo5;l ztkj4q$Vx&U2EA$W@bq*{DVH|AR)(3Xow(hfy3K_&P!ZWA@nqXmR}~d~)pGMZz5Wwl z^Mo$3g#kHs0V;x6T^;xHI+GBMGNKesN?sm+)So7giAvHy73A?F_dq?0fS<+_eL&QQ z_0?7P!QS46a8pRT$e0PRN1n&SDlb}H+|D+zFL!iyHk*OfZ{_RPNjj9Co}SL30U!W~ zgmHms`bw`(e-FEZy>uyDT1`z2GRy=%om$*x?O{PNGLnSRzrGIa0=DOmkAv(S9J0^N z%-0u$;5z+o!p4b>jg1Zy?IY$73dY8))E;DP0ekw}+b>HuB799o#i$Bckl6ByidhLe z>)gyF){mh~tSKB<^puOSjY}4})Cn4?ueQ=O?(MNnRIz_CA1N}sxu=K6U|;gn z-^{lsL&TMp{g}fGjBpFgzOABR>JRGQux$R$_PTzj&!-r(d2*m0?j~E?;3)U`bCDXP z;&gCv+g<`mG}p^}+|1k2uf@s5HDPFEg!v{h3d?n}XGfmbv)77RJM@cqg5-_W#3>zi zaRXc!!ri=9mX@fwrj9YZ^^3J-Wo0SUBC%UB?u%WI>f53X?&o6TW-D^4(mz^U13(`-^ng9R* diff --git a/images/noLibrariesIcon.svg b/images/noLibrariesIcon.svg new file mode 100644 index 000000000..99c432a00 --- /dev/null +++ b/images/noLibrariesIcon.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/openLibrary.png b/images/openLibrary.png deleted file mode 100644 index 320e6882f00dc7e6b04995a3499fac09c53bd29e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 821 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n67)eIEGZ*dUMw>PuNkUz3})s#u}DlrW$5_bp>77ISK_# z3zl%J7ewv)!4hd@<>Y=`?%*7TdtR3nBu_?GAAfx2{baY-YS*&<-QQQc`P_}koIra) z;6Z0`;Hgd%-_0F|LwiDdQhQn}{v}F3Ry?M5Ecf=d+vojK3lB09NM4wW$J^oiunfCfj??H|IhQXZQC5f5_>)OoLhs)zuKOifBMu8zMt?Q z`s4P7kZ<*z^;70OxH;ii!K|My*AL0J*7@D%`*}F?*y{ZkKlGj|y~wm=shryyrk6_E z{taIy9JjJR95OwMamqg%8~xCRsX3cWn_amcH2Oc?-q4zJDkY2S)w4}sgmZ3xTeK}8 z>FO7ERt81~1_1^ZbgDoi(vEN4N99;i1!mvNd&Cm&Zf`K<{KBAefo0MGtp=89jVcNZ zoX0BoCVaj>rC-DG|DT6pN4|zKOl@EQNpLtYF-^eDJdhX0vSNC3eRDg*A@zn2oC-Be z9P{xoPbaK@`*3O9+1vHo)^hKE#HH}3i&dcRC=0H2k7DcF5_8); z<-W-}rUnKD1`Y-+l-%*um+BR5`y-Yyy-CPk^;+z~!I1QY$_$KMA`e#QoZ53?6UT*Z zZ|B-6aNB#uvDHmG|KobpNv1n1m>y62zhcYLZw!BP7x3SA>pP_NMkl-bR;j(XEf_E)H!3HEvS)PI@$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1GR-P`7Ar-fh{`~)M&n)(U;RqX#f~U$Fh9lDdoEbMgX!@VQ xpfd4;JbMDuEZqYQ+yX{o%bO)WR + + + + + + \ No newline at end of file diff --git a/images/searching_icon.png b/images/searching_icon.png deleted file mode 100644 index 95355bfc3f6829a4c9afe75f2d70195e048f9354..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1788 zcmV9cMbfepOvv>F%US zKsz`%*xTEaR~Y_fXJ-e$>I*(TKEA%b^bhav@4sf2)M{w}E=Na4?RFbKfQZE%1Qu*O z9@oMvtq#rU=_$~NUVIrCfz->(3xw8GMo`Mh$qDHAMYC*R^z`%uSWRLCI;S(Ub0|B5 z8$QiUqFB6)YN4}0>fzx5q#|Vm&+7Ghb#r>j1v00TXCyFlvWK0 zgYkG~?ui)8I@NH&l&+5Sf&4Ug`7QZufwB+pU%x+Y*#KyyUPV4_gbBKn4-{+|f$_z~1?go1 zC}e5bBPPTXvediCsN3!GV;Nkmb_H2u0wY|^ba1vHqQPK5iU>iv#u!wBi4WmO1(*u& z4;*|=`ekNu&h_&=C*2=XVp4WBFCsEjL!xL$%q0<|X=D=1-a4(MT_=;NS0bewXfpf zO;%F4OG#;#8zv&72A98m#XDNFM5Lv}M5T7SUE*$v7g2;6BN-o<%StMCs{Fs_bE2(g z#8hJ&G2R#DN=)NRASiMPUPDF1H@-|qWLnf*9r2AXl9FN^O)qzCsPR)=dmTkmMXOp$ zg*svwH7+e$8M&?hmMW)h03*f~3U$N`Y8$|au_6@8;-l&&noBpUWIOCXqiSti7`ZHo zQyY-`RL+P=9GbOG)O*ZQRd+%p#th$uj9ikd|Gu_Sj9hADika-86XM(&LK?Ypve4Ja z{SPCup1;|QN+2kS zRZQgezF9vEAg0abDpAZu+Duoq*KXv3A&L?CVJ5nzLHQ)vS`6zHBiVPyJh<2EH3AR@ z8B+BCRG$6(o70kK2*{4RMtB(+J=gk>n!l9%fTiE>M?N)yi;*H?)^YtMSeLA-tL&;AI(jEg@X?O7SsBCpvtmu4aVDZRBwh z!a)j{LayeL^BIgb(^_c1a9_3re53N??(QzIf^UG0e~?eN+l7LxvsoTfRv!6{0+Xbd zNFDI_>2zA%iX8L==(tabNKDz<0TS;S0x^2F2nrhXeoCkeUPyF(O@VidH3<*fXNMV4CLzSqUud zkNTiree`eOG@=NT!C7N|F~w;sF&Ug$he7@I^%e1WgE6fP;b!Oh0h3fV8*#LsFHD)m zU63Mz6fiY#$-<~O~}tnUK9!|Y6Q@fbdvL`&p|A=ATI zN-)W3Qkmn8&>GoiYkd^G7dmo6l}=NAVM07X0-SkirJRZ$o|LAuJmc|#3GW3`$~?AM zNZ}Q6ia&TV=Yg!nkyAoF-gf-g_}QOP4R_hl4V8a)24Kmw z3vOt~OFkxqD6IGNx?l>yXu;;^Vk?7}p1%400v2mb!{IPAqZ-Wu6ME?8<|f-7MiwC) zgXVNP-6BS&n2`4&Yj?`CHyhLZ>AzdYh{1#`@BaQ?|C%P-YAe5ENHVsUktU@D eRg{AL7GMBf7n;cZ*{G!e0000h#SoTb1O)05g7ckhSF2zh&WB(;IsbGSW}`D|=$Q&1Kb76cnEj(nZ` z0gtOHDk{&>%|#h=Xa5yAX8{DHAReqxqiY`&yDGZ2?aTmN-_a(UUEf6C;EG9N~6y&31HaGryjj;x1_TNVyh zTw@ZB%(?|4c5^x>%(Xj2w$A#HcYk?x8q=QtD^+XBy!1+lB|_oxzil&>(YdcpncMWcl5EghrjhdePS*{P;$m*IvL6!pCLELYbdye3@)wD) zKP#h#_a#Yc_U^sMW3g6~^f?bitZ#1!u9u2_!=LwLPM&&&r_|V6BLqQyw*#Njj)iCXFwdD6%Z6`d3koda~$LC!dFxTxm5o~ z#NGbxdkqsC)l$AwFWTDLwvXd*IK+FCx=9KN0bk8f@t%;dhYdC5-8-4QU;XacgK~4I zLk(bTwL{&`$u`|vn3ZP;+}Y*QCe@Nd#QLrh>NAR)P(qrm9-*_vdQKk~@Nw2jO?iH) z_H3&mCj+i$ju^(D{~Wg_SMd3E1$0MJV#SRyxod*xST)0*q`N&Q^?Y)2GR-UB!MC}$ zug@h)xj{o`wN+ZRL0$IebAlzkSbJv9*h#ft1~W7vnsQTc)rcms38e1$ocOOZuu-4& z?e&F+%(0rW+Y%CKX~Az2#M$K^HRDZ>(oAFRe?5Vo`}5 z&94aPXVeq9-I>w76ILmOKYHYQ8H6LfUSYK3nS+Cax1W&d(y5gA1;IMwEBJ21-rq|# z(udU=obHR@-90^fUJ({FGibEP$jG1UD?9sP9vu`tNQ~1kPXt@7HThK6vQSFB194(Y z#hWm~ZEo|deJRj+T9O;$3{1ms{o;#*IU(Yk)AV39``xnp!_%F|-`nHjRYZcWJve>r z6%5nCTQ4wq7O%BXII2bYo&Twsr>EzwPt8AoARwN!&mUMEEHvO%R*f2x?~U8-d23^* zqd|vWe|%st_gt##S;_8~nGT*kp2w_5DVOTo+s=BSRoi%gq23a2LOr z>yZO(A{WvFkgq$&HY`i)M3Dg_T?$L5YIklbL=hV{#EI)?7p?$i`Ur_VzakjB6s=QF zin=60O`}I$Gi|R4qttlWz?dms(Ja&%GJRK}nsRaU4#I#owxOqxi{-2+*FmK`@8%&D zeH|&8g0rqqVEd}oSa%S!G|Aug#Zb}fhY(f zW#5}Lm5iaXD%Z(54ffpXnJ8IDGMPt$vdSe#_LI0xVpQ{yG59^fo%2GN4CcNlz0Yq& z4|kU3+xi;#DrhO^D8BJZtL#t+DpMZ3232o#Gt8 zSe89WiAbUN*nW9oA&enRWZfe#1d_R`L4AXXywHIfgW*%G*&jGJ|5}!}j)FDJm#DUiK0}x_TOIho7H@rE54n zRYJ=+MuW_+NBTy!ZwpIA?I~+s<%=IyX~2rTN+n?_tW=R;R_+Yr0yBS(b?)z0Y{G}5EUve-;$=D5muSd!W?0*| zG+0%Aef&cbOuV8djat&wL^5PHf@<}fhzWDX^^(~83 z2W^q4>n6Q7!prShQ7WMU)qX(de3iy;?wOO(GY@o`&f_`5-@lu0&efQ83C{xXFRT)W zv(A7BRJq}$&}g(;nalHo<&xoXQlQ5iLPHpcz9}}KWo>e=)hbC{rH%ADo&LN&SH$_R zAad=xde4QgLK-2LH|mg)jh_ont-ZBkKL#@YHdqF(4?on<$a?!0O1*evTH(`!@}{Py z>0jU>As))0tP7>EzXeR8Pj{3KcSE<<8Z(-el7dhwr$F*!`R~E;ZL=Z21OzxOGDH;8 z;H9vp>9wt`8Yp3G?7?2}6h3^ld?vlfs{>T$io) z2r_~!liA#^W>9<-(|M4fN1y&aQU)Mj7aW>^a(8!+f`BYrj?5ihlmpn?63h0$?vU>C z$HquSj*$W}<2`K|8Gk&G4BWF@^}kN6$YlnZi~oJZ{vYQ0U}R{>OoJz0Co1dw>x_Lk zw0e}W%pV+ju%{}tu^W1`FP4W5oDP$el+&B?H8^yN`=UR?i4gj7t-10nnYd6-_l%fbF<>>vxT zlW$Zyai0SqAF}I0X{?gR{uvYbGb$5SG`tLE&;k#AA3mhdf+L^$xCAKku}1>o?nVk6 zkFIh9;FZRr|Mfo>T{KQ=2tRD-X8FMKrpLL}(BtrrzyBRg`pgLbwmiPMyKjpQ0-|k# zAwrT~R0;zyKHrHWck`jzK6Ty-VEDgu;oo9y5iVJ+*&{6QQ(2$e; zj3C)0SdX)kkR=O{nX-|ao10Wv>5$?E=rfCxp%wes*w}wx_v1AKCS!KWSPFFj-&h*u z4;0PAuO0bokxH#J9~EVbVEgs_u6$3zqkq64|IBayke~h|f(t*+7q1f{zy^*wrUhBXcs%Y^4vUo+N zzttlCYB~AG;>W*i;s5Z=e<;F#D}(>H_5bmbzq-EvE%{8mKM*-cX`1f0Zc$R;i)T9) z!G?qaT$CVl)a;6e+z^TID8Be87?6h?%WG@>8B8E3(~H}T|Hl2cwY3*4j|1#xXXm;Q zy1e{K#(jrl09Xj91wJ)3Kvw~pJQOmu);hc#uj2sFG@vJjPUZoCB05#Rb^)LV`(gMU z$7lLh3_v2DxiedQ`yE{3?jjn0Fg7uvj0C7AGkv;=`6k}~^%WNvm&it8&3JN5!;?=B zR5tH_Gu|-#W*kzN7K`57UB#2+t@GgW9zOx&%t0E-sBzLJnd}9PuGyv%yNE<$cUZ-Q zDA%OlFTcE+;#cSN+Z-4eASY3n09_=BzB<*`2EemQ|HgV78=IrnsH@oN?CtHXm~NW- zd_Gy-zTQ^8L3~gW(x&uUyJ`9|wVmN+_@&m(wYAHw>swnRu7H@9GNomdm_Hy@@@|~u z<>h70ShT{KF*Ajsk*wl6h~6_ zzCCTHXVu%UWN_(a+br4yU=}xIY$feXPBN_hOrNv;(3h>53jRsoEi5b?&?+}yp2P+1 z?(X8QdyY*Dr|gY$hWvWjHWmi4#pU8pUg?; ziCyg!&G+*uN-{(bD}4iYTHIiIy0vSkBKkxURK9GSWNT~d%t%^YZ7ZaQ^|a@}pTkcZ zokypmW|Lnuzmb z2jk=8;rnn8*dm9L>%4Ias0;}v@{Zwgt5Hdk2x9T$ftv_uf90jkbLd2xUtnN09-obC z)tjTAv)(eMa)Nl9Ik0MFgG)(}vGH;1ndQ_SY)wscws8hoLTQEGo0FL-coWb9EPtiI z-=-dS!;BL@EE2&^%7)(!Hq14mvw6%M*8pS!ednw6t+cdMFHtU;7(4uur!(&Uf=1;Y z7C;0CrnWPvV3+>Q%|LPyV1dKuc@w;+EPG3uQsp+t_#2xB5Z0(U8^KHR^6dNjbC8Oj zo}QK8Jd$1*{*?4KTqS!08>o4J@akP-rk-U~h@v6Y>CsO4&}SjUEooYD$jZeUX7_B6 zV!LStQ)0*OS8a^CM69xrHIFXR5;@+Z(e=k!3*6k4`NW0R6+p6?Fd$K!O4{2x?lyUM zh@@k^_rCUgLz(VRvX$tR1Q-JB!ePF*cqZ4yC*|FWuo7obNvnNE#r^lj)wYRB2OxHyh`vAeXU=`N!I(W{+yyK#Zhm_ zA+iJ)!C*PSHa0R+wC}eWpz)r3?NQ@SN4+UWCX6^@`?_|^+N4#6fo1DPtIx63_C2mi9 z(UQ>u-rx7sT1b&8C3O2LT|m&>SAK2HUYiYww~6lEl{9216td9Mk|JxXWQzz5RS$dE zaL_dQX?6&}zC_n@p4yS>E|T{xu?V)E3k5II#O$M@$sJQ^CeYcd^Kmb2zZtwV`*ufS zV0(M}Yxvy;XCPIwe`~v7HYFW4lt83(8^5xN1t}I?Rk{#s zs;GEfwX(Fdlx^oDY|OR9ctvMwAXGP(9lb7l#v?{>o6%qw+!AZEcp6wUrp%IgSo zeLc{X83Pp2*V+hWaz{r;wtzE)ofCZ;eGbjFbPg?mnk}?ssWrKjk$k)7OjnKy@@TlK zIvY4L4eRjrVqe=gcbMxLW@cu@<0jWs_*-%RkdP4k>@)jrR6;`K(^DKA`A=t(XKD1! zO*R_IzQ4pFi`gT2Kjsu05GpGBKf<}5+Oq%AFElrqJqb(N`y}c+r6D%!hb`_I}ZuS(355XZ&hE2AGgD_JlHC*ffK@Od(82TX@|) z*}@Zuo7~&j+PXF)Au(%r+zIkn(C(aFI;-YnF+3As-Fx3|9dgCA|D17x=nk#Y{ce-a zFv91*XKfm*FPPAf`#=fZuDPDy{qc;7Oxs3t9lz*zFAQGa%-|slKR-VL+tT5vm?gu? zV{L7HMqL5XwzaUVZSy2Yt%YYkt9kDuaP&~qQb=*!d(Fe+H;VSl2H9U?7v>%U`m@vL)ZNV1xi>&t2VKz)!R4 z?Uf~sEYtE}4j@3$c1InFlsET|Q^iPWS7#iO47WwQ&f>+Lrylke-?xa!^Um|N->@%f zXlO`4ZR;9o0<~j1ggn@>(VcmX>oR#jOMKJ;ibA1g2M_laG`(_wTFG^mmoq#b`c)kA zHY-aeH`t(0DY%(BZyv9cU#8bAbaX5uBf~HUCj_e)G8sA=jtZt^^GN|R!eZTTxYp|G zYC;|29Ivt;&M>$w%!2I)&_7=^O<&}G9J@F=F)=|PBs}KUV(rWyD8+f*+i>g|7X%AO zl9h0Co0n4x7Ix71o!a>DzuBg+`v<33;OnAwEx)vp&|I^Deo+TY5vfj~pm-4kgNg zc{6pYtKma>{P$=;V&0XF(^Bo3J2SY>T+^IQURkl^otd6HFHwp~FhF>A`09>NJiKzG z@+VN2X@D$p@I^42uthH$Ue45)T(wxOca#=E+B?L>|KiMT>GtUX0AniZTT+vIj2Qvz z%+k4O-qeO%3LQ8Kz}H^U4zaQob@B5vIqSm#z=YLhUx)o~1#w!4*L`CfpV#Yl%fLW7 zaO5GKef2dFm;yELx;GY`9l^T4hY%pjib0*=z<_}BLXwGhXd+rFUPeR9GRZf;-_7SY z19m@TX#bP~(H}PnoOz7-moHlE$~}sq+E0i_h~(NwcC+-USHJ%Ov@?i#K#*nWP$$3h zP=W4;c?AK?p$rFJ)>|cmJEhx&TJ3H{pcJ0bBBG8!p8GuH3`GsuY>3_T*)W8BeNB&E zEAZ7kGio%lUGZSLVmkR(FlPE4&bcpT9kd54E>gY(G7)kV!C}?-EFdASCd0&AAk|yXXqmj?mJm2 zXrz?OqEHFovsyrU^QIq$s+)PIo%b}|AJUXRdG2JuLPM2QZf0hto#5eXl_!Tmr-#2o zX8d#0vyE{}j+m_%bKRi}OZu#xe##i``JlJ$KISQzCU^>7jU~ zQ(3_XL?k0G?4d0nCDcQ)H(udKEmD~jecb$BSWHPZD9~{|Q_cC&&r05_%VpW&)nqLW z&DS->4^AOWS7+3iyi<20^Q0Y`YAD%u2h&PjlB^{O + + + + + + + + + + + \ No newline at end of file diff --git a/images/accept_shortcut.svg b/images/shortcuts/accept_shortcut.svg similarity index 100% rename from images/accept_shortcut.svg rename to images/shortcuts/accept_shortcut.svg diff --git a/images/clear_shortcut.svg b/images/shortcuts/clear_shortcut.svg similarity index 100% rename from images/clear_shortcut.svg rename to images/shortcuts/clear_shortcut.svg diff --git a/images/shortcuts/shortcuts_group_comics.svg b/images/shortcuts/shortcuts_group_comics.svg index 66cc3bd6e..d7fadd8a7 100644 --- a/images/shortcuts/shortcuts_group_comics.svg +++ b/images/shortcuts/shortcuts_group_comics.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_folders.svg b/images/shortcuts/shortcuts_group_folders.svg index d66245abb..8b650c1cd 100644 --- a/images/shortcuts/shortcuts_group_folders.svg +++ b/images/shortcuts/shortcuts_group_folders.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_general.svg b/images/shortcuts/shortcuts_group_general.svg index eb25e4de7..762471797 100644 --- a/images/shortcuts/shortcuts_group_general.svg +++ b/images/shortcuts/shortcuts_group_general.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_libraries.svg b/images/shortcuts/shortcuts_group_libraries.svg index 250963dce..59b168dce 100644 --- a/images/shortcuts/shortcuts_group_libraries.svg +++ b/images/shortcuts/shortcuts_group_libraries.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_mglass.svg b/images/shortcuts/shortcuts_group_mglass.svg index 64c1e7807..38d2ae65b 100644 --- a/images/shortcuts/shortcuts_group_mglass.svg +++ b/images/shortcuts/shortcuts_group_mglass.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_page.svg b/images/shortcuts/shortcuts_group_page.svg index 950d28906..5ce4138e5 100644 --- a/images/shortcuts/shortcuts_group_page.svg +++ b/images/shortcuts/shortcuts_group_page.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_reading.svg b/images/shortcuts/shortcuts_group_reading.svg index eccd1f81c..9f8ff719d 100644 --- a/images/shortcuts/shortcuts_group_reading.svg +++ b/images/shortcuts/shortcuts_group_reading.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shortcuts/shortcuts_group_visualization.svg b/images/shortcuts/shortcuts_group_visualization.svg index ee2b6c0be..2924e94c6 100644 --- a/images/shortcuts/shortcuts_group_visualization.svg +++ b/images/shortcuts/shortcuts_group_visualization.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/shownCovers.png b/images/shownCovers.png deleted file mode 100644 index 089baaf026975e15478a99288ad4ac46852d0669..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 445 zcmV;u0Yd(XP)P000sQ1^@s6t}b<;0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzUr9tkRCwB)Re^DXFbu?824Dn6pc51( zs53#c0c{sZS)d6MB%L7X1h7Fe0wXX&Uw7h8btMD&JDoXO*30rEZ;}YU+BU`Pn-;bej*S` zqjALik>+U~YtM@MGLBoNaM&60Bz%kS6PJgwK49O)@RKMherg<5s%3%?);yOv^b4_1 zXB@_uUa8(oWKASZ#Gwe}D{&2^YoSSzO&@HKcokV!Bx6pB77sMYJ2%K-w$+PTuWI$y-MIyi nmgh&yYwF=g>l%Bsegzl+Ihm4ckgl(E00000NkvXXu0mjfntQmE diff --git a/images/sidebar/addLabelIcon.svg b/images/sidebar/addLabelIcon.svg index 732fb362f..bd2f8eded 100644 --- a/images/sidebar/addLabelIcon.svg +++ b/images/sidebar/addLabelIcon.svg @@ -1 +1,11 @@ - \ No newline at end of file + + + + + + + + diff --git a/images/sidebar/addLabelIcon_osx.png b/images/sidebar/addLabelIcon_osx.png deleted file mode 100755 index 3f8a8a51a243bd82bd041b6fadbfbc75ab9ac2ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xrg*wIhE&{2`t$$4J+o@V#5A@y_xHy$c$hL2G6{TM>=|ED zQewhj81W&)j^W5J3!S!ZW5Lyu8Oq8WkH0c8&X!F)mB6;BqLCy0{c*JuE=$r%J_y?K zaCuzdVG_Q;`@^B>S*yc;^8^;93)0*TAvS`ugg+c*vU4^tN%rlu;5oQTGCj!6m}PmI mQ{_U2SqW+vOw5^BBpBo*Lc)b_@}~ja$KdJe=d#Wzp$PzHC{OSJ diff --git a/images/sidebar/addLabelIcon_osx@2x.png b/images/sidebar/addLabelIcon_osx@2x.png deleted file mode 100755 index e0e1fea8c6d6cc5734c563d8bf59bdf593b2d2be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 342 zcmV-c0jd6pP)gMi~@2j2kLR4iUTO{`F@I{fY!l|w;-Z}<$}PR@&T&@=wSInpydkq zqF@1ygM9&^G$24j%NL?oL}b+k6j+`>OfI-UPs?%T0#H1~)5CI{?Exw|f}rJi8zdAu zf+))gwus1d1ksig)g&X)5hPhobeoV!N04keNsUqhjv&i&l3T?%96`3_WHrlyj+g+X o3}6Kp(DH)OuGx@w06>5N0Am)U&b4oe$^ZZW07*qoM6N<$f{3++E&u=k diff --git a/images/sidebar/addNew_sidebar.svg b/images/sidebar/addNew_sidebar.svg index 4c8b6e421..585a1cbf4 100644 --- a/images/sidebar/addNew_sidebar.svg +++ b/images/sidebar/addNew_sidebar.svg @@ -1 +1,11 @@ - \ No newline at end of file + + + + + + + + diff --git a/images/sidebar/addNew_sidebar_osx.png b/images/sidebar/addNew_sidebar_osx.png deleted file mode 100755 index aa101d8b03ce9801f8a76ba10f364b4a78caef18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X0zF+ELn>}1{rUgjo>{eF;xe{3_xIN`c9fNr_#9Z;*4e=N zG2o2DI!2a*2c#MJT{0Su3a`vp)Ja(RoJr>54|%EHp2HSm5ge`G4y36iF*r0ZGR%}# VPE+1h=>jyI!PC{xWt~$(698_YI`9Ah diff --git a/images/sidebar/addNew_sidebar_osx@2x.png b/images/sidebar/addNew_sidebar_osx@2x.png deleted file mode 100755 index 30c05b8af550b03ccd305279bb871055807e5c97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1G(>+}rLn>}1{rUgj{;&g+S{ozVV!i~$@W=oD{+4bCv7K`J z#fuj=9QrJKo~Sr2c*^AP%65~)1;!p_bzX+r--#yTJyr=<7_Tr%unIK=uU9 ot0(kqCEb6wDc@scU}R&sAZj}Cbl|b+KqoSIy85}Sb4q9e02cjLvj6}9 diff --git a/images/sidebar/branch-closed.svg b/images/sidebar/branch-closed.svg index ea2269639..ba3cabfb1 100644 --- a/images/sidebar/branch-closed.svg +++ b/images/sidebar/branch-closed.svg @@ -1 +1,9 @@ - \ No newline at end of file + + + + + + + diff --git a/images/sidebar/branch-open.svg b/images/sidebar/branch-open.svg index c60277d11..e07abfe75 100644 --- a/images/sidebar/branch-open.svg +++ b/images/sidebar/branch-open.svg @@ -1 +1,9 @@ - \ No newline at end of file + + + + + + + diff --git a/images/sidebar/colapse.svg b/images/sidebar/colapse.svg index 3a4f09fe3..fcb89d1cc 100644 --- a/images/sidebar/colapse.svg +++ b/images/sidebar/colapse.svg @@ -1 +1,17 @@ - + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/colapse_osx.png b/images/sidebar/colapse_osx.png deleted file mode 100755 index b5b33008392d7cfffa7cfed41ca86823551e7b45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 216 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XsytmBLn>}1{rUgjo>{e_v(d>xn)%!N`}K?+q8f#bb^^^j zoC}U{|8dwOm*K%|$1Jh&C{uv&t_O|^d<7*Xe;o1@ZZUskUT~0&S*%wbP0l+XkK!+=J0 diff --git a/images/sidebar/colapse_osx@2x.png b/images/sidebar/colapse_osx@2x.png deleted file mode 100755 index 9c746a4783bd85680f36eae75eb0a878c1f2f662..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 319 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1G4?SHRLn>}1{rUgj{;&g+S{ozVVm^sdhKqbR_SgSsRS1(f zA#i~`X@W8nn-SNK#tPdDg1lFX7?d}%3SI~*X=QJ;IB@ae$HNY)PSpx^3?(xTIy_?v zm@i(6(rZLk-RS1|Qj5i9W0S$3kq1XV?i*fZ=_Ne4UDa@#Q# zDj66GiSp`%Z2O~Rq8=mBA;6I8%pRn(JdHzyNq3$@pPQK05%ZJ#mW7ElXeqOL=`2@a zk!lnRUh0*msC>e4WexMzAU*ERNS=`Y_6ySXrOLdO?6pcbV$Gm%fWhdePwcsgBECS+ OGI+ZBxvX \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/sidebar/delete_sidebar_osx.png b/images/sidebar/delete_sidebar_osx.png deleted file mode 100755 index 61bf6f9ed76e2ca317cce88817362a418b86b272..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XQaxQ9Ln>}1{rUgjo>{elbN-V?X7+#0264g;dI#FRzrX)q zURqk#SgE>kL2kf<2M-Q#BpU}wvFY6S9^Y|%DW-VoP+L`oX3bVm{foMJf=^|!1rp0^` zr3Y3pyU7~7Y6xT($Pwgi`{tm;`b|AZhG}tU!3}E$g#!$!%EsRl-gTe~ HDWM4f4p>EE diff --git a/images/sidebar/expand.svg b/images/sidebar/expand.svg index 4918efd7d..22ee714fe 100644 --- a/images/sidebar/expand.svg +++ b/images/sidebar/expand.svg @@ -1 +1,17 @@ - + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/expand_osx.png b/images/sidebar/expand_osx.png deleted file mode 100755 index 754d92c17b886058ac5b5518bf7396540f07cfdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XB0XIkLn>}1{rUgjo>{e_v(d>Qi-DP$yJutl|9`9wTJt<= zxn*T#g#%(3L?b-9(s=X*5;?lk)+9C@7vMQ-!7SLV7-8DXpuBGh4{rop%q&hR1E(M* chXzK5KV=H$W{-pJ0WD$hboFyt=akR{06i`?761SM diff --git a/images/sidebar/expand_osx@2x.png b/images/sidebar/expand_osx@2x.png deleted file mode 100755 index 7bb3316ea934dea6eb6c486daf1bf0d54a9352e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1G(>+}rLn>~)nRb!$fC3Ne))GVYO!w83EoS8&)W0~xWoX1)JE} zyh0wHRg+P0JQTTof%78H^myl17H+*$jEyYPdVET4Egb8-oSd9^!rcoUomlHnf2%ni qoFlEfCz|2BA&bHX?#Ac_Muy_|rtK{ni*Ep($l&Sf=d#Wzp$P!iZdKF( diff --git a/images/sidebar/folder.svg b/images/sidebar/folder.svg index acd1186b8..2cce9a56a 100644 --- a/images/sidebar/folder.svg +++ b/images/sidebar/folder.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/folder_finished.svg b/images/sidebar/folder_finished.svg index 7a437f009..7d3aa4615 100644 --- a/images/sidebar/folder_finished.svg +++ b/images/sidebar/folder_finished.svg @@ -1 +1,24 @@ - \ No newline at end of file + + + + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/folder_read_overlay.svg b/images/sidebar/folder_read_overlay.svg new file mode 100644 index 000000000..3b8628e54 --- /dev/null +++ b/images/sidebar/folder_read_overlay.svg @@ -0,0 +1,13 @@ + + + + + + + \ No newline at end of file diff --git a/images/sidebar/libraryIcon.svg b/images/sidebar/libraryIcon.svg index b9d1deb36..fc7089d40 100644 --- a/images/sidebar/libraryIcon.svg +++ b/images/sidebar/libraryIcon.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/libraryIconSelected.svg b/images/sidebar/libraryIconSelected.svg index 032e708ee..1303e5783 100644 --- a/images/sidebar/libraryIconSelected.svg +++ b/images/sidebar/libraryIconSelected.svg @@ -1 +1,13 @@ - + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/libraryIcon_osx.png b/images/sidebar/libraryIcon_osx.png deleted file mode 100644 index ce99dde64ce3a7ba7e713fe5aac9d665881b1096..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 258 zcmeAS@N?(olHy`uVBq!ia0vp@K+MO%1|+}KPrC%9BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrH1%E%9`545_%4q?7;V|9J(#NQ9fT8V4W=!7)-uFQFGI+ZBxvX \ No newline at end of file + + + + + + + diff --git a/images/sidebar/newLibraryIcon.svg b/images/sidebar/newLibraryIcon.svg index 4c8b6e421..585a1cbf4 100644 --- a/images/sidebar/newLibraryIcon.svg +++ b/images/sidebar/newLibraryIcon.svg @@ -1 +1,11 @@ - \ No newline at end of file + + + + + + + + diff --git a/images/sidebar/newLibraryIcon_osx.png b/images/sidebar/newLibraryIcon_osx.png deleted file mode 100755 index 7c4a5aea2ecd681585d1d051ae85c5c23d3ca07e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xd_7$pLn>}1{rUgjo>{e_v(c&Hdc)t}-}M<1yH>Usq diff --git a/images/sidebar/newLibraryIcon_osx@2x.png b/images/sidebar/newLibraryIcon_osx@2x.png deleted file mode 100755 index 30c05b8af550b03ccd305279bb871055807e5c97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1G(>+}rLn>}1{rUgj{;&g+S{ozVV!i~$@W=oD{+4bCv7K`J z#fuj=9QrJKo~Sr2c*^AP%65~)1;!p_bzX+r--#yTJyr=<7_Tr%unIK=uU9 ot0(kqCEb6wDc@scU}R&sAZj}Cbl|b+KqoSIy85}Sb4q9e02cjLvj6}9 diff --git a/images/sidebar/openLibraryIcon.svg b/images/sidebar/openLibraryIcon.svg index 3e49f2c13..d266567ee 100644 --- a/images/sidebar/openLibraryIcon.svg +++ b/images/sidebar/openLibraryIcon.svg @@ -1 +1,37 @@ - \ No newline at end of file + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/openLibraryIcon_osx.png b/images/sidebar/openLibraryIcon_osx.png deleted file mode 100755 index 0a61bd9aa26b96656767869c3a454b26858e9faa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 244 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xrg^$JhE&{2`t$$4J+o>9>&(sd|NpTlm@;6xt;$Nc#@149@p1#;JoFt*1*BPQ{Hi}1{rUgj{;&g+S{oyq&JUIE@9*a`ERkxsF~6(K zucV|zr=d`y(3SDZCuWB;{>=UAOtKpr0z^zMoG23DP*CIjaoOONY=;-~2?mLjo+&pt zdV-$pcqVVMGvNxO&XQx6271B?kr@k|66{V0hVV0P3GwPtmRKPuG-V0nsuq@|ofDGW z1C+%Bo^&Jz@~H$(l9 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/renameListIcon_osx.png b/images/sidebar/renameListIcon_osx.png deleted file mode 100755 index 3ed190fd66929bc70641ec2404bb713608cbf603..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X7J0fjhE&{2`t$$4J+o>uqzRmB)al* zCLVNE@N2M?U(Q{S!PdxqV%A2f2KUcS3!bs;x#+PfZHj?Ix7H$)#k&_UbO?K1?8##| z@siJ@P2dU-lTJp>jQ_kBou$PSmSpE0VPjz8VfcRB*URAGl{-M!GI+ZBxvXgpME+=n71LKgoqO6NURS(6!4ZHJlZ|+gEttle$=w67I^t zIZ|Ra+*g8-ga|ye4P6pq@R&w4lsHMk*=-0Q_j$YloT~(p{r?SrUf?6Z0Gg+%@RHS) QBme*a07*qoM6N<$f)@#t#{d8T diff --git a/images/sidebar/setRoot.svg b/images/sidebar/setRoot.svg index 49f3e6e9a..ddf029f34 100644 --- a/images/sidebar/setRoot.svg +++ b/images/sidebar/setRoot.svg @@ -1 +1,38 @@ - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/sidebar/setRoot_osx.png b/images/sidebar/setRoot_osx.png deleted file mode 100755 index a2da070d90ad397a588e851d3a32300b2b6245c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 276 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xwt2cZhE&{2`t$$4J+o>9=lm!C{{Ciln4!bmAjR8og;k(! z(?%w@oH&Lo4~8J&h8gl&Uj#e28!GlKUaYLVDN0OdmZQ|?g?E|*Zpkf?T+h9r?k+

Mu{+>4;VaM{an^LB{Ts5DZXIc diff --git a/images/sidebar/setRoot_osx@2x.png b/images/sidebar/setRoot_osx@2x.png deleted file mode 100755 index 5dfcdd991ce275cc0bd821f2cc53a6fe842efc84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 438 zcmV;n0ZIOeP)%x#+@LtiTFZ`B#j~iPzR$0dE+noXf-*vg!HqkOQ^@VTYJJ%$qhFcQXq-66mmE;`D zy#mZ(swg?h7D@L8s&j&WDS0HFh^q4= zK6d02@H^JnE~lX8o0C)dkBx6g_L295LtoS~Qano}o0=?f96}^9Q&3T|#%HR?OcC3C z5^{MH4X;AeFKd8EI}ajF$!+pNN!LjjceriikBs7P%IMt}o3~tb`whPd2LJO%3(EtDd diff --git a/images/social_dialog/close.png b/images/social_dialog/close.png deleted file mode 100644 index 28e7c24f6a4bdb8884d7caab6c675bd198695e2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XW_Y?dhE&{2N@!@hx;k8(VIu>x5W`2uM+SDnAq935Ua>#= zYrq>&W$z)Qb^ZXy)tmh(4_FoWSRQ?K$Z1fC<1ngZ3}NJH5V_+X%rPncKu4PDCZ?3u zzJ&`H%1cbNSb?`AUa r3Z|TIxbvc8Ng`v2>_=%;x=H!^s-`njxgN@xNAm$Xuj diff --git a/images/social_dialog/facebook.png b/images/social_dialog/facebook.png deleted file mode 100644 index 3d7aa8deb7d2e9c66cf4b8e84bfbd0b59d9fa0c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^96-#^!3HF6a`hPlDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9Md6+0&DvF>eM)(%aHUKuPUz@aBanHSuh`py8*!vwv z0)`pi~K<$E(vylyTkOB7e;2D{8&X;IG zIdl>y_-1@gG=7j5crvWm4h);hY)FHxF9SPycX!&b?)j8vZVp4&i6B%G-@ft0hJfyBftQ1`(ZmLdh0>}0000l7BeO>^OI0Z{*LCR$9x6 z)PEu`FE5Ec^vu5>A0Lkr^F|D1MtVG;QXR)>7d>)4PI_co;X)Wl$I@Z&#i>V*4iQ1I zl|Ib$NCGbfMHgDhT)6XYvzLj;6tAiV^25(CLDNbeS`y` zmjo9D9p2!mZ*B~h$k1n??`a|i2ycjEIYT_Y+A9rFcHo-mrWs?NrHG4ZWqSDJs4~_! zvlnpDGW0I~d?r|fy^<`a;#`1;bQj;1)lLZs~|UgD*XAZk!8Fn37=0`qt7pEn7JDg_g;kNjW)QcVKNt$Wge7NZG9nt_BARWBpnDaffUqbGakBw# zM-&yZu~*6mY4@Teii?1A9}sMpV12#<+qmWxP%prGvPuA<75SR-0Qa&vxs@oB0d{pacAX*h7kgoNC_JRAISaV!X(NtY?EcR!HnQ)eY!9;9T?eAeFKn^?SQD z2?Sd!prE7?Ry4FC?vkGglo_=Ex+7lqlT#j8OMB?+sH8SPR&P$-6*woKn$-dbgX1fs zZsL?4_QDW4k9WfY84$ub5d8ll)Dm}LTGI|2z~liT{WCE*E|iQUmL+CHcZIy{fEhR+ z5P;F+j2SB>(4}^9Xw_#FDOc=cMcdj19p0eh1mo#diN3KINW?nCn}HYsJ&F6$yl>1U z`k$5+JtuUW&6%k~>WYt%0}RkzGj77P+HLGUKxXr0dH$gTQU|Skzy!6h^^Qt6uw*<5 zCm5^Z-U%jm7kuKID-U?d0Chn~*&jfR)k#?;gbR$6)qIsxrLGlH0MutUt^q`C?>*u~ zg#*l7(fX;SL5&y-%s4{dJrh@_Rl{Ihpcan!MD>t7CR&aQ&Imy-8-imm-)n?oawgMh z8=4aIV#3W74mdk3KbitlmN|mzl^_KttT7=Q-8NccTDssE{ppTAK5dOcb&s%(1i+NV~2USfEw6yf8->Gr;q;H`~s^EOY#|4zC z_P5$?ITy14VLY0)7*6IYXzR2fh5J3j7FyB1VwvqrKg; zo4c2mym}xjaINsgkRUN^!&PJ`lyQ4(n$v3;6;HgVJ z4{9;^@dy6?vu3m5{p9yGii|sST_E)O!3HFSxVM}GQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jiex-p978H@C8Z=J2rwqqY3TAEDRNlDcVrU-BO3z;7sIwo T_jv1p>KHs-{an^LB{Ts5$ao+& diff --git a/images/social_dialog/twitter.png b/images/social_dialog/twitter.png deleted file mode 100644 index 4a9df502aabb21f1024ac41dc218bd3674f3bf21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 301 zcmeAS@N?(olHy`uVBq!ia0vp^d_c^@!3HFQ8hUO4DajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9Mdv+T978H@CB^Km+RDVte7OC>g$w*V84McJ8J0Y1lvwhN zLBO9SiG9H>&K`%8YzoKaJ7g!CG9P7bxKhRD!(g;v0;k6Z=8cR3^V_xB8Y|e|JYc-g z#N89&Q^#O>mGPB}2*Z^l9E&11%-{){({R{qN4SIE-4hNrI~cBWY^h?LaL-}MvDOo2 zO$S_+Ol%vXnl5mNFt~aunomR;OXk;vd$@?2>`%>4x+5U z%0tdcVgq6Yh80+>z_0?$3NR}WUV-rn5ZL4;FUktS-GTBHgOm8yr*!F-if(DTXGWTl zs?X^oS+-$D{hP0`Ms_51>unel=zocffP5t`j z=ElG>sPeb9wY5<c%{Oi8*SEK~29`mU+x(6D`ue(oWl$BPROkfLr~@qO z*B?KAG_VY+eCAK6Rbyjg!@x4A@_{9Ra%wdKi~9AaPoE4dgDMRuz{IZ(Dg(=)$`2I- zrNP?V+%&KZsx+TU0>$0HGN_`VVuh0CPpX!KY6RBS*4D~{Wl+s%K9IChX~kM~u+|Kl z|2Kf(mSe^W1wa4`gTsHv?Vo@C8TG&a{(IE_`s=U8moHz?2M-Sq`!8O+7#dW|4-TMd z(c3n`@r*hY1)puRDuo<#boQ|%RA0Y-9lZi518d2lLST|W=nw>Z)B#b4!I6>jksshb zlThhU0y_Iy+yE4JsaEKZkB@j=Ik482REZ9#zr+GC!=PtzA*g&2bp3C2(_pb;Ikg%o z76G<0V680?NUs1BnW~ml7Y0PaA_0-Wgt}IztYC2mSOnF8URMIFwHkv2c)EZIAW0L& zzK;(oA1o3W-=DKKhAQB=kHOm6*%=yC)q)9r5kTtd*pbiF@v8MHMlnRzMgK}0#@Ar3icZUYmf?y(uP6?nE$BKL~O;e?^ zAxcoI(X5dEZhvoYZ|T5Vueg~zcL{M5Flne#9P84bR?qKO*NG6vHGTZOK~;Wi35wKX zGv|XzI^rA-r~*h@twN5xct2Q1^S53xb$YY8xp^wr(?T#+NtI@qLH!DoNUxV<`i=~$ z^3(~c)Z5tDXknd=mquopx~hUCeJTObILtu(lAQFV1ga8Hkvg4|Ivw+(Z3w8U!z6+7 zK_wja%blH_r3GrCP?0*dojSE8P&#*M-Y~JxlluGQ8lax}QNMig;>A(}wJ@j!=xNe`Xs8XTA z49@}8@P!QWm^+_Y^937qoQOKW`9Qso1>H`kGjlOl`bzw}`I@D3&WpvX4peDS`GC^d z1u5oE&$Ofh>8Q1Mf8{{BO3AvEU}{HRW+6B~sy0CN`~5Cn>A||JJXBeLN>wMVN*W+B zoxi8gF0j5ds9Yks0g5QU#3AGp!7PLi~-SSZ=E{LEw@_( zg$Y2NfTD-KC&x!FHwmclzD@VmqmK_42G!l&-7yx2^}=vop!AZ5dxbn7k~;P0IVhfZ zSZy*kHBi!w%UGLQB{)C^ELl0C&_93v+^5&?<_(kw z_Sym!%31T3Ln8n96dOrXLcXsSmrywPSKU(MR4{uSkJ8I9 z1p;;d@bGX*vb&Uf;>rX{DwG_XS-!6H8$B5pL+anfgc+igiZ1L_#-mc5a-A(HtD;c< z-hhg0{eBj-C&s&1iuuEAfPTTTuP{bdKWf?&0iaNEj!fRrFp1}i z`hWq^z+^I6fkOx!UVo~gro5{=3P?m_k*F!80^IB;NSQ0Mfytfb(EetB>ON|}!Se5eC zYZ5ATXh0RykY#{u1OAS625c6@Gn zhutYw8z-6tp>l^W=88*s$~>D&Rm-=!)U&{>P5V~D=ROERMgQ=n4tB*j=bn9geN(AQ z`c{`I;RT-w^u?^SQgw9rASO2DQK<_X#!C8D?|e{YF@e66Wtc#@Y||9}6i%($_U*Vx zF@30aKu^V$4PiCoR;b~Xk`@#4ujDMS8B(bj)8{MJiVAi%e3kaCE_?}mS>f`C&)yTL z@L}k@;VjKl-Ofy3g&WFM=2^DUu`7Dt@j=y21(HIP&0k?P^*4y4*LwS+GD8bgSHGIq=XWbTHV-?)xxj(;M>v_n;oi6VAK6& zD^Ia}z2g{9fDKt~W`R#mz=%;PfM(7Cb)$3FbAZ*J3RQ~vbNx3Ps#-xc@SS;>0v22+oH*NbGr#08g1i9t z-a-lWngI@CvK4$#DW@G#gywckB3=kE=~LNI)hk{lVTy%H0>vf}=5IUC5wr4QaB=3O z*H^7lig{?YLOu2-J6AqC8EXdJ`FYmr*M?dkVu6ya>5DrgI(*}cvsSw{(3U4h+iPZ} zFN+B@sA}8(NO90ZoWT5jtLDBlFj?ufbZXPZfg7nzceFSO%4~!hK?V@ zetVc1HXCX&F-0;($ljEyo^3l|c~aVMO`TMivZI1uk(*`XQ_I%Q1C!1g9htv8xinI( zke8L`Kxb0RvqYS}Q=r@6u`xsx;nKf@-ftHoBUodMZ1 z8>(8VR9o*%kJ(M-0c*gszkcctRjpROOj2u=hU!_0N(FYNk4iu?RQGwdKC9iT=2O+E zK?HO$vm9{sN1(dD`)?6@zxbpjbJlC)PoZ#dJGCf_+L|{Kr!iE#^|^@SQJsA@sOn+* z4)pm$u}-?&Gf4fnF;sFxVQQfUH3NKULsko@_NElui1w*C<~f4O%>a`NV0jK3d{SH6 zS|$CdgOnPtKA;dmKouG3Q;jIoP{nM6*2hce+S=AC=T9Brl+lzLufAEIEX*RIx+yBG z5ISDMT6G!$^->>bm3k0^gX-o9R9sjzrC5W{1a53>zyw;%s=BkjgOqczr>NCarILPC ziehOK=w4sj5LR~9x2>Uy0ZN@iG-Q8j0xG9gA5v;-2TraWod<`f!iKSOP`&o4RMw;S zJhQ(3#LrhyUCEOxV@;q2%T+w?+Avni^mX8xv znZRl}=%>m>$^3tPvp(0af>5zqrTSI61hO-Mt-HHBQ>%)o6pcqmo{ybXsX{=J2wm;$ z>b@|<1V4BglP-Jq=r&e!a<;L}Q=I43>DmlCG0Pn_ImhRUf`@Ko>|!B9Bu=jOD} z)$H}Ka17s8=T60_lz^$>xCkD&9)wCB;GAbY&;u5n_MQ#*+{|7lk1rKase8FBlNl)f&! zN&{+}zTX}}wXIbuR;hFpz^T+_GE`EnlPW9~ z%0KyJxDp1lvm*dSdzF8`j2`Z;nCy1Wr zS-u(lGO^Yq%we0<${hD%fa;RjJNEfevH9mIzEl)cNZ@;Xe7x{E?JP1cl-UmMci`$MICX# z36)COawR8b4l1m!oMg60F&9ri{6wmi&bgX((K8y-C*Bz%`G89GqkKw5BEl+l7K)zd zhRU4|{?-Rp2rj)nS}jO&A5!1%bUKwj+KrU7R~MjSHZx2!d(Jt38*^RJC9mn1AjEJF zigoU2k7s*tQ?4`l#0NJU?8^($@~J=5K&3ndivTJmp{)dScMPBiq_#A9GNmPThp}&b z=+8%~*SenPM(F|$=_Y>1VazhXDb1o*ELC+J6OKiiI~^%csn;0-N?4wK zy_sPyO2z&aE`Tpan?pf9+vwT=MFZE>!NYm0l~bqRwYk%Q&6FL+KC|b>=qT^_tmnOP zTmT$*y2u_Y6`laxqQXASXoU() zpst=je|}WNeXJMtg%B`r2&`}Eg1ZVTIDNGMiUxDS6+fh;XvtHzvL*N{dKhj_amm}p>k3#_{@>jZSX5?gplM>5-3fZp& z&MWL1mM}?G%A-!cIFtm+`MLvVMG8CewvW=%7-%@V@CRdXyR0q|oM)KdKDpM#1CCwc>6FjSr>YZBIx?*Xm*3;xF%Z5g zI67Tg!s45~X}>KGOrfBrT+KjWv#2qwD);I@~M+2tw=AuT+Zve zURx!g0F%!#PdVve>X+&p5di#0WTYxEHLqFNS$2x<0Lh~&Y+soINLzZ?()Jk z@21bw^W^vIMPZcHJX&-n$WlUud?+k~_>?KnA=Hb8X$nyAoi31#TZQXiI;c1Wc-n~u zRfkEMIUi7JQ5dB(Ph$4v8C3DDt>LLMP@W@WgX*MGR$%H*vTj8;sPeUa8WdELY5NWs z;P;D!OJ9qg(dn*WLP_$odB&YAPW7)(h0OxjsL0DRKMp6v7Of}}A|FW7%ms?y*9NAg zhRV(UP&{=4tUMbAV!+X#Pcv~oby7<$h&R2f158T~m5WnNfTiPAsk>yf^7x<%f#ma< z<}*!GCVK7D>pL8du!u;wL6r!W zE@qJhtiVCkPgKh1FHJelOoD{NJF(6Dei^>+RmxI8#oi~1HEox#FN-pC2$XLYC!rEQ z;~pn@QU^%=GLz*Dss(}NE5E~F`F8T^(%(LFC%_w0AGnjy5m)Nh*{m5 - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shortcuts_management/actions_groups_model.cpp b/shortcuts_management/actions_groups_model.cpp index d58dbbd00..6656eccc1 100644 --- a/shortcuts_management/actions_groups_model.cpp +++ b/shortcuts_management/actions_groups_model.cpp @@ -62,6 +62,15 @@ QList ActionsGroupsModel::getActions(const QModelIndex &mi) return QList(); } +void ActionsGroupsModel::updateGroupIcon(int row, const QIcon &icon) +{ + if (row >= 0 && row < groups.size()) { + groups[row].setIcon(icon); + QModelIndex idx = index(row, 0); + emit dataChanged(idx, idx, { Qt::DecorationRole }); + } +} + //------------------------------------------------------------------- ActionsGroup::ActionsGroup(const QString &name, const QIcon &icon, QList &actions) @@ -74,6 +83,11 @@ QString ActionsGroup::getName() const return name; } +void ActionsGroup::setIcon(const QIcon &newIcon) +{ + icon = newIcon; +} + QIcon ActionsGroup::getIcon() const { return icon; diff --git a/shortcuts_management/actions_groups_model.h b/shortcuts_management/actions_groups_model.h index 82b4c335e..31d21f576 100644 --- a/shortcuts_management/actions_groups_model.h +++ b/shortcuts_management/actions_groups_model.h @@ -13,6 +13,7 @@ class ActionsGroup QString getName() const; QIcon getIcon() const; QList getActions() const; + void setIcon(const QIcon &icon); protected: QString name; @@ -34,6 +35,7 @@ class ActionsGroupsModel : public QAbstractItemModel void addActionsGroup(const ActionsGroup &group); QList getActions(const QModelIndex &mi); + void updateGroupIcon(int row, const QIcon &icon); signals: public slots: diff --git a/shortcuts_management/edit_shortcut_item_delegate.cpp b/shortcuts_management/edit_shortcut_item_delegate.cpp index ca93e88dd..90a1b0afa 100644 --- a/shortcuts_management/edit_shortcut_item_delegate.cpp +++ b/shortcuts_management/edit_shortcut_item_delegate.cpp @@ -63,12 +63,12 @@ KeySequenceLineEdit::KeySequenceLineEdit(QWidget *parent) acceptButton = new QToolButton(this); QString buttonsStyle = "QToolButton { border: none; padding: 0px; }"; - clearButton->setIcon(QIcon(":/images/clear_shortcut.svg")); + clearButton->setIcon(QIcon(":/images/shortcuts/clear_shortcut.svg")); clearButton->setIconSize(QSize(15, 15)); clearButton->setCursor(Qt::ArrowCursor); clearButton->setStyleSheet(buttonsStyle); - acceptButton->setIcon(QIcon(":/images/accept_shortcut.svg")); + acceptButton->setIcon(QIcon(":/images/shortcuts/accept_shortcut.svg")); acceptButton->setIconSize(QSize(15, 15)); acceptButton->setCursor(Qt::ArrowCursor); acceptButton->setStyleSheet(buttonsStyle); diff --git a/shortcuts_management/edit_shortcuts_dialog.cpp b/shortcuts_management/edit_shortcuts_dialog.cpp index 0f9da75fb..8face33d3 100644 --- a/shortcuts_management/edit_shortcuts_dialog.cpp +++ b/shortcuts_management/edit_shortcuts_dialog.cpp @@ -71,6 +71,32 @@ EditShortcutsDialog::EditShortcutsDialog(QWidget *parent) setWindowTitle(tr("Shortcuts settings")); setModal(true); + + initTheme(this); +} + +void EditShortcutsDialog::applyTheme(const Theme &theme) +{ + updateGroupIcons(theme); +} + +void EditShortcutsDialog::updateGroupIcons(const Theme &theme) +{ + // Update icons for all groups based on the mapping + for (int i = 0; i < groupsModel->rowCount(); ++i) { + QModelIndex idx = groupsModel->index(i, 0); + QString groupName = groupsModel->data(idx, Qt::DisplayRole).toString(); + + if (groupIconMapping.contains(groupName)) { + QIcon newIcon = groupIconMapping[groupName](theme); + groupsModel->updateGroupIcon(i, newIcon); + } + } +} + +void EditShortcutsDialog::setGroupIconMapping(const QMap> &mapping) +{ + groupIconMapping = mapping; } void EditShortcutsDialog::addActionsGroup(const QString &name, const QIcon &ico, QList &group) diff --git a/shortcuts_management/edit_shortcuts_dialog.h b/shortcuts_management/edit_shortcuts_dialog.h index 2e51b76fc..77a8be2be 100644 --- a/shortcuts_management/edit_shortcuts_dialog.h +++ b/shortcuts_management/edit_shortcuts_dialog.h @@ -4,18 +4,21 @@ #include #include +#include "themable.h" + class QListView; class QTableView; class ActionsGroupsModel; class ActionsShortcutsModel; -class EditShortcutsDialog : public QDialog +class EditShortcutsDialog : public QDialog, protected Themable { Q_OBJECT public: explicit EditShortcutsDialog(QWidget *parent = 0); void addActionsGroup(const QString &name, const QIcon &ico, QList &group); + void setGroupIconMapping(const QMap> &mapping); signals: public slots: @@ -24,9 +27,14 @@ public slots: void processConflict(const QString &shortcutInConflict); protected: + void applyTheme(const Theme &theme) override; + void updateGroupIcons(const Theme &theme); + QListView *actionsGroupsListView; QTableView *actionsTableView; ActionsGroupsModel *groupsModel; + + QMap> groupIconMapping; ActionsShortcutsModel *actionsModel; }; From d03e19bbe68007e601af051fdec2db33dad525a8 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 19 Feb 2026 18:07:40 +0100 Subject: [PATCH 065/187] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ad479323..85187da9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Version counting is based on semantic versioning (Major.Feature.Patch) ### All GUI Apps * Migrate Flow implementation from OpenGL to QRhi. This is a full new implementation with better performance and compatibility with operating systems and hardware. +* Add light/dark themes support that follow the system configuration. ## 9.16.4 From 3e72c03ea47499a708066aad6583a8559fb4b267 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 19 Feb 2026 18:19:33 +0100 Subject: [PATCH 066/187] Remove Qt5 jobs from Github actions --- .github/workflows/build.yml | 415 +----------------------------------- 1 file changed, 7 insertions(+), 408 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bd246f114..5670bfc97 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,43 +49,6 @@ jobs: git diff ${{ github.sha }} if [ "$(git diff ${{ github.sha }})" != "" ]; then exit 1; fi - # Linux build (Qt5 with unarr) - linux: - name: Linux (Qt5) - runs-on: ubuntu-22.04 - needs: [initialization, code-format-validation] - steps: - - uses: actions/checkout@v4 - - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y qtchooser qtbase5-dev-tools qt5-qmake \ - qtbase5-dev qtmultimedia5-dev libpoppler-qt5-dev qttools5-dev-tools \ - libqt5opengl5-dev libunarr-dev qtdeclarative5-dev libqt5svg5-dev qtquickcontrols2-5-dev - - - name: Create tarball - run: | - VERSION="$(cat common/yacreader_global.h | grep '#define VERSION "' | tr -d '#define VERSION' | tr -d '"' )" - ./mktarball.sh $VERSION - mkdir tarball - cp yacreader-*-src.tar.xz* tarball/ - - - name: Build - run: | - export DEFINES_VAR=DEFINES+=\"BUILD_NUMBER=\\\\\\\"${{ needs.initialization.outputs.build_number }}\\\\\\\"\" - qmake CONFIG+="unarr" $DEFINES_VAR - make - - - name: Run tests - run: make check TESTARGS="-maxwarnings 100000" - - - name: Upload tarball - uses: actions/upload-artifact@v4 - with: - name: src-${{ needs.initialization.outputs.build_number }}-tarball - path: tarball/* - # Linux Qt6 build linux-qt6: name: Linux (Qt6) @@ -148,12 +111,12 @@ jobs: needs: [initialization, code-format-validation] steps: - uses: actions/checkout@v4 - + - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '18' - + - name: Install dependencies run: | pip3 install --break-system-packages aqtinstall @@ -163,14 +126,14 @@ jobs: mkdir -p ${{ github.workspace }}/compressed_archive wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O ${{ github.workspace }}/compressed_archive/7z2301-src.7z 7z x ${{ github.workspace }}/compressed_archive/7z2301-src.7z -o${{ github.workspace }}/compressed_archive/lib7zip - + - name: Import Code Signing Certificate if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') uses: apple-actions/import-codesign-certs@v2 with: p12-file-base64: ${{ secrets.MACOS_CERTIFICATE_P12_BASE64 }} p12-password: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} - + - name: Build env: MACOSX_DEPLOYMENT_TARGET: "11" @@ -179,231 +142,25 @@ jobs: SKIP_CODESIGN="${{ env.IS_FORK }}" SKIP_CODESIGN=$(echo "$SKIP_CODESIGN" | tr '[:upper:]' '[:lower:]') ./compileOSX.sh $VERSION ${{ needs.initialization.outputs.build_number }} $SKIP_CODESIGN Qt6 universal - - - name: Build and run tests - run: | - cd tests - qmake - make check TESTARGS="-maxwarnings 100000" - - - name: Notarize - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - run: | - xcrun notarytool submit *.dmg --apple-id "${{ secrets.MACOS_APPLE_ID }}" --team-id "${{ secrets.MACOS_TEAM_ID }}" --password "${{ secrets.MACOS_APP_PASSWORD }}" --wait - xcrun stapler staple *.dmg - - - name: Upload DMG - uses: actions/upload-artifact@v4 - with: - name: macos-qt6-universal-${{ needs.initialization.outputs.build_number }}-dmg - path: "*.dmg" - # macOS Qt5 build - macos: - name: macOS (Qt5) - runs-on: macos-15-intel - needs: [initialization, code-format-validation] - steps: - - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '18' - - - name: Install dependencies - run: | - brew install qt@5 - brew link qt@5 --force - npm install -g appdmg - mkdir -p ${{ github.workspace }}/compressed_archive - wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O ${{ github.workspace }}/compressed_archive/7z2301-src.7z - 7z x ${{ github.workspace }}/compressed_archive/7z2301-src.7z -o${{ github.workspace }}/compressed_archive/lib7zip - - - name: Import Code Signing Certificate - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - uses: apple-actions/import-codesign-certs@v2 - with: - p12-file-base64: ${{ secrets.MACOS_CERTIFICATE_P12_BASE64 }} - p12-password: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} - - - name: Build - env: - MACOSX_DEPLOYMENT_TARGET: "10.13" - run: | - VERSION="$(cat common/yacreader_global.h | grep '#define VERSION "' | tr -d '#define VERSION' | tr -d '"' )" - SKIP_CODESIGN="${{ env.IS_FORK }}" - SKIP_CODESIGN=$(echo "$SKIP_CODESIGN" | tr '[:upper:]' '[:lower:]') - ./compileOSX.sh $VERSION ${{ needs.initialization.outputs.build_number }} $SKIP_CODESIGN Qt5 x86_64 - - name: Build and run tests run: | cd tests qmake make check TESTARGS="-maxwarnings 100000" - + - name: Notarize if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') run: | xcrun notarytool submit *.dmg --apple-id "${{ secrets.MACOS_APPLE_ID }}" --team-id "${{ secrets.MACOS_TEAM_ID }}" --password "${{ secrets.MACOS_APP_PASSWORD }}" --wait xcrun stapler staple *.dmg - + - name: Upload DMG uses: actions/upload-artifact@v4 with: - name: macos-${{ needs.initialization.outputs.build_number }}-dmg + name: macos-qt6-universal-${{ needs.initialization.outputs.build_number }}-dmg path: "*.dmg" - # Windows x64 Qt5 build - windows-x64: - name: Windows x64 (Qt5) - runs-on: windows-2022 - needs: [initialization, code-format-validation] - steps: - - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - architecture: 'x64' - - - name: Install dependencies - shell: cmd - run: | - pip install -U pip - pip install aqtinstall - mkdir C:\Qt - python -m aqt install-qt windows desktop 5.15.2 win64_msvc2019_64 -O c:\Qt - dir C:\Qt\5.15.2\msvc2019_64\bin - choco install -y wget - choco install innosetup - mkdir %GITHUB_WORKSPACE%\compressed_archive - wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O %GITHUB_WORKSPACE%\compressed_archive\7z2301-src.7z - 7z x %GITHUB_WORKSPACE%\compressed_archive\7z2301-src.7z -o%GITHUB_WORKSPACE%\compressed_archive\lib7zip - wget "https://aka.ms/vs/17/release/vc_redist.x64.exe" -O %GITHUB_WORKSPACE%\vc_redist.x64.exe - - - name: Build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - set PATH=C:\Qt\5.15.2\msvc2019_64\bin;%PATH% - set DEFINES_VAR=DEFINES+="BUILD_NUMBER=\\\\\\\"${{ needs.initialization.outputs.build_number }}\\\\\\\"" - qmake CONFIG+="7zip" %DEFINES_VAR% - nmake - - - name: Run tests - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - set PATH=C:\Qt\5.15.2\msvc2019_64\bin;%PATH% - nmake check TESTARGS="-maxwarnings 100000" - - - name: Upload executables for signing - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - uses: actions/upload-artifact@v4 - id: upload_executables - with: - name: windows-x64-executables-unsigned-${{ needs.initialization.outputs.build_number }} - path: | - release64/YACReader.exe - release64/YACReaderLibrary.exe - release64/YACReaderLibraryServer.exe - - - name: Sign executables with SignPath - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - uses: signpath/github-action-submit-signing-request@v1 - with: - api-token: ${{ secrets.SIGNPATH_API_TOKEN }} - organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }} - project-slug: 'yacreader' - signing-policy-slug: 'release-signing' - artifact-configuration-slug: 'zipped-files' - github-artifact-id: ${{ steps.upload_executables.outputs.artifact-id }} - wait-for-completion: true - wait-for-completion-timeout-in-seconds: "7200" - output-artifact-directory: release64/signed - - - name: Replace with signed executables - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - shell: pwsh - run: | - Write-Host "=== Replacing executables with signed versions ===" - Get-ChildItem -Path "release64/signed" -Filter "*.exe" | ForEach-Object { - $destPath = "release64/$($_.Name)" - Write-Host "Moving signed: $($_.Name) -> $destPath" - Move-Item -Path $_.FullName -Destination $destPath -Force - Write-Host " Moved successfully" - } - Remove-Item -Path "release64/signed" -Recurse -Force -ErrorAction SilentlyContinue - Write-Host "Signed executables are ready for installer creation" - - - name: Create installer - shell: cmd - working-directory: ci/win - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - set PATH=C:\Qt\5.15.2\msvc2019_64\bin;%PATH% - .\create_installer.cmd x64 7z ${{ needs.initialization.outputs.build_number }} qt5 - - - name: Verify installer was created - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - shell: pwsh - run: | - if (-not (Test-Path "ci/win/Output/YACReader*.exe")) { - throw "Installer file was not created" - } - Get-ChildItem "ci/win/Output/YACReader*.exe" - - - name: Upload unsigned installer - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - uses: actions/upload-artifact@v4 - id: upload_unsigned - with: - name: windows-x64-unsigned-${{ needs.initialization.outputs.build_number }} - path: ci/win/Output/YACReader*.exe - - - name: Submit to SignPath - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - uses: signpath/github-action-submit-signing-request@v1 - with: - api-token: ${{ secrets.SIGNPATH_API_TOKEN }} - organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }} - project-slug: 'yacreader' - signing-policy-slug: 'release-signing' - artifact-configuration-slug: 'zipped-files' - github-artifact-id: ${{ steps.upload_unsigned.outputs.artifact-id }} - wait-for-completion: true - wait-for-completion-timeout-in-seconds: "7200" - output-artifact-directory: ci/win/Output/signed - - - name: Replace with signed installer - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - shell: pwsh - run: | - Write-Host "=== Files in signed directory before move ===" - Get-ChildItem -Path "ci/win/Output/signed" -Filter "*.exe" | ForEach-Object { Write-Host " $($_.Name) - $($_.Length) bytes" } - - $signedFiles = Get-ChildItem -Path "ci/win/Output/signed" -Filter "*.exe" - foreach ($signedFile in $signedFiles) { - $destPath = "ci/win/Output/$($signedFile.Name)" - Write-Host "Moving signed: $($signedFile.Name) -> $destPath" - Move-Item -Path $signedFile.FullName -Destination $destPath -Force - Write-Host " Moved successfully" - } - - Write-Host "=== Files in Output directory after move ===" - Get-ChildItem -Path "ci/win/Output" -Filter "*.exe" | ForEach-Object { Write-Host " $($_.Name) - $($_.Length) bytes" } - - Remove-Item -Path "ci/win/Output/signed" -Recurse -Force -ErrorAction SilentlyContinue - Write-Host "Cleaned up signed directory" - - - name: Upload installer - uses: actions/upload-artifact@v4 - with: - name: windows-x64-${{ needs.initialization.outputs.build_number }} - path: ci/win/Output/YACReader*.exe - # Windows x64 Qt6 build windows-x64-qt6: name: Windows x64 (Qt6) @@ -707,156 +464,6 @@ jobs: name: windows-arm64-qt6-${{ needs.initialization.outputs.build_number }} path: ci/win/Output/YACReader*.exe - # Windows x86 Qt5 build - windows-x86: - name: Windows x86 (Qt5) - runs-on: windows-2022 - needs: [initialization, code-format-validation] - steps: - - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - architecture: 'x64' - - - name: Install dependencies - shell: cmd - run: | - pip install -U pip - pip install aqtinstall - mkdir C:\Qt - python -m aqt install-qt windows desktop 5.15.2 win32_msvc2019 -O c:\Qt - dir C:\Qt\5.15.2\msvc2019\bin - choco install -y wget - choco install innosetup - mkdir %GITHUB_WORKSPACE%\compressed_archive - wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O %GITHUB_WORKSPACE%\compressed_archive\7z2301-src.7z - 7z x %GITHUB_WORKSPACE%\compressed_archive\7z2301-src.7z -o%GITHUB_WORKSPACE%\compressed_archive\lib7zip - wget "https://aka.ms/vs/17/release/vc_redist.x86.exe" -O %GITHUB_WORKSPACE%\vc_redist.x86.exe - - - name: Build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars32.bat" - set PATH=C:\Qt\5.15.2\msvc2019\bin;%PATH% - set DEFINES_VAR=DEFINES+="BUILD_NUMBER=\\\\\\\"${{ needs.initialization.outputs.build_number }}\\\\\\\"" - qmake CONFIG+="7zip" %DEFINES_VAR% - nmake - - - name: Run tests - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars32.bat" - set PATH=C:\Qt\5.15.2\msvc2019\bin;%PATH% - nmake check TESTARGS="-maxwarnings 100000" - - - name: Upload executables for signing - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - uses: actions/upload-artifact@v4 - id: upload_executables - with: - name: windows-x86-executables-unsigned-${{ needs.initialization.outputs.build_number }} - path: | - release/YACReader.exe - release/YACReaderLibrary.exe - release/YACReaderLibraryServer.exe - - - name: Sign executables with SignPath - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - uses: signpath/github-action-submit-signing-request@v1 - with: - api-token: ${{ secrets.SIGNPATH_API_TOKEN }} - organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }} - project-slug: 'yacreader' - signing-policy-slug: 'release-signing' - artifact-configuration-slug: 'zipped-files' - github-artifact-id: ${{ steps.upload_executables.outputs.artifact-id }} - wait-for-completion: true - wait-for-completion-timeout-in-seconds: "7200" - output-artifact-directory: release/signed - - - name: Replace with signed executables - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - shell: pwsh - run: | - Write-Host "=== Replacing executables with signed versions ===" - Get-ChildItem -Path "release/signed" -Filter "*.exe" | ForEach-Object { - $destPath = "release/$($_.Name)" - Write-Host "Moving signed: $($_.Name) -> $destPath" - Move-Item -Path $_.FullName -Destination $destPath -Force - Write-Host " Moved successfully" - } - Remove-Item -Path "release/signed" -Recurse -Force -ErrorAction SilentlyContinue - Write-Host "Signed executables are ready for installer creation" - - - name: Create installer - shell: cmd - working-directory: ci/win - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars32.bat" - set PATH=C:\Qt\5.15.2\msvc2019\bin;%PATH% - .\create_installer.cmd x86 7z ${{ needs.initialization.outputs.build_number }} qt5 - - - name: Verify installer was created - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - shell: pwsh - run: | - if (-not (Test-Path "ci/win/Output/YACReader*.exe")) { - throw "Installer file was not created" - } - Get-ChildItem "ci/win/Output/YACReader*.exe" - - - name: Upload unsigned installer - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - uses: actions/upload-artifact@v4 - id: upload_unsigned - with: - name: windows-x86-unsigned-${{ needs.initialization.outputs.build_number }} - path: ci/win/Output/YACReader*.exe - - - name: Submit to SignPath - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - uses: signpath/github-action-submit-signing-request@v1 - with: - api-token: ${{ secrets.SIGNPATH_API_TOKEN }} - organization-id: ${{ secrets.SIGNPATH_ORGANIZATION_ID }} - project-slug: 'yacreader' - signing-policy-slug: 'release-signing' - artifact-configuration-slug: 'zipped-files' - github-artifact-id: ${{ steps.upload_unsigned.outputs.artifact-id }} - wait-for-completion: true - wait-for-completion-timeout-in-seconds: "7200" - output-artifact-directory: ci/win/Output/signed - - - name: Replace with signed installer - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') - shell: pwsh - run: | - Write-Host "=== Files in signed directory before move ===" - Get-ChildItem -Path "ci/win/Output/signed" -Filter "*.exe" | ForEach-Object { Write-Host " $($_.Name) - $($_.Length) bytes" } - - $signedFiles = Get-ChildItem -Path "ci/win/Output/signed" -Filter "*.exe" - foreach ($signedFile in $signedFiles) { - $destPath = "ci/win/Output/$($signedFile.Name)" - Write-Host "Moving signed: $($signedFile.Name) -> $destPath" - Move-Item -Path $signedFile.FullName -Destination $destPath -Force - Write-Host " Moved successfully" - } - - Write-Host "=== Files in Output directory after move ===" - Get-ChildItem -Path "ci/win/Output" -Filter "*.exe" | ForEach-Object { Write-Host " $($_.Name) - $($_.Length) bytes" } - - Remove-Item -Path "ci/win/Output/signed" -Recurse -Force -ErrorAction SilentlyContinue - Write-Host "Cleaned up signed directory" - - - name: Upload installer - uses: actions/upload-artifact@v4 - with: - name: windows-x86-${{ needs.initialization.outputs.build_number }} - path: ci/win/Output/YACReader*.exe - # Docker amd64 build docker-amd64: name: Docker amd64 Image @@ -907,13 +514,9 @@ jobs: runs-on: ubuntu-24.04 needs: - initialization - - linux - linux-qt6 - linux-qt6-7zip - - macos - macos-qt6-universal - - windows-x86 - - windows-x64 - windows-x64-qt6 - windows-arm64-qt6 - docker-amd64 @@ -1021,13 +624,9 @@ jobs: runs-on: ubuntu-24.04 needs: - initialization - - linux - linux-qt6 - linux-qt6-7zip - - macos - macos-qt6-universal - - windows-x86 - - windows-x64 - windows-x64-qt6 - windows-arm64-qt6 - docker-amd64 From ac5adcf824ef1fbdfe079641dc061790a94a30fa Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 19 Feb 2026 18:21:53 +0100 Subject: [PATCH 067/187] Bump version to 10.0.0 --- common/yacreader_global.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/yacreader_global.h b/common/yacreader_global.h index 7c2bf1ac5..c4718d77b 100644 --- a/common/yacreader_global.h +++ b/common/yacreader_global.h @@ -9,7 +9,7 @@ class QLibrary; -#define VERSION "9.16.4" +#define VERSION "10.0.0" // Used to check if the database needs to be updated, the version is stored in the database. // This value is only incremented when the database structure changes. From 892d6f3b08c38b4f586b925a114138da41ab7223 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 19 Feb 2026 18:41:25 +0100 Subject: [PATCH 068/187] Format --- YACReaderLibrary/add_label_dialog.cpp | 16 ++++++++-------- YACReaderLibrary/info_comics_view.cpp | 1 - YACReaderLibrary/server_config_dialog.h | 2 +- shortcuts_management/edit_shortcuts_dialog.h | 6 +++--- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/YACReaderLibrary/add_label_dialog.cpp b/YACReaderLibrary/add_label_dialog.cpp index 1e06fa363..c1cc0c79a 100644 --- a/YACReaderLibrary/add_label_dialog.cpp +++ b/YACReaderLibrary/add_label_dialog.cpp @@ -2,17 +2,17 @@ namespace { const char *labelColorNames[] = { - QT_TR_NOOP("red"), - QT_TR_NOOP("orange"), + QT_TR_NOOP("red"), + QT_TR_NOOP("orange"), QT_TR_NOOP("yellow"), - QT_TR_NOOP("green"), - QT_TR_NOOP("cyan"), + QT_TR_NOOP("green"), + QT_TR_NOOP("cyan"), QT_TR_NOOP("blue"), - QT_TR_NOOP("violet"), - QT_TR_NOOP("purple"), + QT_TR_NOOP("violet"), + QT_TR_NOOP("purple"), QT_TR_NOOP("pink"), - QT_TR_NOOP("white"), - QT_TR_NOOP("light"), + QT_TR_NOOP("white"), + QT_TR_NOOP("light"), QT_TR_NOOP("dark") }; } diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp index e81ec1400..87e35a534 100644 --- a/YACReaderLibrary/info_comics_view.cpp +++ b/YACReaderLibrary/info_comics_view.cpp @@ -244,4 +244,3 @@ void InfoComicsView::applyTheme(const Theme &theme) ctxt->setContextProperty("showDropShadow", QVariant(qv.showDropShadow)); } - diff --git a/YACReaderLibrary/server_config_dialog.h b/YACReaderLibrary/server_config_dialog.h index e882e573e..0345d381e 100644 --- a/YACReaderLibrary/server_config_dialog.h +++ b/YACReaderLibrary/server_config_dialog.h @@ -29,7 +29,7 @@ class ServerConfigDialog : public QDialog, protected Themable QPushButton *close; QPushButton *accept; QLabel *qrCode; - + // Labels for themable styling QLabel *titleLabel; QLabel *qrMessageLabel; diff --git a/shortcuts_management/edit_shortcuts_dialog.h b/shortcuts_management/edit_shortcuts_dialog.h index 77a8be2be..08f26ee9e 100644 --- a/shortcuts_management/edit_shortcuts_dialog.h +++ b/shortcuts_management/edit_shortcuts_dialog.h @@ -18,7 +18,7 @@ class EditShortcutsDialog : public QDialog, protected Themable public: explicit EditShortcutsDialog(QWidget *parent = 0); void addActionsGroup(const QString &name, const QIcon &ico, QList &group); - void setGroupIconMapping(const QMap> &mapping); + void setGroupIconMapping(const QMap> &mapping); signals: public slots: @@ -33,8 +33,8 @@ public slots: QListView *actionsGroupsListView; QTableView *actionsTableView; ActionsGroupsModel *groupsModel; - - QMap> groupIconMapping; + + QMap> groupIconMapping; ActionsShortcutsModel *actionsModel; }; From 76860ae6c446b77a18f6fd488dfe6dabe89fbdb8 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 19 Feb 2026 19:21:28 +0100 Subject: [PATCH 069/187] Support Qt below 6.5 QStyleHints::colorScheme is only 6.5+ but github actions latest ubuntu image is running Qt 6.4. --- common/themes/theme_manager.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/common/themes/theme_manager.cpp b/common/themes/theme_manager.cpp index 081a7147d..e39554be9 100644 --- a/common/themes/theme_manager.cpp +++ b/common/themes/theme_manager.cpp @@ -4,6 +4,7 @@ #include "theme_factory.h" #include +#include #include // TODO: add API to force color scheme //styleHints->setColorScheme(Qt::ColorScheme::Dark); @@ -20,6 +21,8 @@ ThemeManager &ThemeManager::instance() void ThemeManager::initialize() { + // QStyleHints::colorScheme is only 6.5+ +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) auto *styleHints = qGuiApp->styleHints(); auto colorScheme = styleHints->colorScheme(); @@ -32,6 +35,15 @@ void ThemeManager::initialize() applyColorScheme(colorScheme); connect(styleHints, &QStyleHints::colorSchemeChanged, this, applyColorScheme, Qt::QueuedConnection); +#else + auto applyPalette = [this](const QPalette &palette) { + setTheme(palette.color(QPalette::Window).lightness() < 128 ? ThemeId::Dark : ThemeId::Light); + }; + + applyPalette(qGuiApp->palette()); + + connect(qGuiApp, &QGuiApplication::paletteChanged, this, applyPalette, Qt::QueuedConnection); +#endif } void ThemeManager::setTheme(ThemeId themeId) From 3eaacaf6a75a522b993a14dd9c473d7e53dc71e1 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 19 Feb 2026 21:07:28 +0100 Subject: [PATCH 070/187] Move #include "folder_model.h" where it's actually used --- YACReaderLibrary/db/data_base_management.h | 2 -- YACReaderLibrary/library_creator.cpp | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/YACReaderLibrary/db/data_base_management.h b/YACReaderLibrary/db/data_base_management.h index ec4a5168a..3bb844e8c 100644 --- a/YACReaderLibrary/db/data_base_management.h +++ b/YACReaderLibrary/db/data_base_management.h @@ -5,8 +5,6 @@ #include #include -#include "folder_model.h" - class ComicsInfoExporter : public QThread { Q_OBJECT diff --git a/YACReaderLibrary/library_creator.cpp b/YACReaderLibrary/library_creator.cpp index eaa035b32..587b3fc8c 100644 --- a/YACReaderLibrary/library_creator.cpp +++ b/YACReaderLibrary/library_creator.cpp @@ -17,6 +17,8 @@ #include "pdf_comic.h" #include "yacreader_global.h" +#include "folder_model.h" + #include "QsLog.h" #include From 549f2a259a24bdf7d4c2590f1b49eef2db23baad Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 20 Feb 2026 08:53:01 +0100 Subject: [PATCH 071/187] Remove FolderModel and QModelIndex dependencies from LibraryCreator --- YACReaderLibrary/library_creator.cpp | 10 ++++------ YACReaderLibrary/library_creator.h | 8 +++----- YACReaderLibrary/library_window.cpp | 6 ++++-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/YACReaderLibrary/library_creator.cpp b/YACReaderLibrary/library_creator.cpp index 587b3fc8c..877a96bbc 100644 --- a/YACReaderLibrary/library_creator.cpp +++ b/YACReaderLibrary/library_creator.cpp @@ -17,8 +17,6 @@ #include "pdf_comic.h" #include "yacreader_global.h" -#include "folder_model.h" - #include "QsLog.h" #include @@ -67,11 +65,11 @@ void LibraryCreator::updateLibrary(const QString &source, const QString &target) _mode = UPDATER; } -void LibraryCreator::updateFolder(const QString &source, const QString &target, const QString &sourceFolder, const QModelIndex &dest) +void LibraryCreator::updateFolder(const QString &source, const QString &target, const QString &sourceFolder, qulonglong folderId) { checkModifiedDatesOnUpdate = settings->value(COMPARE_MODIFIED_DATE_ON_LIBRARY_UPDATES, false).toBool(); partialUpdate = true; - folderDestinationModelIndex = dest; + _folderDestinationId = folderId; _currentPathFolders.clear(); @@ -224,7 +222,7 @@ void LibraryCreator::run() if (!canceled) { if (partialUpdate) { - auto folder = DBHelper::updateChildrenInfo(folderDestinationModelIndex.data(FolderModel::IdRole).toULongLong(), _database); + auto folder = DBHelper::updateChildrenInfo(_folderDestinationId, _database); DBHelper::propagateFolderUpdatesToParent(folder, _database); } else { DBHelper::updateChildrenInfo(_database); @@ -250,7 +248,7 @@ void LibraryCreator::run() } if (partialUpdate) { - emit updatedCurrentFolder(folderDestinationModelIndex); + emit updatedCurrentFolder(_folderDestinationId); } creation = false; diff --git a/YACReaderLibrary/library_creator.h b/YACReaderLibrary/library_creator.h index f7b8a6e69..0c13f3447 100644 --- a/YACReaderLibrary/library_creator.h +++ b/YACReaderLibrary/library_creator.h @@ -13,8 +13,6 @@ #include #include #include -#include - #include "folder.h" #include "comic_db.h" @@ -25,7 +23,7 @@ class LibraryCreator : public QThread LibraryCreator(QSettings *settings); void createLibrary(const QString &source, const QString &target); void updateLibrary(const QString &source, const QString &target); - void updateFolder(const QString &source, const QString &target, const QString &folder, const QModelIndex &dest); + void updateFolder(const QString &source, const QString &target, const QString &folder, qulonglong folderId); void stop(); // used to stop the process and keep the changes void cancel(); // cancels this run and changes in the DB are rolled back @@ -56,7 +54,7 @@ class LibraryCreator : public QThread // LibraryCreator está en modo creación si creation == true; bool creation; bool partialUpdate; - QModelIndex folderDestinationModelIndex; + qulonglong _folderDestinationId; QSettings *settings; bool checkModifiedDatesOnUpdate; void cleanup(QSqlDatabase &db, const QString &target); @@ -69,7 +67,7 @@ class LibraryCreator : public QThread void created(); void failedCreatingDB(QString); void failedOpeningDB(QString); - void updatedCurrentFolder(QModelIndex); + void updatedCurrentFolder(qulonglong folderId); }; #endif diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 031eac89a..7ec65a0c6 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -707,7 +707,9 @@ void LibraryWindow::createConnections() connect(libraryCreator, &LibraryCreator::finished, this, &LibraryWindow::showRootWidget); connect(libraryCreator, &LibraryCreator::updated, this, &LibraryWindow::reloadCurrentLibrary); connect(libraryCreator, &LibraryCreator::created, this, &LibraryWindow::openLastCreated); - connect(libraryCreator, &LibraryCreator::updatedCurrentFolder, this, &LibraryWindow::reloadAfterCopyMove); + connect(libraryCreator, &LibraryCreator::updatedCurrentFolder, this, [this](qulonglong folderId) { + reloadAfterCopyMove(foldersModel->getIndexFromFolderId(folderId)); + }); connect(libraryCreator, &LibraryCreator::comicAdded, importWidget, &ImportWidget::newComic); // libraryCreator errors connect(libraryCreator, &LibraryCreator::failedCreatingDB, this, &LibraryWindow::manageCreatingError); @@ -1078,7 +1080,7 @@ void LibraryWindow::updateFolder(const QModelIndex &miFolder) QString currentLibrary = selectedLibrary->currentText(); QString path = QDir::cleanPath(libraries.getPath(currentLibrary)); _lastAdded = currentLibrary; - libraryCreator->updateFolder(path, LibraryPaths::libraryDataPath(path), QDir::cleanPath(currentPath() + foldersModel->getFolderPath(miFolder)), miFolder); + libraryCreator->updateFolder(path, LibraryPaths::libraryDataPath(path), QDir::cleanPath(currentPath() + foldersModel->getFolderPath(miFolder)), miFolder.data(FolderModel::IdRole).toULongLong()); libraryCreator->start(); } From 4218752c09d08d7427d8e82f72f2f1b1ef8cf0cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20A=CC=81ngel=20San=20Marti=CC=81n=20Rodri=CC=81guez?= Date: Fri, 20 Feb 2026 09:58:44 +0100 Subject: [PATCH 072/187] Use jurplel/install-qt-action@v4 ot instal Qt 6.9.3 on Linux jobs --- .github/workflows/build.yml | 46 ++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5670bfc97..b4fcdfce8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,22 +56,27 @@ jobs: needs: [initialization, code-format-validation] steps: - uses: actions/checkout@v4 - + - name: Install dependencies run: | sudo apt-get update - sudo apt-get install -y qtchooser qt6-tools-dev qt6-base-dev-tools qmake6 qmake6-bin \ - qt6-base-dev qt6-multimedia-dev qt6-tools-dev-tools libgl-dev qt6-l10n-tools \ - libqt6opengl6-dev libunarr-dev qt6-declarative-dev libqt6svg6-dev libqt6core5compat6-dev libpoppler-qt6-dev - + sudo apt-get install -y libunarr-dev libgl-dev libgles2-mesa-dev \ + libfontconfig1-dev libfreetype-dev libxkbcommon-dev + + - name: Install Qt + uses: jurplel/install-qt-action@v4 + with: + version: '6.9.3' + modules: 'qt5compat qtmultimedia qtimageformats qtshadertools' + cache: true + - name: Build run: | - qtchooser -list-versions export DEFINES_VAR=DEFINES+=\"BUILD_NUMBER=\\\\\\\"${{ needs.initialization.outputs.build_number }}\\\\\\\"\" - qmake6 CONFIG+="unarr" $DEFINES_VAR - qmake6 -v + qmake CONFIG+="unarr" $DEFINES_VAR + qmake -v make - + - name: Run tests run: make check TESTARGS="-maxwarnings 100000" @@ -82,25 +87,30 @@ jobs: needs: [initialization, code-format-validation] steps: - uses: actions/checkout@v4 - + - name: Install dependencies run: | sudo apt-get update - sudo apt-get install -y qtchooser qt6-tools-dev qt6-base-dev-tools qmake6 qmake6-bin \ - qt6-base-dev qt6-multimedia-dev qt6-tools-dev-tools libgl-dev qt6-l10n-tools \ - libqt6opengl6-dev libunarr-dev qt6-declarative-dev libqt6svg6-dev libqt6core5compat6-dev libpoppler-qt6-dev + sudo apt-get install -y libunarr-dev libgl-dev libgles2-mesa-dev \ + libfontconfig1-dev libfreetype-dev libxkbcommon-dev mkdir -p ${{ github.workspace }}/compressed_archive wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O ${{ github.workspace }}/compressed_archive/7z2301-src.7z 7z x ${{ github.workspace }}/compressed_archive/7z2301-src.7z -o${{ github.workspace }}/compressed_archive/lib7zip - + + - name: Install Qt + uses: jurplel/install-qt-action@v4 + with: + version: '6.9.3' + modules: 'qt5compat qtmultimedia qtimageformats qtshadertools' + cache: true + - name: Build run: | - qtchooser -list-versions export DEFINES_VAR=DEFINES+=\"BUILD_NUMBER=\\\\\\\"${{ needs.initialization.outputs.build_number }}\\\\\\\"\" - qmake6 CONFIG+="7zip" $DEFINES_VAR - qmake6 -v + qmake CONFIG+="7zip" $DEFINES_VAR + qmake -v make - + - name: Run tests run: make check TESTARGS="-maxwarnings 100000" From 1a6cd06915362fa340b6c4b6e879fc938bcc8872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20A=CC=81ngel=20San=20Marti=CC=81n=20Rodri=CC=81guez?= Date: Fri, 20 Feb 2026 10:06:11 +0100 Subject: [PATCH 073/187] Fix YACReaderLibraryServer compilation --- YACReaderLibraryServer/libraries_updater.cpp | 1 + YACReaderLibraryServer/main.cpp | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/YACReaderLibraryServer/libraries_updater.cpp b/YACReaderLibraryServer/libraries_updater.cpp index c49aaa9b5..e39ef326f 100644 --- a/YACReaderLibraryServer/libraries_updater.cpp +++ b/YACReaderLibraryServer/libraries_updater.cpp @@ -1,5 +1,6 @@ #include "libraries_updater.h" +#include "yacreader_global.h" #include "yacreader_libraries.h" #include "data_base_management.h" diff --git a/YACReaderLibraryServer/main.cpp b/YACReaderLibraryServer/main.cpp index 2d27c1897..2b82c93dc 100644 --- a/YACReaderLibraryServer/main.cpp +++ b/YACReaderLibraryServer/main.cpp @@ -487,9 +487,9 @@ void printServerInfo(YACReaderHttpServer *httpServer) for (int x = -border - 1; x < code.getSize() + border + 1; x++) { QRCodeString.append((code.getModule(x, y) && code.getModule(x, y + 1)) ? " " - : code.getModule(x, y + 1) ? u8"\u2580" - : code.getModule(x, y) ? u8"\u2584" - : u8"\u2588"); + : code.getModule(x, y + 1) ? "\u2580" + : code.getModule(x, y) ? "\u2584" + : "\u2588"); } QLOG_INFO() << QRCodeString; } From a70d7ba09b27467c038a516562ccd2747eb3c8c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20A=CC=81ngel=20San=20Marti=CC=81n=20Rodri=CC=81guez?= Date: Fri, 20 Feb 2026 10:19:48 +0100 Subject: [PATCH 074/187] Install libpoppler-qt6-dev --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b4fcdfce8..7bd6bee3e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,7 +61,7 @@ jobs: run: | sudo apt-get update sudo apt-get install -y libunarr-dev libgl-dev libgles2-mesa-dev \ - libfontconfig1-dev libfreetype-dev libxkbcommon-dev + libfontconfig1-dev libfreetype-dev libxkbcommon-dev libpoppler-qt6-dev - name: Install Qt uses: jurplel/install-qt-action@v4 @@ -92,7 +92,7 @@ jobs: run: | sudo apt-get update sudo apt-get install -y libunarr-dev libgl-dev libgles2-mesa-dev \ - libfontconfig1-dev libfreetype-dev libxkbcommon-dev + libfontconfig1-dev libfreetype-dev libxkbcommon-dev libpoppler-qt6-dev mkdir -p ${{ github.workspace }}/compressed_archive wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O ${{ github.workspace }}/compressed_archive/7z2301-src.7z 7z x ${{ github.workspace }}/compressed_archive/7z2301-src.7z -o${{ github.workspace }}/compressed_archive/lib7zip From e3aeb867f47ed2ca3b7f280d108e2cd8d58a260b Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 20 Feb 2026 14:58:18 +0100 Subject: [PATCH 075/187] Simplify Windows builds in CI --- .github/workflows/build.yml | 4 +- ci/win/build_installer.iss | 224 --------------------------------- ci/win/build_installer_qt6.iss | 3 - ci/win/create_installer.cmd | 12 +- 4 files changed, 3 insertions(+), 240 deletions(-) delete mode 100644 ci/win/build_installer.iss diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7bd6bee3e..96454a92f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -277,7 +277,7 @@ jobs: run: | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" set PATH=C:\Qt\6.9.3\msvc2022_64\bin;%PATH% - .\create_installer.cmd x64 7z ${{ needs.initialization.outputs.build_number }} qt6 + .\create_installer.cmd x64 7z ${{ needs.initialization.outputs.build_number }} - name: Verify installer was created if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') @@ -421,7 +421,7 @@ jobs: working-directory: ci/win run: | set PATH=C:\Qt\6.9.3\msvc2022_64\bin;%PATH% - .\create_installer.cmd arm64 7z ${{ needs.initialization.outputs.build_number }} qt6 + .\create_installer.cmd arm64 7z ${{ needs.initialization.outputs.build_number }} - name: Verify installer was created if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') diff --git a/ci/win/build_installer.iss b/ci/win/build_installer.iss deleted file mode 100644 index 2ba8e6bdb..000000000 --- a/ci/win/build_installer.iss +++ /dev/null @@ -1,224 +0,0 @@ -[Setup] -DefaultGroupName=YACReader -LanguageDetectionMethod=locale -AppId={{019AC70F-0312-76B8-BD8F-BE9DCBF49E25} -AppName=YACReader -AppVerName=YACReader v{#VERSION}.{#BUILD_NUMBER} -AppVersion={#VERSION}.{#BUILD_NUMBER} -VersionInfoVersion={#VERSION} -DefaultDirName={pf}\YACReader -OutputBaseFilename=YACReader-v{#VERSION}.{#BUILD_NUMBER}-win{#PLATFORM}-{#COMPRESSED_ARCHIVE_BACKEND} -LicenseFile=COPYING.txt -AlwaysUsePersonalGroup=true -OutputDir=..\Output -ChangesAssociations=true -SetupIconFile=setup.ico -UninstallDisplayIcon=uninstall.ico -ArchitecturesInstallIn64BitMode=x64 -ArchitecturesAllowed=x64 - -[Registry] -Root: HKCR; SubKey: .cbz; ValueType: string; ValueData: Comic Book (zip); Flags: uninsdeletekey; Tasks: File_association -Root: HKCR; SubKey: Comic Book (zip); ValueType: string; ValueData: Comic Book file; Flags: uninsdeletekey; Tasks: File_association -Root: HKCR; SubKey: Comic Book (zip)\Shell\Open\Command; ValueType: string; ValueData: """{app}\YACReader.exe"" ""%1"""; Flags: uninsdeletevalue; Tasks: File_association -Root: HKCR; Subkey: Comic Book (zip)\DefaultIcon; ValueType: string; ValueData: {app}\YACReader.exe,0; Flags: uninsdeletevalue; Tasks: File_association -Root: HKCR; SubKey: .cbr; ValueType: string; ValueData: Comic Book (rar); Flags: uninsdeletekey; Tasks: File_association -Root: HKCR; SubKey: Comic Book (rar); ValueType: string; ValueData: Comic Book file; Flags: uninsdeletekey; Tasks: File_association -Root: HKCR; SubKey: Comic Book (rar)\Shell\Open\Command; ValueType: string; ValueData: """{app}\YACReader.exe"" ""%1"""; Flags: uninsdeletevalue; Tasks: File_association -Root: HKCR; Subkey: Comic Book (rar)\DefaultIcon; ValueType: string; ValueData: {app}\YACReader.exe,0; Flags: uninsdeletevalue; Tasks: File_association -Root: HKCR; Subkey: .clc; ValueType: string; ValueData: Compressed Library Covers (clc); Flags: uninsdeletekey -Root: HKCR; SubKey: Compressed Library Covers (clc); ValueType: string; ValueData: Compressed Library Covers; Flags: uninsdeletekey -Root: HKCR; Subkey: Compressed Library Covers (clc)\DefaultIcon; ValueType: string; ValueData: {app}\YACReaderLibrary.exe,1; Flags: uninsdeletevalue -Root: HKCR; Subkey: .ydb; ValueType: string; ValueData: Compressed Library Covers (clc); Flags: uninsdeletekey -Root: HKCR; SubKey: YACReader Data Base (ydb); ValueType: string; ValueData: Compressed Library Covers; Flags: uninsdeletekey -Root: HKCR; Subkey: YACReader Data Base (ydb)\DefaultIcon; ValueType: string; ValueData: {app}\YACReaderLibrary.exe,1; Flags: uninsdeletevalue - -[Files] -;Qt Frameworks -Source: Qt5Core.dll; DestDir: {app} -Source: Qt5Gui.dll; DestDir: {app} -Source: Qt5Multimedia.dll; DestDir: {app} -Source: Qt5Network.dll; DestDir: {app} -Source: Qt5Qml.dll; DestDir: {app} -Source: Qt5Quick.dll; DestDir: {app} -Source: Qt5Sql.dll; DestDir: {app} -Source: Qt5Svg.dll; DestDir: {app} -Source: Qt5Widgets.dll; DestDir: {app} -Source: Qt5QuickWidgets.dll; DestDir: {app} -Source: Qt5QmlModels.dll; DestDir: {app} -Source: Qt5QmlWorkerScript.dll; DestDir: {app} -Source: Qt5QuickControls2.dll; DestDir: {app} -Source: Qt5QuickTemplates2.dll; DestDir: {app} -Source: Qt5RemoteObjects.dll; DestDir: {app} - -;Qt Angle -Source: D3Dcompiler_47.dll; DestDir: {app} -Source: libEGL.dll; DestDir: {app} -Source: libGLESV2.dll; DestDir: {app} -Source: opengl32sw.dll; DestDir: {app} - -;Qt QML -Source: QtQml\*; DestDir: {app}\QtQml\; Flags: recursesubdirs -Source: QtQuick\*; DestDir: {app}\QtQuick\; Flags: recursesubdirs -Source: QtQuick.2\*; DestDir: {app}\QtQuick.2\; Flags: recursesubdirs -Source: QtGraphicalEffects\*; DestDir: {app}\QtGraphicalEffects\; Flags: recursesubdirs - -;Qt PlugIns -Source:audio\*; DestDir: {app}\audio\ -Source:bearer\*; DestDir: {app}\bearer\ -Source:iconengines\*; DestDir: {app}\iconengines\ -Source:imageformats\*; DestDir: {app}\imageformats\ -Source:mediaservice\*; DestDir: {app}\mediaservice\ -Source:platforms\*; DestDir: {app}\platforms\ -Source:playlistformats\*; DestDir: {app}\playlistformats\ -Source:qmltooling\*; DestDir: {app}\qmltooling\ -Source:scenegraph\*; DestDir: {app}\scenegraph\ -Source:sqldrivers\qsqlite.dll; DestDir: {app}\sqldrivers\ -Source:translations\*; DestDir: {app}\translations\ -Source:styles\*; DestDir: {app}\styles\ - -;Libs -Source: pdfium.dll; DestDir: {app} -Source: openssl\*; DestDir: {app} - -;vcredist -Source: "vc_redist.{#PLATFORM}.exe"; DestDir: {tmp}; Flags: deleteafterinstall - -;Utils -;Source: utils\7zip.exe; DestDir: {app}\utils\ -Source: utils\7z.dll; DestDir: {app}\utils\ - -;Bin -Source: YACReader.exe; DestDir: {app}; Permissions: everyone-full -Source: YACReaderLibrary.exe; DestDir: {app}; Permissions: everyone-full; Tasks: -Source: YACReaderLibraryServer.exe; DestDir: {app}; Permissions: everyone-full; Tasks: - -;License -Source: README.md; DestDir: {app}; Flags: isreadme -Source: COPYING.txt; DestDir: {app} - -;Languages -Source: languages\*; DestDir: {app}\languages\; Flags: recursesubdirs -;Server -Source: server\*; DestDir: {app}\server\; Flags: recursesubdirs - -[Dirs] -Name: {app}; Permissions: everyone-full - -[CustomMessages] -App=YACReader -AppLibrary=YACReaderLibrary -LaunchYACReaderLibrary=Start YACreaderLibrary after finishing installation -LaunchYACReader=Start YACreader after finishing installation - -[Run] -Filename: {tmp}\vc_redist.{#PLATFORM}.exe; \ -Parameters: "/install /quiet /norestart"; \ -StatusMsg: "Installing VC++ Redistributables..." - -Filename: {app}\{cm:AppLibrary}.exe; Description: {cm:LaunchYACReaderLibrary,{cm:AppLibrary}}; Flags: nowait postinstall skipifsilent -Filename: {app}\{cm:App}.exe; Description: {cm:LaunchYACReader,{cm:App}}; Flags: nowait postinstall skipifsilent - -[Icons] -Name: {group}\YACReader; Filename: {app}\YACReader.exe; WorkingDir: {app}; IconIndex: 0 -Name: {group}\YACReader Library; Filename: {app}\YACReaderLibrary.exe; WorkingDir: {app}; IconIndex: 0 -;Name: {group}\YACReader Library Package; Filename: {app}\YACReaderLibrary.exe; WorkingDir: {app}; IconIndex: 0 -[Tasks] -Name: File_association; Description: Associate .cbz and .cbr files with YACReader -;Name: StartYACReaderAfterInstall; Description: Run YACReader after install -;Name: StartYACReaderLibraryAfterInstall; Description: Run YACReaderLibrary after install - -[ThirdPartySettings] -CompileLogMethod=append - -[Code] -var donationPage: TOutputMsgWizardPage; -var URLLabel: TNewStaticText; - -function GetUninstallString(): String; -var - sUnInstPath: String; - sUnInstallString: String; -begin - // First try the new AppId-based key - sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1'); - sUnInstallString := ''; - if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then - RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); - - // If not found, try the old AppName-based key (for versions without AppId) - if sUnInstallString = '' then begin - sUnInstPath := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\YACReader_is1'; - if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then - RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); - end; - - Result := sUnInstallString; -end; - -function IsUpgrade(): Boolean; -begin - Result := (GetUninstallString() <> ''); -end; - -function UnInstallOldVersion(): Integer; -var - sUnInstallString: String; - iResultCode: Integer; -begin - Result := 0; - sUnInstallString := GetUninstallString(); - if sUnInstallString <> '' then begin - sUnInstallString := RemoveQuotes(sUnInstallString); - if Exec(sUnInstallString, '/VERYSILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then - Result := 3 - else - Result := 2; - end else - Result := 1; -end; - -procedure CurStepChanged(CurStep: TSetupStep); -begin - if (CurStep=ssInstall) then - begin - if (IsUpgrade()) then - begin - UnInstallOldVersion(); - end; - end; -end; - -procedure URLLabelOnClick(Sender: TObject); -var ErrorCode: Integer; -begin -ShellExec('open', 'https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=5TAMNQCDDMVP8&item_name=YACReader¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted', '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); -end; - -procedure InitializeWizard(); - -begin - - URLLabel := TNewStaticText.Create(WizardForm); - URLLabel.Caption:='Make a DONATION/Haz una DONACIÓN'; - URLLabel.Cursor:=crHand; - URLLabel.OnClick:=@URLLabelOnClick; - URLLabel.Parent:=WizardForm; - // Alter Font - URLLabel.Font.Style:=URLLabel.Font.Style + [fsUnderline]; - URLLabel.Font.Color:=clBlue; - URLLabel.Top:=250; - - URLLabel.Left:=35; - -donationPage := CreateOutputMsgPage(wpWelcome, - 'Iformation', 'Please read the following information before continuing.', - 'YACReader is FREE software. If you like it, please, consider to make a DONATION'#13#13 + - 'YACReader es software libre y GRATUITO. Si te gusta, por favor, considera realizar una DONACIÓN'#13#13) - -end; - -procedure CurPageChanged(CurPageID: Integer); -begin -if CurPageID=donationPage.ID then URLLabel.Visible:=true else URLLabel.Visible:=false; -end; diff --git a/ci/win/build_installer_qt6.iss b/ci/win/build_installer_qt6.iss index e44da5316..87e03c4d7 100644 --- a/ci/win/build_installer_qt6.iss +++ b/ci/win/build_installer_qt6.iss @@ -42,7 +42,6 @@ Source: Qt6Gui.dll; DestDir: {app} Source: Qt6Multimedia.dll; DestDir: {app} Source: Qt6Network.dll; DestDir: {app} Source: Qt6OpenGL.dll; DestDir: {app} -Source: Qt6OpenGLWidgets.dll; DestDir: {app} Source: Qt6Qml.dll; DestDir: {app} Source: Qt6QmlModels.dll; DestDir: {app} Source: Qt6QmlMeta.dll; DestDir: {app} @@ -61,9 +60,7 @@ Source: Qt6QuickTemplates2.dll; DestDir: {app} Source: Qt6QuickWidgets.dll; DestDir: {app} Source: Qt6Sql.dll; DestDir: {app} Source: Qt6Svg.dll; DestDir: {app} -Source: Qt6ShaderTools.dll; DestDir: {app} -;Qt Angle Source: opengl32sw.dll; DestDir: {app}; Flags: skipifsourcedoesntexist Source: D3Dcompiler_47.dll; DestDir: {app}; Flags: skipifsourcedoesntexist diff --git a/ci/win/create_installer.cmd b/ci/win/create_installer.cmd index 1fc39dc04..583ad2258 100644 --- a/ci/win/create_installer.cmd +++ b/ci/win/create_installer.cmd @@ -5,7 +5,6 @@ SET src_path=..\..\.. set ARCH=%1 set COMPRESSION=%2 set BUILD_NUMBER=%3 -set QT_VERSION=%4 IF "%ARCH%"=="x64" ( SET exe_path=%src_path%\release64 @@ -57,17 +56,8 @@ set VERSION=%VERSION:"=% echo %VERSION% del tmp -if "%ARCH%"=="x86" ( - type build_installer.iss | findstr /v ArchitecturesInstallIn64BitMode | findstr /v ArchitecturesAllowed > copy_build_installer.iss - type copy_build_installer.iss > build_installer.iss -) - echo "iscc start" -if "%QT_VERSION%"=="qt6" ( - iscc /DVERSION=%VERSION% /DPLATFORM=%ARCH% /DCOMPRESSED_ARCHIVE_BACKEND=%COMPRESSION% /DBUILD_NUMBER=%BUILD_NUMBER% build_installer_qt6.iss || exit /b -) else ( - iscc /DVERSION=%VERSION% /DPLATFORM=%ARCH% /DCOMPRESSED_ARCHIVE_BACKEND=%COMPRESSION% /DBUILD_NUMBER=%BUILD_NUMBER% build_installer.iss || exit /b -) +iscc /DVERSION=%VERSION% /DPLATFORM=%ARCH% /DCOMPRESSED_ARCHIVE_BACKEND=%COMPRESSION% /DBUILD_NUMBER=%BUILD_NUMBER% build_installer_qt6.iss || exit /b echo "iscc done!" cd .. From d898a56f3fb319dcf80ed5588342d0658bbafdbd Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 20 Feb 2026 19:01:49 +0100 Subject: [PATCH 076/187] Drop server v1 --- .../server/controllers/v1/comiccontroller.cpp | 116 ------- .../server/controllers/v1/comiccontroller.h | 25 -- .../v1/comicdownloadinfocontroller.cpp | 28 -- .../v1/comicdownloadinfocontroller.h | 21 -- .../server/controllers/v1/covercontroller.cpp | 91 ------ .../server/controllers/v1/covercontroller.h | 21 -- .../server/controllers/v1/errorcontroller.cpp | 27 -- .../server/controllers/v1/errorcontroller.h | 24 -- .../controllers/v1/foldercontroller.cpp | 308 ------------------ .../server/controllers/v1/foldercontroller.h | 21 -- .../controllers/v1/folderinfocontroller.cpp | 47 --- .../controllers/v1/folderinfocontroller.h | 24 -- .../controllers/v1/librariescontroller.cpp | 51 --- .../controllers/v1/librariescontroller.h | 25 -- .../server/controllers/v1/pagecontroller.cpp | 86 ----- .../server/controllers/v1/pagecontroller.h | 21 -- .../controllers/v1/sessioncontroller.cpp | 34 -- .../server/controllers/v1/sessionmanager.h | 0 .../server/controllers/v1/synccontroller.cpp | 60 ---- .../server/controllers/v1/synccontroller.h | 22 -- .../controllers/v1/updatecomiccontroller.cpp | 48 --- .../controllers/v1/updatecomiccontroller.h | 20 -- .../controllers/v2/pagecontroller_v2.cpp | 1 - YACReaderLibrary/server/requestmapper.cpp | 150 +-------- YACReaderLibrary/server/requestmapper.h | 2 - YACReaderLibrary/server/server.pri | 24 -- YACReaderLibrary/server/static.cpp | 7 - YACReaderLibrary/server/static.h | 8 - .../server/yacreader_http_server.cpp | 36 +- .../server/yacreader_http_session_store.cpp | 28 +- .../server/yacreader_http_session_store.h | 16 +- 31 files changed, 6 insertions(+), 1386 deletions(-) delete mode 100644 YACReaderLibrary/server/controllers/v1/comiccontroller.cpp delete mode 100644 YACReaderLibrary/server/controllers/v1/comiccontroller.h delete mode 100644 YACReaderLibrary/server/controllers/v1/comicdownloadinfocontroller.cpp delete mode 100644 YACReaderLibrary/server/controllers/v1/comicdownloadinfocontroller.h delete mode 100644 YACReaderLibrary/server/controllers/v1/covercontroller.cpp delete mode 100644 YACReaderLibrary/server/controllers/v1/covercontroller.h delete mode 100644 YACReaderLibrary/server/controllers/v1/errorcontroller.cpp delete mode 100644 YACReaderLibrary/server/controllers/v1/errorcontroller.h delete mode 100644 YACReaderLibrary/server/controllers/v1/foldercontroller.cpp delete mode 100644 YACReaderLibrary/server/controllers/v1/foldercontroller.h delete mode 100644 YACReaderLibrary/server/controllers/v1/folderinfocontroller.cpp delete mode 100644 YACReaderLibrary/server/controllers/v1/folderinfocontroller.h delete mode 100644 YACReaderLibrary/server/controllers/v1/librariescontroller.cpp delete mode 100644 YACReaderLibrary/server/controllers/v1/librariescontroller.h delete mode 100644 YACReaderLibrary/server/controllers/v1/pagecontroller.cpp delete mode 100644 YACReaderLibrary/server/controllers/v1/pagecontroller.h delete mode 100644 YACReaderLibrary/server/controllers/v1/sessioncontroller.cpp delete mode 100644 YACReaderLibrary/server/controllers/v1/sessionmanager.h delete mode 100644 YACReaderLibrary/server/controllers/v1/synccontroller.cpp delete mode 100644 YACReaderLibrary/server/controllers/v1/synccontroller.h delete mode 100644 YACReaderLibrary/server/controllers/v1/updatecomiccontroller.cpp delete mode 100644 YACReaderLibrary/server/controllers/v1/updatecomiccontroller.h diff --git a/YACReaderLibrary/server/controllers/v1/comiccontroller.cpp b/YACReaderLibrary/server/controllers/v1/comiccontroller.cpp deleted file mode 100644 index 896d5044b..000000000 --- a/YACReaderLibrary/server/controllers/v1/comiccontroller.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "comiccontroller.h" - -#include "db_helper.h" -#include "yacreader_libraries.h" -#include "yacreader_http_session.h" - -#include "template.h" -#include "../static.h" - -#include "comic_db.h" -#include "comic.h" - -#include "QsLog.h" - -#include - -using stefanfrings::HttpRequest; -using stefanfrings::HttpResponse; -using stefanfrings::HttpSession; - -ComicController::ComicController() { } - -void ComicController::service(HttpRequest &request, HttpResponse &response) -{ - HttpSession session = Static::sessionStore->getSession(request, response, false); - YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(session.getId()); - - QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); - QStringList pathElements = path.split('/'); - qulonglong libraryId = pathElements.at(2).toLongLong(); - QString libraryName = DBHelper::getLibraryName(libraryId); - qulonglong comicId = pathElements.at(4).toULongLong(); - - bool remoteComic = path.endsWith("remote"); - - // TODO - // if(pathElements.size() == 6) - //{ - // QString action = pathElements.at(5); - // if(!action.isEmpty() && (action == "close")) - // { - // session.dismissCurrentComic(); - // response.write("",true); - // return; - // } - // } - - YACReaderLibraries libraries = DBHelper::getLibraries(); - - ComicDB comic = DBHelper::getComicInfo(libraryId, comicId); - - if (!remoteComic) - ySession->setDownloadedComic(comic.info.hash); - - Comic *comicFile = FactoryComic::newComic(libraries.getPath(libraryId) + comic.path); - - if (comicFile != nullptr) { - QThread *thread = nullptr; - - thread = new QThread(); - - comicFile->moveToThread(thread); - - connect(comicFile, QOverload<>::of(&Comic::errorOpening), thread, &QThread::quit); - connect(comicFile, QOverload::of(&Comic::errorOpening), thread, &QThread::quit); - connect(comicFile, &Comic::imagesLoaded, thread, &QThread::quit); - connect(thread, &QThread::started, comicFile, &Comic::process); - connect(thread, &QThread::finished, thread, &QObject::deleteLater); - - comicFile->load(libraries.getPath(libraryId) + comic.path); - - if (thread != nullptr) - thread->start(); - - if (remoteComic) { - QLOG_TRACE() << "remote comic requested"; - ySession->setCurrentRemoteComic(comic.id, comicFile); - - } else { - QLOG_TRACE() << "comic requested"; - ySession->setCurrentComic(comic.id, comicFile); - } - - response.setHeader("Content-Type", "text/plain; charset=utf-8"); - // TODO this field is not used by the client! - response.write(QString("library:%1\r\n").arg(libraryName).toUtf8()); - response.write(QString("libraryId:%1\r\n").arg(libraryId).toUtf8()); - if (remoteComic) // send previous and next comics id - { - QList siblings = DBHelper::getFolderComicsFromLibrary(libraryId, comic.parentId, true); - bool found = false; - int i; - for (i = 0; i < siblings.length(); i++) { - if (siblings.at(i)->id == comic.id) { - found = true; - break; - } - } - if (found) { - if (i > 0) - response.write(QString("previousComic:%1\r\n").arg(siblings.at(i - 1)->id).toUtf8()); - if (i < siblings.length() - 1) - response.write(QString("nextComic:%1\r\n").arg(siblings.at(i + 1)->id).toUtf8()); - } else { - // ERROR - } - qDeleteAll(siblings); - } - response.write(comic.toTXT().toUtf8(), true); - } else { - // delete comicFile; - response.setStatus(404, "not found"); - response.write("404 not found", true); - } - // response.write(t.toLatin1(),true); -} diff --git a/YACReaderLibrary/server/controllers/v1/comiccontroller.h b/YACReaderLibrary/server/controllers/v1/comiccontroller.h deleted file mode 100644 index 1dbaffeba..000000000 --- a/YACReaderLibrary/server/controllers/v1/comiccontroller.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef COMICCONTROLLER_H -#define COMICCONTROLLER_H - -#include "httprequest.h" -#include "httpresponse.h" -#include "httprequesthandler.h" - -#include -class Comic; -class QString; - -class ComicController : public stefanfrings::HttpRequestHandler -{ - Q_OBJECT - Q_DISABLE_COPY(ComicController); - -public: - /** Constructor */ - ComicController(); - - /** Generates the response */ - void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override; -}; - -#endif // COMICCONTROLLER_H diff --git a/YACReaderLibrary/server/controllers/v1/comicdownloadinfocontroller.cpp b/YACReaderLibrary/server/controllers/v1/comicdownloadinfocontroller.cpp deleted file mode 100644 index c1f75d1af..000000000 --- a/YACReaderLibrary/server/controllers/v1/comicdownloadinfocontroller.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "comicdownloadinfocontroller.h" - -#include "db_helper.h" -#include "yacreader_libraries.h" - -#include "comic_db.h" - -using stefanfrings::HttpRequest; -using stefanfrings::HttpResponse; - -ComicDownloadInfoController::ComicDownloadInfoController() { } - -void ComicDownloadInfoController::service(HttpRequest &request, HttpResponse &response) -{ - response.setHeader("Content-Type", "text/plain; charset=utf-8"); - - QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); - QStringList pathElements = path.split('/'); - - qulonglong libraryId = pathElements.at(2).toLongLong(); - qulonglong comicId = pathElements.at(4).toULongLong(); - - ComicDB comic = DBHelper::getComicInfo(libraryId, comicId); - - // TODO: check if the comic wasn't found; - response.write(QString("fileName:%1\r\n").arg(comic.getFileName()).toUtf8()); - response.write(QString("fileSize:%1\r\n").arg(comic.getFileSize()).toUtf8(), true); -} diff --git a/YACReaderLibrary/server/controllers/v1/comicdownloadinfocontroller.h b/YACReaderLibrary/server/controllers/v1/comicdownloadinfocontroller.h deleted file mode 100644 index 742c782cd..000000000 --- a/YACReaderLibrary/server/controllers/v1/comicdownloadinfocontroller.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef COMICDOWNLOADINFOCONTROLLER_H -#define COMICDOWNLOADINFOCONTROLLER_H - -#include "httprequest.h" -#include "httpresponse.h" -#include "httprequesthandler.h" - -class ComicDownloadInfoController : public stefanfrings::HttpRequestHandler -{ - Q_OBJECT - Q_DISABLE_COPY(ComicDownloadInfoController); - -public: - /** Constructor **/ - ComicDownloadInfoController(); - - /** Generates the response */ - void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override; -}; - -#endif // COMICDOWNLOADINFOCONTROLLER_H diff --git a/YACReaderLibrary/server/controllers/v1/covercontroller.cpp b/YACReaderLibrary/server/controllers/v1/covercontroller.cpp deleted file mode 100644 index 4d3163b84..000000000 --- a/YACReaderLibrary/server/controllers/v1/covercontroller.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include - -#include "covercontroller.h" -#include "db_helper.h" //get libraries -#include "yacreader_libraries.h" -#include "yacreader_http_session.h" - -#include "template.h" -#include "../static.h" - -using stefanfrings::HttpRequest; -using stefanfrings::HttpResponse; -using stefanfrings::HttpSession; - -CoverController::CoverController() { } - -void CoverController::service(HttpRequest &request, HttpResponse &response) -{ - HttpSession session = Static::sessionStore->getSession(request, response, false); - YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(session.getId()); - - response.setHeader("Content-Type", "image/jpeg"); - response.setHeader("Connection", "close"); - // response.setHeader("Content-Type", "plain/text; charset=ISO-8859-1"); - - YACReaderLibraries libraries = DBHelper::getLibraries(); - - QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); - QStringList pathElements = path.split('/'); - QString libraryName = DBHelper::getLibraryName(pathElements.at(2).toInt()); - QString fileName = pathElements.at(4); - - bool folderCover = request.getParameter("folderCover").length() > 0; - - // response.writeText(path+"
"); - // response.writeText(libraryName+"
"); - // response.writeText(libraries.value(libraryName)+"/.yacreaderlibrary/covers/"+fileName+"
"); - - // QFile file(libraries.value(libraryName)+"/.yacreaderlibrary/covers/"+fileName); - // if (file.exists()) { - // if (file.open(QIODevice::ReadOnly)) - // { - // qDebug("StaticFileController: Open file %s",qPrintable(file.fileName())); - // // Return the file content, do not store in cache - // while (!file.atEnd() && !file.error()) { - // response.write(file.read(131072)); - // } - // } - - // file.close(); - //} - - QImage img(libraries.getPath(libraryName) + "/.yacreaderlibrary/covers/" + fileName); - if (!img.isNull()) { - - int width = 80, height = 120; - if (ySession->getDisplayType() == "@2x") { - width = 160; - height = 240; - } - - if (float(img.width()) / img.height() < 0.66666) - img = img.scaledToWidth(width, Qt::SmoothTransformation); - else - img = img.scaledToHeight(height, Qt::SmoothTransformation); - - QImage destImg(width, height, QImage::Format_RGB32); - destImg.fill(Qt::black); - QPainter p(&destImg); - - p.drawImage((width - img.width()) / 2, (height - img.height()) / 2, img); - - if (folderCover) { - if (ySession->getDisplayType() == "@2x") - p.drawImage(0, 0, QImage(":/images/f_overlayed_retina.png")); - else - p.drawImage(0, 0, QImage(":/images/f_overlayed.png")); - } - - QByteArray ba; - QBuffer buffer(&ba); - buffer.open(QIODevice::WriteOnly); - destImg.save(&buffer, "JPG"); - response.write(ba, true); - } - // DONE else, hay que devolver un 404 - else { - response.setStatus(404, "not found"); - response.write("404 not found", true); - } -} diff --git a/YACReaderLibrary/server/controllers/v1/covercontroller.h b/YACReaderLibrary/server/controllers/v1/covercontroller.h deleted file mode 100644 index bf0e9c335..000000000 --- a/YACReaderLibrary/server/controllers/v1/covercontroller.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef COVERCONTROLLER_H -#define COVERCONTROLLER_H - -#include "httprequest.h" -#include "httpresponse.h" -#include "httprequesthandler.h" - -class CoverController : public stefanfrings::HttpRequestHandler -{ - Q_OBJECT - Q_DISABLE_COPY(CoverController); - -public: - /** Constructor */ - CoverController(); - - /** Generates the response */ - void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override; -}; - -#endif // COVERCONTROLLER_H diff --git a/YACReaderLibrary/server/controllers/v1/errorcontroller.cpp b/YACReaderLibrary/server/controllers/v1/errorcontroller.cpp deleted file mode 100644 index 887f263af..000000000 --- a/YACReaderLibrary/server/controllers/v1/errorcontroller.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "errorcontroller.h" - -#include "template.h" -#include "../static.h" - -using stefanfrings::HttpRequest; -using stefanfrings::HttpResponse; - -ErrorController::ErrorController(int errorCode) - : error(errorCode) -{ -} - -void ErrorController::service(HttpRequest &request, HttpResponse &response) -{ - Q_UNUSED(request) - switch (error) { - case 300: - response.setStatus(300, "redirect"); - response.write(" ", true); - break; - case 404: - response.setStatus(404, "not found"); - response.write("404 not found", true); - break; - } -} diff --git a/YACReaderLibrary/server/controllers/v1/errorcontroller.h b/YACReaderLibrary/server/controllers/v1/errorcontroller.h deleted file mode 100644 index bcd745fda..000000000 --- a/YACReaderLibrary/server/controllers/v1/errorcontroller.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef ERRORCONTROLLER_H -#define ERRORCONTROLLER_H - -#include "httprequest.h" -#include "httpresponse.h" -#include "httprequesthandler.h" - -class ErrorController : public stefanfrings::HttpRequestHandler -{ - Q_OBJECT - Q_DISABLE_COPY(ErrorController); - -public: - /** Constructor */ - ErrorController(int errorCode); - - /** Generates the response */ - void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override; - -private: - int error; -}; - -#endif // ERRORCONTROLLER_H diff --git a/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp b/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp deleted file mode 100644 index 4c791f3ae..000000000 --- a/YACReaderLibrary/server/controllers/v1/foldercontroller.cpp +++ /dev/null @@ -1,308 +0,0 @@ -#include "foldercontroller.h" -#include "controllers/v1/errorcontroller.h" - -#include "yacreader_http_session.h" - -#include "db_helper.h" //get libraries -#include "comic_db.h" - -#include "folder.h" - -#include "template.h" -#include "../static.h" - -#include "qnaturalsorting.h" -#include "yacreader_global.h" - -#include "QsLog.h" - -#include - -using stefanfrings::HttpRequest; -using stefanfrings::HttpResponse; -using stefanfrings::HttpSession; -using stefanfrings::Template; - -FolderController::FolderController() { } - -void FolderController::service(HttpRequest &request, HttpResponse &response) -{ - QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); // TODO unificar la creación del fichero de config con el servidor - settings->beginGroup("libraryConfig"); - - HttpSession session = Static::sessionStore->getSession(request, response, false); - YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(session.getId()); - - response.setHeader("Content-Type", "text/html; charset=utf-8"); - response.setHeader("Connection", "close"); - - // QString y = session.get("xxx").toString(); - // response.writeText(QString("session xxx : %1
").arg(y)); - - Template t = Static::templateLoader->getTemplate("folder", request.getHeader("Accept-Language")); - t.enableWarnings(); - - // set device type for templates - t.setVariable("device", ySession->getDeviceType()); - t.setVariable("display", ySession->getDisplayType()); - t.setCondition("device.ipad", ySession->getDeviceType() == "ipad"); - - QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); - QStringList pathElements = path.split('/'); - int libraryId = pathElements.at(2).toInt(); - QString libraryName = DBHelper::getLibraryName(libraryId); - qulonglong folderId = pathElements.at(4).toULongLong(); - - folderId = qMax(1, folderId); - - QString folderName = DBHelper::getFolderName(libraryId, folderId); - if (folderName.isEmpty()) { - ErrorController(300).service(request, response); - return; - } - - if (folderId != 1) - t.setVariable("folder.name", folderName); - else - t.setVariable("folder.name", libraryName); - QList folderContent = DBHelper::getFolderSubfoldersFromLibrary(libraryId, folderId); - QList folderComics = DBHelper::getFolderComicsFromLibrary(libraryId, folderId); - - // response.writeText(libraryName); - - folderContent.append(folderComics); - - std::sort(folderContent.begin(), folderContent.end(), LibraryItemSorter()); - folderComics.clear(); - - // qulonglong backId = DBHelper::getParentFromComicFolderId(libraryName,folderId); - - int page = 0; - QByteArray p = request.getParameter("page"); - if (p.length() != 0) - page = p.toInt(); - - // /comicIdi/pagei/comicIdj/pagej/....../comicIdn/pagen - // QString currentPath = session.get("currentPath").toString(); - // QStringList pathSize = currentPath.split("/").last().toInt; - - bool fromUp = false; - - QMultiMap map = request.getParameterMap(); - if (map.contains("up")) - fromUp = true; - - // int upPage = 0; - - if (folderId == 1) { - ySession->clearNavigationPath(); - ySession->pushNavigationItem(QPair(folderId, page)); - t.setVariable(QString("upurl"), "/"); - } else { - if (fromUp) - ySession->popNavigationItem(); - else // drill down or direct access - { - QStack> path = ySession->getNavigationPath(); - bool found = false; - for (QStack>::const_iterator itr = path.begin(); itr != path.end(); itr++) - if (itr->first == folderId) { - found = true; - break; - } - - if (found) { - while (ySession->topNavigationItem().first != folderId) - ySession->popNavigationItem(); - - ySession->updateTopItem(QPair(folderId, page)); - } else - ySession->pushNavigationItem(QPair(folderId, page)); - } - - QStack> path = ySession->getNavigationPath(); - if (path.count() > 1) { - QPair parentItem = path.at(path.count() - 2); - qulonglong upParent = parentItem.first; - quint32 upPage = parentItem.second; - t.setVariable(QString("upurl"), "/library/" + QString::number(libraryId) + "/folder/" + QString("%1?page=%2&up=true").arg(upParent).arg(upPage)); - } else - t.setVariable(QString("upurl"), "/"); - } - - int elementsPerPage = 24; - - int numFolders = folderContent.length(); - // int numComics = folderComics.length(); - int totalLength = folderContent.length() + folderComics.length(); - - // int numFolderPages = numFolders / elementsPerPage + ((numFolders%elementsPerPage)>0?1:0); - int numPages = totalLength / elementsPerPage + ((totalLength % elementsPerPage) > 0 ? 1 : 0); - - // response.writeText(QString("Number of pages : %1
").arg(numPages)); - - if (page < 0) - page = 0; - else if (page >= numPages) - page = numPages - 1; - - int indexCurrentPage = page * elementsPerPage; - int numFoldersAtCurrentPage = qMax(0, qMin(numFolders - indexCurrentPage, elementsPerPage)); - - // PATH - QStack> foldersPath = ySession->getNavigationPath(); - t.setVariable(QString("library.name"), libraryName); - t.setVariable(QString("library.url"), QString("/library/%1/folder/1").arg(libraryId)); - t.loop("path", foldersPath.count() - 1); - for (int i = 1; i < foldersPath.count(); i++) { - t.setVariable(QString("path%1.url").arg(i - 1), QString("/library/%1/folder/%2").arg(libraryId).arg(foldersPath[i].first)); - t.setVariable(QString("path%1.name").arg(i - 1), DBHelper::getFolderName(libraryId, foldersPath[i].first)); - } - - 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()) { - t.setVariable(QString("element%1.class").arg(i), "folder"); - - QList children = DBHelper::getFolderComicsFromLibrary(libraryId, item->id); - if (children.length() > 0) { - const ComicDB *comic = static_cast(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("BROWSE").arg(QString("/library/%1/folder/%2").arg(libraryId).arg(item->id))); - t.setVariable(QString("element%1.cover.browse").arg(i), QString("").arg(QString("/library/%1/folder/%2").arg(libraryId).arg(item->id))); - t.setVariable(QString("element%1.cover.browse.end").arg(i), ""); - // 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("IMPORT").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 (!ySession->isComicOnDevice(comic->info.hash) && !ySession->isComicDownloaded(comic->info.hash)) - t.setVariable(QString("element%1.download").arg(i), QString("IMPORT").arg("/library/" + QString::number(libraryId) + "/comic/" + QString("%1").arg(comic->id))); - else if (ySession->isComicOnDevice(comic->info.hash)) - t.setVariable(QString("element%1.download").arg(i), QString("

IMPORTED
")); - else - t.setVariable(QString("element%1.download").arg(i), QString("
IMPORTING
")); - - // t.setVariable(QString("element%1.image.url").arg(i),"/images/f.png"); - - t.setVariable(QString("element%1.read").arg(i), QString("READ").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.size").arg(i), "" + QString::number(comic->info.hash.right(comic->info.hash.length() - 40).toInt() / 1024.0 / 1024.0, 'f', 2) + "Mb"); - if (comic->info.hasBeenOpened) - t.setVariable(QString("element%1.pages").arg(i), QString("%1/%2 pages").arg(comic->info.currentPage).arg(comic->info.numPages.toInt())); - else - t.setVariable(QString("element%1.pages").arg(i), QString("%1 pages").arg(comic->info.numPages.toInt())); - - if (comic->info.read) - t.setVariable(QString("element%1.status").arg(i), QString("
")); - else if (comic->info.hasBeenOpened) - t.setVariable(QString("element%1.status").arg(i), QString("
")); - 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++; - } - } else { - t.loop("element", 0); - } - - if (numPages > 1) { - t.setCondition("pageIndex", true); - - QMap indexCount; - - QString firstChar; - int xyz = 1; - for (QList::const_iterator itr = folderContent.constBegin(); itr != folderContent.constEnd(); itr++) { - firstChar = QString((*itr)->name[0]).toUpper(); - firstChar = firstChar.normalized(QString::NormalizationForm_D).at(0); // TODO _D or _KD?? - bool ok; - /*int dec = */ firstChar.toInt(&ok, 10); - if (ok) - firstChar = "#"; - // response.writeText(QString("%1 - %2
").arg((*itr)->name).arg(xyz)); - if (indexCount.contains(firstChar)) - indexCount.insert(firstChar, indexCount.value(firstChar) + 1); - else - indexCount.insert(firstChar, 1); - - xyz++; - } - - QList index = indexCount.keys(); - if (index.length() > 1) { - t.setCondition("alphaIndex", true); - - std::sort(index.begin(), index.end(), naturalSortLessThanCI); - t.loop("index", index.length()); - int i = 0; - int count = 0; - int indexPage = 0; - for (QList::const_iterator itr = index.constBegin(); itr != index.constEnd(); itr++) { - // response.writeText(QString("%1 - %2
").arg(*itr).arg(count)); - t.setVariable(QString("index%1.indexname").arg(i), *itr); - t.setVariable(QString("index%1.url").arg(i), QString("/library/%1/folder/%2?page=%3").arg(libraryId).arg(folderId).arg(indexPage)); - i++; - count += indexCount.value(*itr); - indexPage = count / elementsPerPage; - } - } else { - t.loop("index", 0); - t.setCondition("alphaIndex", false); - } - - t.loop("page", numPages); - int z = 0; - while (z < numPages) { - - t.setVariable(QString("page%1.url").arg(z), QString("/library/%1/folder/%2?page=%3").arg(libraryId).arg(folderId).arg(z)); - t.setVariable(QString("page%1.number").arg(z), QString("%1").arg(z + 1)); - if (page == z) - t.setVariable(QString("page%1.current").arg(z), "current"); - else - t.setVariable(QString("page%1.current").arg(z), ""); - z++; - } - - t.setVariable("page.first", QString("/library/%1/folder/%2?page=%3").arg(libraryId).arg(folderId).arg(0)); - t.setVariable("page.previous", QString("/library/%1/folder/%2?page=%3").arg(libraryId).arg(folderId).arg((page == 0) ? page : page - 1)); - t.setVariable("page.next", QString("/library/%1/folder/%2?page=%3").arg(libraryId).arg(folderId).arg((page == numPages - 1) ? page : page + 1)); - t.setVariable("page.last", QString("/library/%1/folder/%2?page=%3").arg(libraryId).arg(folderId).arg(numPages - 1)); - t.setCondition("index", true); - } else { - - t.loop("page", 0); - t.loop("index", 0); - t.setCondition("index", false); - t.setCondition("pageIndex", false); - t.setCondition("alphaIndex", false); - } - - t.setVariable("page", QString("%1").arg(page + 1)); - t.setVariable("pages", QString("%1").arg(numPages)); - - qDeleteAll(folderContent); - - response.write(t.toUtf8(), true); -} diff --git a/YACReaderLibrary/server/controllers/v1/foldercontroller.h b/YACReaderLibrary/server/controllers/v1/foldercontroller.h deleted file mode 100644 index f468366d5..000000000 --- a/YACReaderLibrary/server/controllers/v1/foldercontroller.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef FOLDERCONTROLLER_H -#define FOLDERCONTROLLER_H - -#include "httprequest.h" -#include "httpresponse.h" -#include "httprequesthandler.h" - -class FolderController : public stefanfrings::HttpRequestHandler -{ - Q_OBJECT - Q_DISABLE_COPY(FolderController); - -public: - /** Constructor */ - FolderController(); - - /** Generates the response */ - void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override; -}; - -#endif // FOLDERCONTROLLER_H diff --git a/YACReaderLibrary/server/controllers/v1/folderinfocontroller.cpp b/YACReaderLibrary/server/controllers/v1/folderinfocontroller.cpp deleted file mode 100644 index 18189b8b3..000000000 --- a/YACReaderLibrary/server/controllers/v1/folderinfocontroller.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "folderinfocontroller.h" -#include "db_helper.h" //get libraries - -#include "folder.h" -#include "comic_db.h" - -#include "template.h" -#include "../static.h" - -using stefanfrings::HttpRequest; -using stefanfrings::HttpResponse; - -FolderInfoController::FolderInfoController() { } - -void FolderInfoController::service(HttpRequest &request, HttpResponse &response) -{ - response.setHeader("Content-Type", "text/plain; charset=utf-8"); - - QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); - QStringList pathElements = path.split('/'); - int libraryId = pathElements.at(2).toInt(); - qulonglong parentId = pathElements.at(4).toULongLong(); - - serviceComics(libraryId, parentId, response); - - response.write("", true); -} - -void FolderInfoController::serviceComics(const int &library, const qulonglong &folderId, HttpResponse &response) -{ - QList folderContent = DBHelper::getFolderSubfoldersFromLibrary(library, folderId); - QList folderComics = DBHelper::getFolderComicsFromLibrary(library, folderId); - - ComicDB *currentComic; - for (QList::const_iterator itr = folderComics.constBegin(); itr != folderComics.constEnd(); itr++) { - currentComic = (ComicDB *)(*itr); - response.write(QString("/library/%1/comic/%2:%3:%4\r\n").arg(library).arg(currentComic->id).arg(currentComic->getFileName()).arg(currentComic->getFileSize()).toUtf8()); - delete currentComic; - } - - Folder *currentFolder; - for (QList::const_iterator itr = folderContent.constBegin(); itr != folderContent.constEnd(); itr++) { - currentFolder = (Folder *)(*itr); - serviceComics(library, currentFolder->id, response); - delete currentFolder; - } -} diff --git a/YACReaderLibrary/server/controllers/v1/folderinfocontroller.h b/YACReaderLibrary/server/controllers/v1/folderinfocontroller.h deleted file mode 100644 index f52cd50fa..000000000 --- a/YACReaderLibrary/server/controllers/v1/folderinfocontroller.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef FOLDERINFOCONTROLLER_H -#define FOLDERINFOCONTROLLER_H - -#include "httprequest.h" -#include "httpresponse.h" -#include "httprequesthandler.h" - -class FolderInfoController : public stefanfrings::HttpRequestHandler -{ - Q_OBJECT - Q_DISABLE_COPY(FolderInfoController); - -public: - /** Constructor */ - FolderInfoController(); - - /** Generates the response */ - void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override; - -private: - void serviceComics(const int &library, const qulonglong &folderId, stefanfrings::HttpResponse &response); -}; - -#endif // FOLDERINFOCONTROLLER_H diff --git a/YACReaderLibrary/server/controllers/v1/librariescontroller.cpp b/YACReaderLibrary/server/controllers/v1/librariescontroller.cpp deleted file mode 100644 index 32ad96e82..000000000 --- a/YACReaderLibrary/server/controllers/v1/librariescontroller.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "librariescontroller.h" -#include "db_helper.h" //get libraries -#include "yacreader_libraries.h" -#include "yacreader_http_session.h" - -#include "template.h" -#include "../static.h" - -#include "QsLog.h" - -using stefanfrings::HttpRequest; -using stefanfrings::HttpResponse; -using stefanfrings::HttpSession; -using stefanfrings::Template; - -LibrariesController::LibrariesController() { } - -void LibrariesController::service(HttpRequest &request, HttpResponse &response) -{ - HttpSession session = Static::sessionStore->getSession(request, response, false); - YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(session.getId()); - - response.setHeader("Content-Type", "text/html; charset=utf-8"); - response.setHeader("Connection", "close"); - - ySession->clearNavigationPath(); - - Template t = Static::templateLoader->getTemplate("libraries", request.getHeader("Accept-Language")); - t.enableWarnings(); - - // set device type and display - t.setVariable("device", ySession->getDeviceType()); - t.setVariable("display", ySession->getDisplayType()); - - YACReaderLibraries libraries = DBHelper::getLibraries(); - QList names = DBHelper::getLibrariesNames(); - - t.loop("library", names.length()); - - int currentId = 0; - int i = 0; - foreach (QString name, names) { - currentId = libraries.getId(name); - t.setVariable(QString("library%1.name").arg(i), QString::number(currentId)); - t.setVariable(QString("library%1.label").arg(i), name); - i++; - } - - response.setStatus(200, "OK"); - response.write(t.toUtf8(), true); -} diff --git a/YACReaderLibrary/server/controllers/v1/librariescontroller.h b/YACReaderLibrary/server/controllers/v1/librariescontroller.h deleted file mode 100644 index 26a60b05a..000000000 --- a/YACReaderLibrary/server/controllers/v1/librariescontroller.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef LIBRARIESCONTROLLER_H -#define LIBRARIESCONTROLLER_H - -#include "httprequest.h" -#include "httpresponse.h" -#include "httprequesthandler.h" - -/** - This controller displays a HTML form and dumps the submitted input. -*/ - -class LibrariesController : public stefanfrings::HttpRequestHandler -{ - Q_OBJECT - Q_DISABLE_COPY(LibrariesController); - -public: - /** Constructor */ - LibrariesController(); - - /** Generates the response */ - void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override; -}; - -#endif // LIBRARIESCONTROLLER_H diff --git a/YACReaderLibrary/server/controllers/v1/pagecontroller.cpp b/YACReaderLibrary/server/controllers/v1/pagecontroller.cpp deleted file mode 100644 index 58ea334c5..000000000 --- a/YACReaderLibrary/server/controllers/v1/pagecontroller.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "pagecontroller.h" - -#include "../static.h" - -#include "comic.h" -#include "comiccontroller.h" -#include "yacreader_http_session.h" - -#include -#include - -#include - -using stefanfrings::HttpRequest; -using stefanfrings::HttpResponse; -using stefanfrings::HttpSession; - -PageController::PageController() { } - -void PageController::service(HttpRequest &request, HttpResponse &response) -{ - HttpSession session = Static::sessionStore->getSession(request, response, false); - YACReaderHttpSession *ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(session.getId()); - - QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); - bool remote = path.endsWith("remote"); - - // QByteArray path2=request.getPath(); - // qDebug("PageController: request to -> %s ",path2.data()); - - QStringList pathElements = path.split('/'); - qulonglong comicId = pathElements.at(4).toULongLong(); - unsigned int page = pathElements.at(6).toUInt(); - - // qDebug("lib name : %s",pathElements.at(2).data()); - - Comic *comicFile; - qulonglong currentComicId; - if (remote) { - QLOG_TRACE() << "se recupera comic remoto para servir páginas"; - comicFile = ySession->getCurrentRemoteComic(); - currentComicId = ySession->getCurrentRemoteComicId(); - } else { - QLOG_TRACE() << "se recupera comic para servir páginas"; - comicFile = ySession->getCurrentComic(); - currentComicId = ySession->getCurrentComicId(); - } - - if (currentComicId != 0 && !QPointer(comicFile).isNull()) { - if (comicId == currentComicId && page < comicFile->numPages()) { - if (comicFile->pageIsLoaded(page)) { - // qDebug("PageController: La página estaba cargada -> %s ",path.data()); - response.setHeader("Content-Type", "image/jpeg"); - response.setHeader("Transfer-Encoding", "chunked"); - QByteArray pageData = comicFile->getRawPage(page); - QDataStream data(pageData); - char buffer[4096]; - while (!data.atEnd()) { - int len = data.readRawData(buffer, 4096); - response.write(QByteArray(buffer, len)); - } - // response.write(pageData,true); - response.write(QByteArray(), true); - } else { - // qDebug("PageController: La página NO estaba cargada 404 -> %s ",path.data()); - response.setStatus(404, "not found"); // TODO qué mensaje enviar - response.write("404 not found", true); - } - } else { - if (comicId != currentComicId) { - // delete comicFile; - if (remote) - ySession->dismissCurrentRemoteComic(); - else - ySession->dismissCurrentComic(); - } - response.setStatus(404, "not found"); // TODO qué mensaje enviar - response.write("404 not found", true); - } - } else { - response.setStatus(404, "not found"); - response.write("404 not found", true); - } - - // response.write(t.toLatin1(),true); -} diff --git a/YACReaderLibrary/server/controllers/v1/pagecontroller.h b/YACReaderLibrary/server/controllers/v1/pagecontroller.h deleted file mode 100644 index fdd48541b..000000000 --- a/YACReaderLibrary/server/controllers/v1/pagecontroller.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef PAGECONTROLLER_H -#define PAGECONTROLLER_H - -#include "httprequest.h" -#include "httpresponse.h" -#include "httprequesthandler.h" - -class PageController : public stefanfrings::HttpRequestHandler -{ - Q_OBJECT - Q_DISABLE_COPY(PageController); - -public: - /** Constructor */ - PageController(); - - /** Generates the response */ - void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override; -}; - -#endif // PAGECONTROLLER_H diff --git a/YACReaderLibrary/server/controllers/v1/sessioncontroller.cpp b/YACReaderLibrary/server/controllers/v1/sessioncontroller.cpp deleted file mode 100644 index 3381046f0..000000000 --- a/YACReaderLibrary/server/controllers/v1/sessioncontroller.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/** - @file - @author Stefan Frings -*/ - -#include "sessioncontroller.h" -#include "../static.h" -#include -#include - -using stefanfrings::HttpRequest; -using stefanfrings::HttpResponse; - -SessionController::SessionController() { } - -void SessionController::service(HttpRequest &request, HttpResponse &response) -{ - - response.setHeader("Content-Type", "text/html; charset=ISO-8859-1"); - - // Get current session, or create a new one - HttpSession session = Static::sessionStore->getSession(request, response); - if (!session.contains("startTime")) { - response.write("New session started. Reload this page now."); - session.set("startTime", QDateTime::currentDateTime()); - } - - else { - QDateTime startTime = session.get("startTime").toDateTime(); - response.write("Your session started "); - response.write(startTime.toString().toLatin1()); - response.write(""); - } -} diff --git a/YACReaderLibrary/server/controllers/v1/sessionmanager.h b/YACReaderLibrary/server/controllers/v1/sessionmanager.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/YACReaderLibrary/server/controllers/v1/synccontroller.cpp b/YACReaderLibrary/server/controllers/v1/synccontroller.cpp deleted file mode 100644 index 3239b64e8..000000000 --- a/YACReaderLibrary/server/controllers/v1/synccontroller.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "synccontroller.h" - -#include "QsLog.h" -#include - -#include "comic_db.h" -#include "db_helper.h" - -using stefanfrings::HttpRequest; -using stefanfrings::HttpResponse; - -SyncController::SyncController() -{ -} - -void SyncController::service(HttpRequest &request, HttpResponse &response) -{ - QString postData = QString::fromUtf8(request.getBody()); - - QLOG_TRACE() << "POST DATA: " << postData; - - if (postData.length() > 0) { - QList data = postData.split("\n"); - - qulonglong libraryId; - qulonglong comicId; - int currentPage; - int currentRating; - QString hash; - foreach (QString comicInfo, data) { - QList comicInfoProgress = comicInfo.split("\t"); - - if (comicInfoProgress.length() == 4 || comicInfoProgress.length() == 5) { - 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; - - // Client 2.1+ version - if (comicInfoProgress.length() > 4) { - currentRating = comicInfoProgress.at(4).toInt(); - info.rating = currentRating; - } - - DBHelper::updateFromRemoteClient(libraryId, info); - } - } - } else { - response.setStatus(412, "No comic info received"); - response.write("", true); - return; - } - - response.write("OK", true); -} diff --git a/YACReaderLibrary/server/controllers/v1/synccontroller.h b/YACReaderLibrary/server/controllers/v1/synccontroller.h deleted file mode 100644 index 1780429e8..000000000 --- a/YACReaderLibrary/server/controllers/v1/synccontroller.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef SYNCCONTROLLER_H -#define SYNCCONTROLLER_H - -#include - -#include "httprequest.h" -#include "httpresponse.h" -#include "httprequesthandler.h" - -class SyncController : public stefanfrings::HttpRequestHandler -{ - Q_OBJECT - Q_DISABLE_COPY(SyncController) -public: - /** Constructor */ - SyncController(); - - /** Generates the response */ - void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override; -}; - -#endif // SYNCCONTROLLER_H diff --git a/YACReaderLibrary/server/controllers/v1/updatecomiccontroller.cpp b/YACReaderLibrary/server/controllers/v1/updatecomiccontroller.cpp deleted file mode 100644 index ffc14e8f2..000000000 --- a/YACReaderLibrary/server/controllers/v1/updatecomiccontroller.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "updatecomiccontroller.h" - -#include "db_helper.h" -#include "yacreader_libraries.h" - -#include "template.h" -#include "../static.h" - -#include "comic_db.h" -#include "comic.h" - -#include "QsLog.h" - -using stefanfrings::HttpRequest; -using stefanfrings::HttpResponse; -using stefanfrings::HttpSession; - -UpdateComicController::UpdateComicController() { } - -void UpdateComicController::service(HttpRequest &request, HttpResponse &response) -{ - HttpSession session = Static::sessionStore->getSession(request, response, false); - - QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8(); - QStringList pathElements = path.split('/'); - qulonglong libraryId = pathElements.at(2).toULongLong(); - QString libraryName = DBHelper::getLibraryName(libraryId); - qulonglong comicId = pathElements.at(4).toULongLong(); - - QString postData = QString::fromUtf8(request.getBody()); - - QLOG_TRACE() << "POST DATA: " << postData; - - if (postData.length() > 0) { - QList data = postData.split("\n"); - int currentPage = data.at(0).split(":").at(1).toInt(); - ComicInfo info; - info.currentPage = currentPage; - info.id = comicId; - DBHelper::updateProgress(libraryId, info); - } else { - response.setStatus(412, "No comic info received"); - response.write("", true); - return; - } - - response.write("OK", true); -} diff --git a/YACReaderLibrary/server/controllers/v1/updatecomiccontroller.h b/YACReaderLibrary/server/controllers/v1/updatecomiccontroller.h deleted file mode 100644 index 2dcf4c598..000000000 --- a/YACReaderLibrary/server/controllers/v1/updatecomiccontroller.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef UPDATECOMICCONTROLLER_H -#define UPDATECOMICCONTROLLER_H - -#include "httprequest.h" -#include "httpresponse.h" -#include "httprequesthandler.h" - -class UpdateComicController : public stefanfrings::HttpRequestHandler -{ - Q_OBJECT - Q_DISABLE_COPY(UpdateComicController); - -public: - UpdateComicController(); - - /** Generates the response */ - void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override; -}; - -#endif // UPDATECOMICCONTROLLER_H diff --git a/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.cpp index d0a93d004..bf9585cbf 100644 --- a/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.cpp @@ -3,7 +3,6 @@ #include "../static.h" #include "comic.h" -#include "comiccontroller.h" #include "yacreader_http_session.h" #include diff --git a/YACReaderLibrary/server/requestmapper.cpp b/YACReaderLibrary/server/requestmapper.cpp index 5f767bb00..7e181c639 100644 --- a/YACReaderLibrary/server/requestmapper.cpp +++ b/YACReaderLibrary/server/requestmapper.cpp @@ -4,17 +4,6 @@ #include "controllers/versioncontroller.h" -#include "controllers/v1/librariescontroller.h" -#include "controllers/v1/foldercontroller.h" -#include "controllers/v1/covercontroller.h" -#include "controllers/v1/comiccontroller.h" -#include "controllers/v1/folderinfocontroller.h" -#include "controllers/v1/pagecontroller.h" -#include "controllers/v1/updatecomiccontroller.h" -#include "controllers/v1/errorcontroller.h" -#include "controllers/v1/comicdownloadinfocontroller.h" -#include "controllers/v1/synccontroller.h" - #include "controllers/v2/librariescontroller_v2.h" #include "controllers/v2/covercontroller_v2.h" #include "controllers/v2/comiccontroller_v2.h" @@ -51,83 +40,12 @@ using stefanfrings::HttpRequest; using stefanfrings::HttpRequestHandler; using stefanfrings::HttpResponse; -using stefanfrings::HttpSession; QMutex RequestMapper::mutex; RequestMapper::RequestMapper(QObject *parent) : HttpRequestHandler(parent) { } -void RequestMapper::loadSessionV1(HttpRequest &request, HttpResponse &response) -{ - QMutexLocker locker(&mutex); - - HttpSession session = Static::sessionStore->getSession(request, response); - if (session.contains("ySession")) // session is already alive check if it is needed to update comics - { - auto ySession = Static::yacreaderSessionStore->getYACReaderSessionHttpSession(session.getId()); - - QString postData = QString::fromUtf8(request.getBody()); - - if (postData.contains("currentPage")) - return; - - if (postData.length() > 0) { - - QList data = postData.split("\n"); - if (data.length() > 2) { - ySession->setDeviceType(data.at(0).split(":").at(1)); - ySession->setDisplayType(data.at(1).split(":").at(1)); - QList comics = data.at(2).split(":").at(1).split("\t"); - ySession->clearComics(); - foreach (QString hash, comics) { - ySession->setComicOnDevice(hash); - } - } else { - if (data.length() > 1) { - ySession->setDeviceType(data.at(0).split(":").at(1)); - ySession->setDisplayType(data.at(1).split(":").at(1)); - } - } - } - } else { - auto ySession = new YACReaderHttpSession(this); - - Static::yacreaderSessionStore->addYACReaderHttpSession(session.getId(), ySession); - - session.set("ySession", "ok"); - - QString postData = QString::fromUtf8(request.getBody()); - // response.writeText(postData); - - QList data = postData.split("\n"); - - if (data.length() > 2) { - auto deviceTypeData = data.at(0).split(":"); - if (deviceTypeData.length() == 2) { - ySession->setDeviceType(deviceTypeData.at(1)); - } - - auto displayTypeData = data.at(1).split(":"); - if (displayTypeData.length() == 2) { - ySession->setDisplayType(displayTypeData.at(1)); - } - - auto comicsData = data.at(2).split(":"); - if (comicsData.length() == 2) { - QList comics = comicsData.at(1).split("\t"); - foreach (QString hash, comics) { - ySession->setComicOnDevice(hash); - } - } - } else // values by default, only for debug purposes. - { - ySession->setDeviceType("ipad"); - ySession->setDisplayType("@2x"); - } - } -} - void RequestMapper::loadSessionV2(HttpRequest &request, HttpResponse & /* response */) { QMutexLocker locker(&mutex); @@ -160,7 +78,8 @@ void RequestMapper::service(HttpRequest &request, HttpResponse &response) } else if (path.startsWith("/webui")) { serviceWebUI(request, response); } else { - serviceV1(request, response); + response.setStatus(404, "not found"); + response.write("404 not found", true); } } @@ -169,71 +88,6 @@ void RequestMapper::serviceWebUI(HttpRequest &request, HttpResponse &response) StatusPageController().service(request, response); } -void RequestMapper::serviceV1(HttpRequest &request, HttpResponse &response) -{ - QByteArray path = request.getPath(); - - 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 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(); - - if (!sync.exactMatch(path)) // no session is needed for syncback info, until security will be added - loadSessionV1(request, response); - - // 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 { - if (sync.exactMatch(path)) - SyncController().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")) { - 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)) { - 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 { - // response.writeText(library.cap(1)); - Static::staticFileController->service(request, response); - } - } else // acceso no autorizado, redirección - { - ErrorController(300).service(request, response); - } - } - } -} - void RequestMapper::serviceV2(HttpRequest &request, HttpResponse &response) { QByteArray path = request.getPath(); diff --git a/YACReaderLibrary/server/requestmapper.h b/YACReaderLibrary/server/requestmapper.h index 3f089ba1b..1767639ee 100644 --- a/YACReaderLibrary/server/requestmapper.h +++ b/YACReaderLibrary/server/requestmapper.h @@ -12,7 +12,6 @@ class RequestMapper : public stefanfrings::HttpRequestHandler RequestMapper(QObject *parent = nullptr); void service(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response) override; - void loadSessionV1(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response); void loadSessionV2(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response); signals: @@ -20,7 +19,6 @@ class RequestMapper : public stefanfrings::HttpRequestHandler void comicUpdated(qulonglong libraryId, qulonglong comicId); private: - void serviceV1(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response); void serviceV2(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response); void serviceWebUI(stefanfrings::HttpRequest &request, stefanfrings::HttpResponse &response); diff --git a/YACReaderLibrary/server/server.pri b/YACReaderLibrary/server/server.pri index 7452130a5..f94c36624 100644 --- a/YACReaderLibrary/server/server.pri +++ b/YACReaderLibrary/server/server.pri @@ -1,10 +1,8 @@ INCLUDEPATH += $$PWD INCLUDEPATH += $$PWD/controllers -INCLUDEPATH += $$PWD/controllers/v1 INCLUDEPATH += $$PWD/controllers/v2 DEPENDPATH += $$PWD DEPENDPATH += $$PWD/controllers -DEPENDPATH += $$PWD/controllers/v1 DEPENDPATH += $$PWD/controllers/v2 @@ -18,17 +16,6 @@ HEADERS += \ $$PWD/yacreader_http_session_store.h \ $$PWD/yacreader_server_data_helper.h \ $$PWD/controllers/versioncontroller.h \ - #v1 - $$PWD/controllers/v1/comiccontroller.h \ - $$PWD/controllers/v1/errorcontroller.h \ - $$PWD/controllers/v1/foldercontroller.h \ - $$PWD/controllers/v1/folderinfocontroller.h \ - $$PWD/controllers/v1/librariescontroller.h \ - $$PWD/controllers/v1/pagecontroller.h \ - $$PWD/controllers/v1/covercontroller.h \ - $$PWD/controllers/v1/updatecomiccontroller.h \ - $$PWD/controllers/v1/comicdownloadinfocontroller.h \ - $$PWD/controllers/v1/synccontroller.h \ #v2 $$PWD/controllers/v2/comiccontroller_v2.h \ $$PWD/controllers/v2/errorcontroller_v2.h \ @@ -64,17 +51,6 @@ SOURCES += \ $$PWD/yacreader_http_session_store.cpp \ $$PWD/yacreader_server_data_helper.cpp \ $$PWD/controllers/versioncontroller.cpp \ - #v1 - $$PWD/controllers/v1/comiccontroller.cpp \ - $$PWD/controllers/v1/errorcontroller.cpp \ - $$PWD/controllers/v1/foldercontroller.cpp \ - $$PWD/controllers/v1/folderinfocontroller.cpp \ - $$PWD/controllers/v1/librariescontroller.cpp \ - $$PWD/controllers/v1/pagecontroller.cpp \ - $$PWD/controllers/v1/covercontroller.cpp \ - $$PWD/controllers/v1/updatecomiccontroller.cpp \ - $$PWD/controllers/v1/comicdownloadinfocontroller.cpp \ - $$PWD/controllers/v1/synccontroller.cpp \ #v2 $$PWD/controllers/v2/comiccontroller_v2.cpp \ $$PWD/controllers/v2/errorcontroller_v2.cpp \ diff --git a/YACReaderLibrary/server/static.cpp b/YACReaderLibrary/server/static.cpp index e13f828d8..509a04672 100644 --- a/YACReaderLibrary/server/static.cpp +++ b/YACReaderLibrary/server/static.cpp @@ -9,17 +9,10 @@ #include #include -using stefanfrings::HttpResponse; -using stefanfrings::HttpSessionStore; using stefanfrings::StaticFileController; -using stefanfrings::TemplateLoader; QString Static::configDir = nullptr; -TemplateLoader *Static::templateLoader = nullptr; - -HttpSessionStore *Static::sessionStore = nullptr; - StaticFileController *Static::staticFileController = 0; YACReaderHttpSessionStore *Static::yacreaderSessionStore = nullptr; diff --git a/YACReaderLibrary/server/static.h b/YACReaderLibrary/server/static.h index 5c2296f58..d97eef0ea 100644 --- a/YACReaderLibrary/server/static.h +++ b/YACReaderLibrary/server/static.h @@ -7,8 +7,6 @@ #define STATIC_H #include -#include "templatecache.h" -#include "httpsessionstore.h" #include "staticfilecontroller.h" #include "yacreader_http_session_store.h" @@ -46,12 +44,6 @@ class Static */ static QString getConfigDir(); - /** Cache for template files */ - static stefanfrings::TemplateLoader *templateLoader; - - /** Storage for session cookies */ - static stefanfrings::HttpSessionStore *sessionStore; - static YACReaderHttpSessionStore *yacreaderSessionStore; /** Controller for static files */ diff --git a/YACReaderLibrary/server/yacreader_http_server.cpp b/YACReaderLibrary/server/yacreader_http_server.cpp index b60280aa8..55f1bc3cf 100644 --- a/YACReaderLibrary/server/yacreader_http_server.cpp +++ b/YACReaderLibrary/server/yacreader_http_server.cpp @@ -25,12 +25,7 @@ #define DESCRIPTION "Comic reader and organizer" using stefanfrings::HttpListener; -using stefanfrings::HttpRequest; -using stefanfrings::HttpResponse; - -using stefanfrings::HttpSessionStore; using stefanfrings::StaticFileController; -using stefanfrings::TemplateCache; void YACReaderHttpServer::start(quint16 port) { @@ -38,36 +33,7 @@ void YACReaderHttpServer::start(quint16 port) QCoreApplication *app = QCoreApplication::instance(); QString configFileName = YACReader::getSettingsPath() + "/" + QCoreApplication::applicationName() + ".ini"; - // Configure template loader and cache - auto templateSettings = new QSettings(configFileName, QSettings::IniFormat, app); - templateSettings->beginGroup("templates"); - - if (templateSettings->value("cacheSize").isNull()) - templateSettings->setValue("cacheSize", "160000"); - - QString baseTemplatePath = QString("./server/templates"); - QString templatePath; - -#if defined Q_OS_UNIX && !defined Q_OS_MACOS - templatePath = QFileInfo(QString(DATADIR) + "/yacreader", baseTemplatePath).absoluteFilePath(); -#else - templatePath = QFileInfo(QCoreApplication::applicationDirPath(), baseTemplatePath).absoluteFilePath(); -#endif - if (!templateSettings->contains("path")) - templateSettings->setValue("path", templatePath); - - Static::templateLoader = new TemplateCache(templateSettings, app); - - // Configure session store - auto sessionSettings = new QSettings(configFileName, QSettings::IniFormat, app); - sessionSettings->beginGroup("sessions"); - - if (sessionSettings->value("expirationTime").isNull()) - sessionSettings->setValue("expirationTime", 864000000); - - Static::sessionStore = new HttpSessionStore(sessionSettings, app); - - Static::yacreaderSessionStore = new YACReaderHttpSessionStore(Static::sessionStore, app); + Static::yacreaderSessionStore = new YACReaderHttpSessionStore(app); // Configure static file controller auto fileSettings = new QSettings(configFileName, QSettings::IniFormat, app); diff --git a/YACReaderLibrary/server/yacreader_http_session_store.cpp b/YACReaderLibrary/server/yacreader_http_session_store.cpp index ba92a7851..fdcb7f3aa 100644 --- a/YACReaderLibrary/server/yacreader_http_session_store.cpp +++ b/YACReaderLibrary/server/yacreader_http_session_store.cpp @@ -2,17 +2,9 @@ #include "yacreader_http_session.h" -#include "httpsessionstore.h" - -using stefanfrings::HttpSessionStore; - -YACReaderHttpSessionStore::YACReaderHttpSessionStore(HttpSessionStore *sessionStore, QObject *parent) - : QObject(parent), sessionStore(sessionStore) +YACReaderHttpSessionStore::YACReaderHttpSessionStore(QObject *parent) + : QObject(parent) { - // sessions are no longer http sessions in v2, we need another mechanism for cleaning - - // connect(&cleanupTimer,SIGNAL(timeout()),this,SLOT(sessionTimerEvent())); - // cleanupTimer.start(60000); } void YACReaderHttpSessionStore::addYACReaderHttpSession(const QByteArray &httpSessionId, YACReaderHttpSession *yacreaderHttpSession) @@ -29,19 +21,3 @@ YACReaderHttpSession *YACReaderHttpSessionStore::getYACReaderSessionHttpSession( return sessions.value(httpSessionId, nullptr); } -void YACReaderHttpSessionStore::sessionTimerEvent() -{ - // sessions are no longer http sessions in v2, we are using a token, so sessionStore->getSession(id).isNull() is always true. - /*QMutexLocker locker(&mutex); - for(const QByteArray &id : sessions.keys()) - { - if(sessionStore->getSession(id).isNull()) - { - YACReaderHttpSession *session = sessions.value(id, nullptr); - if(session != nullptr) - delete session; - - sessions.remove(id); - } - }*/ -} diff --git a/YACReaderLibrary/server/yacreader_http_session_store.h b/YACReaderLibrary/server/yacreader_http_session_store.h index fe3e7e422..c3a6caa22 100644 --- a/YACReaderLibrary/server/yacreader_http_session_store.h +++ b/YACReaderLibrary/server/yacreader_http_session_store.h @@ -4,34 +4,20 @@ #include #include -namespace stefanfrings { -class HttpSessionStore; -} class YACReaderHttpSession; class YACReaderHttpSessionStore : public QObject { Q_OBJECT public: - explicit YACReaderHttpSessionStore(stefanfrings::HttpSessionStore *sessionStore, QObject *parent = nullptr); + explicit YACReaderHttpSessionStore(QObject *parent = nullptr); void addYACReaderHttpSession(const QByteArray &httpSessionId, YACReaderHttpSession *yacreaderHttpSession); YACReaderHttpSession *getYACReaderSessionHttpSession(const QByteArray &httpSessionId); -signals: - -public slots: - private: QMap sessions; - stefanfrings::HttpSessionStore *sessionStore; - QTimer cleanupTimer; - QMutex mutex; - -private slots: - - void sessionTimerEvent(); }; #endif // YACREADERHTTPSESSIONSTORE_H From 6c4583a57a961285ee8d171efdfab0a97a8959f1 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 20 Feb 2026 19:07:50 +0100 Subject: [PATCH 077/187] Run CI when targeting yacreader10 in PRs --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 96454a92f..8f4bcff7c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,6 +9,7 @@ on: branches: - master - develop + - yacreader10 env: IS_ORIGINAL_REPO: ${{ github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') }} From cdb33aef3b387b6b25b5234477248907419224b3 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 20 Feb 2026 19:17:17 +0100 Subject: [PATCH 078/187] Format --- YACReaderLibrary/server/yacreader_http_session_store.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/YACReaderLibrary/server/yacreader_http_session_store.cpp b/YACReaderLibrary/server/yacreader_http_session_store.cpp index fdcb7f3aa..aadb6a313 100644 --- a/YACReaderLibrary/server/yacreader_http_session_store.cpp +++ b/YACReaderLibrary/server/yacreader_http_session_store.cpp @@ -20,4 +20,3 @@ YACReaderHttpSession *YACReaderHttpSessionStore::getYACReaderSessionHttpSession( return sessions.value(httpSessionId, nullptr); } - From 7218d0dc8751c1c757ff9201dae386242887756c Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 20 Feb 2026 21:48:15 +0100 Subject: [PATCH 079/187] Drop Qt 5 support --- Qt5-DROP.md | 2 +- YACReader/YACReader.pro | 7 +- YACReader/main.cpp | 10 +-- YACReader/main_window_viewer.cpp | 4 +- YACReader/mouse_handler.cpp | 12 --- YACReader/translator.cpp | 14 --- YACReader/viewer.cpp | 4 - YACReaderLibrary/YACReaderLibrary.pro | 7 +- .../comic_vine/comic_vine_dialog.cpp | 8 -- .../comic_vine/scraper_tableview.cpp | 12 --- .../initial_comic_info_extractor.cpp | 5 -- YACReaderLibrary/library_window.cpp | 6 -- YACReaderLibrary/main.cpp | 2 - YACReaderLibrary/trayhandler.mm | 2 - .../YACReaderLibraryServer.pro | 4 +- YACReaderLibraryServer/main.cpp | 2 - build_scripts/ubuntu_22.04/README.md | 6 -- build_scripts/ubuntu_22.04/build.sh | 88 ------------------- build_scripts/ubuntu_24.04/build.sh | 2 +- common/comic.cpp | 5 -- common/pdf_comic.h | 4 - common/pdf_comic.mm | 2 - config.pri | 4 +- custom_widgets/help_about_dialog.cpp | 8 -- custom_widgets/yacreader_table_view.cpp | 12 --- dependencies/pdf_backend.pri | 36 +++----- docker/Dockerfile.aarch64 | 73 +++++++-------- 27 files changed, 56 insertions(+), 285 deletions(-) delete mode 100644 build_scripts/ubuntu_22.04/README.md delete mode 100644 build_scripts/ubuntu_22.04/build.sh diff --git a/Qt5-DROP.md b/Qt5-DROP.md index 658c4c283..a0fefe529 100644 --- a/Qt5-DROP.md +++ b/Qt5-DROP.md @@ -181,7 +181,7 @@ These add `QT += core5compat` for Qt6 builds. Needed by third-party QtWebApp (QT | `docker/Dockerfile` | Ubuntu x64 Qt6 — installs `libqt6core5compat6-dev` (build) and `libqt6core5compat6` (runtime) | | `docker/Dockerfile.aarch64` | Ubuntu ARM64 Qt5-only build | -**Action**: Remove or convert `Dockerfile.aarch64` to Qt6. Keep core5compat packages in main Dockerfile (QtWebApp). +**Action**: Convert `Dockerfile.aarch64` to Qt6. Keep core5compat packages in main Dockerfile (QtWebApp). Make sure the conversion is good, there must be other images online that use the arm+qt6 combo, we can search online. --- diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro index 2a9b3f69c..06ef1432a 100644 --- a/YACReader/YACReader.pro +++ b/YACReader/YACReader.pro @@ -45,16 +45,13 @@ macx { CONFIG += objective_c LIBS += -framework Foundation -framework ApplicationServices -framework AppKit - lessThan(QT_MAJOR_VERSION, 6): QT += macextras } QT += network widgets core multimedia svg -greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat +QT += core5compat -greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - QT += gui-private -} +greaterThan(QT_MINOR_VERSION, 6): QT += gui-private #CONFIG += release CONFIG -= flat diff --git a/YACReader/main.cpp b/YACReader/main.cpp index cb408d36d..813674cff 100644 --- a/YACReader/main.cpp +++ b/YACReader/main.cpp @@ -99,9 +99,7 @@ int main(int argc, char *argv[]) QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QImageReader::setAllocationLimit(0); -#endif #if defined(_MSC_VER) && defined(_DEBUG) _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); @@ -131,16 +129,10 @@ int main(int argc, char *argv[]) QCommandLineOption comicId("comicId", "", "comicId"); QCommandLineOption libraryId("libraryId", "", "libraryId"); QCommandLineOption readingListId("readingListId", "", "readingListId"); -// hide comicId and libraryId from help -#if QT_VERSION >= 0x050800 + // hide comicId and libraryId from help comicId.setFlags(QCommandLineOption::HiddenFromHelp); libraryId.setFlags(QCommandLineOption::HiddenFromHelp); readingListId.setFlags(QCommandLineOption::HiddenFromHelp); -#else - comicId.setHidden(true); - libraryId.setHidden(true); - readingListId.setHidden(true); -#endif // process parser.addOption(comicId); diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 4c671ca1f..2018b25f4 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -480,9 +480,7 @@ void MainWindowViewer::createToolBars() { #ifdef Y_MAC_UI comicToolBar = new YACReaderMacOSXToolbar(this); -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) comicToolBar->setIconSize(QSize(18, 18)); -#endif #else comicToolBar = addToolBar(tr("&File")); #endif @@ -1354,7 +1352,7 @@ void MainWindowViewer::toggleFitToWidthSlider() if (zoomSliderAction->isVisible()) { zoomSliderAction->hide(); } else { -#if defined(Y_MAC_UI) && (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#ifdef Y_MAC_UI zoomSliderAction->move((this->width() - zoomSliderAction->width()) / 2, y); #else zoomSliderAction->move(250, y); diff --git a/YACReader/mouse_handler.cpp b/YACReader/mouse_handler.cpp index 331d33f26..9ab6055e7 100644 --- a/YACReader/mouse_handler.cpp +++ b/YACReader/mouse_handler.cpp @@ -19,11 +19,7 @@ void YACReader::MouseHandler::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { viewer->drag = true; -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) auto position = event->position(); -#else - auto position = QPointF(event->x(), event->y()); -#endif dragOrigin = dragLatestPosition = position; viewer->setCursor(Qt::ClosedHandCursor); event->accept(); @@ -53,11 +49,7 @@ void YACReader::MouseHandler::mouseReleaseEvent(QMouseEvent *event) event->accept(); } -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) auto position = event->position(); -#else - auto position = QPointF(event->x(), event->y()); -#endif auto dragDistance = QLineF(position, dragOrigin).length(); auto mouseMode = Configuration::getConfiguration().getMouseMode(); @@ -104,11 +96,7 @@ void YACReader::MouseHandler::mouseMoveEvent(QMouseEvent *event) viewer->showCursor(); viewer->hideCursorTimer->start(2500); -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) auto position = event->position(); -#else - auto position = QPointF(event->x(), event->y()); -#endif if (viewer->magnifyingGlassShown) viewer->mglass->move(static_cast(position.x() - float(viewer->mglass->width()) / 2), static_cast(position.y() - float(viewer->mglass->height()) / 2)); diff --git a/YACReader/translator.cpp b/YACReader/translator.cpp index 1419adba9..a2524706f 100644 --- a/YACReader/translator.cpp +++ b/YACReader/translator.cpp @@ -1,11 +1,6 @@ #include -#if QT_VERSION >= 0x050000 #include -#else -#include -#include -#endif #include #include @@ -160,12 +155,7 @@ YACReaderTranslator::YACReaderTranslator(Viewer *parent) connect(speakButton, &QAbstractButton::pressed, this, &YACReaderTranslator::play); connect(clearButton, &QAbstractButton::pressed, this, &YACReaderTranslator::clear); - // multimedia/phonon -#if QT_VERSION >= 0x050000 player = new QMediaPlayer; -#else - music = createPlayer(MusicCategory); -#endif } void YACReaderTranslator::hideResults() @@ -288,11 +278,7 @@ void YACReaderTranslator::populateCombos() void YACReaderTranslator::play() { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) player->setSource(ttsSource); -#else - player->setMedia(ttsSource); -#endif player->play(); } diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index 80ea83388..7187f77b0 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -759,11 +759,7 @@ void Viewer::resizeEvent(QResizeEvent *event) QPixmap Viewer::pixmap() const { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) return content->pixmap(); -#else - return content->pixmap(Qt::ReturnByValue); -#endif } void Viewer::magnifyingGlassSwitch() diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index e7ca65bce..2755861ff 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -41,18 +41,15 @@ macx { LIBS += -framework Foundation -framework ApplicationServices -framework AppKit CONFIG += objective_c QT += gui-private - lessThan(QT_MAJOR_VERSION, 6): QT += macextras } #CONFIG += release CONFIG -= flat QT += sql network widgets svg quickcontrols2 -greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat +QT += core5compat -greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { - QT += gui-private -} +greaterThan(QT_MINOR_VERSION, 6): QT += gui-private # Input HEADERS += \ diff --git a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp index 2c172d1d4..23d74cd3c 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp +++ b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp @@ -146,22 +146,14 @@ void ComicVineDialog::goNext() QList> matchingInfo = sortVolumeComicsWidget->getMatchingInfo(); auto volumeInfo = selectVolumeWidget->getSelectedVolumeInfo(); -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QtConcurrent::run(&ComicVineDialog::getComicsInfo, this, matchingInfo, volumeInfo); -#else - QtConcurrent::run(this, &ComicVineDialog::getComicsInfo, matchingInfo, volumeInfo); -#endif } else if (content->currentWidget() == selectComicWidget) { showLoading(); QString comicId = selectComicWidget->getSelectedComicId(); auto volumeInfo = selectVolumeWidget->getSelectedVolumeInfo(); -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QtConcurrent::run(&ComicVineDialog::getComicInfo, this, comicId, volumeInfo); -#else - QtConcurrent::run(this, &ComicVineDialog::getComicInfo, comicId, volumeInfo); -#endif } } diff --git a/YACReaderLibrary/comic_vine/scraper_tableview.cpp b/YACReaderLibrary/comic_vine/scraper_tableview.cpp index 0fa134a87..0b5288022 100644 --- a/YACReaderLibrary/comic_vine/scraper_tableview.cpp +++ b/YACReaderLibrary/comic_vine/scraper_tableview.cpp @@ -6,25 +6,13 @@ ScraperTableView::ScraperTableView(QWidget *parent) : QTableView(parent) { setShowGrid(false); -#if QT_VERSION >= 0x050000 verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); -#else - verticalHeader()->setResizeMode(QHeaderView::Fixed); -#endif horizontalHeader()->setStretchLastSection(true); -#if QT_VERSION >= 0x050000 horizontalHeader()->setSectionsClickable(false); -#else - horizontalHeader()->setClickable(false); -#endif // comicView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents); verticalHeader()->setDefaultSectionSize(24); -#if QT_VERSION >= 0x050000 verticalHeader()->setSectionsClickable(false); // TODO comportamiento anómalo -#else - verticalHeader()->setClickable(false); // TODO comportamiento anómalo -#endif setCornerButtonEnabled(false); diff --git a/YACReaderLibrary/initial_comic_info_extractor.cpp b/YACReaderLibrary/initial_comic_info_extractor.cpp index 15528eded..23f96ef02 100644 --- a/YACReaderLibrary/initial_comic_info_extractor.cpp +++ b/YACReaderLibrary/initial_comic_info_extractor.cpp @@ -41,12 +41,7 @@ void InitialComicInfoExtractor::extract() return; } #else -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) auto pdfComic = Poppler::Document::load(_fileSource); -#else - auto _pdfComic = Poppler::Document::load(_fileSource); - auto pdfComic = std::unique_ptr(_pdfComic); -#endif #endif if (!pdfComic) { QLOG_WARN() << "Extracting cover: unable to open PDF file " << _fileSource; diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 7ec65a0c6..e7e9551e4 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -169,13 +169,11 @@ bool LibraryWindow::eventFilter(QObject *object, QEvent *event) return QMainWindow::eventFilter(object, event); } -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) auto keyCombination = keySequence[0]; if (keyCombination.keyboardModifiers() != Qt::NoModifier) { return QMainWindow::eventFilter(object, event); } -#endif auto string = keySequence.toString(); @@ -774,11 +772,7 @@ void LibraryWindow::createConnections() // Search filter #ifdef Y_MAC_UI -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) connect(libraryToolBar, &YACReaderMacOSXToolbar::filterChanged, searchDebouncer, &KDToolBox::KDStringSignalDebouncer::throttle); -#else - connect(searchEdit, &YACReaderMacOSXSearchLineEdit::filterChanged, searchDebouncer, &KDToolBox::KDStringSignalDebouncer::throttle); -#endif connect(searchDebouncer, &KDToolBox::KDStringSignalDebouncer::triggered, this, [=](QString filter) { setSearchFilter(filter); }); diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index d7c357881..5507e25ea 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -131,9 +131,7 @@ int main(int argc, char **argv) QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QImageReader::setAllocationLimit(0); -#endif QApplication app(argc, argv); diff --git a/YACReaderLibrary/trayhandler.mm b/YACReaderLibrary/trayhandler.mm index c53f0897c..05eb65028 100644 --- a/YACReaderLibrary/trayhandler.mm +++ b/YACReaderLibrary/trayhandler.mm @@ -1,8 +1,6 @@ #include -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #undef __OBJC_BOOL_IS_BOOL -#endif #import #include "trayhandler.h" diff --git a/YACReaderLibraryServer/YACReaderLibraryServer.pro b/YACReaderLibraryServer/YACReaderLibraryServer.pro index ed7ca78f8..89e0938e9 100644 --- a/YACReaderLibraryServer/YACReaderLibraryServer.pro +++ b/YACReaderLibraryServer/YACReaderLibraryServer.pro @@ -17,7 +17,7 @@ include(headless_config.pri) include(../dependencies/pdf_backend.pri) include(../third_party/QrCode/QrCode.pri) -greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat +QT += core5compat win32 { LIBS += -loleaut32 -lole32 -lshell32 -luser32 @@ -37,8 +37,6 @@ macx { CONFIG -= flat QT += core sql network -greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat - # Source files HEADERS += ../YACReaderLibrary/library_creator.h \ ../YACReaderLibrary/package_manager.h \ diff --git a/YACReaderLibraryServer/main.cpp b/YACReaderLibraryServer/main.cpp index 2b82c93dc..ac6fb4351 100644 --- a/YACReaderLibraryServer/main.cpp +++ b/YACReaderLibraryServer/main.cpp @@ -50,9 +50,7 @@ int main(int argc, char **argv) QCoreApplication app(argc, argv); -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QImageReader::setAllocationLimit(0); -#endif app.setApplicationName("YACReaderLibrary"); app.setOrganizationName("YACReader"); diff --git a/build_scripts/ubuntu_22.04/README.md b/build_scripts/ubuntu_22.04/README.md deleted file mode 100644 index b65a6d7a4..000000000 --- a/build_scripts/ubuntu_22.04/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## Ubuntu 22.04 build script -You can use `build.sh` to build YACReader from scratch in `Ubuntu 22.04` with `7zip` (including `RAR5` support) and `poppler` (pdf). This build uses Qt5. - -The script will create a folder next to it where all the downloads and building will happen, it will also install all the required dependencies. The installs 7z.so in /usr/lib/7zip/. Once the scrip finishes succesfully `YACReader`, `YACReaderLibrary` and `YACReaderLibraryServer` should be installed in your system. - -WARNIG: This doesn't work with the latest release (9.14), there is a bug and some of the code is still looking for the old p7zip library, you need to build from develop, to do so run: `build.sh develop`. \ No newline at end of file diff --git a/build_scripts/ubuntu_22.04/build.sh b/build_scripts/ubuntu_22.04/build.sh deleted file mode 100644 index 3153fb504..000000000 --- a/build_scripts/ubuntu_22.04/build.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/bash - -# Exit immediately if a command exits with a non-zero status -set -e - -# Define variables -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -BUILD_DIR="$SCRIPT_DIR/yacreader_build" -YACREADER_DIR="$BUILD_DIR/yacreader" -COMPRESSED_ARCHIVE_DIR="$YACREADER_DIR/compressed_archive" -YACREADER_REPO="https://github.com/YACReader/yacreader.git" -SEVENZIP_URL="https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -SEVENZIP_ARCHIVE="$COMPRESSED_ARCHIVE_DIR/7z2301-src.7z" -SEVENZIP_DIR="$COMPRESSED_ARCHIVE_DIR/lib7zip" - -# Function to download the latest release source tarball -download_latest_release() { - echo "Fetching the latest release information..." - LATEST_RELEASE_URL=$(curl -s https://api.github.com/repos/YACReader/yacreader/releases/latest | grep "browser_download_url.*src.tar.xz" | cut -d '"' -f 4 | head -n 1) - if [ -z "$LATEST_RELEASE_URL" ]; then - echo "Failed to fetch the latest release information." - exit 1 - fi - echo "Downloading the latest release source tarball..." - wget "$LATEST_RELEASE_URL" -O "$BUILD_DIR/latest_release_src.tar.xz" - echo "Extracting the latest release source tarball..." - mkdir -p "$YACREADER_DIR" - tar -xf "$BUILD_DIR/latest_release_src.tar.xz" -C "$YACREADER_DIR" --strip-components=1 -} - -# Step 1: Create a folder for the build process -if [ -d "$BUILD_DIR" ]; then - echo "Removing existing build directory..." - rm -rf "$BUILD_DIR" -fi -echo "Creating build directory..." -mkdir -p "$BUILD_DIR" -mkdir -p "$COMPRESSED_ARCHIVE_DIR" - -# Step 2: Install required packages -echo "Updating package list and installing required packages..." -sudo apt-get update -sudo apt-get install -y qtchooser qtbase5-dev-tools qt5-qmake \ - qtbase5-dev qtmultimedia5-dev libpoppler-qt5-dev qttools5-dev-tools \ - libqt5opengl5-dev qtdeclarative5-dev libqt5svg5-dev qtquickcontrols2-5-dev \ - qt5-image-formats-plugins qml-module-qtquick-controls2 qml-module-qtquick-layouts \ - qml-module-qtgraphicaleffects qml-module-qtquick2 qml-module-qtquick-controls \ - libqt5multimedia5-plugins qt5-image-formats-plugins qml-module-qtquick-controls2 qml-module-qtquick-layouts \ - qml-module-qtgraphicaleffects qml-module-qtquick2 qml-module-qtquick-controls \ - git build-essential - -# Step 3: Download YACReader source code -if [ "$1" == "develop" ]; then - if [ -d "$YACREADER_DIR" ]; then - echo "Removing existing YACReader directory..." - rm -rf "$YACREADER_DIR" - fi - echo "Cloning YACReader repository..." - git clone "$YACREADER_REPO" "$YACREADER_DIR" -else - download_latest_release -fi - -# Step 4: Download and extract 7zip source code -echo "Downloading 7zip source code..." -wget "$SEVENZIP_URL" -O "$SEVENZIP_ARCHIVE" -echo "Extracting 7zip source code..." -7z x "$SEVENZIP_ARCHIVE" -o"$SEVENZIP_DIR" - -# Step 5: Build and install 7z.so with RAR support -echo "Building and installing 7z.so with RAR support..." -cd "$SEVENZIP_DIR/CPP/7zip/Bundles/Format7zF" -make -f makefile.gcc -sudo mkdir -p /usr/lib/7zip -sudo cp ./_o/7z.so /usr/lib/7zip - -# Step 6: Build YACReader -echo "Building YACReader..." -cd "$YACREADER_DIR" -export DEFINES_VAR=DEFINES+\=\"BUILD_NUMBER=\\\\\\\"CUSTOM_BUILD\\\\\\\"\" -qmake CONFIG+="7zip" $DEFINES_VAR -make - -# Step 7: Install YACReader -echo "Installing YACReader..." -sudo make install - -echo "YACReader build and installation complete." \ No newline at end of file diff --git a/build_scripts/ubuntu_24.04/build.sh b/build_scripts/ubuntu_24.04/build.sh index 979b53305..eb7b78943 100644 --- a/build_scripts/ubuntu_24.04/build.sh +++ b/build_scripts/ubuntu_24.04/build.sh @@ -40,7 +40,7 @@ mkdir -p "$COMPRESSED_ARCHIVE_DIR" # Step 2: Install required packages echo "Updating package list and installing required packages..." sudo apt-get update -sudo apt-get install -y qtchooser qt6-tools-dev qt6-base-dev-tools qmake6 qmake6-bin qt6-base-dev qt6-multimedia-dev qt6-tools-dev-tools libgl-dev qt6-l10n-tools libqt6opengl6-dev qt6-declarative-dev libqt6svg6-dev libqt6core5compat6-dev qml6-module-qt5compat-graphicaleffects qt6-5compat-dev libpoppler-qt6-dev qt6-image-formats-plugins qml6-module-qtquick-controls qml6-module-qtquick-layouts qml6-module-qtqml-workerscript qml6-module-qtquick-templates 7zip-full 7zip-rar git build-essential +sudo apt-get install -y qtchooser qt6-tools-dev qt6-base-dev-tools qmake6 qmake6-bin qt6-base-dev qt6-multimedia-dev qt6-tools-dev-tools libgl-dev qt6-l10n-tools libqt6opengl6-dev qt6-declarative-dev libqt6svg6-dev libqt6core5compat6-dev qt6-5compat-dev libpoppler-qt6-dev qt6-image-formats-plugins qml6-module-qtquick-controls qml6-module-qtquick-layouts qml6-module-qtqml-workerscript qml6-module-qtquick-templates 7zip-full 7zip-rar git build-essential # Step 3: Download YACReader source code if [ "$1" == "develop" ]; then diff --git a/common/comic.cpp b/common/comic.cpp index 6763db2a2..04ea4886d 100644 --- a/common/comic.cpp +++ b/common/comic.cpp @@ -809,12 +809,7 @@ void PDFComic::process() } #else -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) pdfComic = Poppler::Document::load(_path); -#else - auto _pdfComic = Poppler::Document::load(_path); - pdfComic = std::unique_ptr(_pdfComic); -#endif if (!pdfComic) { moveToThread(QCoreApplication::instance()->thread()); diff --git a/common/pdf_comic.h b/common/pdf_comic.h index 1eadd705f..cc47d0cde 100644 --- a/common/pdf_comic.h +++ b/common/pdf_comic.h @@ -46,10 +46,6 @@ class PdfiumComic QFile pdfFile; }; #else -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #include -#else -#include "poppler-qt5.h" -#endif // QT_VERSION #endif // Q_OS_MACOS #endif // PDF_COMIC_H diff --git a/common/pdf_comic.mm b/common/pdf_comic.mm index 9f671cb34..c242169ad 100644 --- a/common/pdf_comic.mm +++ b/common/pdf_comic.mm @@ -1,8 +1,6 @@ #include "pdf_comic.h" -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #undef __OBJC_BOOL_IS_BOOL -#endif #import #import diff --git a/config.pri b/config.pri index 2ca74575c..083bef24b 100644 --- a/config.pri +++ b/config.pri @@ -38,8 +38,8 @@ defineTest(minQtVersion) { return(false) } -!minQtVersion(5, 15, 0) { - error(YACReader requires Qt 5.15 or newer but $$[QT_VERSION] was detected) +!minQtVersion(6, 0, 0) { + error(YACReader requires Qt 6.0 or newer but $$[QT_VERSION] was detected) } # reduce log pollution diff --git a/custom_widgets/help_about_dialog.cpp b/custom_widgets/help_about_dialog.cpp index 17c4a82d7..2b8de003f 100644 --- a/custom_widgets/help_about_dialog.cpp +++ b/custom_widgets/help_about_dialog.cpp @@ -11,10 +11,6 @@ #include #include -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -#include -#endif - #include "yacreader_global.h" HelpAboutDialog::HelpAboutDialog(QWidget *parent) @@ -85,11 +81,7 @@ QString HelpAboutDialog::fileToString(const QString &path) f.open(QIODevice::ReadOnly); QTextStream txtS(&f); -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) txtS.setEncoding(QStringConverter::Utf8); -#else - txtS.setCodec(QTextCodec::codecForName("UTF-8")); -#endif QString content = txtS.readAll(); f.close(); diff --git a/custom_widgets/yacreader_table_view.cpp b/custom_widgets/yacreader_table_view.cpp index 7c8b2507c..85c6ccba5 100644 --- a/custom_widgets/yacreader_table_view.cpp +++ b/custom_widgets/yacreader_table_view.cpp @@ -26,26 +26,14 @@ YACReaderTableView::YACReaderTableView(QWidget *parent) setContextMenuPolicy(Qt::ActionsContextMenu); setShowGrid(false); -#if QT_VERSION >= 0x050000 verticalHeader()->setSectionResizeMode(QHeaderView::Fixed); -#else - verticalHeader()->setResizeMode(QHeaderView::Fixed); -#endif // comicView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents); horizontalHeader()->setStretchLastSection(true); -#if QT_VERSION >= 0x050000 horizontalHeader()->setSectionsClickable(false); -#else - horizontalHeader()->setClickable(false); -#endif // comicView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents); verticalHeader()->setDefaultSectionSize(24); -#if QT_VERSION >= 0x050000 verticalHeader()->setSectionsClickable(false); // TODO comportamiento anómalo -#else - verticalHeader()->setClickable(false); // TODO comportamiento anómalo -#endif setCornerButtonEnabled(false); diff --git a/dependencies/pdf_backend.pri b/dependencies/pdf_backend.pri index e008dc955..1402b9e20 100644 --- a/dependencies/pdf_backend.pri +++ b/dependencies/pdf_backend.pri @@ -49,38 +49,24 @@ CONFIG(poppler) { contains(QMAKE_TARGET.arch, x86_64): { error ("We currently don't ship precompiled poppler libraries for 64 bit builds on Windows") } - INCLUDEPATH += $$PWD/poppler/include/qt5 - LIBS += -L$$PWD/poppler/lib -lpoppler-qt5 + INCLUDEPATH += $$PWD/poppler/include/qt6 + LIBS += -L$$PWD/poppler/lib -lpoppler-qt6 # Add extra paths for dll dependencies so the executables don't crash when launching # from QtCreator LIBS += -L$$PWD/poppler/bin LIBS += -L$$PWD/poppler/dependencies/bin } if(unix|mingw):!macx { - greaterThan (QT_MAJOR_VERSION, 5) { - !contains(QT_CONFIG, no-pkg-config):packagesExist(poppler-qt6) { - message("Using system provided installation of poppler-qt6 found by pkg-config.") - CONFIG += link_pkgconfig - PKGCONFIG += poppler-qt6 - } else:!macx:exists(/usr/include/poppler/qt6) { - message("Using system provided installation of poppler-qt6.") - INCLUDEPATH += /usr/include/poppler/qt6 - LIBS += -lpoppler-qt6 - } else { - error("Could not find poppler-qt6") - } + !contains(QT_CONFIG, no-pkg-config):packagesExist(poppler-qt6) { + message("Using system provided installation of poppler-qt6 found by pkg-config.") + CONFIG += link_pkgconfig + PKGCONFIG += poppler-qt6 + } else:!macx:exists(/usr/include/poppler/qt6) { + message("Using system provided installation of poppler-qt6.") + INCLUDEPATH += /usr/include/poppler/qt6 + LIBS += -lpoppler-qt6 } else { - !contains(QT_CONFIG, no-pkg-config):packagesExist(poppler-qt5) { - message("Using system provided installation of poppler-qt5 found by pkg-config.") - CONFIG += link_pkgconfig - PKGCONFIG += poppler-qt5 - } else:!macx:exists(/usr/include/poppler/qt5) { - message("Using system provided installation of poppler-qt5.") - INCLUDEPATH += /usr/include/poppler/qt5 - LIBS += -lpoppler-qt5 - } else { - error("Could not find poppler-qt5") - } + error("Could not find poppler-qt6") } } unix:macx { diff --git a/docker/Dockerfile.aarch64 b/docker/Dockerfile.aarch64 index faf2c4303..bd4660c7a 100644 --- a/docker/Dockerfile.aarch64 +++ b/docker/Dockerfile.aarch64 @@ -17,37 +17,36 @@ RUN \ desktop-file-utils \ g++ \ git \ - libglu1-mesa-dev \ - libpoppler-qt5-dev \ - libpoppler-qt5-1 \ - libqt5core5a \ - libqt5gui5 \ - libqt5multimedia5 \ - libqt5network5 \ - libqt5opengl5-dev \ - libqt5qml5 \ - libqt5quickcontrols2-5 \ - libqt5script5 \ - libqt5sql5-sqlite \ - libqt5sql5 \ - libqt5svg5-dev \ + qt6-tools-dev \ + qt6-base-dev-tools \ + qmake6 \ + qt6-base-dev \ + qt6-multimedia-dev \ + qt6-tools-dev-tools \ + qt6-l10n-tools \ + qt6-declarative-dev \ + libqt6svg6-dev \ + libqt6core5compat6-dev \ + libqt6gui6t64 \ + libqt6multimedia6 \ + libqt6network6t64 \ + libqt6qml6 \ + libqt6quickcontrols2-6 \ + qt6-image-formats-plugins \ + libqt6sql6 \ + libqt6sql6-sqlite \ + libpoppler-qt6-dev \ libsqlite3-dev \ + libbz2-dev \ + libglu1-mesa-dev \ + liblzma-dev \ make \ - 7zip \ - 7zip-rar \ - qtchooser \ - qtbase5-dev-tools \ - qt5-qmake \ - qtbase5-dev \ - qtmultimedia5-dev \ - qt5-image-formats-plugins \ - qtdeclarative5-dev \ - qtquickcontrols2-5-dev \ - qtscript5-dev \ - qttools5-dev-tools \ sqlite3 \ unzip \ - wget && \ + wget \ + 7zip \ + 7zip-rar \ + zlib1g-dev && \ ldconfig # clone YACReader repo @@ -62,7 +61,7 @@ RUN cd /src/git/compressed_archive && \ # build yacreaderlibraryserver RUN cd /src/git/YACReaderLibraryServer && \ - qmake PREFIX=/app CONFIG+="7zip server_standalone" YACReaderLibraryServer.pro && \ + qmake6 PREFIX=/app CONFIG+="7zip server_standalone" YACReaderLibraryServer.pro && \ make && \ make install @@ -72,7 +71,7 @@ RUN echo "Building and installing 7z.so with RAR support..." && \ make -f makefile.gcc && \ mkdir -p /app/lib/7zip && \ cp ./_o/7z.so /app/lib/7zip - + FROM ghcr.io/linuxserver/baseimage-ubuntu:arm64v8-noble # env variables @@ -82,19 +81,15 @@ LABEL maintainer="luisangelsm" # Copy the built application from the builder stage COPY --from=builder /app /app - + # runtime packages RUN apt-get update && \ apt-get install -y --no-install-recommends \ - libqt5core5a \ - libqt5network5 \ - libqt5script5 \ - libqt5sql5-sqlite \ - libqt5sql5 \ - libqt5svg5 \ - libsqlite3-0 \ - libpoppler-qt5-1 \ - qt5-image-formats-plugins && \ + libqt6core5compat6 \ + libpoppler-qt6-3t64 \ + qt6-image-formats-plugins \ + libqt6network6t64 \ + libqt6sql6-sqlite && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* From 2450c9497249fe959f49e29c803811c7b042beb5 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 21 Feb 2026 08:55:47 +0100 Subject: [PATCH 080/187] Publish YACReader 10 as a pre-release to make testing easier --- .github/workflows/build.yml | 113 ++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8f4bcff7c..7935900c7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,6 +5,7 @@ on: branches: - master - develop + - yacreader10 pull_request: branches: - master @@ -741,3 +742,115 @@ jobs: files: staging/* env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Publish yacreader10 pre-release builds + publish-yacreader10-builds: + name: Publish YACReader10 Pre-release Builds + if: github.repository == 'YACReader/yacreader' && github.ref == 'refs/heads/yacreader10' + runs-on: ubuntu-24.04 + needs: + - initialization + - linux-qt6 + - linux-qt6-7zip + - macos-qt6-universal + - windows-x64-qt6 + - windows-arm64-qt6 + - docker-amd64 + - docker-arm64 + steps: + - uses: actions/checkout@v4 + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: List downloaded artifacts + run: | + echo "=== All artifacts downloaded ===" + ls -lR artifacts/ + echo "" + echo "=== Windows artifacts only ===" + ls -l artifacts/windows-*/ + + - name: Flatten artifacts (exclude unsigned Windows installers) + run: | + mkdir -p staging + # Copy all files except those from unsigned Windows artifact directories + find artifacts -type f ! -path "*/windows-*-unsigned-*/*" -exec cp {} staging/ \; + echo "" + echo "=== Files copied to staging ===" + ls -lh staging/ + echo "" + echo "=== Windows installers in staging ===" + ls -lh staging/YACReader*.exe || echo "No Windows installers found" + + - name: Verify Windows installer signatures + run: | + echo "=== Installing osslsigncode to verify signatures ===" + sudo apt-get update + sudo apt-get install -y osslsigncode + + echo "" + echo "=== Checking signatures on Windows installers ===" + for installer in staging/YACReader*.exe; do + if [ -f "$installer" ]; then + echo "Checking: $(basename $installer)" + echo "File size: $(stat -c%s $installer) bytes" + + # Try to extract signature info + if osslsigncode verify -in "$installer" 2>&1 | grep -q "Signature verification: ok"; then + echo " ✓ SIGNED - Signature verified successfully" + osslsigncode verify -in "$installer" 2>&1 | grep -E "(Signed|Signer|Timestamp)" + else + echo " ✗ UNSIGNED or INVALID - No valid signature found (expected for yacreader10 pre-releases)" + osslsigncode verify -in "$installer" 2>&1 | head -20 + fi + echo "" + fi + done + + echo "=== Summary ===" + echo "Total installers in staging: $(ls staging/YACReader*.exe 2>/dev/null | wc -l)" + + - name: Get version + id: version + run: | + VERSION="$(cat common/yacreader_global.h | grep '#define VERSION "' | tr -d '#define VERSION' | tr -d '"' ).${{ needs.initialization.outputs.build_number }}" + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Version: $VERSION" + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Push Docker Images + run: | + for arch in amd64 arm64; do + docker load -i staging/${arch}.tar + docker tag yacreader/yacreaderlibraryserver:develop-${arch} yacreader/yacreaderlibraryserver:develop-yacreader10-${arch} + docker push yacreader/yacreaderlibraryserver:develop-yacreader10-${arch} + rm staging/${arch}.tar + done + + docker buildx imagetools create \ + -t yacreader/yacreaderlibraryserver:develop-yacreader10 \ + yacreader/yacreaderlibraryserver:develop-yacreader10-amd64 \ + yacreader/yacreaderlibraryserver:develop-yacreader10-arm64 + + - name: Create GitHub Release + uses: softprops/action-gh-release@v1 + with: + repository: YACReader/yacreader-dev-builds + tag_name: ${{ steps.version.outputs.version }} + name: ${{ steps.version.outputs.version }} + prerelease: true + target_commitish: 25313e3d4d03fcbe44d3943db23bc03bbd1a5205 + files: staging/* + env: + GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }} From adfa0587425a829e3bbb93da3b9cc0f76745fb99 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 22 Feb 2026 19:28:37 +0100 Subject: [PATCH 081/187] Implement continuous scrolling --- YACReader/YACReader.pro | 2 + YACReader/configuration.h | 2 + YACReader/continuous_page_widget.cpp | 393 ++++++++++++++++++ YACReader/continuous_page_widget.h | 86 ++++ YACReader/main.cpp | 2 +- YACReader/main_window_viewer.cpp | 50 ++- YACReader/main_window_viewer.h | 1 + YACReader/render.cpp | 13 + YACReader/render.h | 2 + YACReader/themes/theme.h | 2 + YACReader/themes/theme_factory.cpp | 1 + YACReader/viewer.cpp | 290 ++++++++++++- YACReader/viewer.h | 14 + YACReader/yacreader_images.qrc | 2 + common/yacreader_global_gui.h | 1 + images/viewer_toolbar/toContinuousScroll.svg | 13 + .../toContinuousScroll_18x18.svg | 13 + 17 files changed, 848 insertions(+), 39 deletions(-) create mode 100644 YACReader/continuous_page_widget.cpp create mode 100644 YACReader/continuous_page_widget.h create mode 100644 images/viewer_toolbar/toContinuousScroll.svg create mode 100644 images/viewer_toolbar/toContinuousScroll_18x18.svg diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro index 06ef1432a..f2bdd8f09 100644 --- a/YACReader/YACReader.pro +++ b/YACReader/YACReader.pro @@ -62,6 +62,7 @@ HEADERS += ../common/comic.h \ goto_dialog.h \ magnifying_glass.h \ main_window_viewer.h \ + continuous_page_widget.h \ mouse_handler.h \ viewer.h \ options_dialog.h \ @@ -98,6 +99,7 @@ SOURCES += ../common/comic.cpp \ goto_dialog.cpp \ magnifying_glass.cpp \ main_window_viewer.cpp \ + continuous_page_widget.cpp \ mouse_handler.cpp \ viewer.cpp \ options_dialog.cpp \ diff --git a/YACReader/configuration.h b/YACReader/configuration.h index b70594bfd..23cc5348f 100644 --- a/YACReader/configuration.h +++ b/YACReader/configuration.h @@ -82,6 +82,8 @@ class Configuration : public QObject void setDoublePage(bool b) { settings->setValue(DOUBLE_PAGE, b); } bool getDoubleMangaPage() { return settings->value(DOUBLE_MANGA_PAGE).toBool(); } void setDoubleMangaPage(bool b) { settings->setValue(DOUBLE_MANGA_PAGE, b); } + bool getContinuousScroll() { return settings->value(CONTINUOUS_SCROLL, false).toBool(); } + void setContinuousScroll(bool b) { settings->setValue(CONTINUOUS_SCROLL, b); } bool getEnlargeImages() { return settings->value(ENLARGE_IMAGES, true).toBool(); } void setEnlargeImages(bool b) { settings->setValue(ENLARGE_IMAGES, b); } diff --git a/YACReader/continuous_page_widget.cpp b/YACReader/continuous_page_widget.cpp new file mode 100644 index 000000000..59a148aec --- /dev/null +++ b/YACReader/continuous_page_widget.cpp @@ -0,0 +1,393 @@ +#include "continuous_page_widget.h" +#include "render.h" + +#include +#include +#include +#include + +ContinuousPageWidget::ContinuousPageWidget(QWidget *parent) + : QWidget(parent) +{ + QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); + sp.setHeightForWidth(true); + setSizePolicy(sp); + setMouseTracking(true); + initTheme(this); +} + +void ContinuousPageWidget::applyTheme(const Theme &) +{ + update(); +} + +void ContinuousPageWidget::setRender(Render *r) +{ + render = r; +} + +void ContinuousPageWidget::setNumPages(int count) +{ + numPages = count; + defaultPageSize = QSize(800, 1200); + pageSizes.fill(QSize(0, 0), count); + relayout(false); +} + +void ContinuousPageWidget::setZoomFactor(int zoom) +{ + if (zoomFactor == zoom) { + return; + } + zoomFactor = zoom; + relayout(true); + update(); +} + +void ContinuousPageWidget::probeBufferedPages() +{ + if (!render || numPages == 0) { + return; + } + + bool changed = false; + for (int i = 0; i < numPages; ++i) { + const QImage *img = render->bufferedImage(i); + bool hasKnownSize = pageSizes[i].width() > 0 && pageSizes[i].height() > 0; + if (img && !img->isNull() && !hasKnownSize) { + pageSizes[i] = img->size(); + if (defaultPageSize == QSize(800, 1200)) { + defaultPageSize = img->size(); + } + changed = true; + } + } + + if (changed) { + relayout(true); + update(); + } +} + +void ContinuousPageWidget::reset() +{ + numPages = 0; + pageSizes.clear(); + yPositions.clear(); + currentTotalHeight = 0; + layoutSnapshot = LayoutSnapshot(); + defaultPageSize = QSize(800, 1200); + setMinimumHeight(0); + setMaximumHeight(QWIDGETSIZE_MAX); + updateGeometry(); + update(); +} + +int ContinuousPageWidget::centerPage(int scrollY, int viewportHeight) const +{ + const int centerY = scrollY + std::max(0, viewportHeight / 2); + return pageAtY(centerY); +} + +int ContinuousPageWidget::yPositionForPage(int pageIndex) const +{ + if (pageIndex < 0 || pageIndex >= yPositions.size()) { + return 0; + } + return yPositions[pageIndex]; +} + +int ContinuousPageWidget::totalHeight() const +{ + return currentTotalHeight; +} + +bool ContinuousPageWidget::hasHeightForWidth() const +{ + return true; +} + +int ContinuousPageWidget::heightForWidth(int w) const +{ + if (numPages == 0 || w <= 0) { + return 0; + } + + int h = 0; + for (int i = 0; i < numPages; ++i) { + QSize scaled = scaledPageSize(i, w); + h += scaled.height(); + } + return h; +} + +QSize ContinuousPageWidget::sizeHint() const +{ + return QSize(defaultPageSize.width(), currentTotalHeight > 0 ? currentTotalHeight : 0); +} + +void ContinuousPageWidget::onPageAvailable(int absolutePageIndex) +{ + if (!render || absolutePageIndex < 0 || absolutePageIndex >= numPages) { + return; + } + + const QImage *img = render->bufferedImage(absolutePageIndex); + if (!img || img->isNull()) { + return; + } + + QSize naturalSize = img->size(); + + // update default page size from the first real page we see + if (defaultPageSize == QSize(800, 1200) && !naturalSize.isNull()) { + defaultPageSize = naturalSize; + } + + bool sizeChanged = (pageSizes[absolutePageIndex] != naturalSize); + pageSizes[absolutePageIndex] = naturalSize; + + if (sizeChanged) { + // keep anchor page visually stable while refined page sizes arrive + relayout(true); + } + + // repaint the region where this page lives + if (absolutePageIndex < yPositions.size()) { + QSize scaled = scaledPageSize(absolutePageIndex, width()); + QRect pageRect(0, yPositions[absolutePageIndex], scaled.width(), scaled.height()); + update(pageRect); + } +} + +void ContinuousPageWidget::paintEvent(QPaintEvent *event) +{ + if (numPages == 0 || !render) { + return; + } + + QPainter painter(this); + + QRect visibleRect = event->rect(); + int firstPage = pageAtY(visibleRect.top()); + int lastPage = pageAtY(visibleRect.bottom()); + + int w = width(); + for (int i = firstPage; i <= lastPage && i < numPages; ++i) { + int y = yPositions[i]; + QSize scaled = scaledPageSize(i, w); + // center horizontally if page is narrower than widget + int x = (w - scaled.width()) / 2; + if (x < 0) { + x = 0; + } + QRect pageRect(x, y, scaled.width(), scaled.height()); + + const QImage *img = render->bufferedImage(i); + if (img && !img->isNull()) { + if (img->size() != scaled) { + painter.drawImage(pageRect, img->scaled(scaled, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + } else { + painter.drawImage(pageRect, *img); + } + } else { + // placeholder + painter.fillRect(pageRect, QColor(45, 45, 45)); + painter.setPen(theme.viewer.defaultTextColor); + painter.drawText(pageRect, Qt::AlignCenter, tr("Loading page %1").arg(i + 1)); + } + } +} + +void ContinuousPageWidget::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + relayout(true); +} + +void ContinuousPageWidget::setAnchorPage(int page) +{ + anchorPage = page; +} + +void ContinuousPageWidget::setViewportState(int scrollY, int viewportHeight) +{ + viewportScrollY = std::max(0, scrollY); + currentViewportHeight = std::max(0, viewportHeight); + hasViewportState = true; +} + +void ContinuousPageWidget::updateLayout() +{ + relayout(false); +} + +void ContinuousPageWidget::updateLayoutWithAnchor() +{ + relayout(true); +} + +void ContinuousPageWidget::relayout(bool preserveAnchor) +{ + int w = width(); + if (w <= 0) { + w = parentWidget() ? parentWidget()->width() : 0; + } + if (w <= 0) { + w = defaultPageSize.width(); + } + + const LayoutSnapshot oldSnapshot = layoutSnapshot; + + ViewportAnchor anchor; + if (preserveAnchor && hasViewportState && !oldSnapshot.yPositions.isEmpty()) { + anchor = anchorFromViewport(oldSnapshot, viewportScrollY, currentViewportHeight); + } else if (preserveAnchor && anchorPage >= 0) { + anchor.pageIndex = anchorPage; + anchor.offsetRatio = 0.5f; + anchor.valid = true; + } + + layoutSnapshot = buildLayoutSnapshot(w); + +#ifndef NDEBUG + Q_ASSERT(layoutSnapshot.yPositions.size() == numPages); + Q_ASSERT(layoutSnapshot.scaledSizes.size() == numPages); + for (int i = 0; i < layoutSnapshot.scaledSizes.size(); ++i) { + Q_ASSERT(layoutSnapshot.scaledSizes[i].width() > 0); + Q_ASSERT(layoutSnapshot.scaledSizes[i].height() > 0); + if (i > 0) { + Q_ASSERT(layoutSnapshot.yPositions[i] >= layoutSnapshot.yPositions[i - 1]); + } + } +#endif + + yPositions = layoutSnapshot.yPositions; + currentTotalHeight = layoutSnapshot.totalHeight; + + setFixedHeight(currentTotalHeight); + updateGeometry(); + + if (!preserveAnchor || !anchor.valid || currentViewportHeight <= 0) { + return; + } + + const int newScrollForAnchor = resolveAnchorToScrollY(layoutSnapshot, anchor, currentViewportHeight); + emit layoutScrollPositionRequested(newScrollForAnchor); +} + +ContinuousPageWidget::LayoutSnapshot ContinuousPageWidget::buildLayoutSnapshot(int w) const +{ + LayoutSnapshot snapshot; + + if (numPages <= 0 || w <= 0) { + return snapshot; + } + + snapshot.yPositions.resize(numPages); + snapshot.scaledSizes.resize(numPages); + + qint64 y = 0; + for (int i = 0; i < numPages; ++i) { + snapshot.yPositions[i] = static_cast(std::min(y, std::numeric_limits::max())); + QSize scaled = scaledPageSize(i, w); + scaled.setWidth(std::max(1, scaled.width())); + scaled.setHeight(std::max(1, scaled.height())); + snapshot.scaledSizes[i] = scaled; + y += scaled.height(); + } + + snapshot.totalHeight = static_cast(std::min(y, static_cast(QWIDGETSIZE_MAX))); + return snapshot; +} + +int ContinuousPageWidget::pageAtY(const LayoutSnapshot &snapshot, int y) const +{ + if (snapshot.yPositions.isEmpty()) { + return 0; + } + + auto it = std::upper_bound(snapshot.yPositions.constBegin(), snapshot.yPositions.constEnd(), y); + if (it == snapshot.yPositions.constBegin()) { + return 0; + } + --it; + return static_cast(it - snapshot.yPositions.constBegin()); +} + +ContinuousPageWidget::ViewportAnchor ContinuousPageWidget::anchorFromViewport(const LayoutSnapshot &snapshot, int scrollY, int viewportHeight) const +{ + ViewportAnchor anchor; + + if (snapshot.yPositions.isEmpty() || viewportHeight <= 0) { + return anchor; + } + + const int maxScroll = std::max(0, snapshot.totalHeight - viewportHeight); + const int clampedScroll = qBound(0, scrollY, maxScroll); + const int anchorY = clampedScroll + viewportHeight / 2; + const int page = pageAtY(snapshot, anchorY); + + if (page < 0 || page >= snapshot.scaledSizes.size()) { + return anchor; + } + + const int pageTop = snapshot.yPositions[page]; + const int pageHeight = std::max(1, snapshot.scaledSizes[page].height()); + const float ratio = static_cast(anchorY - pageTop) / static_cast(pageHeight); + + anchor.pageIndex = page; + anchor.offsetRatio = qBound(0.0f, ratio, 1.0f); + anchor.valid = true; + return anchor; +} + +int ContinuousPageWidget::resolveAnchorToScrollY(const LayoutSnapshot &snapshot, const ViewportAnchor &anchor, int viewportHeight) const +{ + if (!anchor.valid || viewportHeight <= 0 || snapshot.yPositions.isEmpty()) { + return 0; + } + + if (anchor.pageIndex < 0 || anchor.pageIndex >= snapshot.yPositions.size() || anchor.pageIndex >= snapshot.scaledSizes.size()) { + return 0; + } + + const int pageTop = snapshot.yPositions[anchor.pageIndex]; + const int pageHeight = std::max(1, snapshot.scaledSizes[anchor.pageIndex].height()); + const int anchorY = pageTop + qRound(anchor.offsetRatio * pageHeight); + const int maxScroll = std::max(0, snapshot.totalHeight - viewportHeight); + const int target = anchorY - viewportHeight / 2; + return qBound(0, target, maxScroll); +} + +int ContinuousPageWidget::pageAtY(int y) const +{ + return pageAtY(layoutSnapshot, y); +} + +QSize ContinuousPageWidget::scaledPageSize(int pageIndex, int forWidth) const +{ + QSize natural = (pageIndex < pageSizes.size() && pageSizes[pageIndex].width() > 0 && pageSizes[pageIndex].height() > 0) + ? pageSizes[pageIndex] + : defaultPageSize; + + float scale = scaleForPage(pageIndex, forWidth); + int scaledW = std::max(1, qRound(natural.width() * scale)); + int scaledH = std::max(1, qRound(natural.height() * scale)); + return QSize(scaledW, scaledH); +} + +float ContinuousPageWidget::scaleForPage(int pageIndex, int forWidth) const +{ + QSize natural = (pageIndex < pageSizes.size() && pageSizes[pageIndex].width() > 0 && pageSizes[pageIndex].height() > 0) + ? pageSizes[pageIndex] + : defaultPageSize; + + if (natural.width() <= 0 || forWidth <= 0) { + return 1.0f; + } + + float baseScale = static_cast(forWidth) / natural.width(); + float zoomMultiplier = zoomFactor / 100.0f; + return baseScale * zoomMultiplier; +} diff --git a/YACReader/continuous_page_widget.h b/YACReader/continuous_page_widget.h new file mode 100644 index 000000000..55393a5b9 --- /dev/null +++ b/YACReader/continuous_page_widget.h @@ -0,0 +1,86 @@ +#ifndef CONTINUOUS_PAGE_WIDGET_H +#define CONTINUOUS_PAGE_WIDGET_H + +#include +#include +#include + +#include "themable.h" + +class Render; + +class ContinuousPageWidget : public QWidget, protected Themable +{ + Q_OBJECT +public: + explicit ContinuousPageWidget(QWidget *parent = nullptr); + + void setRender(Render *r); + void setNumPages(int count); + void setZoomFactor(int zoom); + void probeBufferedPages(); + void reset(); + + int centerPage(int scrollY, int viewportHeight) const; + int yPositionForPage(int pageIndex) const; + int totalHeight() const; + + bool hasHeightForWidth() const override; + int heightForWidth(int w) const override; + QSize sizeHint() const override; + + void setAnchorPage(int page); + void setViewportState(int scrollY, int viewportHeight); + +signals: + // emitted after layout recomputation when the preserved viewport anchor + // resolves to an absolute scroll position + void layoutScrollPositionRequested(int scrollY); + +public slots: + void onPageAvailable(int absolutePageIndex); + +protected: + void paintEvent(QPaintEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void applyTheme(const Theme &theme) override; + +private: + struct LayoutSnapshot { + QVector yPositions; + QVector scaledSizes; + int totalHeight = 0; + }; + + struct ViewportAnchor { + int pageIndex = -1; + float offsetRatio = 0.0f; + bool valid = false; + }; + + void updateLayout(); + void updateLayoutWithAnchor(); + void relayout(bool preserveAnchor); + LayoutSnapshot buildLayoutSnapshot(int w) const; + int pageAtY(const LayoutSnapshot &snapshot, int y) const; + ViewportAnchor anchorFromViewport(const LayoutSnapshot &snapshot, int scrollY, int viewportHeight) const; + int resolveAnchorToScrollY(const LayoutSnapshot &snapshot, const ViewportAnchor &anchor, int viewportHeight) const; + int pageAtY(int y) const; + QSize scaledPageSize(int pageIndex, int forWidth) const; + float scaleForPage(int pageIndex, int forWidth) const; + + Render *render = nullptr; + int numPages = 0; + QVector pageSizes; + QVector yPositions; + int currentTotalHeight = 0; + LayoutSnapshot layoutSnapshot; + QSize defaultPageSize { 800, 1200 }; + int zoomFactor = 100; + int anchorPage = -1; + int viewportScrollY = 0; + int currentViewportHeight = 0; + bool hasViewportState = false; +}; + +#endif // CONTINUOUS_PAGE_WIDGET_H diff --git a/YACReader/main.cpp b/YACReader/main.cpp index 813674cff..e71f6791b 100644 --- a/YACReader/main.cpp +++ b/YACReader/main.cpp @@ -144,7 +144,7 @@ int main(int argc, char *argv[]) QDir().mkpath(YACReader::getSettingsPath()); Logger &logger = Logger::instance(); - logger.setLoggingLevel(QsLogging::InfoLevel); + logger.setLoggingLevel(QsLogging::TraceLevel); if (parser.isSet("loglevel")) { if (parser.value("loglevel") == "trace") { diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 2018b25f4..449c198f9 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -77,6 +77,7 @@ MainWindowViewer::~MainWindowViewer() delete rightRotationAction; delete doublePageAction; delete doubleMangaPageAction; + delete continuousScrollAction; delete increasePageZoomAction; delete decreasePageZoomAction; delete resetZoomAction; @@ -309,28 +310,38 @@ void MainWindowViewer::createActions() fitToPageAction->setCheckable(true); connect(fitToPageAction, &QAction::triggered, this, &MainWindowViewer::fitToPageSwitch); + continuousScrollAction = new QAction(tr("Continuous scroll"), this); + continuousScrollAction->setToolTip(tr("Switch to continuous scroll mode")); + continuousScrollAction->setIcon(QIcon(":/images/viewer_toolbar/toContinuousScroll.svg")); + continuousScrollAction->setCheckable(true); + continuousScrollAction->setChecked(Configuration::getConfiguration().getContinuousScroll()); + connect(continuousScrollAction, &QAction::toggled, viewer, &Viewer::setContinuousScroll); + // fit modes have to be exclusive and checkable auto fitModes = new QActionGroup(this); fitModes->addAction(adjustHeightAction); fitModes->addAction(adjustWidthAction); fitModes->addAction(adjustToFullSizeAction); fitModes->addAction(fitToPageAction); + fitModes->addAction(continuousScrollAction); - switch (Configuration::getConfiguration().getFitMode()) { - case YACReader::FitMode::ToWidth: - adjustWidthAction->setChecked(true); - break; - case YACReader::FitMode::ToHeight: - adjustHeightAction->setChecked(true); - break; - case YACReader::FitMode::FullRes: - adjustToFullSizeAction->setChecked(true); - break; - case YACReader::FitMode::FullPage: - fitToPageAction->setChecked(true); - break; - default: - fitToPageAction->setChecked(true); + if (Configuration::getConfiguration().getContinuousScroll()) { + continuousScrollAction->setChecked(true); + } else { + switch (Configuration::getConfiguration().getFitMode()) { + case YACReader::FitMode::ToWidth: + adjustWidthAction->setChecked(true); + break; + case YACReader::FitMode::ToHeight: + adjustHeightAction->setChecked(true); + break; + case YACReader::FitMode::FullRes: + adjustToFullSizeAction->setChecked(true); + break; + case YACReader::FitMode::FullPage: + default: + fitToPageAction->setChecked(true); + } } resetZoomAction = new QAction(tr("Reset zoom"), this); @@ -536,11 +547,14 @@ void MainWindowViewer::createToolBars() auto fitToPageTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/fitToPage")), fitToPageAction); comicToolBar->addAction(fitToPageTBAction); + auto continuousScroollTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/toContinuousScroll")), continuousScrollAction); + auto fitModes = new QActionGroup(this); fitModes->addAction(adjustToWidthTBAction); fitModes->addAction(adjustToHeightTBAction); fitModes->addAction(adjustToFullSizeTBAction); fitModes->addAction(fitToPageTBAction); + fitModes->addAction(continuousScroollTBAction); zoomSliderAction = new YACReaderSlider(this); zoomSliderAction->hide(); @@ -555,6 +569,7 @@ void MainWindowViewer::createToolBars() comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/rotateR")), rightRotationAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/doublePage")), doublePageAction)); comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/doubleMangaPage")), doubleMangaPageAction)); + comicToolBar->addAction(continuousScroollTBAction); comicToolBar->addSeparator(); @@ -603,6 +618,7 @@ void MainWindowViewer::createToolBars() viewer->addAction(rightRotationAction); viewer->addAction(doublePageAction); viewer->addAction(doubleMangaPageAction); + viewer->addAction(continuousScrollAction); YACReader::addSperator(viewer); viewer->addAction(showMagnifyingGlassAction); @@ -675,6 +691,7 @@ void MainWindowViewer::createToolBars() viewMenu->addSeparator(); viewMenu->addAction(doublePageAction); viewMenu->addAction(doubleMangaPageAction); + viewMenu->addAction(continuousScrollAction); viewMenu->addSeparator(); viewMenu->addAction(showMagnifyingGlassAction); @@ -1247,6 +1264,7 @@ void MainWindowViewer::setUpShortcutsManagement() << rightRotationAction << doublePageAction << doubleMangaPageAction + << continuousScrollAction << adjustToFullSizeAction << fitToPageAction << increasePageZoomAction @@ -1540,6 +1558,7 @@ void MainWindowViewer::setActionsEnabled(bool enabled) showMagnifyingGlassAction, doublePageAction, doubleMangaPageAction, + continuousScrollAction, adjustToFullSizeAction, fitToPageAction, showZoomSliderlAction, @@ -1613,6 +1632,7 @@ void MainWindowViewer::applyTheme(const Theme &theme) setIcon(showDictionaryAction, toolbarTheme.showDictionaryAction, toolbarTheme.showDictionaryAction18x18); setIcon(adjustToFullSizeAction, toolbarTheme.adjustToFullSizeAction, toolbarTheme.adjustToFullSizeAction18x18); setIcon(fitToPageAction, toolbarTheme.fitToPageAction, toolbarTheme.fitToPageAction18x18); + setIcon(continuousScrollAction, toolbarTheme.continuousScrollAction, toolbarTheme.continuousScrollAction18x18); setIcon(showFlowAction, toolbarTheme.showFlowAction, toolbarTheme.showFlowAction18x18); } diff --git a/YACReader/main_window_viewer.h b/YACReader/main_window_viewer.h index f480ef28c..561c54c88 100644 --- a/YACReader/main_window_viewer.h +++ b/YACReader/main_window_viewer.h @@ -140,6 +140,7 @@ public slots: QAction *closeAction; QAction *doublePageAction; QAction *doubleMangaPageAction; + QAction *continuousScrollAction; QAction *showShorcutsAction; QAction *showDictionaryAction; QAction *adjustToFullSizeAction; diff --git a/YACReader/render.cpp b/YACReader/render.cpp index fee12b11d..595df27c4 100644 --- a/YACReader/render.cpp +++ b/YACReader/render.cpp @@ -546,6 +546,17 @@ QPixmap *Render::getCurrentDoubleMangaPage() } } +const QImage *Render::bufferedImage(int absolutePageIndex) const +{ + int offset = absolutePageIndex - currentIndex; + int pos = currentPageBufferedIndex + offset; + if (pos < 0 || pos >= buffer.size()) { + return nullptr; + } + const QImage *img = buffer[pos]; + return (img && !img->isNull()) ? img : nullptr; +} + bool Render::currentPageIsDoublePage() { if (currentIndex == 0 && Configuration::getConfiguration().getSettings()->value(COVER_IS_SP, true).toBool()) { @@ -627,6 +638,8 @@ void Render::setComic(Comic *c) void Render::prepareAvailablePage(int page) { + emit pageRendered(page); + if (!doublePage) { if (currentIndex == page) { emit currentPageReady(); diff --git a/YACReader/render.h b/YACReader/render.h index bfeb81aff..25ad71663 100644 --- a/YACReader/render.h +++ b/YACReader/render.h @@ -142,6 +142,7 @@ public slots: bool currentPageIsDoublePage(); bool nextPageIsDoublePage(); bool previousPageIsDoublePage(); + const QImage *bufferedImage(int absolutePageIndex) const; void goTo(int index); void doublePageSwitch(); void setManga(bool manga); @@ -197,6 +198,7 @@ public slots: void isLast(); void isCover(); + void pageRendered(int absolutePageIndex); void bookmarksUpdated(); private: diff --git a/YACReader/themes/theme.h b/YACReader/themes/theme.h index 509942093..2cc5e8cf8 100644 --- a/YACReader/themes/theme.h +++ b/YACReader/themes/theme.h @@ -102,6 +102,8 @@ struct ToolbarTheme { QIcon adjustToFullSizeAction18x18; QIcon fitToPageAction; QIcon fitToPageAction18x18; + QIcon continuousScrollAction; + QIcon continuousScrollAction18x18; QIcon showFlowAction; QIcon showFlowAction18x18; }; diff --git a/YACReader/themes/theme_factory.cpp b/YACReader/themes/theme_factory.cpp index 7fd7d1f76..d798a5a43 100644 --- a/YACReader/themes/theme_factory.cpp +++ b/YACReader/themes/theme_factory.cpp @@ -139,6 +139,7 @@ Theme makeTheme(const ThemeParams ¶ms) setToolbarIconPairT(theme.toolbar.showDictionaryAction, theme.toolbar.showDictionaryAction18x18, ":/images/viewer_toolbar/translator.svg"); setToolbarIconPairT(theme.toolbar.adjustToFullSizeAction, theme.toolbar.adjustToFullSizeAction18x18, ":/images/viewer_toolbar/full.svg"); setToolbarIconPairT(theme.toolbar.fitToPageAction, theme.toolbar.fitToPageAction18x18, ":/images/viewer_toolbar/fitToPage.svg"); + setToolbarIconPairT(theme.toolbar.continuousScrollAction, theme.toolbar.continuousScrollAction18x18, ":/images/viewer_toolbar/toContinuousScroll.svg"); setToolbarIconPairT(theme.toolbar.showFlowAction, theme.toolbar.showFlowAction18x18, ":/images/viewer_toolbar/flow.svg"); // end Toolbar & actions diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index 7187f77b0..32c9911be 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -1,4 +1,5 @@ #include "viewer.h" +#include "continuous_page_widget.h" #include "configuration.h" #include "magnifying_glass.h" #include "goto_flow_widget.h" @@ -23,6 +24,7 @@ Viewer::Viewer(QWidget *parent) information(false), doublePage(false), doubleMangaPage(false), + continuousScroll(false), zoom(100), currentPage(nullptr), wheelStop(false), @@ -40,15 +42,30 @@ Viewer::Viewer(QWidget *parent) translatorAnimation->setDuration(150); translatorXPos = -10000; translator->move(-translator->width(), 10); - // current comic page + // current comic page (used in non-continuous mode when a comic is open) content = new QLabel(this); - configureContent(tr("Press 'O' to open comic.")); + content->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + if (!(devicePixelRatioF() > 1)) + content->setScaledContents(true); + content->setAlignment(Qt::AlignTop | Qt::AlignHCenter); + content->setMouseTracking(true); - setWidget(content); + // dedicated widget for status messages ("Press 'O' to open comic.", "Loading...", etc.) + messageLabel = new QLabel(this); + messageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + messageLabel->setAlignment(Qt::AlignTop | Qt::AlignHCenter); + messageLabel->setText(tr("Press 'O' to open comic.")); + messageLabel->setFont(QFont("courier new", 12)); + messageLabel->setMouseTracking(true); + + setWidget(messageLabel); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setFrameStyle(QFrame::NoFrame); setAlignment(Qt::AlignCenter); + + continuousWidget = new ContinuousPageWidget(); + continuousWidget->installEventFilter(this); //--------------------------------------- mglass = new MagnifyingGlass( Configuration::getConfiguration().getMagnifyingGlassSize(), @@ -63,7 +80,6 @@ Viewer::Viewer(QWidget *parent) }); mglass->hide(); - content->setMouseTracking(true); setMouseTracking(true); showCursor(); @@ -81,6 +97,7 @@ Viewer::Viewer(QWidget *parent) bd = new BookmarksDialog(this->parentWidget()); render = new Render(); + continuousWidget->setRender(render); hideCursorTimer = new QTimer(); hideCursorTimer->setSingleShot(true); @@ -91,6 +108,9 @@ Viewer::Viewer(QWidget *parent) if (Configuration::getConfiguration().getDoubleMangaPage()) doubleMangaPageSwitch(); + if (Configuration::getConfiguration().getContinuousScroll()) + setContinuousScroll(true); + createConnections(); hideCursorTimer->start(2500); @@ -122,7 +142,17 @@ Viewer::~Viewer() delete goToFlow; delete translator; delete translatorAnimation; - delete content; + // messageLabel, content or continuousWidget may not be owned by the scroll area + // (after takeWidget), so delete whichever ones are not currently set + if (widget() != messageLabel) { + delete messageLabel; + } + if (widget() != content) { + delete content; + } + if (widget() != continuousWidget) { + delete continuousWidget; + } delete hideCursorTimer; delete informationLabel; delete verticalScroller; @@ -173,9 +203,14 @@ void Viewer::createConnections() connect(render, qOverload(&Render::numPages), this, &Viewer::comicLoaded); connect(render, QOverload::of(&Render::imageLoaded), goToFlow, &GoToFlowWidget::setImageReady); connect(render, &Render::currentPageReady, this, &Viewer::updatePage); + connect(render, &Render::pageRendered, continuousWidget, &ContinuousPageWidget::onPageAvailable); + connect(continuousWidget, &ContinuousPageWidget::layoutScrollPositionRequested, this, &Viewer::onContinuousLayoutScrollRequested); + connect(render, qOverload(&Render::numPages), this, &Viewer::onNumPagesReady); + connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &Viewer::onContinuousScroll); connect(render, &Render::processingPage, this, &Viewer::setLoadingMessage); connect(render, &Render::currentPageIsBookmark, this, &Viewer::pageIsBookmark); connect(render, &Render::pageChanged, this, &Viewer::updateInformation); + connect(render, &Render::pageChanged, this, &Viewer::onRenderPageChanged); connect(render, &Render::isLast, this, &Viewer::showIsLastMessage); connect(render, &Render::isCover, this, &Viewer::showIsCoverMessage); @@ -304,11 +339,26 @@ void Viewer::goToLastPage() void Viewer::goTo(unsigned int page) { direction = 1; // in "go to" direction is always fordward + + if (continuousScroll) { + lastCenterPage = page; + continuousWidget->setAnchorPage(page); + render->goTo(page); + scrollToCurrentContinuousPage(); + return; + } + render->goTo(page); } void Viewer::updatePage() { + if (continuousScroll) { + return; + } + + setActiveWidget(content); + QPixmap *previousPage = currentPage; if (doublePage) { if (!doubleMangaPage) @@ -397,7 +447,11 @@ void Viewer::increaseZoomFactor() { zoom = std::min(zoom + 10, 500); - updateContentSize(); + if (continuousScroll) { + continuousWidget->setZoomFactor(zoom); + } else { + updateContentSize(); + } notificationsLabel->setText(QString::number(getZoomFactor()) + "%"); notificationsLabel->flash(); @@ -407,7 +461,11 @@ void Viewer::decreaseZoomFactor() { zoom = std::max(zoom - 10, 30); - updateContentSize(); + if (continuousScroll) { + continuousWidget->setZoomFactor(zoom); + } else { + updateContentSize(); + } notificationsLabel->setText(QString::number(getZoomFactor()) + "%"); notificationsLabel->flash(); @@ -435,16 +493,22 @@ void Viewer::setZoomFactor(int z) void Viewer::updateVerticalScrollBar() { - if (direction > 0) + if (direction > 0) { verticalScrollBar()->setSliderPosition(verticalScrollBar()->minimum()); - else + } else { verticalScrollBar()->setSliderPosition(verticalScrollBar()->maximum()); + } } void Viewer::scrollDown() { if (verticalScrollBar()->sliderPosition() == verticalScrollBar()->maximum()) { - next(); + if (continuousScroll) { + shouldOpenNext = true; + emit openNextComic(); + } else { + next(); + } } else { int currentPos = verticalScrollBar()->sliderPosition(); verticalScroller->setDuration(animationDuration()); @@ -460,7 +524,12 @@ void Viewer::scrollDown() void Viewer::scrollUp() { if (verticalScrollBar()->sliderPosition() == verticalScrollBar()->minimum()) { - prev(); + if (continuousScroll) { + shouldOpenPrevious = true; + emit openPreviousComic(); + } else { + prev(); + } } else { int currentPos = verticalScrollBar()->sliderPosition(); verticalScroller->setDuration(animationDuration()); @@ -670,6 +739,11 @@ void Viewer::wheelEventMouse(QWheelEvent *event) return; } + if (continuousScroll) { + animateScroll(*verticalScroller, *verticalScrollBar(), delta.y()); + return; + } + auto turnPageOnScroll = !Configuration::getConfiguration().getDoNotTurnPageOnScroll(); auto getUseSingleScrollStepToTurnPage = Configuration::getConfiguration().getUseSingleScrollStepToTurnPage(); @@ -718,6 +792,10 @@ void Viewer::wheelEventTrackpad(QWheelEvent *event) verticalScrollBar()->setValue(newVerticalValue); } + if (continuousScroll) { + return; + } + auto turnPageOnScroll = !Configuration::getConfiguration().getDoNotTurnPageOnScroll(); auto getUseSingleScrollStepToTurnPage = Configuration::getConfiguration().getUseSingleScrollStepToTurnPage(); @@ -750,11 +828,16 @@ void Viewer::wheelEventTrackpad(QWheelEvent *event) void Viewer::resizeEvent(QResizeEvent *event) { + QScrollArea::resizeEvent(event); + + if (continuousScroll) { + continuousWidget->setViewportState(verticalScrollBar()->value(), viewport()->height()); + } + updateContentSize(); goToFlow->updateSize(); goToFlow->move((width() - goToFlow->width()) / 2, height() - goToFlow->height()); informationLabel->updatePosition(); - QScrollArea::resizeEvent(event); } QPixmap Viewer::pixmap() const @@ -927,6 +1010,132 @@ void Viewer::doublePageSwitch() Configuration::getConfiguration().setDoublePage(doublePage); } +void Viewer::setContinuousScroll(bool enabled) +{ + if (continuousScroll == enabled) { + return; + } + continuousScroll = enabled; + Configuration::getConfiguration().setContinuousScroll(continuousScroll); + + if (continuousScroll) { + continuousWidget->setZoomFactor(zoom); + if (render->hasLoadedComic()) { + continuousWidget->setViewportState(verticalScrollBar()->value(), viewport()->height()); + continuousWidget->setNumPages(render->numPages()); + // set the current page as model state before any layout/scroll happens + lastCenterPage = render->getIndex(); + continuousWidget->setAnchorPage(lastCenterPage); + // pick up sizes of pages already in the buffer + continuousWidget->probeBufferedPages(); + // trigger a render cycle so new pages arrive via pageRendered signal + render->update(); + setActiveWidget(continuousWidget); + scrollToCurrentContinuousPage(); + continuousWidget->update(); + viewport()->update(); + } + // if no comic is loaded, messageLabel stays as the active widget + } else { + lastCenterPage = -1; + if (render->hasLoadedComic()) { + updatePage(); + } + // if no comic is loaded, messageLabel stays as the active widget + } +} + +void Viewer::onContinuousScroll(int value) +{ + if (!continuousScroll || !render->hasLoadedComic()) { + return; + } + + continuousWidget->setViewportState(value, viewport()->height()); + + int center = continuousWidget->centerPage(value, viewport()->height()); + + if (center != lastCenterPage && center >= 0) { + lastCenterPage = center; + continuousWidget->setAnchorPage(center); + syncingRenderFromContinuousScroll = true; + render->goTo(center); + syncingRenderFromContinuousScroll = false; + emit pageAvailable(true); + } +} + +void Viewer::onContinuousLayoutScrollRequested(int scrollY) +{ + if (!continuousScroll) { + return; + } + + auto *sb = verticalScrollBar(); + const int target = qBound(sb->minimum(), scrollY, sb->maximum()); + + sb->blockSignals(true); + sb->setValue(target); + sb->blockSignals(false); + + continuousWidget->setViewportState(target, viewport()->height()); +} + +void Viewer::scrollToCurrentContinuousPage() +{ + if (lastCenterPage < 0) { + return; + } + + auto applyPosition = [this]() { + auto *sb = verticalScrollBar(); + int targetY = continuousWidget->yPositionForPage(lastCenterPage); + targetY = qBound(sb->minimum(), targetY, sb->maximum()); + + sb->blockSignals(true); + sb->setValue(targetY); + sb->blockSignals(false); + + continuousWidget->setViewportState(targetY, viewport()->height()); + + continuousWidget->update(); + viewport()->update(); + }; + + applyPosition(); +} + +void Viewer::onNumPagesReady(unsigned int numPages) +{ + if (continuousScroll && numPages > 0) { + setActiveWidget(continuousWidget); + + continuousWidget->setViewportState(verticalScrollBar()->value(), viewport()->height()); + continuousWidget->setNumPages(numPages); + + int page = lastCenterPage; + if (page < 0) { + page = render->getIndex(); + } + page = qBound(0, page, static_cast(numPages) - 1); + lastCenterPage = page; + continuousWidget->setAnchorPage(page); + + scrollToCurrentContinuousPage(); + } +} + +void Viewer::onRenderPageChanged(int page) +{ + if (!continuousScroll || page < 0 || page == lastCenterPage || syncingRenderFromContinuousScroll) { + return; + } + + lastCenterPage = page; + continuousWidget->setAnchorPage(page); + scrollToCurrentContinuousPage(); +} + void Viewer::setMangaWithoutStoringSetting(bool manga) { doubleMangaPage = manga; @@ -948,6 +1157,8 @@ void Viewer::resetContent() { configureContent(tr("Press 'O' to open comic.")); goToFlow->reset(); + continuousWidget->reset(); + lastCenterPage = -1; emit reset(); } @@ -958,7 +1169,9 @@ void Viewer::setLoadingMessage() restoreMagnifyingGlass = true; } emit pageAvailable(false); - configureContent(tr("Loading...please wait!")); + if (!continuousScroll) { + configureContent(tr("Loading...please wait!")); + } } void Viewer::setPageUnavailableMessage() @@ -973,15 +1186,9 @@ void Viewer::setPageUnavailableMessage() void Viewer::configureContent(QString msg) { - content->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); - if (!(devicePixelRatioF() > 1)) - content->setScaledContents(true); - content->setAlignment(Qt::AlignTop | Qt::AlignHCenter); - content->setText(msg); - content->setFont(QFont("courier new", 12)); - content->adjustSize(); + messageLabel->setText(msg); + setActiveWidget(messageLabel); setFocus(Qt::ShortcutFocusReason); - // emit showingText(); } void Viewer::hideCursor() @@ -1022,7 +1229,8 @@ void Viewer::applyTheme(const Theme &theme) updateBackgroundColor(Configuration::getConfiguration().getBackgroundColor(viewerTheme.defaultBackgroundColor)); const QString textColor = viewerTheme.defaultTextColor.name(QColor::HexArgb); - content->setStyleSheet(QStringLiteral("QLabel { color : %1; background: transparent; }").arg(textColor)); + messageLabel->setStyleSheet(QStringLiteral("QLabel { color : %1; background: transparent; }").arg(textColor)); + content->setStyleSheet(QStringLiteral("QLabel { background: transparent; }")); } void Viewer::animateShowTranslator() @@ -1072,10 +1280,46 @@ void Viewer::mouseMoveEvent(QMouseEvent *event) mouseHandler->mouseMoveEvent(event); } +bool Viewer::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == continuousWidget && event->type() == QEvent::MouseMove) { + auto *mouseEvent = static_cast(event); + // Map position from continuousWidget coords to Viewer coords so the + // go-to-flow proximity check and cursor management work correctly. + QPointF viewerPos = mapFromGlobal(mouseEvent->globalPosition().toPoint()); + QMouseEvent mappedEvent(mouseEvent->type(), + viewerPos, + mouseEvent->globalPosition(), + mouseEvent->button(), + mouseEvent->buttons(), + mouseEvent->modifiers()); + mouseHandler->mouseMoveEvent(&mappedEvent); + } + return QScrollArea::eventFilter(obj, event); +} + +void Viewer::setActiveWidget(QWidget *w) +{ + if (widget() == w) { + return; + } + verticalScrollBar()->blockSignals(true); + takeWidget(); + const bool isContinuous = (w == continuousWidget); + setWidgetResizable(isContinuous); + setVerticalScrollBarPolicy(isContinuous ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff); + setWidget(w); + verticalScrollBar()->blockSignals(false); +} + void Viewer::updateZoomRatio(int ratio) { zoom = ratio; - updateContentSize(); + if (continuousScroll) { + continuousWidget->setZoomFactor(zoom); + } else { + updateContentSize(); + } } bool Viewer::getIsMangaMode() diff --git a/YACReader/viewer.h b/YACReader/viewer.h index 0684e501e..d5b852f56 100644 --- a/YACReader/viewer.h +++ b/YACReader/viewer.h @@ -30,6 +30,7 @@ class GoToDialog; class YACReaderTranslator; class GoToFlowWidget; class Bookmarks; +class ContinuousPageWidget; class PageLabelWidget; class NotificationsLabelWidget; @@ -113,11 +114,13 @@ public slots: int getCurrentPageNumber(); void updateZoomRatio(int ratio); bool getIsMangaMode(); + void setContinuousScroll(bool enabled); private: bool information; bool doublePage; bool doubleMangaPage; + bool continuousScroll; int zoom; @@ -144,6 +147,10 @@ public slots: //! Widgets QLabel *content; + QLabel *messageLabel; + ContinuousPageWidget *continuousWidget; + int lastCenterPage = -1; + bool syncingRenderFromContinuousScroll = false; YACReaderTranslator *translator; int translatorXPos; @@ -183,12 +190,19 @@ public slots: // Zero when animations are disabled int animationDuration() const; void animateScroll(QPropertyAnimation &scroller, const QScrollBar &scrollBar, int delta); + void onContinuousScroll(int value); + void onContinuousLayoutScrollRequested(int scrollY); + void scrollToCurrentContinuousPage(); + void onNumPagesReady(unsigned int numPages); + void onRenderPageChanged(int page); + void setActiveWidget(QWidget *w); //! Mouse handler std::unique_ptr mouseHandler; protected: void applyTheme(const Theme &theme) override; + bool eventFilter(QObject *obj, QEvent *event) override; public: Viewer(QWidget *parent = nullptr); diff --git a/YACReader/yacreader_images.qrc b/YACReader/yacreader_images.qrc index ed7b9a8e2..df996b67c 100644 --- a/YACReader/yacreader_images.qrc +++ b/YACReader/yacreader_images.qrc @@ -55,6 +55,7 @@ ../images/viewer_toolbar/shortcuts.svg ../images/viewer_toolbar/showBookmarks.svg ../images/viewer_toolbar/toHeight.svg + ../images/viewer_toolbar/toContinuousScroll.svg ../images/viewer_toolbar/toWidth.svg ../images/viewer_toolbar/translator.svg ../images/viewer_toolbar/zoom.svg @@ -82,6 +83,7 @@ ../images/viewer_toolbar/shortcuts_18x18.svg ../images/viewer_toolbar/showBookmarks_18x18.svg ../images/viewer_toolbar/toHeight_18x18.svg + ../images/viewer_toolbar/toContinuousScroll_18x18.svg ../images/viewer_toolbar/toWidth_18x18.svg ../images/viewer_toolbar/translator_18x18.svg ../images/viewer_toolbar/zoom_18x18.svg diff --git a/common/yacreader_global_gui.h b/common/yacreader_global_gui.h index 7f25ad993..2738e3462 100644 --- a/common/yacreader_global_gui.h +++ b/common/yacreader_global_gui.h @@ -23,6 +23,7 @@ #define START_TO_TRAY "START_TO_TRAY" #define DOUBLE_PAGE "DOUBLE_PAGE" #define DOUBLE_MANGA_PAGE "DOUBLE_MANGA_PAGE" +#define CONTINUOUS_SCROLL "CONTINUOUS_SCROLL" #define COVER_IS_SP "COVER_IS_SP" #define BACKGROUND_COLOR "BACKGROUND_COLOR_10" #define SHOW_TOOLBARS "SHOW_TOOLBARS" diff --git a/images/viewer_toolbar/toContinuousScroll.svg b/images/viewer_toolbar/toContinuousScroll.svg new file mode 100644 index 000000000..17ded9c24 --- /dev/null +++ b/images/viewer_toolbar/toContinuousScroll.svg @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/images/viewer_toolbar/toContinuousScroll_18x18.svg b/images/viewer_toolbar/toContinuousScroll_18x18.svg new file mode 100644 index 000000000..76040304a --- /dev/null +++ b/images/viewer_toolbar/toContinuousScroll_18x18.svg @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file From 68dd26e20fcebf88c92b72858b750807d408a5c7 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 22 Feb 2026 21:30:03 +0100 Subject: [PATCH 082/187] Clean leftover code after theming that set QIcons directly --- YACReader/main_window_viewer.cpp | 94 +++++++++++--------------------- common/yacreader_global_gui.cpp | 11 +--- common/yacreader_global_gui.h | 3 +- 3 files changed, 35 insertions(+), 73 deletions(-) diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 449c198f9..f8f5a8cac 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -188,7 +188,6 @@ void MainWindowViewer::setupUI() void MainWindowViewer::createActions() { openAction = new QAction(tr("&Open"), this); - openAction->setIcon(QIcon(":/images/viewer_toolbar/open.svg")); openAction->setToolTip(tr("Open a comic")); openAction->setData(OPEN_ACTION_Y); openAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_ACTION_Y)); @@ -215,7 +214,6 @@ void MainWindowViewer::createActions() #endif openFolderAction = new QAction(tr("Open Folder"), this); - openFolderAction->setIcon(QIcon(":/images/viewer_toolbar/openFolder.svg")); openFolderAction->setToolTip(tr("Open image folder")); openFolderAction->setData(OPEN_FOLDER_ACTION_Y); openFolderAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_FOLDER_ACTION_Y)); @@ -239,28 +237,24 @@ void MainWindowViewer::createActions() connect(clearRecentFilesAction, &QAction::triggered, this, &MainWindowViewer::clearRecentFiles); saveImageAction = new QAction(tr("Save"), this); - saveImageAction->setIcon(QIcon(":/images/viewer_toolbar/save.svg")); saveImageAction->setToolTip(tr("Save current page")); saveImageAction->setData(SAVE_IMAGE_ACTION_Y); saveImageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SAVE_IMAGE_ACTION_Y)); connect(saveImageAction, &QAction::triggered, this, &MainWindowViewer::saveImage); openComicOnTheLeftAction = new QAction(tr("Previous Comic"), this); - openComicOnTheLeftAction->setIcon(QIcon(":/images/viewer_toolbar/openPrevious.svg")); openComicOnTheLeftAction->setToolTip(tr("Open previous comic")); openComicOnTheLeftAction->setData(OPEN_PREVIOUS_COMIC_ACTION_Y); openComicOnTheLeftAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_PREVIOUS_COMIC_ACTION_Y)); connect(openComicOnTheLeftAction, &QAction::triggered, this, &MainWindowViewer::openLeftComic); openComicOnTheRightAction = new QAction(tr("Next Comic"), this); - openComicOnTheRightAction->setIcon(QIcon(":/images/viewer_toolbar/openNext.svg")); openComicOnTheRightAction->setToolTip(tr("Open next comic")); openComicOnTheRightAction->setData(OPEN_NEXT_COMIC_ACTION_Y); openComicOnTheRightAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPEN_NEXT_COMIC_ACTION_Y)); connect(openComicOnTheRightAction, &QAction::triggered, this, &MainWindowViewer::openRightComic); goToPageOnTheLeftAction = new QAction(tr("&Previous"), this); - goToPageOnTheLeftAction->setIcon(QIcon(":/images/viewer_toolbar/previous.svg")); goToPageOnTheLeftAction->setShortcutContext(Qt::WidgetShortcut); goToPageOnTheLeftAction->setToolTip(tr("Go to previous page")); goToPageOnTheLeftAction->setData(PREV_ACTION_Y); @@ -268,7 +262,6 @@ void MainWindowViewer::createActions() connect(goToPageOnTheLeftAction, &QAction::triggered, viewer, &Viewer::left); goToPageOnTheRightAction = new QAction(tr("&Next"), this); - goToPageOnTheRightAction->setIcon(QIcon(":/images/viewer_toolbar/next.svg")); goToPageOnTheRightAction->setShortcutContext(Qt::WidgetShortcut); goToPageOnTheRightAction->setToolTip(tr("Go to next page")); goToPageOnTheRightAction->setData(NEXT_ACTION_Y); @@ -276,27 +269,20 @@ void MainWindowViewer::createActions() connect(goToPageOnTheRightAction, &QAction::triggered, viewer, &Viewer::right); adjustHeightAction = new QAction(tr("Fit Height"), this); - adjustHeightAction->setIcon(QIcon(":/images/viewer_toolbar/toHeight.svg")); - // adjustWidth->setCheckable(true); adjustHeightAction->setToolTip(tr("Fit image to height")); - // adjustWidth->setIcon(QIcon(":/images/fitWidth.svg")); adjustHeightAction->setData(ADJUST_HEIGHT_ACTION_Y); adjustHeightAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_HEIGHT_ACTION_Y)); adjustHeightAction->setCheckable(true); connect(adjustHeightAction, &QAction::triggered, this, &MainWindowViewer::fitToHeight); adjustWidthAction = new QAction(tr("Fit Width"), this); - adjustWidthAction->setIcon(QIcon(":/images/viewer_toolbar/toWidth.svg")); - // adjustWidth->setCheckable(true); adjustWidthAction->setToolTip(tr("Fit image to width")); - // adjustWidth->setIcon(QIcon(":/images/fitWidth.svg")); adjustWidthAction->setData(ADJUST_WIDTH_ACTION_Y); adjustWidthAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_WIDTH_ACTION_Y)); adjustWidthAction->setCheckable(true); connect(adjustWidthAction, &QAction::triggered, this, &MainWindowViewer::fitToWidth); adjustToFullSizeAction = new QAction(tr("Show full size"), this); - adjustToFullSizeAction->setIcon(QIcon(":/images/viewer_toolbar/full.svg")); adjustToFullSizeAction->setCheckable(false); adjustToFullSizeAction->setData(ADJUST_TO_FULL_SIZE_ACTION_Y); adjustToFullSizeAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(ADJUST_TO_FULL_SIZE_ACTION_Y)); @@ -304,7 +290,6 @@ void MainWindowViewer::createActions() connect(adjustToFullSizeAction, &QAction::triggered, this, &MainWindowViewer::adjustToFullSizeSwitch); fitToPageAction = new QAction(tr("Fit to page"), this); - fitToPageAction->setIcon(QIcon(":/images/viewer_toolbar/fitToPage.svg")); fitToPageAction->setData(FIT_TO_PAGE_ACTION_Y); fitToPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(FIT_TO_PAGE_ACTION_Y)); fitToPageAction->setCheckable(true); @@ -312,7 +297,6 @@ void MainWindowViewer::createActions() continuousScrollAction = new QAction(tr("Continuous scroll"), this); continuousScrollAction->setToolTip(tr("Switch to continuous scroll mode")); - continuousScrollAction->setIcon(QIcon(":/images/viewer_toolbar/toContinuousScroll.svg")); continuousScrollAction->setCheckable(true); continuousScrollAction->setChecked(Configuration::getConfiguration().getContinuousScroll()); connect(continuousScrollAction, &QAction::toggled, viewer, &Viewer::setContinuousScroll); @@ -350,7 +334,6 @@ void MainWindowViewer::createActions() connect(resetZoomAction, &QAction::triggered, this, &MainWindowViewer::resetZoomLevel); showZoomSliderlAction = new QAction(tr("Show zoom slider"), this); - showZoomSliderlAction->setIcon(QIcon(":/images/viewer_toolbar/zoom.svg")); increasePageZoomAction = new QAction(tr("Zoom+"), this); increasePageZoomAction->setData(ZOOM_PLUS_ACTION_Y); @@ -363,20 +346,17 @@ void MainWindowViewer::createActions() connect(decreasePageZoomAction, &QAction::triggered, this, &MainWindowViewer::decreasePageZoomLevel); leftRotationAction = new QAction(tr("Rotate image to the left"), this); - leftRotationAction->setIcon(QIcon(":/images/viewer_toolbar/rotateL.svg")); leftRotationAction->setData(LEFT_ROTATION_ACTION_Y); leftRotationAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(LEFT_ROTATION_ACTION_Y)); connect(leftRotationAction, &QAction::triggered, viewer, &Viewer::rotateLeft); rightRotationAction = new QAction(tr("Rotate image to the right"), this); - rightRotationAction->setIcon(QIcon(":/images/viewer_toolbar/rotateR.svg")); rightRotationAction->setData(RIGHT_ROTATION_ACTION_Y); rightRotationAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(RIGHT_ROTATION_ACTION_Y)); connect(rightRotationAction, &QAction::triggered, viewer, &Viewer::rotateRight); doublePageAction = new QAction(tr("Double page mode"), this); doublePageAction->setToolTip(tr("Switch to double page mode")); - doublePageAction->setIcon(QIcon(":/images/viewer_toolbar/doublePage.svg")); doublePageAction->setCheckable(true); doublePageAction->setChecked(Configuration::getConfiguration().getDoublePage()); doublePageAction->setData(DOUBLE_PAGE_ACTION_Y); @@ -386,7 +366,6 @@ void MainWindowViewer::createActions() // inversed pictures mode doubleMangaPageAction = new QAction(tr("Double page manga mode"), this); doubleMangaPageAction->setToolTip(tr("Reverse reading order in double page mode")); - doubleMangaPageAction->setIcon(QIcon(":/images/viewer_toolbar/doubleMangaPage.svg")); doubleMangaPageAction->setCheckable(true); doubleMangaPageAction->setChecked(Configuration::getConfiguration().getDoubleMangaPage()); doubleMangaPageAction->setData(DOUBLE_MANGA_PAGE_ACTION_Y); @@ -395,7 +374,6 @@ void MainWindowViewer::createActions() connect(doubleMangaPageAction, &QAction::triggered, this, &MainWindowViewer::doubleMangaPageSwitch); goToPageAction = new QAction(tr("Go To"), this); - goToPageAction->setIcon(QIcon(":/images/viewer_toolbar/goto.svg")); goToPageAction->setToolTip(tr("Go to page ...")); goToPageAction->setData(GO_TO_PAGE_ACTION_Y); goToPageAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(GO_TO_PAGE_ACTION_Y)); @@ -405,20 +383,17 @@ void MainWindowViewer::createActions() optionsAction->setToolTip(tr("YACReader options")); optionsAction->setData(OPTIONS_ACTION_Y); optionsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(OPTIONS_ACTION_Y)); - optionsAction->setIcon(QIcon(":/images/viewer_toolbar/options.svg")); connect(optionsAction, &QAction::triggered, optionsDialog, &OptionsDialog::show); helpAboutAction = new QAction(tr("Help"), this); helpAboutAction->setToolTip(tr("Help, About YACReader")); - helpAboutAction->setIcon(QIcon(":/images/viewer_toolbar/help.svg")); helpAboutAction->setData(HELP_ABOUT_ACTION_Y); helpAboutAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(HELP_ABOUT_ACTION_Y)); connect(helpAboutAction, &QAction::triggered, had, &QWidget::show); showMagnifyingGlassAction = new QAction(tr("Magnifying glass"), this); showMagnifyingGlassAction->setToolTip(tr("Switch Magnifying glass")); - showMagnifyingGlassAction->setIcon(QIcon(":/images/viewer_toolbar/magnifyingGlass.svg")); showMagnifyingGlassAction->setCheckable(true); showMagnifyingGlassAction->setData(SHOW_MAGNIFYING_GLASS_ACTION_Y); showMagnifyingGlassAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_MAGNIFYING_GLASS_ACTION_Y)); @@ -426,7 +401,6 @@ void MainWindowViewer::createActions() setBookmarkAction = new QAction(tr("Set bookmark"), this); setBookmarkAction->setToolTip(tr("Set a bookmark on the current page")); - setBookmarkAction->setIcon(QIcon(":/images/viewer_toolbar/bookmark.svg")); setBookmarkAction->setCheckable(true); setBookmarkAction->setData(SET_BOOKMARK_ACTION_Y); setBookmarkAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SET_BOOKMARK_ACTION_Y)); @@ -436,38 +410,32 @@ void MainWindowViewer::createActions() showBookmarksAction = new QAction(tr("Show bookmarks"), this); showBookmarksAction->setToolTip(tr("Show the bookmarks of the current comic")); - showBookmarksAction->setIcon(QIcon(":/images/viewer_toolbar/showBookmarks.svg")); showBookmarksAction->setData(SHOW_BOOKMARKS_ACTION_Y); showBookmarksAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_BOOKMARKS_ACTION_Y)); connect(showBookmarksAction, &QAction::triggered, viewer->getBookmarksDialog(), &QWidget::show); showShorcutsAction = new QAction(tr("Show keyboard shortcuts"), this); - showShorcutsAction->setIcon(QIcon(":/images/viewer_toolbar/shortcuts.svg")); showShorcutsAction->setData(SHOW_SHORCUTS_ACTION_Y); showShorcutsAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_SHORCUTS_ACTION_Y)); connect(showShorcutsAction, &QAction::triggered, editShortcutsDialog, &QWidget::show); showInfoAction = new QAction(tr("Show Info"), this); - showInfoAction->setIcon(QIcon(":/images/viewer_toolbar/info.svg")); showInfoAction->setData(SHOW_INFO_ACTION_Y); showInfoAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_INFO_ACTION_Y)); connect(showInfoAction, &QAction::triggered, viewer, &Viewer::informationSwitch); closeAction = new QAction(tr("Close"), this); - closeAction->setIcon(QIcon(":/images/viewer_toolbar/close.svg")); closeAction->setData(CLOSE_ACTION_Y); closeAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(CLOSE_ACTION_Y)); connect(closeAction, &QAction::triggered, this, &QWidget::close); showDictionaryAction = new QAction(tr("Show Dictionary"), this); - showDictionaryAction->setIcon(QIcon(":/images/viewer_toolbar/translator.svg")); // showDictionaryAction->setCheckable(true); showDictionaryAction->setData(SHOW_DICTIONARY_ACTION_Y); showDictionaryAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_DICTIONARY_ACTION_Y)); connect(showDictionaryAction, &QAction::triggered, viewer, &Viewer::translatorSwitch); showFlowAction = new QAction(tr("Show go to flow"), this); - showFlowAction->setIcon(QIcon(":/images/viewer_toolbar/flow.svg")); showFlowAction->setData(SHOW_FLOW_ACTION_Y); showFlowAction->setShortcut(ShortcutsManager::getShortcutsManager().getShortcut(SHOW_FLOW_ACTION_Y)); connect(showFlowAction, &QAction::triggered, viewer, &Viewer::goToFlowSwitch); @@ -505,8 +473,8 @@ void MainWindowViewer::createToolBars() #endif #ifdef Y_MAC_UI - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/open")), openAction)); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openFolder")), openFolderAction)); + comicToolBar->addAction(wrappedToolbarAction(openAction)); + comicToolBar->addAction(wrappedToolbarAction(openFolderAction)); #else auto recentmenu = new QMenu(tr("Open recent")); recentmenu->addActions(recentFilesActionList); @@ -515,10 +483,10 @@ void MainWindowViewer::createToolBars() refreshRecentFilesActionList(); openToolButton = new QToolButton(); - auto open = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/open")), openAction); + auto open = wrappedToolbarAction(openAction); openToolButton->addAction(open); - openToolButton->addAction(actionWithCustomIcon(QIcon(), openLatestComicAction)); - openToolButton->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openFolder")), openFolderAction)); + openToolButton->addAction(wrappedToolbarAction(openLatestComicAction)); + openToolButton->addAction(wrappedToolbarAction(openFolderAction)); openToolButton->addAction(recentmenu->menuAction()); openToolButton->setPopupMode(QToolButton::MenuButtonPopup); openToolButton->setDefaultAction(open); @@ -526,28 +494,28 @@ void MainWindowViewer::createToolBars() comicToolBar->addWidget(openToolButton); #endif - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/save")), saveImageAction)); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openPrevious")), openComicOnTheLeftAction)); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/openNext")), openComicOnTheRightAction)); + comicToolBar->addAction(wrappedToolbarAction(saveImageAction)); + comicToolBar->addAction(wrappedToolbarAction(openComicOnTheLeftAction)); + comicToolBar->addAction(wrappedToolbarAction(openComicOnTheRightAction)); comicToolBar->addSeparator(); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/previous")), goToPageOnTheLeftAction)); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/next")), goToPageOnTheRightAction)); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/goto")), goToPageAction)); + comicToolBar->addAction(wrappedToolbarAction(goToPageOnTheLeftAction)); + comicToolBar->addAction(wrappedToolbarAction(goToPageOnTheRightAction)); + comicToolBar->addAction(wrappedToolbarAction(goToPageAction)); comicToolBar->addSeparator(); - auto adjustToWidthTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/toWidth")), adjustWidthAction); + auto adjustToWidthTBAction = wrappedToolbarAction(adjustWidthAction); comicToolBar->addAction(adjustToWidthTBAction); - auto adjustToHeightTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/toHeight")), adjustHeightAction); + auto adjustToHeightTBAction = wrappedToolbarAction(adjustHeightAction); comicToolBar->addAction(adjustToHeightTBAction); - auto adjustToFullSizeTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/full")), adjustToFullSizeAction); + auto adjustToFullSizeTBAction = wrappedToolbarAction(adjustToFullSizeAction); comicToolBar->addAction(adjustToFullSizeAction); - auto fitToPageTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/fitToPage")), fitToPageAction); + auto fitToPageTBAction = wrappedToolbarAction(fitToPageAction); comicToolBar->addAction(fitToPageTBAction); - auto continuousScroollTBAction = actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/toContinuousScroll")), continuousScrollAction); + auto continuousScroollTBAction = wrappedToolbarAction(continuousScrollAction); auto fitModes = new QActionGroup(this); fitModes->addAction(adjustToWidthTBAction); @@ -559,32 +527,32 @@ void MainWindowViewer::createToolBars() zoomSliderAction = new YACReaderSlider(this); zoomSliderAction->hide(); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/zoom")), showZoomSliderlAction)); + comicToolBar->addAction(wrappedToolbarAction(showZoomSliderlAction)); connect(showZoomSliderlAction, &QAction::triggered, this, &MainWindowViewer::toggleFitToWidthSlider); connect(zoomSliderAction, &YACReaderSlider::zoomRatioChanged, viewer, &Viewer::updateZoomRatio); connect(viewer, &Viewer::zoomUpdated, zoomSliderAction, &YACReaderSlider::updateZoomRatio); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/rotateL")), leftRotationAction)); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/rotateR")), rightRotationAction)); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/doublePage")), doublePageAction)); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/doubleMangaPage")), doubleMangaPageAction)); + comicToolBar->addAction(wrappedToolbarAction(leftRotationAction)); + comicToolBar->addAction(wrappedToolbarAction(rightRotationAction)); + comicToolBar->addAction(wrappedToolbarAction(doublePageAction)); + comicToolBar->addAction(wrappedToolbarAction(doubleMangaPageAction)); comicToolBar->addAction(continuousScroollTBAction); comicToolBar->addSeparator(); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/magnifyingGlass")), showMagnifyingGlassAction)); + comicToolBar->addAction(wrappedToolbarAction(showMagnifyingGlassAction)); comicToolBar->addSeparator(); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/bookmark")), setBookmarkAction)); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/showBookmarks")), showBookmarksAction)); + comicToolBar->addAction(wrappedToolbarAction(setBookmarkAction)); + comicToolBar->addAction(wrappedToolbarAction(showBookmarksAction)); comicToolBar->addSeparator(); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/translator")), showDictionaryAction)); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/flow")), showFlowAction)); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/info")), showInfoAction)); + comicToolBar->addAction(wrappedToolbarAction(showDictionaryAction)); + comicToolBar->addAction(wrappedToolbarAction(showFlowAction)); + comicToolBar->addAction(wrappedToolbarAction(showInfoAction)); #ifdef Y_MAC_UI comicToolBar->addStretch(); @@ -592,9 +560,9 @@ void MainWindowViewer::createToolBars() comicToolBar->addWidget(new YACReaderToolBarStretch()); #endif - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/shortcuts")), showShorcutsAction)); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/options")), optionsAction)); - comicToolBar->addAction(actionWithCustomIcon(QIcon(addExtensionToIconPathInToolbar(":/images/viewer_toolbar/help")), helpAboutAction)); + comicToolBar->addAction(wrappedToolbarAction(showShorcutsAction)); + comicToolBar->addAction(wrappedToolbarAction(optionsAction)); + comicToolBar->addAction(wrappedToolbarAction(helpAboutAction)); #ifndef Y_MAC_UI comicToolBar->setMovable(false); @@ -1597,7 +1565,7 @@ void MainWindowViewer::applyTheme(const Theme &theme) if (action) { action->setIcon(icon); - auto action18x18 = action->property("customIconAction").value(); + auto action18x18 = action->property("wrappedToolbarAction").value(); if (action18x18) { action18x18->setIcon(icon18x18); diff --git a/common/yacreader_global_gui.cpp b/common/yacreader_global_gui.cpp index f80f1aff9..ccce5861d 100644 --- a/common/yacreader_global_gui.cpp +++ b/common/yacreader_global_gui.cpp @@ -53,14 +53,9 @@ QList YACReader::mimeDataToComicsIds(const QMimeData *data) return comicIds; } -QString YACReader::addExtensionToIconPathInToolbar(const QString &path) +QAction *YACReader::wrappedToolbarAction(QAction *action) { - return path + "_18x18.svg"; -} - -QAction *YACReader::actionWithCustomIcon(const QIcon &icon, QAction *action) -{ - auto a = new QAction(icon, action->text()); + auto a = new QAction(action->text()); a->setEnabled(action->isEnabled()); a->setCheckable(action->isCheckable()); @@ -79,7 +74,7 @@ QAction *YACReader::actionWithCustomIcon(const QIcon &icon, QAction *action) QObject::connect(action, &QAction::toggled, a, &QAction::setChecked); // asign a to action somehow so we can retrieve it later - action->setProperty("customIconAction", QVariant::fromValue(a)); + action->setProperty("wrappedToolbarAction", QVariant::fromValue(a)); return a; } diff --git a/common/yacreader_global_gui.h b/common/yacreader_global_gui.h index 2738e3462..60d455455 100644 --- a/common/yacreader_global_gui.h +++ b/common/yacreader_global_gui.h @@ -111,8 +111,7 @@ QAction *createSeparator(); QIcon noHighlightedIcon(const QString &path); void colorize(QImage &img, const QColor &col); QList mimeDataToComicsIds(const QMimeData *data); -QString addExtensionToIconPathInToolbar(const QString &path); -QAction *actionWithCustomIcon(const QIcon &icon, QAction *action); +QAction *wrappedToolbarAction(QAction *action); QPixmap hdpiPixmap(const QString &file, QSize size); QString imageFileLoader(QWidget *parent); QString imagePathFromMimeData(const QMimeData *mimeData); From 6dcea10cd49c0c1da9adfaad17361136d87e5ef0 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 22 Feb 2026 22:02:09 +0100 Subject: [PATCH 083/187] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85187da9b..aeda4c969 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ Version counting is based on semantic versioning (Major.Feature.Patch) ## 10 (WIP) +### YACReader +* Add support for continuous scroll mode. + ### All GUI Apps * Migrate Flow implementation from OpenGL to QRhi. This is a full new implementation with better performance and compatibility with operating systems and hardware. * Add light/dark themes support that follow the system configuration. From 19c8b7681a1f91231b47d4657b8ebec752f585d2 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 22 Feb 2026 22:04:14 +0100 Subject: [PATCH 084/187] Don't commit .claude --- .claude/settings.local.json | 8 -------- .gitignore | 3 +++ 2 files changed, 3 insertions(+), 8 deletions(-) delete mode 100644 .claude/settings.local.json diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index ad2f5cfa0..000000000 --- a/.claude/settings.local.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(qsb:*)", - "Bash(ls:*)" - ] - } -} diff --git a/.gitignore b/.gitignore index 397e9743e..f3b81f389 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,6 @@ c_x86_64.pch compile_commands.json .ccls-cache + +# Claude Code +.claude/ From 5f8951ac09da00fa68131d51efcf67b07931c7b3 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 22 Feb 2026 22:04:24 +0100 Subject: [PATCH 085/187] Remove plan file --- Qt5-DROP.md | 208 ---------------------------------------------------- 1 file changed, 208 deletions(-) delete mode 100644 Qt5-DROP.md diff --git a/Qt5-DROP.md b/Qt5-DROP.md deleted file mode 100644 index a0fefe529..000000000 --- a/Qt5-DROP.md +++ /dev/null @@ -1,208 +0,0 @@ -# Qt5 Drop - Cleanup Checklist - -Inventory of all Qt5 compatibility code and version branching across the project. -Goal: support only Qt6, remove all Qt5 conditionals and dead branches. - ---- - -## 1. Build System (.pro / .pri files) - -### core5compat module additions -These add `QT += core5compat` for Qt6 builds. Needed by third-party QtWebApp (QTextCodec, QRegExp). - -| File | Line | Code | -|------|------|------| -| `YACReaderLibrary/YACReaderLibrary.pro` | 51 | `greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat` | -| `YACReader/YACReader.pro` | 53 | `greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat` | -| `YACReaderLibraryServer/YACReaderLibraryServer.pro` | 20 | `greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat` | -| `YACReaderLibraryServer/YACReaderLibraryServer.pro` | 40 | `greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat` (duplicate) | - -**Action**: Replace conditionals with unconditional `QT += core5compat` (still needed for QtWebApp). Remove the duplicate in YACReaderLibraryServer. - -### macextras module (Qt5-only, removed in Qt6) - -| File | Line | Code | -|------|------|------| -| `YACReaderLibrary/YACReaderLibrary.pro` | 44 | `lessThan(QT_MAJOR_VERSION, 6): QT += macextras` | -| `YACReader/YACReader.pro` | 48 | `lessThan(QT_MAJOR_VERSION, 6): QT += macextras` | - -**Action**: Remove these lines entirely. - -### gui-private module (Qt 6.7+) - -| File | Line | Code | -|------|------|------| -| `YACReaderLibrary/YACReaderLibrary.pro` | 53-55 | `greaterThan(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 6) { QT += gui-private }` | -| `YACReader/YACReader.pro` | 55-57 | Same | - -**Action**: Simplify to `greaterThan(QT_MINOR_VERSION, 6): QT += gui-private` (drop the Qt5 guard). - -### Poppler backend version branching - -| File | Lines | What | -|------|-------|------| -| `dependencies/pdf_backend.pri` | 60-84 | Qt5 uses poppler-qt5, Qt6 uses poppler-qt6 (pkg-config, include paths, link flags) | - -**Action**: Keep only the Qt6 (poppler-qt6) branch, remove poppler-qt5 paths. - -### Minimum version check - -| File | Lines | What | -|------|-------|------| -| `config.pri` | 18-41 | `minQtVersion()` function, enforces minimum Qt 5.15.0 | - -**Action**: Update minimum to Qt 6.x. - -### QML resource branching (DONE) - -| File | Lines | What | -|------|-------|------| -| `YACReaderLibrary/YACReaderLibrary.pro` | 317-321 | Was `greaterThan(QT_MAJOR_VERSION, 5) { qml6.qrc } else { qml.qrc }` | - -**Action**: Already cleaned up - now unconditional `RESOURCES += qml.qrc`. - -### Qt4 compatibility in third-party - -| File | Line | Code | -|------|------|------| -| `third_party/QsLog/QsLog.pri` | 11 | `greaterThan(QT_MAJOR_VERSION, 4): QT += widgets` | - -**Action**: Replace with unconditional `QT += widgets`. - ---- - -## 2. C++ Source Code (#if QT_VERSION checks) - -### Qt5 vs Qt6 API changes (own code) - -| File | Line(s) | Qt5 branch | Qt6 branch | API change | -|------|---------|------------|------------|------------| -| `common/pdf_comic.h` | 49 | `#include "poppler-qt5.h"` | `#include ` | Poppler header | -| `common/pdf_comic.mm` | 3 | (nothing) | `#undef __OBJC_BOOL_IS_BOOL` | macOS ObjC compat | -| `common/comic.cpp` | 812 | `auto _pdfComic = Poppler::Document::load()` | `pdfComic = Poppler::Document::load()` | Poppler return type | -| `YACReaderLibrary/initial_comic_info_extractor.cpp` | 44 | Same Poppler pattern | Same | Poppler return type | -| `YACReader/mouse_handler.cpp` | 22, 56, 107 | `QPointF(event->x(), event->y())` | `event->position()` | QMouseEvent API | -| `YACReader/viewer.cpp` | 762 | `pixmap(Qt::ReturnByValue)` | `pixmap()` | QPixmap return semantics | -| `custom_widgets/help_about_dialog.cpp` | 14, 88 | `QTextCodec` / `setCodec()` | `QStringConverter` / `setEncoding()` | Text encoding API | -| `YACReader/translator.cpp` | 291 | `player->setMedia()` | `player->setSource()` | QMediaPlayer API | -| `YACReaderLibrary/comic_vine/comic_vine_dialog.cpp` | 149, 160 | `QtConcurrent::run(this, &fn, args)` | `QtConcurrent::run(&fn, this, args)` | Argument order | -| `YACReaderLibrary/library_window.cpp` | 173 | Different key handling | `keySequence[0]` (QKeyCombination) | Key event API | -| `YACReaderLibrary/library_window.cpp` | 790-793 | Qt5 toolbar connections | Qt6 toolbar connections | macOS toolbar | -| `YACReader/main_window_viewer.cpp` | 483, 1357 | Qt5 toolbar/slider | Qt6 toolbar/slider | macOS toolbar | -| `YACReaderLibrary/trayhandler.mm` | 3 | (nothing) | `#undef __OBJC_BOOL_IS_BOOL` | macOS ObjC compat | -| `YACReader/main.cpp` | 102 | (nothing) | `QImageReader::setAllocationLimit(0)` | Image reader limit | -| `YACReaderLibraryServer/main.cpp` | 53 | (nothing) | `QImageReader::setAllocationLimit(0)` | Image reader limit | - -**Action**: For each, keep only the Qt6 branch, remove the `#if`/`#else`/`#endif` and the Qt5 code. - -### Qt4 vs Qt5 leftovers (very old) - -| File | Line(s) | What | -|------|---------|------| -| `custom_widgets/yacreader_table_view.cpp` | 31, 39, 46 | `#if QT_VERSION >= 0x050000` — `setResizeMode` vs `setSectionResizeMode` | -| `YACReaderLibrary/comic_vine/scraper_tableview.cpp` | 9, 16, 23 | Same Qt4 vs Qt5 header API | -| `YACReader/translator.cpp` | 3, 164 | `#if QT_VERSION >= 0x050000` — Phonon vs QMediaPlayer | -| `YACReader/main.cpp` | 135 | `#if QT_VERSION >= 0x050800` — QCommandLineOption::HiddenFromHelp | - -**Action**: Remove the `#if` guards entirely, keep only the Qt5+ code (which is also valid Qt6). - -### Qt 6.7+ specific (RHI widget) - -| File | Lines | What | -|------|-------|------| -| `common/rhi/yacreader_flow_rhi.h` | 8-302 | `#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)` — entire QRhiWidget implementation | - -**Action**: Keep this conditional (gates on Qt 6.7 minor version, not Qt5 vs Qt6). - -### Qt 6.9+ specific (test code) - -| File | Line | What | -|------|------|------| -| `tests/concurrent_queue_test/concurrent_queue_test.cpp` | 212 | `#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)` — QDebug for std::array | - -**Action**: Keep this conditional (Qt6 minor version gate). - ---- - -## 3. Third-Party Libraries - -### QtWebApp (`third_party/QtWebApp/`) - -| File | Lines | What | -|------|-------|------| -| `templateengine/templateengine.pri` | 5 | `QT += core5compat` | -| `templateengine/templateloader.cpp` | 13, 77, 86, 107 | QRegExp→QRegularExpression, QString::split flag | -| `httpserver/httpconnectionhandler.h` | 23 | `tSocketDescriptor` typedef (Qt4 vs Qt5) | -| `httpserver/httpconnectionhandlerpool.cpp` | 152 | SSL cert handling (Qt <5.15 vs 5.15+) | - -**Action**: Decide whether to update QtWebApp or replace it. If updating: remove Qt4/Qt5 branches, keep Qt6 code, potentially drop core5compat dependency by migrating QTextCodec→QStringConverter and QRegExp→QRegularExpression. - -### QsLog (`third_party/QsLog/`) - -| File | Lines | What | -|------|-------|------| -| `QsLog.pri` | 11 | Qt4 widgets guard | -| `QsLogDestFile.cpp` | 32, 157, 179 | QTextCodec vs QStringConverter | -| `QsLogWindow.cpp` | 129 | Qt4 header resize API | - -**Action**: Same approach — remove Qt4/Qt5 branches, keep Qt6 code. - ---- - -## 4. CI/CD and Build Scripts - -### GitHub Actions (`.github/workflows/build.yml`) - -**Qt5 build targets to remove:** -- Ubuntu Linux Qt5 build (~line 63) -- Windows x64 Qt5 build (~line 346) -- Windows x86 Qt5 build (~line 798) -- macOS Qt5 build (~line 201) - -**Qt6 build targets to keep (and simplify):** -- Linux Qt6 builds (~lines 90, 116) -- macOS Qt6 Universal (~line 145) — still installs `qt5compat` module (needed for QtWebApp) -- Windows x64 Qt6 (~line 408) — same -- Windows ARM64 Qt6 (~line 574) — same - -### Build scripts - -| File | What | -|------|------| -| `build_scripts/ubuntu_24.04/build.sh` | Qt6 — installs `libqt6core5compat6-dev`, `qml6-module-qt5compat-graphicaleffects` | -| `build_scripts/ubuntu_22.04/build.sh` | Qt5 — entire script is Qt5-only | - -**Action**: Remove `ubuntu_22.04` build script. In `ubuntu_24.04`, remove `qml6-module-qt5compat-graphicaleffects` (no longer used in QML). Keep `libqt6core5compat6-dev` (needed for QtWebApp). - -### Docker - -| File | What | -|------|------| -| `docker/Dockerfile` | Ubuntu x64 Qt6 — installs `libqt6core5compat6-dev` (build) and `libqt6core5compat6` (runtime) | -| `docker/Dockerfile.aarch64` | Ubuntu ARM64 Qt5-only build | - -**Action**: Convert `Dockerfile.aarch64` to Qt6. Keep core5compat packages in main Dockerfile (QtWebApp). Make sure the conversion is good, there must be other images online that use the arm+qt6 combo, we can search online. - ---- - -## 5. Summary - -### Safe to remove now (no dependencies) -- All `lessThan(QT_MAJOR_VERSION, 6)` lines (macextras) -- All `#if QT_VERSION >= 0x050000` / `0x050800` guards (Qt4 leftovers) -- All Qt5 CI build targets -- `build_scripts/ubuntu_22.04/` (Qt5-only) -- `qml6-module-qt5compat-graphicaleffects` from build scripts (QML migration done) - -### Requires code changes (keep Qt6 branch only) -- ~15 `#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)` blocks in own code -- Poppler backend selection in `pdf_backend.pri` -- `config.pri` minimum version bump - -### Keep as-is (Qt6 minor version gates) -- `QT_VERSION_CHECK(6, 7, 0)` — RHI widget -- `QT_VERSION_CHECK(6, 9, 0)` — test code -- `gui-private` for Qt 6.7+ (simplify guard only) - -### Depends on third-party decisions -- `core5compat` — still needed unless QtWebApp and QsLog are updated to drop QTextCodec/QRegExp From 865020fe110f71756f9d74e9453e10af42c7ab62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20A=CC=81ngel=20San=20Marti=CC=81n=20Rodri=CC=81guez?= Date: Wed, 25 Feb 2026 09:19:39 +0100 Subject: [PATCH 086/187] Migrate the build system to cmake --- .github/workflows/build.yml | 237 +++++------- .gitignore | 51 +-- CMakeLists.txt | 191 ++++++++++ INSTALL.md | 114 +++--- README.md | 14 +- YACReader.pro | 4 - YACReader/CMakeLists.txt | 124 +++++++ YACReader/YACReader.pro | 229 ------------ YACReader/themes/themes.pri | 7 - YACReaderLibrary/CMakeLists.txt | 304 ++++++++++++++++ YACReaderLibrary/YACReaderLibrary.pro | 343 ------------------ YACReaderLibrary/comic_vine/CMakeLists.txt | 71 ++++ YACReaderLibrary/comic_vine/comic_vine.pri | 52 --- YACReaderLibrary/server/CMakeLists.txt | 85 +++++ YACReaderLibrary/server/server.pri | 81 ----- YACReaderLibrary/themes/themes.pri | 7 - YACReaderLibraryServer/CMakeLists.txt | 94 +++++ .../YACReaderLibraryServer.pro | 178 --------- YACReaderLibraryServer/headless_config.pri | 37 -- ci/win/create_installer.cmd | 14 +- cleanOSX.sh | 19 +- cmake/CompilerOptions.cmake | 20 + cmake/PdfBackend.cmake | 97 +++++ common/CMakeLists.txt | 197 ++++++++++ common/rhi/README.md | 39 +- common/rhi/shaders/README.md | 49 --- common/rhi/shaders/compile_shaders.bat | 19 - common/rhi/shaders/compile_shaders.sh | 19 - common/rhi/shaders/flow.frag.qsb | Bin 3066 -> 0 bytes common/rhi/shaders/flow.vert.qsb | Bin 2689 -> 0 bytes common/rhi/shaders/shaders.qrc | 6 - common/themes/themes_common.pri | 16 - compileOSX.sh | 49 +-- compressed_archive/CMakeLists.txt | 158 ++++++++ compressed_archive/libarchive/README.md | 4 +- .../libarchive/libarchive-wrapper.pri | 31 -- compressed_archive/unarr/unarr-wrapper.pri | 52 --- compressed_archive/unarr/unarr.pro | 46 --- compressed_archive/wrapper.pri | 62 ---- config.pri | 101 ------ custom_widgets/CMakeLists.txt | 106 ++++++ custom_widgets/custom_widgets_yacreader.pri | 34 -- .../custom_widgets_yacreaderlibrary.pri | 50 --- dependencies/pdf_backend.pri | 75 ---- docker/Dockerfile | 27 +- docker/Dockerfile.aarch64 | 23 +- shortcuts_management/CMakeLists.txt | 34 ++ shortcuts_management/shortcuts_management.pri | 16 - tests/CMakeLists.txt | 4 + tests/compressed_archive_test/CMakeLists.txt | 13 + .../compressed_archive_test.pro | 26 -- tests/concurrent_queue_test/CMakeLists.txt | 12 + .../concurrent_queue_test.pro | 9 - tests/qt_test.pri | 9 - tests/tests.pro | 2 - third_party/CMakeLists.txt | 80 ++++ third_party/KDToolBox/KDToolBox.pri | 4 - third_party/QrCode/QrCode.pri | 4 - third_party/QsLog/QsLog.pri | 41 --- third_party/QsLog/QsLogSharedLibrary.pro | 46 --- third_party/QsLog/unittest/unittest.pro | 29 -- .../QtWebApp/httpserver/httpserver.pri | 33 -- .../templateengine/templateengine.pri | 15 - 63 files changed, 1856 insertions(+), 2057 deletions(-) create mode 100644 CMakeLists.txt delete mode 100644 YACReader.pro create mode 100644 YACReader/CMakeLists.txt delete mode 100644 YACReader/YACReader.pro delete mode 100644 YACReader/themes/themes.pri create mode 100644 YACReaderLibrary/CMakeLists.txt delete mode 100644 YACReaderLibrary/YACReaderLibrary.pro create mode 100644 YACReaderLibrary/comic_vine/CMakeLists.txt delete mode 100644 YACReaderLibrary/comic_vine/comic_vine.pri create mode 100644 YACReaderLibrary/server/CMakeLists.txt delete mode 100644 YACReaderLibrary/server/server.pri delete mode 100644 YACReaderLibrary/themes/themes.pri create mode 100644 YACReaderLibraryServer/CMakeLists.txt delete mode 100644 YACReaderLibraryServer/YACReaderLibraryServer.pro delete mode 100644 YACReaderLibraryServer/headless_config.pri create mode 100644 cmake/CompilerOptions.cmake create mode 100644 cmake/PdfBackend.cmake create mode 100644 common/CMakeLists.txt delete mode 100644 common/rhi/shaders/README.md delete mode 100644 common/rhi/shaders/compile_shaders.bat delete mode 100755 common/rhi/shaders/compile_shaders.sh delete mode 100644 common/rhi/shaders/flow.frag.qsb delete mode 100644 common/rhi/shaders/flow.vert.qsb delete mode 100644 common/rhi/shaders/shaders.qrc delete mode 100644 common/themes/themes_common.pri create mode 100644 compressed_archive/CMakeLists.txt delete mode 100644 compressed_archive/libarchive/libarchive-wrapper.pri delete mode 100644 compressed_archive/unarr/unarr-wrapper.pri delete mode 100644 compressed_archive/unarr/unarr.pro delete mode 100644 compressed_archive/wrapper.pri delete mode 100644 config.pri create mode 100644 custom_widgets/CMakeLists.txt delete mode 100644 custom_widgets/custom_widgets_yacreader.pri delete mode 100644 custom_widgets/custom_widgets_yacreaderlibrary.pri delete mode 100644 dependencies/pdf_backend.pri create mode 100644 shortcuts_management/CMakeLists.txt delete mode 100644 shortcuts_management/shortcuts_management.pri create mode 100644 tests/CMakeLists.txt create mode 100644 tests/compressed_archive_test/CMakeLists.txt delete mode 100644 tests/compressed_archive_test/compressed_archive_test.pro create mode 100644 tests/concurrent_queue_test/CMakeLists.txt delete mode 100644 tests/concurrent_queue_test/concurrent_queue_test.pro delete mode 100644 tests/qt_test.pri delete mode 100644 tests/tests.pro create mode 100644 third_party/CMakeLists.txt delete mode 100644 third_party/KDToolBox/KDToolBox.pri delete mode 100644 third_party/QrCode/QrCode.pri delete mode 100644 third_party/QsLog/QsLog.pri delete mode 100644 third_party/QsLog/QsLogSharedLibrary.pro delete mode 100644 third_party/QsLog/unittest/unittest.pro delete mode 100644 third_party/QtWebApp/httpserver/httpserver.pri delete mode 100644 third_party/QtWebApp/templateengine/templateengine.pri diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7935900c7..d866bd151 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,10 +41,10 @@ jobs: needs: initialization steps: - uses: actions/checkout@v4 - + - name: Install dependencies run: brew install clang-format - + - name: Run clang-format run: | find . \( -name '*.h' -or -name '*.cpp' -or -name '*.c' -or -name '*.mm' -or -name '*.m' \) -print0 | xargs -0 clang-format -style=file -i @@ -74,13 +74,14 @@ jobs: - name: Build run: | - export DEFINES_VAR=DEFINES+=\"BUILD_NUMBER=\\\\\\\"${{ needs.initialization.outputs.build_number }}\\\\\\\"\" - qmake CONFIG+="unarr" $DEFINES_VAR - qmake -v - make + cmake -B build \ + -DDECOMPRESSION_BACKEND=unarr \ + -DBUILD_NUMBER="${{ needs.initialization.outputs.build_number }}" \ + -DCMAKE_BUILD_TYPE=Release + cmake --build build --parallel 2 - name: Run tests - run: make check TESTARGS="-maxwarnings 100000" + run: ctest --test-dir build --output-on-failure # Linux Qt6 with 7zip linux-qt6-7zip: @@ -93,11 +94,8 @@ jobs: - name: Install dependencies run: | sudo apt-get update - sudo apt-get install -y libunarr-dev libgl-dev libgles2-mesa-dev \ + sudo apt-get install -y libgl-dev libgles2-mesa-dev \ libfontconfig1-dev libfreetype-dev libxkbcommon-dev libpoppler-qt6-dev - mkdir -p ${{ github.workspace }}/compressed_archive - wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O ${{ github.workspace }}/compressed_archive/7z2301-src.7z - 7z x ${{ github.workspace }}/compressed_archive/7z2301-src.7z -o${{ github.workspace }}/compressed_archive/lib7zip - name: Install Qt uses: jurplel/install-qt-action@v4 @@ -108,13 +106,14 @@ jobs: - name: Build run: | - export DEFINES_VAR=DEFINES+=\"BUILD_NUMBER=\\\\\\\"${{ needs.initialization.outputs.build_number }}\\\\\\\"\" - qmake CONFIG+="7zip" $DEFINES_VAR - qmake -v - make + cmake -B build \ + -DDECOMPRESSION_BACKEND=7zip \ + -DBUILD_NUMBER="${{ needs.initialization.outputs.build_number }}" \ + -DCMAKE_BUILD_TYPE=Release + cmake --build build --parallel 2 - name: Run tests - run: make check TESTARGS="-maxwarnings 100000" + run: ctest --test-dir build --output-on-failure # macOS Qt6 Universal build macos-qt6-universal: @@ -135,9 +134,6 @@ jobs: python3 -m aqt install-qt mac desktop 6.9.3 -m qt5compat qtmultimedia qtimageformats qtshadertools echo "${{ github.workspace }}/6.9.3/macos/bin" >> $GITHUB_PATH npm install -g appdmg - mkdir -p ${{ github.workspace }}/compressed_archive - wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O ${{ github.workspace }}/compressed_archive/7z2301-src.7z - 7z x ${{ github.workspace }}/compressed_archive/7z2301-src.7z -o${{ github.workspace }}/compressed_archive/lib7zip - name: Import Code Signing Certificate if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') @@ -155,11 +151,8 @@ jobs: SKIP_CODESIGN=$(echo "$SKIP_CODESIGN" | tr '[:upper:]' '[:lower:]') ./compileOSX.sh $VERSION ${{ needs.initialization.outputs.build_number }} $SKIP_CODESIGN Qt6 universal - - name: Build and run tests - run: | - cd tests - qmake - make check TESTARGS="-maxwarnings 100000" + - name: Run tests + run: ctest --test-dir build --output-on-failure - name: Notarize if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') @@ -180,13 +173,13 @@ jobs: needs: [initialization, code-format-validation] steps: - uses: actions/checkout@v4 - + - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.10' architecture: 'x64' - + - name: Install dependencies shell: cmd run: | @@ -197,43 +190,23 @@ jobs: dir C:\Qt\6.9.3\msvc2022_64\bin choco install -y wget choco install innosetup - mkdir %GITHUB_WORKSPACE%\compressed_archive - wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O %GITHUB_WORKSPACE%\compressed_archive\7z2301-src.7z - 7z x %GITHUB_WORKSPACE%\compressed_archive\7z2301-src.7z -o%GITHUB_WORKSPACE%\compressed_archive\lib7zip wget "https://aka.ms/vs/17/release/vc_redist.x64.exe" -O %GITHUB_WORKSPACE%\vc_redist.x64.exe - - - name: Check MSVC installations - shell: pwsh - run: | - Write-Host "=== Checking for VS 2019 installation ===" - if (Test-Path "C:\Program Files (x86)\Microsoft Visual Studio\2019") { - Get-ChildItem "C:\Program Files (x86)\Microsoft Visual Studio\2019" -Recurse -Depth 2 - } else { - Write-Host "VS 2019 path does not exist" - } - Write-Host "`n=== Checking VS 2022 MSVC Tools ===" - if (Test-Path "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC") { - Get-ChildItem "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC" - } - Write-Host "`n=== Testing vcvars with -vcvars_ver=14.29 ===" - cmd /c '"C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" -vcvars_ver=14.29 && set' | Select-String -Pattern "MSVC|VCTools" - + - name: Build shell: cmd run: | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" set PATH=C:\Qt\6.9.3\msvc2022_64\bin;%PATH% - set DEFINES_VAR=DEFINES+="BUILD_NUMBER=\\\\\\\"${{ needs.initialization.outputs.build_number }}\\\\\\\"" - qmake CONFIG+="7zip" %DEFINES_VAR% - nmake - + cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DDECOMPRESSION_BACKEND=7zip -DBUILD_NUMBER="${{ needs.initialization.outputs.build_number }}" -DCMAKE_PREFIX_PATH=C:\Qt\6.9.3\msvc2022_64 + cmake --build build --parallel + - name: Run tests shell: cmd run: | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" set PATH=C:\Qt\6.9.3\msvc2022_64\bin;%PATH% - nmake check TESTARGS="-maxwarnings 100000" - + ctest --test-dir build --output-on-failure + - name: Upload executables for signing if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') uses: actions/upload-artifact@v4 @@ -241,10 +214,10 @@ jobs: with: name: windows-x64-qt6-executables-unsigned-${{ needs.initialization.outputs.build_number }} path: | - release64/YACReader.exe - release64/YACReaderLibrary.exe - release64/YACReaderLibraryServer.exe - + build/bin/YACReader.exe + build/bin/YACReaderLibrary.exe + build/bin/YACReaderLibraryServer.exe + - name: Sign executables with SignPath if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') uses: signpath/github-action-submit-signing-request@v1 @@ -257,22 +230,22 @@ jobs: github-artifact-id: ${{ steps.upload_executables.outputs.artifact-id }} wait-for-completion: true wait-for-completion-timeout-in-seconds: "7200" - output-artifact-directory: release64/signed - + output-artifact-directory: build/bin/signed + - name: Replace with signed executables if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') shell: pwsh run: | Write-Host "=== Replacing executables with signed versions ===" - Get-ChildItem -Path "release64/signed" -Filter "*.exe" | ForEach-Object { - $destPath = "release64/$($_.Name)" + Get-ChildItem -Path "build/bin/signed" -Filter "*.exe" | ForEach-Object { + $destPath = "build/bin/$($_.Name)" Write-Host "Moving signed: $($_.Name) -> $destPath" Move-Item -Path $_.FullName -Destination $destPath -Force Write-Host " Moved successfully" } - Remove-Item -Path "release64/signed" -Recurse -Force -ErrorAction SilentlyContinue + Remove-Item -Path "build/bin/signed" -Recurse -Force -ErrorAction SilentlyContinue Write-Host "Signed executables are ready for installer creation" - + - name: Create installer shell: cmd working-directory: ci/win @@ -280,7 +253,7 @@ jobs: call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" set PATH=C:\Qt\6.9.3\msvc2022_64\bin;%PATH% .\create_installer.cmd x64 7z ${{ needs.initialization.outputs.build_number }} - + - name: Verify installer was created if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') shell: pwsh @@ -289,7 +262,7 @@ jobs: throw "Installer file was not created" } Get-ChildItem "ci/win/Output/YACReader*.exe" - + - name: Upload unsigned installer if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') uses: actions/upload-artifact@v4 @@ -297,7 +270,7 @@ jobs: with: name: windows-x64-qt6-unsigned-${{ needs.initialization.outputs.build_number }} path: ci/win/Output/YACReader*.exe - + - name: Submit to SignPath if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') uses: signpath/github-action-submit-signing-request@v1 @@ -311,14 +284,14 @@ jobs: wait-for-completion: true wait-for-completion-timeout-in-seconds: "7200" output-artifact-directory: ci/win/Output/signed - + - name: Replace with signed installer if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') shell: pwsh run: | Write-Host "=== Files in signed directory before move ===" Get-ChildItem -Path "ci/win/Output/signed" -Filter "*.exe" | ForEach-Object { Write-Host " $($_.Name) - $($_.Length) bytes" } - + $signedFiles = Get-ChildItem -Path "ci/win/Output/signed" -Filter "*.exe" foreach ($signedFile in $signedFiles) { $destPath = "ci/win/Output/$($signedFile.Name)" @@ -326,13 +299,13 @@ jobs: Move-Item -Path $signedFile.FullName -Destination $destPath -Force Write-Host " Moved successfully" } - + Write-Host "=== Files in Output directory after move ===" Get-ChildItem -Path "ci/win/Output" -Filter "*.exe" | ForEach-Object { Write-Host " $($_.Name) - $($_.Length) bytes" } - + Remove-Item -Path "ci/win/Output/signed" -Recurse -Force -ErrorAction SilentlyContinue Write-Host "Cleaned up signed directory" - + - name: Upload installer uses: actions/upload-artifact@v4 with: @@ -346,13 +319,13 @@ jobs: needs: [initialization, code-format-validation] steps: - uses: actions/checkout@v4 - + - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.10' architecture: 'x64' - + - name: Install dependencies shell: cmd run: | @@ -363,26 +336,16 @@ jobs: dir C:\Qt\6.9.3\msvc2022_arm64\bin choco install -y wget choco install innosetup - mkdir %GITHUB_WORKSPACE%\compressed_archive - wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O %GITHUB_WORKSPACE%\compressed_archive\7z2301-src.7z - 7z x %GITHUB_WORKSPACE%\compressed_archive\7z2301-src.7z -o%GITHUB_WORKSPACE%\compressed_archive\lib7zip wget "https://aka.ms/vs/17/release/vc_redist.arm64.exe" -O %GITHUB_WORKSPACE%\vc_redist.arm64.exe - - - name: Prepare Build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64 - set PATH=C:\Qt\6.9.3\msvc2022_arm64\bin;%PATH% - set DEFINES_VAR=DEFINES+="BUILD_NUMBER=\\\\\\\"${{ needs.initialization.outputs.build_number }}\\\\\\\"" - qmake CONFIG+="7zip" %DEFINES_VAR% - - - name: Build + + - name: Build shell: cmd run: | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64 set PATH=C:\Qt\6.9.3\msvc2022_arm64\bin;%PATH% - nmake - + cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DDECOMPRESSION_BACKEND=7zip -DBUILD_NUMBER="${{ needs.initialization.outputs.build_number }}" -DCMAKE_PREFIX_PATH=C:\Qt\6.9.3\msvc2022_arm64 -DQT_HOST_PATH=C:\Qt\6.9.3\msvc2022_64 -DCMAKE_SYSTEM_PROCESSOR=ARM64 + cmake --build build --parallel + - name: Upload executables for signing if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') uses: actions/upload-artifact@v4 @@ -390,10 +353,10 @@ jobs: with: name: windows-arm64-qt6-executables-unsigned-${{ needs.initialization.outputs.build_number }} path: | - release/YACReader.exe - release/YACReaderLibrary.exe - release/YACReaderLibraryServer.exe - + build/bin/YACReader.exe + build/bin/YACReaderLibrary.exe + build/bin/YACReaderLibraryServer.exe + - name: Submit to SignPath if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') uses: signpath/github-action-submit-signing-request@v1 @@ -406,25 +369,25 @@ jobs: github-artifact-id: ${{ steps.upload_executables.outputs.artifact-id }} wait-for-completion: true wait-for-completion-timeout-in-seconds: "7200" - output-artifact-directory: 'release/signed' - + output-artifact-directory: 'build/bin/signed' + - name: Replace executables with signed versions if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') shell: pwsh run: | - Copy-Item "release/signed/YACReader.exe" "release/YACReader.exe" -Force - Copy-Item "release/signed/YACReaderLibrary.exe" "release/YACReaderLibrary.exe" -Force - Copy-Item "release/signed/YACReaderLibraryServer.exe" "release/YACReaderLibraryServer.exe" -Force - Remove-Item -Path "release/signed" -Recurse -Force -ErrorAction SilentlyContinue + Copy-Item "build/bin/signed/YACReader.exe" "build/bin/YACReader.exe" -Force + Copy-Item "build/bin/signed/YACReaderLibrary.exe" "build/bin/YACReaderLibrary.exe" -Force + Copy-Item "build/bin/signed/YACReaderLibraryServer.exe" "build/bin/YACReaderLibraryServer.exe" -Force + Remove-Item -Path "build/bin/signed" -Recurse -Force -ErrorAction SilentlyContinue Write-Host "Signed executables are ready for installer creation" - + - name: Create installer shell: cmd working-directory: ci/win run: | set PATH=C:\Qt\6.9.3\msvc2022_64\bin;%PATH% .\create_installer.cmd arm64 7z ${{ needs.initialization.outputs.build_number }} - + - name: Verify installer was created if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') shell: pwsh @@ -433,7 +396,7 @@ jobs: throw "Installer file was not created" } Get-ChildItem "ci/win/Output/YACReader*.exe" - + - name: Upload unsigned installer if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') uses: actions/upload-artifact@v4 @@ -441,7 +404,7 @@ jobs: with: name: windows-arm64-qt6-unsigned-${{ needs.initialization.outputs.build_number }} path: ci/win/Output/YACReader*.exe - + - name: Submit to SignPath if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') uses: signpath/github-action-submit-signing-request@v1 @@ -455,7 +418,7 @@ jobs: wait-for-completion: true wait-for-completion-timeout-in-seconds: "7200" output-artifact-directory: 'ci/win/Output/signed' - + - name: Replace with signed installer and cleanup if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') shell: pwsh @@ -469,7 +432,7 @@ jobs: } Remove-Item -Path "signed" -Recurse -Force -ErrorAction SilentlyContinue Write-Host "Cleaned up signed directory" - + - name: Upload installer uses: actions/upload-artifact@v4 with: @@ -483,16 +446,16 @@ jobs: needs: [initialization, code-format-validation] steps: - uses: actions/checkout@v4 - + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - + - name: Build amd64 Image working-directory: docker run: | - docker build --no-cache --platform linux/amd64 -f Dockerfile -t yacreader/yacreaderlibraryserver:develop-amd64 . + docker build --no-cache --platform linux/amd64 -f Dockerfile --build-arg YACR_VERSION=${{ github.head_ref || github.ref_name }} -t yacreader/yacreaderlibraryserver:develop-amd64 . docker save yacreader/yacreaderlibraryserver:develop-amd64 -o amd64.tar - + - name: Upload Docker Image uses: actions/upload-artifact@v4 with: @@ -506,13 +469,13 @@ jobs: needs: [initialization, code-format-validation] steps: - uses: actions/checkout@v4 - + - name: Build arm64 Image (native) working-directory: docker run: | - docker build --no-cache -f Dockerfile.aarch64 -t yacreader/yacreaderlibraryserver:develop-arm64 . + docker build --no-cache -f Dockerfile.aarch64 --build-arg YACR_VERSION=${{ github.head_ref || github.ref_name }} -t yacreader/yacreaderlibraryserver:develop-arm64 . docker save yacreader/yacreaderlibraryserver:develop-arm64 -o arm64.tar - + - name: Upload Docker Image uses: actions/upload-artifact@v4 with: @@ -535,12 +498,12 @@ jobs: - docker-arm64 steps: - uses: actions/checkout@v4 - + - name: Download all artifacts uses: actions/download-artifact@v4 with: path: artifacts - + - name: List downloaded artifacts run: | echo "=== All artifacts downloaded ===" @@ -548,7 +511,7 @@ jobs: echo "" echo "=== Windows artifacts only ===" ls -l artifacts/windows-*/ - + - name: Flatten artifacts (exclude unsigned Windows installers) run: | mkdir -p staging @@ -560,20 +523,20 @@ jobs: echo "" echo "=== Windows installers in staging ===" ls -lh staging/YACReader*.exe || echo "No Windows installers found" - + - name: Verify Windows installer signatures run: | echo "=== Installing osslsigncode to verify signatures ===" sudo apt-get update sudo apt-get install -y osslsigncode - + echo "" echo "=== Checking signatures on Windows installers ===" for installer in staging/YACReader*.exe; do if [ -f "$installer" ]; then echo "Checking: $(basename $installer)" echo "File size: $(stat -c%s $installer) bytes" - + # Try to extract signature info if osslsigncode verify -in "$installer" 2>&1 | grep -q "Signature verification: ok"; then echo " ✓ SIGNED - Signature verified successfully" @@ -585,26 +548,26 @@ jobs: echo "" fi done - + echo "=== Summary ===" echo "Total installers in staging: $(ls staging/YACReader*.exe 2>/dev/null | wc -l)" - + - name: Get version id: version run: | VERSION="$(cat common/yacreader_global.h | grep '#define VERSION "' | tr -d '#define VERSION' | tr -d '"' ).${{ needs.initialization.outputs.build_number }}" echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" - + - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - + - name: Push Docker Images run: | for arch in amd64 arm64; do @@ -612,12 +575,12 @@ jobs: docker push yacreader/yacreaderlibraryserver:develop-${arch} rm staging/${arch}.tar done - + docker buildx imagetools create \ -t yacreader/yacreaderlibraryserver:develop \ yacreader/yacreaderlibraryserver:develop-amd64 \ yacreader/yacreaderlibraryserver:develop-arm64 - + - name: Create GitHub Release uses: softprops/action-gh-release@v1 with: @@ -645,12 +608,12 @@ jobs: - docker-arm64 steps: - uses: actions/checkout@v4 - + - name: Download all artifacts uses: actions/download-artifact@v4 with: path: artifacts - + - name: List downloaded artifacts run: | echo "=== All artifacts downloaded ===" @@ -658,7 +621,7 @@ jobs: echo "" echo "=== Windows artifacts only ===" ls -l artifacts/windows-*/ - + - name: Flatten artifacts (exclude unsigned Windows installers) run: | mkdir -p staging @@ -670,20 +633,20 @@ jobs: echo "" echo "=== Windows installers in staging ===" ls -lh staging/YACReader*.exe || echo "No Windows installers found" - + - name: Verify Windows installer signatures run: | echo "=== Installing osslsigncode to verify signatures ===" sudo apt-get update sudo apt-get install -y osslsigncode - + echo "" echo "=== Checking signatures on Windows installers ===" for installer in staging/YACReader*.exe; do if [ -f "$installer" ]; then echo "Checking: $(basename $installer)" echo "File size: $(stat -c%s $installer) bytes" - + # Try to extract signature info if osslsigncode verify -in "$installer" 2>&1 | grep -q "Signature verification: ok"; then echo " ✓ SIGNED - Signature verified successfully" @@ -695,26 +658,26 @@ jobs: echo "" fi done - + echo "=== Summary ===" echo "Total installers in staging: $(ls staging/YACReader*.exe 2>/dev/null | wc -l)" - + - name: Get version id: version run: | VERSION="$(cat common/yacreader_global.h | grep '#define VERSION "' | tr -d '#define VERSION' | tr -d '"' )" echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" - + - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - + - name: Push Docker Images run: | for arch in amd64 arm64; do @@ -723,17 +686,17 @@ jobs: docker push yacreader/yacreaderlibraryserver:latest-${arch} rm staging/${arch}.tar done - + docker buildx imagetools create \ -t yacreader/yacreaderlibraryserver:latest \ yacreader/yacreaderlibraryserver:latest-amd64 \ yacreader/yacreaderlibraryserver:latest-arm64 - + docker buildx imagetools create \ -t yacreader/yacreaderlibraryserver:${{ steps.version.outputs.version }} \ yacreader/yacreaderlibraryserver:latest-amd64 \ yacreader/yacreaderlibraryserver:latest-arm64 - + - name: Create GitHub Release uses: softprops/action-gh-release@v1 with: diff --git a/.gitignore b/.gitignore index f3b81f389..e90e8a215 100644 --- a/.gitignore +++ b/.gitignore @@ -6,10 +6,6 @@ dependencies/create-dmg signapps.sh lib7zip libp7zip -YACReader/build -YACReaderLibrary/build -YACReaderLibraryServer/build -build/ # C++ objects and libs *.slo @@ -24,16 +20,7 @@ build/ *.pch *.obj -# Qt-es -object_script.*.Release -object_script.*.Debug -*_plugin_import.cpp -/.qmake.cache -/.qmake.stash -*.pro.user -*.pro.user.* -*.qbs.user -*.qbs.user.* +# Qt generated files *.moc moc_*.cpp moc_*.h @@ -41,41 +28,43 @@ qrc_*.cpp ui_*.h *.qmlc *.jsc -Makefile* -*build-* -*.build* -*.app* -*.pbxproj -*.mak -*.xcworkspace* -*xcshareddata* -*.swp *.qm # Qt unit tests target_wrapper.* # QtCreator +.qtcreator/ *.autosave - -# QtCreator Qml *.qmlproject.user *.qmlproject.user.* - -# QtCreator CMake CMakeLists.txt.user* *.stash +*build-* +*.build* + +# CMake +build*/ +CMakeCache.txt +CMakeFiles/ +cmake_install.cmake +CMakeUserPresets.json +# IDE / platform +*.app* +*.pbxproj +*.xcworkspace* +*xcshareddata* +*.swp *.plist *.dmg - YACReaderLibrary/YACReaderLibrary\.xcodeproj/ .DS_Store -compressed_archive/libp7zip -c_x86_64.pch - compile_commands.json .ccls-cache +compressed_archive/libp7zip +c_x86_64.pch + # Claude Code .claude/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..badd9f259 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,191 @@ +cmake_minimum_required(VERSION 3.25) + +project(YACReader + VERSION 10.0.0 + LANGUAGES C CXX +) + +# Enable Objective-C/C++ on Apple platforms +if(APPLE) + enable_language(OBJC) + enable_language(OBJCXX) +endif() + +# Enforce out-of-source build +file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" _in_source_check) +if(EXISTS "${_in_source_check}") + message(FATAL_ERROR "In-source builds are not allowed. Use: cmake -B build") +endif() + +# C++ standard +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Default build type (single-config generators only) +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Release" "MinSizeRel" "RelWithDebInfo") +endif() + +# Install paths +include(GNUInstallDirs) +find_package(PkgConfig) + +# Compiler options (MSVC flags, NOMINMAX, etc.) +include(cmake/CompilerOptions.cmake) + +# --- Build options --- + +# Archive decompression backend (mutually exclusive) +set(DECOMPRESSION_BACKEND "" CACHE STRING "Archive backend: unarr | 7zip | libarchive") +set_property(CACHE DECOMPRESSION_BACKEND PROPERTY STRINGS "unarr" "7zip" "libarchive") + +# PDF rendering backend (mutually exclusive) +set(PDF_BACKEND "" CACHE STRING "PDF backend: pdfium | poppler | pdfkit | no_pdf") +set_property(CACHE PDF_BACKEND PROPERTY STRINGS "pdfium" "poppler" "pdfkit" "no_pdf") + +# Build configuration +option(BUILD_TESTS "Build tests" ON) +option(BUILD_SERVER_STANDALONE "Server standalone install (Linux only)" OFF) + +# Build number (set by CI) +set(BUILD_NUMBER "" CACHE STRING "CI build number") + +# --- Platform defaults (mirrors config.pri) --- +if(NOT DECOMPRESSION_BACKEND OR DECOMPRESSION_BACKEND STREQUAL "") + if(UNIX AND NOT APPLE) + set(DECOMPRESSION_BACKEND "unarr") + else() + set(DECOMPRESSION_BACKEND "7zip") + endif() + message(STATUS "DECOMPRESSION_BACKEND defaulted to: ${DECOMPRESSION_BACKEND}") +endif() + +if(NOT PDF_BACKEND OR PDF_BACKEND STREQUAL "") + if(UNIX AND NOT APPLE) + set(PDF_BACKEND "poppler") + elseif(APPLE) + set(PDF_BACKEND "pdfkit") + else() + set(PDF_BACKEND "pdfium") + endif() + message(STATUS "PDF_BACKEND defaulted to: ${PDF_BACKEND}") +endif() + +# macOS universal binary default +if(APPLE AND NOT CMAKE_OSX_ARCHITECTURES) + set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Target architectures") +endif() + +# --- Qt --- +# BUILD_SERVER_STANDALONE only needs Qt 6.4+ (no GUI/shader components required) +if(BUILD_SERVER_STANDALONE) + find_package(Qt6 6.4 REQUIRED COMPONENTS + Core + Core5Compat + Gui + LinguistTools + Network + Sql + ) +else() + find_package(Qt6 6.7 REQUIRED COMPONENTS + Core + Core5Compat + Gui + LinguistTools + Multimedia + Network + OpenGLWidgets + Quick + QuickControls2 + QuickWidgets + Qml + ShaderTools + Sql + Svg + Test + Widgets + ) +endif() +qt_standard_project_setup() + +# PDF backend detection (creates pdf_backend_iface INTERFACE target) +include(cmake/PdfBackend.cmake) + +# Output directory +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") + +# Build number define +if(BUILD_NUMBER) + add_compile_definitions("BUILD_NUMBER=\"${BUILD_NUMBER}\"") +endif() + +# --- Subdirectories (dependency order) --- +add_subdirectory(third_party) +add_subdirectory(compressed_archive) +add_subdirectory(common) + +# GUI-only subdirectories (not needed for server-standalone builds) +if(NOT BUILD_SERVER_STANDALONE) + add_subdirectory(shortcuts_management) + add_subdirectory(custom_widgets) +endif() + +add_subdirectory(YACReaderLibrary/server) + +if(NOT BUILD_SERVER_STANDALONE) + add_subdirectory(YACReaderLibrary/comic_vine) +endif() + +# Always add YACReaderLibrary: defines library_common and db_helper (shared with server) +# When BUILD_SERVER_STANDALONE=ON, only those shared targets are built (not the app) +add_subdirectory(YACReaderLibrary) + +if(NOT BUILD_SERVER_STANDALONE) + add_subdirectory(YACReader) +endif() + +add_subdirectory(YACReaderLibraryServer) + +if(BUILD_TESTS AND NOT BUILD_SERVER_STANDALONE) + enable_testing() + add_subdirectory(tests) +endif() + +# --- Linux top-level install rules --- +if(UNIX AND NOT APPLE) + # Man pages + if(EXISTS "${CMAKE_SOURCE_DIR}/YACReader.1") + install(FILES YACReader.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + endif() + if(EXISTS "${CMAKE_SOURCE_DIR}/YACReaderLibrary.1") + install(FILES YACReaderLibrary.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + endif() + + # Desktop files + if(EXISTS "${CMAKE_SOURCE_DIR}/YACReader.desktop") + install(FILES YACReader.desktop YACReaderLibrary.desktop + DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) + endif() + + # Icons + if(EXISTS "${CMAKE_SOURCE_DIR}/YACReader.svg") + install(FILES YACReader.svg YACReaderLibrary.svg + DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps) + endif() +endif() + +# Summary +message(STATUS "") +message(STATUS "YACReader ${PROJECT_VERSION} build configuration:") +message(STATUS " Decompression backend: ${DECOMPRESSION_BACKEND}") +message(STATUS " PDF backend: ${PDF_BACKEND}") +message(STATUS " Build tests: ${BUILD_TESTS}") +message(STATUS " Server standalone: ${BUILD_SERVER_STANDALONE}") +message(STATUS " Build type: ${CMAKE_BUILD_TYPE}") +if(BUILD_NUMBER) + message(STATUS " Build number: ${BUILD_NUMBER}") +endif() +message(STATUS "") diff --git a/INSTALL.md b/INSTALL.md index 8a3155f2c..182b2b55f 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,36 +1,40 @@ # Building YACReader from source -YACReader and YACReaderLibrary are build using qmake. To build and install the -program, run: +YACReader and YACReaderLibrary are built using CMake. To build from the top +source directory: ``` -qmake CONFIG+=[Options] -make -make install +cmake -B build -DCMAKE_BUILD_TYPE=Release +cmake --build build --parallel ``` -from the top source dir. For separate builds of YACReader or YACReaderLibrary, -enter their respective subfolders and run the commands from there. +To install (Linux): + +``` +cmake --install build +``` -The headless version of YACReaderLibrary is located in the YACReaderLibraryServer -folder. To build it, enter the folder and run the commands described above. ## Build dependencies: -- Qt >= 5.15 with the following modules: - - declarative - - quickcontrols - - sql - - multimedia - - imageformats - - opengl - - sql-sqlite - - network +- CMake >= 3.25 +- C++20 compiler +- Qt >= 6.7 with the following modules: + - Core, Core5Compat, Gui, Widgets + - Quick, QuickControls2, QuickWidgets, Qml + - Sql (with SQLite driver) + - Multimedia + - Network + - Svg + - OpenGLWidgets + - ShaderTools + - LinguistTools + - Test (for running tests) - Backends for pdf rendering (optional) and file decompression (see below) Not all dependencies are needed at build time. For example the qml components in YACReaderLibrary (GridView, InfoView) will only show a white page if the -required qml modules (declarative, quickcontrols) are missing. +required qml modules (Quick, QuickControls2) are missing. ## Backends @@ -38,26 +42,26 @@ required qml modules (declarative, quickcontrols) are missing. YACReader currently supports two decompression backends, 7zip and (lib)unarr. YACReader defaults to 7zip for Windows and Mac OS and unarr for Linux and other OS, but you can -override this using one of the following config options: +override this using the `DECOMPRESSION_BACKEND` option: -`CONFIG+=7zip` - -`CONFIG+=unarr` +``` +cmake -B build -DDECOMPRESSION_BACKEND=7zip +cmake -B build -DDECOMPRESSION_BACKEND=unarr +cmake -B build -DDECOMPRESSION_BACKEND=libarchive +``` #### 7zip -[7zip](https://www.7-zip.org/) and [p7zip](http://p7zip.sourceforge.net/) -are the default decompression backend for Windows and Mac OS builds. +[7zip](https://www.7-zip.org/) is the default decompression backend for Windows and Mac OS builds. -They are recommended for these systems, as they currently have better support for 7z -files and support the RAR5 format. +It is recommended for these systems, as it currently has better support for 7z +files and supports the RAR5 format. -As this backend requires specific versions of 7zip for Windows and p7zip for *NIX and -is not 100% GPL compatible (unrar License restriction), it is not recommended for -installations where you can't guarantee the installed version of (p7zip) or the license is an issue. +The 7zip source code is automatically downloaded during configuration via CMake's +FetchContent. No manual setup is needed. -To build using this backend, you need to install additional sources to the build environment. -For more information, please refer to [README_7zip](compressed_archive/README_7zip.txt). +As this backend is not 100% GPL compatible (unrar license restriction), it is not +recommended for installations where the license is an issue. #### unarr @@ -77,12 +81,18 @@ For more information, please consult the [README](compressed_archive/unarr/READM Starting with version 9.0.0 YACReader supports the following pdf rendering engines: - poppler (Linux/Unix default) -- pdfium (default for Windows and MacOS) -- pdfkit (MacOS only) +- pdfium (default for Windows) +- pdfkit (macOS default, macOS only) - no_pdf (disable pdf support) -To override the default for a given platform add CONFIG+=[pdfbackend] as an option -when running qmake. +To override the default for a given platform use the `PDF_BACKEND` option: + +``` +cmake -B build -DPDF_BACKEND=poppler +cmake -B build -DPDF_BACKEND=pdfium +cmake -B build -DPDF_BACKEND=pdfkit +cmake -B build -DPDF_BACKEND=no_pdf +``` While the Poppler backend is well tested and has been the standard for YACReader for a long time, its performance is a bit lacking. The pdfium engine offers @@ -92,33 +102,31 @@ prepackaged for Linux. ### Other build options: -You can adjust the installation prefix as well als the path "make install" uses -to install the files. +You can adjust the installation prefix: -`qmake PREFIX=DIR` - -sets the default prefix (for example "/", "/usr", "/usr/local"). - -`make install INSTALL_ROOT=DIR` +``` +cmake -B build -DCMAKE_INSTALL_PREFIX=/usr/local +``` -can be used to install to a different location, which is usefull for packaging. +Default value on Linux is `/usr`. -Default values: +For packaging, use `DESTDIR` with the install command: ``` -PREFIX=/usr -INSTALL_ROOT="" +DESTDIR=/path/to/staging cmake --install build ``` -On embedded devices that don't support desktop OpenGL, it is recommended to use -the no_opengl config option: +To build only YACReaderLibraryServer (headless server): -`qmake CONFIG+=no_opengl` +``` +cmake -B build -DBUILD_SERVER_STANDALONE=ON +``` -This will remove any dependency on desktop OpenGL and hardlock YACReader's -coverflow to software rendering. Please note that it does not actually remove -OpenGL from the build, the Qt toolkit will still make use of it. +### Running tests +``` +ctest --test-dir build --output-on-failure +``` # Feedback and contribution diff --git a/README.md b/README.md index 8df7d43ef..4e5b9c269 100644 --- a/README.md +++ b/README.md @@ -52,15 +52,21 @@ If you are interested in contributing to the project the first step should be to Contributions are not restricted to coding; you can help the project by bringing new UI/UX ideas, designing new assets, writing manuals or tutorials, translating the apps, etc. If you are interested in DevOps, YACReader uses Azure Pipelines for CI/CD, any improvements in that area are welcome. Testing pre-releases is also really appreciated. #### Dev Setup -YACReader is developed in *c++/Qt*, so the first thing you need to do is to install a *C++* compiler or environment that supports at least *C++17* and *Qt*. In *Windows* I use *Visual Studio Community Edition 2019* as build system and in *macos* I use Xcode, but I do all the coding using *QtCreator*. The project support *Qt5* and *Qt6* at the moment so you need to make sure that everything works in both *Qt5* and *Qt6*, you only need to install one flavor of *Qt* and *CI* will check that everything builds with both, I recommend using *Qt6*. +YACReader is developed in *C++/Qt* and built with *CMake*. You need a *C++20* compiler and *Qt 6.7+*. In *Windows* I use *Visual Studio 2022* and in *macOS* I use Xcode, but I do all the coding using *QtCreator*. -The repo includes binaries for the dependencies needed for *Windows* (MSVC compiler) and *macos* (clang) but you need to configure *7zip* dependency manually, please take a look at *compressed_archive/README_7zip.txt*. +The repo includes binaries for the dependencies needed for *Windows* (MSVC compiler) and *macOS* (clang). The *7zip* decompression backend source is downloaded automatically by CMake during configuration. + +To build: +``` +cmake -B build -DCMAKE_BUILD_TYPE=Release +cmake --build build --parallel +``` + +See [INSTALL.md](./INSTALL.md) for detailed build options. ##### Running and debugging YACReader needs to find its dependencies at runtime, make sure that *Qt* binaries are in your *PATH* and the third-party binaries are next to the executable. The best way to make sure you have all the third-party binaries in place is to check YACReader installation and copy the binaries in your output folder. -If you have the time and the energy, please open a PR with a script that automatizes any of these manual processes. - #### Code Format YACReader uses `clang-format` to ensure a common style and avoid deviances from it. CI checks this and will fail if the correct format is not used. `clang-format` needs to be called recursively in all the folders because some of them have their own `.clang-format` file, mainly to exclude changing the format in third-party libraries which are included in the source code. I recommend configuring your development tools to use `clang-format`, you can try to use it manually, but please, do it always before committing changes. I recommend using QtCreator configured properly, you can find a tutorial [here]( https://www.vikingsoftware.com/using-clang-format-with-qtcreator/). diff --git a/YACReader.pro b/YACReader.pro deleted file mode 100644 index f3106c4f4..000000000 --- a/YACReader.pro +++ /dev/null @@ -1,4 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS = YACReader YACReaderLibrary YACReaderLibraryServer -YACReaderLibrary.depends = YACReader -!CONFIG(no_tests): SUBDIRS += tests diff --git a/YACReader/CMakeLists.txt b/YACReader/CMakeLists.txt new file mode 100644 index 000000000..3f4010cdb --- /dev/null +++ b/YACReader/CMakeLists.txt @@ -0,0 +1,124 @@ +# YACReader - Comic Viewer + +qt_add_executable(YACReader WIN32 + configuration.h + configuration.cpp + goto_dialog.h + goto_dialog.cpp + magnifying_glass.h + magnifying_glass.cpp + main_window_viewer.h + main_window_viewer.cpp + continuous_page_widget.h + continuous_page_widget.cpp + mouse_handler.h + mouse_handler.cpp + viewer.h + viewer.cpp + options_dialog.h + options_dialog.cpp + bookmarks_dialog.h + bookmarks_dialog.cpp + render.h + render.cpp + translator.h + translator.cpp + goto_flow_widget.h + goto_flow_widget.cpp + page_label_widget.h + page_label_widget.cpp + goto_flow_toolbar.h + goto_flow_toolbar.cpp + width_slider.h + width_slider.cpp + notifications_label_widget.h + notifications_label_widget.cpp + yacreader_local_client.h + yacreader_local_client.cpp + main.cpp + # App-specific themes + shared theme_manager (depends on app theme.h) + themes/theme.h + themes/theme_factory.h + themes/theme_factory.cpp + ${CMAKE_SOURCE_DIR}/common/themes/theme_manager.h + ${CMAKE_SOURCE_DIR}/common/themes/theme_manager.cpp +) + +target_include_directories(YACReader PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/themes +) + +target_compile_definitions(YACReader PRIVATE YACREADER) + +# Resources +qt_add_resources(yacreader_images_rcc "${CMAKE_CURRENT_SOURCE_DIR}/yacreader_images.qrc") +qt_add_resources(yacreader_files_rcc "${CMAKE_CURRENT_SOURCE_DIR}/yacreader_files.qrc") +target_sources(YACReader PRIVATE + ${yacreader_images_rcc} + ${yacreader_files_rcc} +) + +# Translations +qt_add_translations(YACReader + TS_FILES + yacreader_es.ts + yacreader_fr.ts + yacreader_ru.ts + yacreader_pt.ts + yacreader_nl.ts + yacreader_tr.ts + yacreader_de.ts + yacreader_zh_CN.ts + yacreader_zh_TW.ts + yacreader_zh_HK.ts + yacreader_it.ts + yacreader_en.ts +) + +target_link_libraries(YACReader PRIVATE + Qt::Core + Qt::Gui + Qt::GuiPrivate + Qt::Network + Qt::Widgets + Qt::Multimedia + Qt::Svg + Qt::Core5Compat + comic_backend + common_gui + rhi_flow_reader + custom_widgets_reader + shortcuts_reader + cbx_backend + QsLog +) + +# Platform-specific +if(WIN32) + target_sources(YACReader PRIVATE icon.rc) + target_link_libraries(YACReader PRIVATE oleaut32 ole32 shell32 user32) +endif() + +if(APPLE) + target_sources(YACReader PRIVATE YACReader.icns) + set_source_files_properties(YACReader.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + set_target_properties(YACReader PROPERTIES + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist" + MACOSX_BUNDLE_GUI_IDENTIFIER "com.yacreader.YACReader" + MACOSX_BUNDLE_BUNDLE_NAME "YACReader" + ) + target_link_libraries(YACReader PRIVATE + "-framework Foundation" + "-framework ApplicationServices" + "-framework AppKit" + ) +endif() + +# Linux install +if(UNIX AND NOT APPLE) + target_compile_definitions(YACReader PRIVATE + "DATADIR=\"${CMAKE_INSTALL_FULL_DATADIR}\"") + install(TARGETS YACReader RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif() diff --git a/YACReader/YACReader.pro b/YACReader/YACReader.pro deleted file mode 100644 index f2bdd8f09..000000000 --- a/YACReader/YACReader.pro +++ /dev/null @@ -1,229 +0,0 @@ -TEMPLATE = app -TARGET = YACReader - -QMAKE_TARGET_BUNDLE_PREFIX = "com.yacreader" - -DEPENDPATH += . \ - release - -DEFINES += YACREADER - -#load default build flags -include (../config.pri) -include (../dependencies/pdf_backend.pri) -include (./themes/themes.pri) -include (../common/themes/themes_common.pri) - -contains(QMAKE_TARGET.arch, x86_64) { - Release:DESTDIR = ../release64 - Debug:DESTDIR = ../debug64 -} else { - Release:DESTDIR = ../release - Debug:DESTDIR = ../debug -} - -SOURCES += main.cpp - -INCLUDEPATH += ../common \ - ../custom_widgets -INCLUDEPATH += ../common/rhi - -HEADERS += ../common/rhi/flow_types.h -SOURCES += ../common/rhi/flow_types.cpp - -win32 { - LIBS += -loleaut32 -lole32 -lshell32 -luser32 - msvc { - QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL - QMAKE_LFLAGS_RELEASE += /LTCG - } - CONFIG -= embed_manifest_exe -} - -macx { - QT += gui-private - CONFIG += objective_c - LIBS += -framework Foundation -framework ApplicationServices -framework AppKit - -} - -QT += network widgets core multimedia svg - -QT += core5compat - -greaterThan(QT_MINOR_VERSION, 6): QT += gui-private - -#CONFIG += release -CONFIG -= flat - -# Sources -HEADERS += ../common/comic.h \ - configuration.h \ - goto_dialog.h \ - magnifying_glass.h \ - main_window_viewer.h \ - continuous_page_widget.h \ - mouse_handler.h \ - viewer.h \ - options_dialog.h \ - ../common/bookmarks.h \ - bookmarks_dialog.h \ - render.h \ - translator.h \ - goto_flow_widget.h \ - page_label_widget.h \ - goto_flow_toolbar.h \ - width_slider.h \ - notifications_label_widget.h \ - ../common/custom_widgets.h \ - ../common/check_new_version.h \ - ../common/qnaturalsorting.h \ - ../common/yacreader_global.h \ - ../common/yacreader_global_gui.h \ - ../common/comic_db.h \ - ../common/folder.h \ - ../common/library_item.h \ - yacreader_local_client.h \ - ../common/http_worker.h \ - ../common/exit_check.h \ - ../common/scroll_management.h \ - ../common/pdf_comic.h \ - ../common/global_info_provider.h \ - ../common/rhi/yacreader_flow_rhi.h \ - ../common/rhi/yacreader_comic_flow_rhi.h \ - ../common/rhi/yacreader_page_flow_rhi.h - - -SOURCES += ../common/comic.cpp \ - configuration.cpp \ - goto_dialog.cpp \ - magnifying_glass.cpp \ - main_window_viewer.cpp \ - continuous_page_widget.cpp \ - mouse_handler.cpp \ - viewer.cpp \ - options_dialog.cpp \ - ../common/bookmarks.cpp \ - bookmarks_dialog.cpp \ - render.cpp \ - translator.cpp \ - goto_flow_widget.cpp \ - page_label_widget.cpp \ - goto_flow_toolbar.cpp \ - width_slider.cpp \ - notifications_label_widget.cpp \ - ../common/custom_widgets.cpp \ - ../common/check_new_version.cpp \ - ../common/qnaturalsorting.cpp \ - ../common/comic_db.cpp \ - ../common/folder.cpp \ - ../common/library_item.cpp \ - yacreader_local_client.cpp \ - ../common/http_worker.cpp \ - ../common/yacreader_global.cpp \ - ../common/yacreader_global_gui.cpp \ - ../common/exit_check.cpp \ - ../common/scroll_management.cpp \ - ../common/global_info_provider.cpp \ - ../common/rhi/yacreader_flow_rhi.cpp \ - ../common/rhi/yacreader_comic_flow_rhi.cpp \ - ../common/rhi/yacreader_page_flow_rhi.cpp - -RESOURCES += ../common/rhi/shaders/shaders.qrc -# Make raw GLSL shader sources editable in Qt Creator -OTHER_FILES += ../common/rhi/shaders/flow.vert \ - ../common/rhi/shaders/flow.frag - -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:CONFIG(libarchive) { -include(../compressed_archive/libarchive/libarchive-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 \ - yacreader_files.qrc - -include(../third_party/QsLog/QsLog.pri) - -RC_FILE = icon.rc - -macx { - ICON = YACReader.icns - QMAKE_INFO_PLIST = Info.plist -} - -TRANSLATIONS = yacreader_es.ts \ - yacreader_fr.ts \ - yacreader_ru.ts \ - yacreader_pt.ts \ - yacreader_nl.ts \ - yacreader_tr.ts \ - yacreader_de.ts \ - yacreader_zh_CN.ts \ - yacreader_zh_TW.ts \ - yacreader_zh_HK.ts \ - yacreader_it.ts \ - yacreader_en.ts - -CONFIG += lrelease - -win32 { - CONFIG(release, debug|release) { - SOURCE_QM_DIR = $$OUT_PWD/release/*.qm - } - CONFIG(debug, debug|release) { - SOURCE_QM_DIR = $$OUT_PWD/debug/*.qm - } - - DEPLOYMENT_OUT_QM_DIR = ../release/languages/ - OUT_QM_DIR = $${DESTDIR}/languages/ - - QMAKE_POST_LINK += $(MKDIR) $$shell_path($${OUT_QM_DIR}) 2> NULL & \ - $(COPY) $$shell_path($${SOURCE_QM_DIR}) $$shell_path($${OUT_QM_DIR}) & \ - $(MKDIR) $$shell_path($${DEPLOYMENT_OUT_QM_DIR}) 2> NULL & \ - $(COPY) $$shell_path($${SOURCE_QM_DIR}) $$shell_path($${DEPLOYMENT_OUT_QM_DIR}) -} else { - LRELEASE_DIR = ../release/languages/ - QM_FILES_INSTALL_PATH = $$DATADIR/yacreader/languages -} - -unix:!macx { - -DEFINES += "LIBDIR=\\\"$$LIBDIR\\\"" "DATADIR=\\\"$$DATADIR\\\"" - -#MAKE INSTALL - -INSTALLS += bin docs icon desktop manpage - -bin.path = $$BINDIR -isEmpty(DESTDIR) { - bin.files = YACReader -} else { - bin.files = $$DESTDIR/YACReader -} - -docs.path = $$DATADIR/doc/yacreader - -#rename docs for better packageability -docs.extra = cp ../README.md ../README -docs.files = ../README ../CHANGELOG.md - -icon.path = $$DATADIR/icons/hicolor/scalable/apps -icon.files = ../YACReader.svg - -desktop.path = $$DATADIR/applications -desktop.files = ../YACReader.desktop - -manpage.path = $$DATADIR/man/man1 -manpage.files = ../YACReader.1 - -#remove leftover doc files when 'make clean' is invoked -QMAKE_CLEAN += "../README" -} diff --git a/YACReader/themes/themes.pri b/YACReader/themes/themes.pri deleted file mode 100644 index eee35324e..000000000 --- a/YACReader/themes/themes.pri +++ /dev/null @@ -1,7 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/theme.h \ - $$PWD/theme_factory.h -SOURCES += \ - $$PWD/theme_factory.cpp diff --git a/YACReaderLibrary/CMakeLists.txt b/YACReaderLibrary/CMakeLists.txt new file mode 100644 index 000000000..cae71e34f --- /dev/null +++ b/YACReaderLibrary/CMakeLists.txt @@ -0,0 +1,304 @@ +# YACReaderLibrary - Comic Library Manager + +# --- library_common (shared with YACReaderLibraryServer) --- +add_library(library_common STATIC + library_creator.h + library_creator.cpp + package_manager.h + package_manager.cpp + bundle_creator.h + bundle_creator.cpp + initial_comic_info_extractor.h + initial_comic_info_extractor.cpp + xml_info_parser.h + xml_info_parser.cpp + xml_info_library_scanner.h + xml_info_library_scanner.cpp + yacreader_local_server.h + yacreader_local_server.cpp + comics_remover.h + comics_remover.cpp + yacreader_libraries.h + yacreader_libraries.cpp + comic_files_manager.h + comic_files_manager.cpp + ip_config_helper.h + ip_config_helper.cpp + libraries_update_coordinator.h + libraries_update_coordinator.cpp +) +target_include_directories(library_common PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/db +) +target_link_libraries(library_common PUBLIC + Qt::Core + Qt::Core5Compat + Qt::Network + Qt::Sql + common_all + comic_backend + cbx_backend + db_helper + QsLog +) + +# --- db_helper (database layer, shared with YACReaderLibraryServer) --- +add_library(db_helper STATIC + db_helper.h + db_helper.cpp + db/data_base_management.h + db/data_base_management.cpp + db/reading_list.h + db/reading_list.cpp + db/query_lexer.h + db/query_lexer.cpp + db/query_parser.h + db/query_parser.cpp + db/search_query.h + db/search_query.cpp +) +target_include_directories(db_helper PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/db +) +target_link_libraries(db_helper PUBLIC + Qt::Core + Qt::Sql + common_all + QsLog +) + +# When BUILD_SERVER_STANDALONE=ON, only library_common and db_helper are built. +# The full YACReaderLibrary GUI app requires Qt::Widgets and other full-build components. +if(NOT BUILD_SERVER_STANDALONE) + +# --- YACReaderLibrary executable --- +qt_add_executable(YACReaderLibrary WIN32 + main.cpp + library_window.h + library_window.cpp + library_window_actions.h + library_window_actions.cpp + create_library_dialog.h + create_library_dialog.cpp + add_library_dialog.h + add_library_dialog.cpp + rename_library_dialog.h + rename_library_dialog.cpp + properties_dialog.h + properties_dialog.cpp + options_dialog.h + options_dialog.cpp + export_library_dialog.h + export_library_dialog.cpp + import_library_dialog.h + import_library_dialog.cpp + export_comics_info_dialog.h + export_comics_info_dialog.cpp + import_comics_info_dialog.h + import_comics_info_dialog.cpp + server_config_dialog.h + server_config_dialog.cpp + comic_flow_widget.h + comic_flow_widget.cpp + no_libraries_widget.h + no_libraries_widget.cpp + import_widget.h + import_widget.cpp + trayicon_controller.h + trayicon_controller.cpp + yacreader_content_views_manager.h + yacreader_content_views_manager.cpp + yacreader_main_toolbar.h + yacreader_main_toolbar.cpp + comics_view.h + comics_view.cpp + comics_view_transition.h + comics_view_transition.cpp + classic_comics_view.h + classic_comics_view.cpp + grid_comics_view.h + grid_comics_view.cpp + no_search_results_widget.h + no_search_results_widget.cpp + folder_content_view.h + folder_content_view.cpp + recent_visibility_coordinator.h + recent_visibility_coordinator.cpp + library_comic_opener.h + library_comic_opener.cpp + db/comic_query_result_processor.h + db/comic_query_result_processor.cpp + db/folder_query_result_processor.h + db/folder_query_result_processor.cpp + db/folder_item.h + db/folder_item.cpp + db/folder_model.h + db/folder_model.cpp + db/comic_model.h + db/comic_model.cpp + db/comic_item.h + db/comic_item.cpp + db/reading_list_model.h + db/reading_list_model.cpp + db/reading_list_item.h + db/reading_list_item.cpp + yacreader_folders_view.h + yacreader_folders_view.cpp + yacreader_reading_lists_view.h + yacreader_reading_lists_view.cpp + add_label_dialog.h + add_label_dialog.cpp + yacreader_history_controller.h + yacreader_history_controller.cpp + yacreader_navigation_controller.h + yacreader_navigation_controller.cpp + empty_label_widget.h + empty_label_widget.cpp + empty_folder_widget.h + empty_folder_widget.cpp + empty_container_info.h + empty_container_info.cpp + empty_special_list.h + empty_special_list.cpp + empty_reading_list_widget.h + empty_reading_list_widget.cpp + info_comics_view.h + info_comics_view.cpp + yacreader_comics_selection_helper.h + yacreader_comics_selection_helper.cpp + yacreader_comic_info_helper.h + yacreader_comic_info_helper.cpp + current_comic_view_helper.h + current_comic_view_helper.cpp + # App-specific themes + shared theme_manager (depends on app theme.h) + themes/theme.h + themes/theme_factory.h + themes/theme_factory.cpp + ${CMAKE_SOURCE_DIR}/common/themes/theme_manager.h + ${CMAKE_SOURCE_DIR}/common/themes/theme_manager.cpp +) + +# macOS-specific sources +if(APPLE) + target_sources(YACReaderLibrary PRIVATE + trayhandler.h + trayhandler.mm + ) +endif() + +target_include_directories(YACReaderLibrary PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/db + ${CMAKE_CURRENT_SOURCE_DIR}/themes +) + +target_compile_definitions(YACReaderLibrary PRIVATE + SERVER_RELEASE + YACREADER_LIBRARY +) + +# Resources +qt_add_resources(yacreaderlibrary_images_rcc "${CMAKE_CURRENT_SOURCE_DIR}/images.qrc") +qt_add_resources(yacreaderlibrary_files_rcc "${CMAKE_CURRENT_SOURCE_DIR}/files.qrc") +qt_add_resources(yacreaderlibrary_qml_rcc "${CMAKE_CURRENT_SOURCE_DIR}/qml.qrc") +target_sources(YACReaderLibrary PRIVATE + ${yacreaderlibrary_images_rcc} + ${yacreaderlibrary_files_rcc} + ${yacreaderlibrary_qml_rcc} +) +if(WIN32 OR (UNIX AND NOT APPLE)) + qt_add_resources(yacreaderlibrary_images_win_rcc "${CMAKE_CURRENT_SOURCE_DIR}/images_win.qrc") + target_sources(YACReaderLibrary PRIVATE ${yacreaderlibrary_images_win_rcc}) +endif() +if(APPLE) + qt_add_resources(yacreaderlibrary_images_osx_rcc "${CMAKE_CURRENT_SOURCE_DIR}/images_osx.qrc") + target_sources(YACReaderLibrary PRIVATE ${yacreaderlibrary_images_osx_rcc}) +endif() + +# Translations +qt_add_translations(YACReaderLibrary + TS_FILES + yacreaderlibrary_es.ts + yacreaderlibrary_ru.ts + yacreaderlibrary_pt.ts + yacreaderlibrary_fr.ts + yacreaderlibrary_nl.ts + yacreaderlibrary_tr.ts + yacreaderlibrary_de.ts + yacreaderlibrary_zh_CN.ts + yacreaderlibrary_zh_TW.ts + yacreaderlibrary_zh_HK.ts + yacreaderlibrary_it.ts + yacreaderlibrary_en.ts +) + +target_link_libraries(YACReaderLibrary PRIVATE + Qt::Core + Qt::Gui + Qt::GuiPrivate + Qt::Network + Qt::Widgets + Qt::Sql + Qt::Svg + Qt::Quick + Qt::Qml + Qt::QuickWidgets + Qt::QuickControls2 + Qt::Core5Compat + library_common + db_helper + comic_backend + common_gui + rhi_flow_library + custom_widgets_library + shortcuts_library + server + comic_vine + cbx_backend + concurrent_queue + worker + QsLog + QrCode + KDSignalThrottler +) + +# Platform-specific +if(WIN32) + target_sources(YACReaderLibrary PRIVATE icon.rc) + target_link_libraries(YACReaderLibrary PRIVATE oleaut32 ole32 shell32 user32) +endif() + +if(APPLE) + target_sources(YACReaderLibrary PRIVATE YACReaderLibrary.icns) + set_source_files_properties(YACReaderLibrary.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + set_target_properties(YACReaderLibrary PROPERTIES + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist" + MACOSX_BUNDLE_GUI_IDENTIFIER "com.yacreader.YACReaderLibrary" + MACOSX_BUNDLE_BUNDLE_NAME "YACReaderLibrary" + ) + target_link_libraries(YACReaderLibrary PRIVATE + "-framework Foundation" + "-framework ApplicationServices" + "-framework AppKit" + ) +endif() + +# Linux install +if(UNIX AND NOT APPLE) + target_compile_definitions(YACReaderLibrary PRIVATE + "LIBDIR=\"${CMAKE_INSTALL_FULL_LIBDIR}\"" + "DATADIR=\"${CMAKE_INSTALL_FULL_DATADIR}\"" + "BINDIR=\"${CMAKE_INSTALL_FULL_BINDIR}\"") + install(TARGETS YACReaderLibrary RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + + # Server web files (for bundled server mode) + if(NOT BUILD_SERVER_STANDALONE) + install(DIRECTORY ${CMAKE_SOURCE_DIR}/release/server + DESTINATION ${CMAKE_INSTALL_DATADIR}/yacreader) + endif() +endif() + +endif() # NOT BUILD_SERVER_STANDALONE (YACReaderLibrary executable) diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro deleted file mode 100644 index 2755861ff..000000000 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ /dev/null @@ -1,343 +0,0 @@ -TEMPLATE = app -TARGET = YACReaderLibrary - -QMAKE_TARGET_BUNDLE_PREFIX = "com.yacreader" - -DEPENDPATH += . -INCLUDEPATH += . \ - ../common \ - ./server \ - ./db \ - ../custom_widgets \ - ./comic_vine \ - ./comic_vine/model - -DEFINES += SERVER_RELEASE YACREADER_LIBRARY - -# load default build flags -include (../config.pri) -include (../dependencies/pdf_backend.pri) - -INCLUDEPATH += ../common/rhi - -win32 { - LIBS += -loleaut32 -lole32 -lshell32 -luser32 - msvc { - QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL - QMAKE_LFLAGS_RELEASE += /LTCG - } - CONFIG -= embed_manifest_exe -} - -contains(QMAKE_TARGET.arch, x86_64) { - Release:DESTDIR = ../release64 - Debug:DESTDIR = ../debug64 -} else { - Release:DESTDIR = ../release - Debug:DESTDIR = ../debug -} - -macx { - LIBS += -framework Foundation -framework ApplicationServices -framework AppKit - CONFIG += objective_c - QT += gui-private -} - -#CONFIG += release -CONFIG -= flat -QT += sql network widgets svg quickcontrols2 - -QT += core5compat - -greaterThan(QT_MINOR_VERSION, 6): QT += gui-private - -# Input -HEADERS += \ - ../common/concurrent_queue.h \ - ../common/cover_utils.h \ - create_library_dialog.h \ - db/comic_query_result_processor.h \ - db/folder_query_result_processor.h \ - db/query_lexer.h \ - db/search_query.h \ - folder_content_view.h \ - initial_comic_info_extractor.h \ - libraries_update_coordinator.h \ - library_comic_opener.h \ - library_creator.h \ - library_window.h \ - add_library_dialog.h \ - library_window_actions.h \ - recent_visibility_coordinator.h \ - rename_library_dialog.h \ - properties_dialog.h \ - options_dialog.h \ - export_library_dialog.h \ - import_library_dialog.h \ - package_manager.h \ - bundle_creator.h \ - export_comics_info_dialog.h \ - import_comics_info_dialog.h \ - server_config_dialog.h \ - comic_flow_widget.h \ - db_helper.h \ - ./db/data_base_management.h \ - ./db/folder_item.h \ - ./db/folder_model.h \ - ./db/comic_model.h \ - ./db/comic_item.h \ - ../common/comic_db.h \ - ../common/folder.h \ - ../common/library_item.h \ - ../common/comic.h \ - ../common/bookmarks.h \ - ../common/release_acquire_atomic.h \ - ../common/worker_thread.h \ - ../common/custom_widgets.h \ - ../common/qnaturalsorting.h \ - ../common/yacreader_global.h \ - ../common/yacreader_global_gui.h \ - ../common/pdf_comic.h \ - no_libraries_widget.h \ - import_widget.h \ - trayicon_controller.h \ - xml_info_library_scanner.h \ - xml_info_parser.h \ - yacreader_content_views_manager.h \ - yacreader_local_server.h \ - yacreader_main_toolbar.h \ - comics_remover.h \ - ../common/http_worker.h \ - yacreader_libraries.h \ - ../common/exit_check.h \ - comics_view.h \ - classic_comics_view.h \ - no_search_results_widget.h \ - comic_files_manager.h \ - db/reading_list_model.h \ - db/reading_list_item.h \ - yacreader_folders_view.h \ - yacreader_reading_lists_view.h \ - add_label_dialog.h \ - yacreader_history_controller.h \ - yacreader_navigation_controller.h \ - empty_label_widget.h \ - empty_folder_widget.h \ - empty_container_info.h \ - empty_special_list.h \ - empty_reading_list_widget.h \ - ../common/scroll_management.h \ - info_comics_view.h \ - yacreader_comics_selection_helper.h \ - yacreader_comic_info_helper.h \ - db/reading_list.h \ - db/query_parser.h \ - current_comic_view_helper.h \ - ip_config_helper.h \ - ../common/global_info_provider.h \ - ../common/rhi/flow_types.h \ - ../common/rhi/yacreader_flow_rhi.h \ - ../common/rhi/yacreader_comic_flow_rhi.h \ - ../common/rhi/yacreader_page_flow_rhi.h - -SOURCES += \ - ../common/concurrent_queue.cpp \ - ../common/cover_utils.cpp \ - create_library_dialog.cpp \ - db/comic_query_result_processor.cpp \ - db/folder_query_result_processor.cpp \ - db/query_lexer.cpp \ - db/search_query.cpp \ - folder_content_view.cpp \ - initial_comic_info_extractor.cpp \ - libraries_update_coordinator.cpp \ - library_comic_opener.cpp \ - library_creator.cpp \ - library_window.cpp \ - library_window_actions.cpp \ - main.cpp \ - add_library_dialog.cpp \ - recent_visibility_coordinator.cpp \ - rename_library_dialog.cpp \ - properties_dialog.cpp \ - options_dialog.cpp \ - export_library_dialog.cpp \ - import_library_dialog.cpp \ - package_manager.cpp \ - bundle_creator.cpp \ - export_comics_info_dialog.cpp \ - import_comics_info_dialog.cpp \ - server_config_dialog.cpp \ - comic_flow_widget.cpp \ - db_helper.cpp \ - ./db/data_base_management.cpp \ - ./db/folder_item.cpp \ - ./db/folder_model.cpp \ - ./db/comic_model.cpp \ - ./db/comic_item.cpp \ - ../common/comic_db.cpp \ - ../common/folder.cpp \ - ../common/library_item.cpp \ - ../common/comic.cpp \ - ../common/bookmarks.cpp \ - ../common/custom_widgets.cpp \ - ../common/qnaturalsorting.cpp \ - no_libraries_widget.cpp \ - import_widget.cpp \ - trayicon_controller.cpp \ - xml_info_library_scanner.cpp \ - xml_info_parser.cpp \ - yacreader_content_views_manager.cpp \ - yacreader_local_server.cpp \ - yacreader_main_toolbar.cpp \ - comics_remover.cpp \ - ../common/http_worker.cpp \ - ../common/yacreader_global.cpp \ - ../common/yacreader_global_gui.cpp \ - yacreader_libraries.cpp \ - ../common/exit_check.cpp \ - comics_view.cpp \ - classic_comics_view.cpp \ - no_search_results_widget.cpp \ - comic_files_manager.cpp \ - db/reading_list_model.cpp \ - db/reading_list_item.cpp \ - yacreader_folders_view.cpp \ - yacreader_reading_lists_view.cpp \ - add_label_dialog.cpp \ - yacreader_history_controller.cpp \ - yacreader_navigation_controller.cpp \ - empty_label_widget.cpp \ - empty_folder_widget.cpp \ - empty_container_info.cpp \ - empty_special_list.cpp \ - empty_reading_list_widget.cpp \ - ../common/scroll_management.cpp \ - info_comics_view.cpp \ - yacreader_comics_selection_helper.cpp \ - yacreader_comic_info_helper.cpp\ - db/reading_list.cpp \ - current_comic_view_helper.cpp \ - db/query_parser.cpp \ - ip_config_helper.cpp \ - ../common/global_info_provider.cpp \ - ../common/rhi/flow_types.cpp \ - ../common/rhi/yacreader_flow_rhi.cpp \ - ../common/rhi/yacreader_comic_flow_rhi.cpp \ - ../common/rhi/yacreader_page_flow_rhi.cpp - - RESOURCES += ../common/rhi/shaders/shaders.qrc - # Make raw GLSL shader sources editable in Qt Creator - OTHER_FILES += ../common/rhi/shaders/flow.vert \ - ../common/rhi/shaders/flow.frag - -macx { - HEADERS += trayhandler.h - OBJECTIVE_SOURCES += trayhandler.mm -} - -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:CONFIG(libarchive) { -include(../compressed_archive/libarchive/libarchive-wrapper.pri) -} else { - error(No compression backend specified. Did you mess with the build system?) -} - -include(./comic_vine/comic_vine.pri) -include(../third_party/QsLog/QsLog.pri) -include(../shortcuts_management/shortcuts_management.pri) -include(../third_party/QrCode/QrCode.pri) -include(../third_party/KDToolBox/KDToolBox.pri) -include(./themes/themes.pri) -include(../common/themes/themes_common.pri) - -RESOURCES += images.qrc files.qrc -win32:RESOURCES += images_win.qrc -unix:!macx:RESOURCES += images_win.qrc -macx:RESOURCES += images_osx.qrc - -RC_FILE = icon.rc - -macx { - ICON = YACReaderLibrary.icns - QMAKE_INFO_PLIST = Info.plist -} - -TRANSLATIONS = yacreaderlibrary_es.ts \ - yacreaderlibrary_ru.ts \ - yacreaderlibrary_pt.ts \ - yacreaderlibrary_fr.ts \ - yacreaderlibrary_nl.ts \ - yacreaderlibrary_tr.ts \ - yacreaderlibrary_de.ts \ - yacreaderlibrary_zh_CN.ts \ - yacreaderlibrary_zh_TW.ts \ - yacreaderlibrary_zh_HK.ts \ - yacreaderlibrary_it.ts \ - yacreaderlibrary_en.ts - -CONFIG += lrelease - -win32 { - CONFIG(release, debug|release) { - SOURCE_QM_DIR = $$OUT_PWD/release/*.qm - } - CONFIG(debug, debug|release) { - SOURCE_QM_DIR = $$OUT_PWD/debug/*.qm - } - - DEPLOYMENT_OUT_QM_DIR = ../release/languages/ - OUT_QM_DIR = $${DESTDIR}/languages/ - - QMAKE_POST_LINK += $(MKDIR) $$shell_path($${OUT_QM_DIR}) 2> NULL & \ - $(COPY) $$shell_path($${SOURCE_QM_DIR}) $$shell_path($${OUT_QM_DIR}) & \ - $(MKDIR) $$shell_path($${DEPLOYMENT_OUT_QM_DIR}) 2> NULL & \ - $(COPY) $$shell_path($${SOURCE_QM_DIR}) $$shell_path($${DEPLOYMENT_OUT_QM_DIR}) -} else { - LRELEASE_DIR = ../release/languages/ - QM_FILES_INSTALL_PATH = $$DATADIR/yacreader/languages -} - -#QML/GridView -QT += quick qml quickwidgets - -HEADERS += grid_comics_view.h \ - comics_view_transition.h - -SOURCES += grid_comics_view.cpp \ - comics_view_transition.cpp - -RESOURCES += qml.qrc - -unix:!macx { - -DEFINES += "LIBDIR=\\\"$$LIBDIR\\\"" "DATADIR=\\\"$$DATADIR\\\"" "BINDIR=\\\"$$BINDIR\\\"" - -#MAKE INSTALL -INSTALLS += bin icon desktop server manpage - -bin.path = $$BINDIR -isEmpty(DESTDIR) { - bin.files = YACReaderLibrary -} else { - bin.files = $$DESTDIR/YACReaderLibrary -} - -server.path = $$DATADIR/yacreader -server.files = ../release/server - -icon.path = $$DATADIR/icons/hicolor/scalable/apps -icon.files = ../YACReaderLibrary.svg - -desktop.path = $$DATADIR/applications -desktop.files = ../YACReaderLibrary.desktop - -manpage.path = $$DATADIR/man/man1 -manpage.files = ../YACReaderLibrary.1 -} diff --git a/YACReaderLibrary/comic_vine/CMakeLists.txt b/YACReaderLibrary/comic_vine/CMakeLists.txt new file mode 100644 index 000000000..e6ea50d69 --- /dev/null +++ b/YACReaderLibrary/comic_vine/CMakeLists.txt @@ -0,0 +1,71 @@ +# Comic Vine scraper for YACReaderLibrary + +add_library(comic_vine STATIC + comic_vine_json_parser.h + comic_vine_json_parser.cpp + comic_vine_all_volume_comics_retriever.h + comic_vine_all_volume_comics_retriever.cpp + scraper_checkbox.h + scraper_checkbox.cpp + comic_vine_dialog.h + comic_vine_dialog.cpp + comic_vine_client.h + comic_vine_client.cpp + scraper_lineedit.h + scraper_lineedit.cpp + title_header.h + title_header.cpp + series_question.h + series_question.cpp + search_single_comic.h + search_single_comic.cpp + search_volume.h + search_volume.cpp + select_comic.h + select_comic.cpp + select_volume.h + select_volume.cpp + scraper_tableview.h + scraper_tableview.cpp + sort_volume_comics.h + sort_volume_comics.cpp + scraper_scroll_label.h + scraper_scroll_label.cpp + scraper_results_paginator.h + scraper_results_paginator.cpp + api_key_dialog.h + api_key_dialog.cpp + model/volumes_model.h + model/volumes_model.cpp + model/comics_model.h + model/comics_model.cpp + model/json_model.h + model/json_model.cpp + model/response_parser.h + model/response_parser.cpp + model/local_comic_list_model.h + model/local_comic_list_model.cpp + model/volume_comics_model.h + model/volume_comics_model.cpp + model/selected_volume_info.h + model/volume_search_query.h +) +target_include_directories(comic_vine PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/model +) +# App-specific theme.h needed for themable.h → theme_manager.h → theme.h chain +target_include_directories(comic_vine PRIVATE + ${CMAKE_SOURCE_DIR}/YACReaderLibrary/themes + ${CMAKE_SOURCE_DIR}/YACReaderLibrary/db +) +target_link_libraries(comic_vine PUBLIC + Qt::Core + Qt::Widgets + Qt::Network + common_all + common_gui + custom_widgets_library + db_helper + QsLog +) diff --git a/YACReaderLibrary/comic_vine/comic_vine.pri b/YACReaderLibrary/comic_vine/comic_vine.pri deleted file mode 100644 index 978360233..000000000 --- a/YACReaderLibrary/comic_vine/comic_vine.pri +++ /dev/null @@ -1,52 +0,0 @@ - -HEADERS += \ - $$PWD/comic_vine_json_parser.h \ - $$PWD/model/selected_volume_info.h \ - $$PWD/model/volume_search_query.h \ - $$PWD/scraper_checkbox.h \ - comic_vine/comic_vine_dialog.h \ - comic_vine/comic_vine_client.h \ - comic_vine/scraper_lineedit.h \ - comic_vine/title_header.h \ - comic_vine/series_question.h \ - comic_vine/search_single_comic.h \ - comic_vine/search_volume.h \ - comic_vine/select_comic.h \ - comic_vine/select_volume.h \ - comic_vine/model/volumes_model.h \ - comic_vine/model/comics_model.h \ - comic_vine/model/json_model.h \ - comic_vine/model/response_parser.h \ - comic_vine/scraper_tableview.h \ - comic_vine/sort_volume_comics.h \ - comic_vine/model/local_comic_list_model.h \ - comic_vine/model/volume_comics_model.h \ - comic_vine/scraper_scroll_label.h \ - comic_vine/scraper_results_paginator.h \ - comic_vine/api_key_dialog.h \ - $$PWD/comic_vine_all_volume_comics_retriever.h - -SOURCES += \ - $$PWD/comic_vine_json_parser.cpp \ - $$PWD/scraper_checkbox.cpp \ - comic_vine/comic_vine_dialog.cpp \ - comic_vine/comic_vine_client.cpp \ - comic_vine/scraper_lineedit.cpp \ - comic_vine/title_header.cpp \ - comic_vine/series_question.cpp \ - comic_vine/search_single_comic.cpp \ - comic_vine/search_volume.cpp \ - comic_vine/select_comic.cpp \ - comic_vine/select_volume.cpp \ - comic_vine/model/volumes_model.cpp \ - comic_vine/model/comics_model.cpp \ - comic_vine/model/json_model.cpp \ - comic_vine/model/response_parser.cpp \ - comic_vine/scraper_tableview.cpp \ - comic_vine/sort_volume_comics.cpp \ - comic_vine/model/local_comic_list_model.cpp \ - comic_vine/model/volume_comics_model.cpp \ - comic_vine/scraper_scroll_label.cpp \ - comic_vine/scraper_results_paginator.cpp \ - comic_vine/api_key_dialog.cpp \ - $$PWD/comic_vine_all_volume_comics_retriever.cpp diff --git a/YACReaderLibrary/server/CMakeLists.txt b/YACReaderLibrary/server/CMakeLists.txt new file mode 100644 index 000000000..5a78620cb --- /dev/null +++ b/YACReaderLibrary/server/CMakeLists.txt @@ -0,0 +1,85 @@ +# YACReaderLibrary server (REST API + HTTP server) + +add_library(server STATIC + static.h + static.cpp + requestmapper.h + requestmapper.cpp + yacreader_http_server.h + yacreader_http_server.cpp + yacreader_http_session.h + yacreader_http_session.cpp + yacreader_http_session_store.h + yacreader_http_session_store.cpp + yacreader_server_data_helper.h + yacreader_server_data_helper.cpp + controllers/versioncontroller.h + controllers/versioncontroller.cpp + controllers/v2/comiccontroller_v2.h + controllers/v2/comiccontroller_v2.cpp + controllers/v2/errorcontroller_v2.h + controllers/v2/errorcontroller_v2.cpp + controllers/v2/folderinfocontroller_v2.h + controllers/v2/folderinfocontroller_v2.cpp + controllers/v2/librariescontroller_v2.h + controllers/v2/librariescontroller_v2.cpp + controllers/v2/pagecontroller_v2.h + controllers/v2/pagecontroller_v2.cpp + controllers/v2/covercontroller_v2.h + controllers/v2/covercontroller_v2.cpp + controllers/v2/updatecomiccontroller_v2.h + controllers/v2/updatecomiccontroller_v2.cpp + controllers/v2/comicdownloadinfocontroller_v2.h + controllers/v2/comicdownloadinfocontroller_v2.cpp + controllers/v2/synccontroller_v2.h + controllers/v2/synccontroller_v2.cpp + controllers/v2/foldercontentcontroller_v2.h + controllers/v2/foldercontentcontroller_v2.cpp + controllers/v2/tagscontroller_v2.h + controllers/v2/tagscontroller_v2.cpp + controllers/v2/tagcontentcontroller_v2.h + controllers/v2/tagcontentcontroller_v2.cpp + controllers/v2/favoritescontroller_v2.h + controllers/v2/favoritescontroller_v2.cpp + controllers/v2/readingcomicscontroller_v2.h + controllers/v2/readingcomicscontroller_v2.cpp + controllers/v2/readinglistscontroller_v2.h + controllers/v2/readinglistscontroller_v2.cpp + controllers/v2/readinglistcontentcontroller_v2.h + controllers/v2/readinglistcontentcontroller_v2.cpp + controllers/v2/comicfullinfocontroller_v2.h + controllers/v2/comicfullinfocontroller_v2.cpp + controllers/v2/readinglistinfocontroller_v2.h + controllers/v2/readinglistinfocontroller_v2.cpp + controllers/v2/taginfocontroller_v2.h + controllers/v2/taginfocontroller_v2.cpp + controllers/v2/comiccontrollerinreadinglist_v2.h + controllers/v2/comiccontrollerinreadinglist_v2.cpp + controllers/v2/foldermetadatacontroller_v2.h + controllers/v2/foldermetadatacontroller_v2.cpp + controllers/v2/searchcontroller_v2.h + controllers/v2/searchcontroller_v2.cpp + controllers/webui/statuspagecontroller.h + controllers/webui/statuspagecontroller.cpp +) +target_include_directories(server PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/controllers + ${CMAKE_CURRENT_SOURCE_DIR}/controllers/v2 +) +target_compile_definitions(server PUBLIC SERVER_VERSION_NUMBER="2.1") +if(UNIX AND NOT APPLE) + target_compile_definitions(server PRIVATE + "DATADIR=\"${CMAKE_INSTALL_FULL_DATADIR}\"") +endif() +target_link_libraries(server PUBLIC + Qt::Core + Qt::Network + Qt::Sql + QtWebApp_httpserver + QtWebApp_templateengine + QsLog + common_all + comic_backend + db_helper +) diff --git a/YACReaderLibrary/server/server.pri b/YACReaderLibrary/server/server.pri deleted file mode 100644 index f94c36624..000000000 --- a/YACReaderLibrary/server/server.pri +++ /dev/null @@ -1,81 +0,0 @@ -INCLUDEPATH += $$PWD -INCLUDEPATH += $$PWD/controllers -INCLUDEPATH += $$PWD/controllers/v2 -DEPENDPATH += $$PWD -DEPENDPATH += $$PWD/controllers -DEPENDPATH += $$PWD/controllers/v2 - - -HEADERS += \ - $$PWD/controllers/v2/foldermetadatacontroller_v2.h \ - $$PWD/controllers/v2/searchcontroller_v2.h \ - $$PWD/static.h \ - $$PWD/requestmapper.h \ - $$PWD/yacreader_http_server.h \ - $$PWD/yacreader_http_session.h \ - $$PWD/yacreader_http_session_store.h \ - $$PWD/yacreader_server_data_helper.h \ - $$PWD/controllers/versioncontroller.h \ - #v2 - $$PWD/controllers/v2/comiccontroller_v2.h \ - $$PWD/controllers/v2/errorcontroller_v2.h \ - $$PWD/controllers/v2/folderinfocontroller_v2.h \ - $$PWD/controllers/v2/librariescontroller_v2.h \ - $$PWD/controllers/v2/pagecontroller_v2.h \ - $$PWD/controllers/v2/covercontroller_v2.h \ - $$PWD/controllers/v2/updatecomiccontroller_v2.h \ - $$PWD/controllers/v2/comicdownloadinfocontroller_v2.h \ - $$PWD/controllers/v2/synccontroller_v2.h \ - $$PWD/controllers/v2/foldercontentcontroller_v2.h \ - $$PWD/controllers/v2/tagscontroller_v2.h \ - $$PWD/controllers/v2/tagcontentcontroller_v2.h \ - $$PWD/controllers/v2/favoritescontroller_v2.h \ - $$PWD/controllers/v2/readingcomicscontroller_v2.h \ - $$PWD/controllers/v2/readinglistscontroller_v2.h \ - $$PWD/controllers/v2/readinglistcontentcontroller_v2.h \ - $$PWD/controllers/v2/comicfullinfocontroller_v2.h \ - $$PWD/controllers/v2/readinglistinfocontroller_v2.h \ - $$PWD/controllers/v2/taginfocontroller_v2.h \ - $$PWD/controllers/v2/comiccontrollerinreadinglist_v2.h\ - #Browser - $$PWD/controllers/webui/statuspagecontroller.h - - -SOURCES += \ - $$PWD/controllers/v2/foldermetadatacontroller_v2.cpp \ - $$PWD/controllers/v2/searchcontroller_v2.cpp \ - $$PWD/static.cpp \ - $$PWD/requestmapper.cpp \ - $$PWD/yacreader_http_server.cpp \ - $$PWD/yacreader_http_session.cpp \ - $$PWD/yacreader_http_session_store.cpp \ - $$PWD/yacreader_server_data_helper.cpp \ - $$PWD/controllers/versioncontroller.cpp \ - #v2 - $$PWD/controllers/v2/comiccontroller_v2.cpp \ - $$PWD/controllers/v2/errorcontroller_v2.cpp \ - $$PWD/controllers/v2/folderinfocontroller_v2.cpp \ - $$PWD/controllers/v2/librariescontroller_v2.cpp \ - $$PWD/controllers/v2/pagecontroller_v2.cpp \ - $$PWD/controllers/v2/covercontroller_v2.cpp \ - $$PWD/controllers/v2/updatecomiccontroller_v2.cpp \ - $$PWD/controllers/v2/comicdownloadinfocontroller_v2.cpp \ - $$PWD/controllers/v2/synccontroller_v2.cpp \ - $$PWD/controllers/v2/foldercontentcontroller_v2.cpp \ - $$PWD/controllers/v2/tagscontroller_v2.cpp \ - $$PWD/controllers/v2/tagcontentcontroller_v2.cpp \ - $$PWD/controllers/v2/favoritescontroller_v2.cpp \ - $$PWD/controllers/v2/readingcomicscontroller_v2.cpp \ - $$PWD/controllers/v2/readinglistscontroller_v2.cpp \ - $$PWD/controllers/v2/readinglistcontentcontroller_v2.cpp \ - $$PWD/controllers/v2/comicfullinfocontroller_v2.cpp \ - $$PWD/controllers/v2/readinglistinfocontroller_v2.cpp \ - $$PWD/controllers/v2/taginfocontroller_v2.cpp \ - $$PWD/controllers/v2/comiccontrollerinreadinglist_v2.cpp \ - #WebUI - $$PWD/controllers/webui/statuspagecontroller.cpp - -include(../../third_party/QtWebApp/httpserver/httpserver.pri) -include(../../third_party/QtWebApp/templateengine/templateengine.pri) - -DEFINES += SERVER_VERSION_NUMBER=\\\"2.1\\\" diff --git a/YACReaderLibrary/themes/themes.pri b/YACReaderLibrary/themes/themes.pri deleted file mode 100644 index eee35324e..000000000 --- a/YACReaderLibrary/themes/themes.pri +++ /dev/null @@ -1,7 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/theme.h \ - $$PWD/theme_factory.h -SOURCES += \ - $$PWD/theme_factory.cpp diff --git a/YACReaderLibraryServer/CMakeLists.txt b/YACReaderLibraryServer/CMakeLists.txt new file mode 100644 index 000000000..619f10a82 --- /dev/null +++ b/YACReaderLibraryServer/CMakeLists.txt @@ -0,0 +1,94 @@ +# YACReaderLibraryServer - Headless REST server + +qt_add_executable(YACReaderLibraryServer + main.cpp + console_ui_library_creator.h + console_ui_library_creator.cpp + libraries_updater.h + libraries_updater.cpp +) + +target_include_directories(YACReaderLibraryServer PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/YACReaderLibrary + ${CMAKE_SOURCE_DIR}/YACReaderLibrary/db +) + +target_compile_definitions(YACReaderLibraryServer PRIVATE + SERVER_RELEASE + YACREADER_LIBRARY +) + +# Resources +qt_add_resources(yacreaderlibraryserver_images_rcc "${CMAKE_CURRENT_SOURCE_DIR}/images.qrc") +target_sources(YACReaderLibraryServer PRIVATE ${yacreaderlibraryserver_images_rcc}) + +# Translations +qt_add_translations(YACReaderLibraryServer + TS_FILES + yacreaderlibraryserver_es.ts + yacreaderlibraryserver_ru.ts + yacreaderlibraryserver_pt.ts + yacreaderlibraryserver_fr.ts + yacreaderlibraryserver_nl.ts + yacreaderlibraryserver_tr.ts + yacreaderlibraryserver_de.ts + yacreaderlibraryserver_zh_CN.ts + yacreaderlibraryserver_zh_TW.ts + yacreaderlibraryserver_zh_HK.ts +) + +target_link_libraries(YACReaderLibraryServer PRIVATE + Qt::Core + Qt::Network + Qt::Sql + Qt::Core5Compat + library_common + db_helper + comic_backend + common_all + naturalsort + cbx_backend + server + QsLog + QrCode +) + +# Platform-specific +if(WIN32) + target_link_libraries(YACReaderLibraryServer PRIVATE oleaut32 ole32 shell32 user32) +endif() + +if(APPLE) + set_target_properties(YACReaderLibraryServer PROPERTIES + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_GUI_IDENTIFIER "com.yacreader.YACReaderLibraryServer" + MACOSX_BUNDLE_BUNDLE_NAME "YACReaderLibraryServer" + ) + target_link_libraries(YACReaderLibraryServer PRIVATE + "-framework Foundation" + "-framework ApplicationServices" + "-framework AppKit" + ) +endif() + +# Linux install rules +if(UNIX AND NOT APPLE) + target_compile_definitions(YACReaderLibraryServer PRIVATE + "LIBDIR=\"${CMAKE_INSTALL_FULL_LIBDIR}\"" + "DATADIR=\"${CMAKE_INSTALL_FULL_DATADIR}\"" + "BINDIR=\"${CMAKE_INSTALL_FULL_BINDIR}\"" + ) + + install(TARGETS YACReaderLibraryServer RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + + # Standalone server: install server web files alongside the binary + if(BUILD_SERVER_STANDALONE) + install(DIRECTORY ${CMAKE_SOURCE_DIR}/release/server + DESTINATION ${CMAKE_INSTALL_DATADIR}/yacreader) + endif() + + # systemd service + install(FILES yacreaderlibraryserver.service + DESTINATION ${CMAKE_INSTALL_LIBDIR}/systemd/user) +endif() diff --git a/YACReaderLibraryServer/YACReaderLibraryServer.pro b/YACReaderLibraryServer/YACReaderLibraryServer.pro deleted file mode 100644 index 89e0938e9..000000000 --- a/YACReaderLibraryServer/YACReaderLibraryServer.pro +++ /dev/null @@ -1,178 +0,0 @@ -TEMPLATE = app -TARGET = YACReaderLibraryServer - -QMAKE_TARGET_BUNDLE_PREFIX = "com.yacreader" - -CONFIG += console -DEPENDPATH += ../YACReaderLibrary -INCLUDEPATH += ../YACReaderLibrary \ - ../common \ - ../YACReaderLibrary/server \ - ../YACReaderLibrary/db - -DEFINES += SERVER_RELEASE YACREADER_LIBRARY -# load default build flags -# do a basic dependency check -include(headless_config.pri) -include(../dependencies/pdf_backend.pri) -include(../third_party/QrCode/QrCode.pri) - -QT += core5compat - -win32 { - LIBS += -loleaut32 -lole32 -lshell32 -luser32 - msvc { - QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT /GL - QMAKE_LFLAGS_RELEASE += /LTCG - } - CONFIG -= embed_manifest_exe -} - -macx { - LIBS += -framework Foundation -framework ApplicationServices -framework AppKit - CONFIG += objective_c -} - -#CONFIG += release -CONFIG -= flat -QT += core sql network - -# Source files -HEADERS += ../YACReaderLibrary/library_creator.h \ - ../YACReaderLibrary/package_manager.h \ - ../YACReaderLibrary/bundle_creator.h \ - ../YACReaderLibrary/db_helper.h \ - ../YACReaderLibrary/db/data_base_management.h \ - ../YACReaderLibrary/db/reading_list.h \ - ../YACReaderLibrary/initial_comic_info_extractor.h \ - ../YACReaderLibrary/xml_info_parser.h \ - ../YACReaderLibrary/xml_info_library_scanner.h \ - ../common/comic_db.h \ - ../common/folder.h \ - ../common/library_item.h \ - ../common/comic.h \ - ../common/pdf_comic.h \ - ../common/bookmarks.h \ - ../common/qnaturalsorting.h \ - ../common/yacreader_global.h \ - ../common/cover_utils.h \ - ../YACReaderLibrary/yacreader_local_server.h \ - ../YACReaderLibrary/comics_remover.h \ - ../common/http_worker.h \ - ../YACReaderLibrary/yacreader_libraries.h \ - ../YACReaderLibrary/comic_files_manager.h \ - console_ui_library_creator.h \ - libraries_updater.h \ - ../YACReaderLibrary/ip_config_helper.h \ - ../YACReaderLibrary/db/query_lexer.h \ - ../YACReaderLibrary/db/query_parser.h \ - ../YACReaderLibrary/db/search_query.h \ - ../YACReaderLibrary/libraries_update_coordinator.h \ - ../common/global_info_provider.h \ - - -SOURCES += ../YACReaderLibrary/library_creator.cpp \ - ../YACReaderLibrary/package_manager.cpp \ - ../YACReaderLibrary/bundle_creator.cpp \ - ../YACReaderLibrary/db_helper.cpp \ - ../YACReaderLibrary/db/data_base_management.cpp \ - ../YACReaderLibrary/db/reading_list.cpp \ - ../YACReaderLibrary/initial_comic_info_extractor.cpp \ - ../YACReaderLibrary/xml_info_parser.cpp \ - ../YACReaderLibrary/xml_info_library_scanner.cpp \ - ../common/comic_db.cpp \ - ../common/folder.cpp \ - ../common/library_item.cpp \ - ../common/comic.cpp \ - ../common/bookmarks.cpp \ - ../common/qnaturalsorting.cpp \ - ../common/cover_utils.cpp \ - ../YACReaderLibrary/yacreader_local_server.cpp \ - ../YACReaderLibrary/comics_remover.cpp \ - ../common/http_worker.cpp \ - ../common/yacreader_global.cpp \ - ../YACReaderLibrary/yacreader_libraries.cpp \ - ../YACReaderLibrary/comic_files_manager.cpp \ - console_ui_library_creator.cpp \ - main.cpp \ - libraries_updater.cpp \ - ../YACReaderLibrary/ip_config_helper.cpp \ - ../YACReaderLibrary/db/query_lexer.cpp \ - ../YACReaderLibrary/db/query_parser.cpp \ - ../YACReaderLibrary/db/search_query.cpp \ - ../YACReaderLibrary/libraries_update_coordinator.cpp \ - ../common/global_info_provider.cpp \ - -include(../YACReaderLibrary/server/server.pri) - -CONFIG(7zip) { -include(../compressed_archive/wrapper.pri) -} else:CONFIG(unarr) { -include(../compressed_archive/unarr/unarr-wrapper.pri) -} else:CONFIG(libarchive) { -include(../compressed_archive/libarchive/libarchive-wrapper.pri) -} else { - error(No compression backend specified. Did you mess with the build system?) -} -include(../third_party/QsLog/QsLog.pri) - -TRANSLATIONS = yacreaderlibraryserver_es.ts \ - yacreaderlibraryserver_ru.ts \ - yacreaderlibraryserver_pt.ts \ - yacreaderlibraryserver_fr.ts \ - yacreaderlibraryserver_nl.ts \ - yacreaderlibraryserver_tr.ts \ - yacreaderlibraryserver_de.ts \ - yacreaderlibraryserver_zh_CN.ts \ - yacreaderlibraryserver_zh_TW.ts \ - yacreaderlibraryserver_zh_HK.ts \ - yacreaderlibraryserver_source.ts - -RESOURCES += images.qrc - -contains(QMAKE_TARGET.arch, x86_64) { - Release:DESTDIR = ../release64 - Debug:DESTDIR = ../debug64 -} else { - Release:DESTDIR = ../release - Debug:DESTDIR = ../debug -} - -unix:!macx { -#set install prefix if it's empty - -DEFINES += "LIBDIR=\\\"$$LIBDIR\\\"" "DATADIR=\\\"$$DATADIR\\\"" "BINDIR=\\\"$$BINDIR\\\"" - -#make install - -!CONFIG(server_bundled):!CONFIG(server_standalone): { - CONFIG+=server_bundled - message("No build type specified. Defaulting to bundled server build (CONFIG+=server_bundled).") - message("If you wish to run YACReaderLibraryServer on a system without an existing install of YACReaderLibrary,\ - please specify CONFIG+=server_standalone as an option when running qmake to avoid missing dependencies.") -} - -CONFIG(server_standalone) { - INSTALLS += bin server systemd -} -else:CONFIG(server_bundled) { - INSTALLS += bin systemd -} - -bin.path = $$BINDIR -isEmpty(DESTDIR) { - bin.files = YACReaderLibraryServer -} else { - bin.files = $$DESTDIR/YACReaderLibraryServer -} - -server.path = $$DATADIR/yacreader -server.files = ../release/server - -systemd.path = $$LIBDIR/systemd/user -systemd.files = yacreaderlibraryserver.service - -# TODO: We need a manpage for yaclibserver -#manpage.path = $$DATADIR/man/man1 -#manpage.files = ../YACReaderLibrary.1 -} diff --git a/YACReaderLibraryServer/headless_config.pri b/YACReaderLibraryServer/headless_config.pri deleted file mode 100644 index 4e499be4d..000000000 --- a/YACReaderLibraryServer/headless_config.pri +++ /dev/null @@ -1,37 +0,0 @@ -# functions to automatically initialize some of YACReaderLibraryServer's build -# options to default values if they're not set at build time -# for a more detailed description, see INSTALL.TXT - -include (../config.pri) - -unix!macx { - !contains(QT_CONFIG, no-pkg-config) { - packagesExist(Qt5Core) { - message("Found Qt5Core") - } else: { - message("Missing dependency: Qt5Core") - } - packagesExist(Qt5Gui) { - message("Found Qt5Gui") - } else: { - message("Missing dependency: Qt5Gui") - } - packagesExist(Qt5Network) { - message("Found Qt5Network") - } else: { - message("Missing dependency: Qt5Network") - } - packagesExist(Qt5Sql) { - message("Found Qt5Sql") - } else: { - message("Missing dependency: Qt5Sql") - } - packagesExist(sqlite3) { - message("Found sqlite3") - } else: { - message("Missing dependency: sqlite3") - } - } else { - message("Qmake was compiled without support for pkg-config. Skipping dependency checks.") - } -} diff --git a/ci/win/create_installer.cmd b/ci/win/create_installer.cmd index 583ad2258..10f0d6c86 100644 --- a/ci/win/create_installer.cmd +++ b/ci/win/create_installer.cmd @@ -6,11 +6,7 @@ set ARCH=%1 set COMPRESSION=%2 set BUILD_NUMBER=%3 -IF "%ARCH%"=="x64" ( - SET exe_path=%src_path%\release64 -) ELSE ( - SET exe_path=%src_path%\release -) +SET exe_path=%src_path%\build\bin rmdir /S /Q installer_contents @@ -45,7 +41,13 @@ mkdir openssl copy %src_path%\dependencies\openssl\win\%ARCH%\* .\openssl\ xcopy %src_path%\release\server .\server /i /e -xcopy %src_path%\release\languages .\languages /i /e + +rem Collect cmake-generated .qm translation files from the build tree +rem (release\languages is not tracked in git; cmake generates .qm in build subdirs) +mkdir languages +for /r %src_path%\build %%f in (*.qm) do ( + copy "%%f" .\languages\ >nul +) copy %src_path%\vc_redist.%ARCH%.exe . diff --git a/cleanOSX.sh b/cleanOSX.sh index a1757f063..dd35cf3ec 100755 --- a/cleanOSX.sh +++ b/cleanOSX.sh @@ -1,17 +1,6 @@ #!/bin/bash -rm -R *.app -rm -R YACReader-* -rm -R *.dmg -cd YACReader -make distclean -rm -R YACReader.app -cd .. -cd YACReaderLibrary -make distclean -rm -R YACReaderLibrary.app -cd .. -cd YACReaderLibraryServer -make distclean -rm -R YACReaderLibraryServer.app -cd .. +rm -rf build +rm -rf *.app +rm -rf YACReader-* +rm -rf *.dmg diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake new file mode 100644 index 000000000..2b1378dc7 --- /dev/null +++ b/cmake/CompilerOptions.cmake @@ -0,0 +1,20 @@ +# Compiler options for YACReader +# Mirrors config.pri: C++20, NOMINMAX, MSVC conformance flags + +add_compile_definitions(NOMINMAX) + +if(MSVC) + # /Zc:__cplusplus: report correct __cplusplus value + # /permissive-: strict standard conformance + add_compile_options(/Zc:__cplusplus /permissive-) + + # Release optimizations (mirrors qmake QMAKE_CXXFLAGS_RELEASE) + string(APPEND CMAKE_CXX_FLAGS_RELEASE " /DNDEBUG") +elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + string(APPEND CMAKE_CXX_FLAGS_RELEASE " -DNDEBUG") +endif() + +# Qt deprecation warnings +add_compile_definitions( + QT_DEPRECATED_WARNINGS +) diff --git a/cmake/PdfBackend.cmake b/cmake/PdfBackend.cmake new file mode 100644 index 000000000..a9f9ce1fd --- /dev/null +++ b/cmake/PdfBackend.cmake @@ -0,0 +1,97 @@ +# PDF backend detection for YACReader +# Creates an INTERFACE target 'pdf_backend_iface' that propagates +# compile definitions and link libraries based on PDF_BACKEND. + +add_library(pdf_backend_iface INTERFACE) + +if(PDF_BACKEND STREQUAL "no_pdf") + message(STATUS "PDF backend: disabled") + target_compile_definitions(pdf_backend_iface INTERFACE NO_PDF) + +elseif(PDF_BACKEND STREQUAL "pdfium") + message(STATUS "PDF backend: pdfium") + target_compile_definitions(pdf_backend_iface INTERFACE USE_PDFIUM) + + if(MSVC) + target_include_directories(pdf_backend_iface INTERFACE + "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/public") + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64" OR CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64") + target_link_directories(pdf_backend_iface INTERFACE + "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/arm64") + else() + target_link_directories(pdf_backend_iface INTERFACE + "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/x64") + endif() + target_link_libraries(pdf_backend_iface INTERFACE pdfium) + elseif(APPLE) + target_include_directories(pdf_backend_iface INTERFACE + "${CMAKE_SOURCE_DIR}/dependencies/pdfium/macx/include") + target_link_directories(pdf_backend_iface INTERFACE + "${CMAKE_SOURCE_DIR}/dependencies/pdfium/macx/bin") + target_link_libraries(pdf_backend_iface INTERFACE pdfium) + else() + # Linux: try pkg-config first, then system path + pkg_check_modules(PDFIUM QUIET IMPORTED_TARGET libpdfium) + if(PDFIUM_FOUND) + message(STATUS " Found pdfium via pkg-config") + target_link_libraries(pdf_backend_iface INTERFACE PkgConfig::PDFIUM) + elseif(EXISTS "/usr/include/pdfium") + message(STATUS " Found pdfium at /usr/include/pdfium") + target_include_directories(pdf_backend_iface INTERFACE /usr/include/pdfium) + target_link_libraries(pdf_backend_iface INTERFACE pdfium) + else() + message(FATAL_ERROR "Could not find libpdfium. Install it or use a different PDF_BACKEND.") + endif() + endif() + +elseif(PDF_BACKEND STREQUAL "poppler") + message(STATUS "PDF backend: poppler") + target_compile_definitions(pdf_backend_iface INTERFACE USE_POPPLER) + + if(APPLE) + message(FATAL_ERROR "Poppler backend is not supported on macOS") + endif() + + # Try cmake config mode first (poppler built with cmake, or vcpkg with cmake integration) + # On Windows: vcpkg install poppler[qt6]:x64-windows, then pass the vcpkg toolchain file + find_package(Poppler QUIET CONFIG) + if(TARGET Poppler::Qt6) + message(STATUS " Found poppler-qt6 via cmake config") + target_link_libraries(pdf_backend_iface INTERFACE Poppler::Qt6) + else() + # Fall back to pkg-config (standard on Linux; on Windows requires vcpkg pkgconf) + pkg_check_modules(POPPLER QUIET IMPORTED_TARGET poppler-qt6) + if(POPPLER_FOUND) + message(STATUS " Found poppler-qt6 via pkg-config") + target_link_libraries(pdf_backend_iface INTERFACE PkgConfig::POPPLER) + elseif(NOT MSVC AND EXISTS "/usr/include/poppler/qt6") + message(STATUS " Found poppler-qt6 at /usr/include/poppler/qt6") + target_include_directories(pdf_backend_iface INTERFACE /usr/include/poppler/qt6) + target_link_libraries(pdf_backend_iface INTERFACE poppler-qt6) + elseif(MSVC) + message(FATAL_ERROR "Could not find poppler-qt6. " + "Install via vcpkg: vcpkg install poppler[qt6]:x64-windows " + "then configure cmake with the vcpkg toolchain file.") + else() + message(FATAL_ERROR "Could not find poppler-qt6. Install libpoppler-qt6-dev or use a different PDF_BACKEND.") + endif() + endif() + +elseif(PDF_BACKEND STREQUAL "pdfkit") + message(STATUS "PDF backend: pdfkit (macOS)") + if(NOT APPLE) + message(FATAL_ERROR "pdfkit backend is macOS only") + endif() + target_compile_definitions(pdf_backend_iface INTERFACE USE_PDFKIT) + +else() + message(FATAL_ERROR "Unknown PDF_BACKEND: '${PDF_BACKEND}'. Use: pdfium, poppler, pdfkit, or no_pdf") +endif() + +# Set QT_DISABLE_DEPRECATED_BEFORE based on backend +# poppler requires older deprecated API +if(PDF_BACKEND STREQUAL "poppler") + target_compile_definitions(pdf_backend_iface INTERFACE QT_DISABLE_DEPRECATED_BEFORE=0x050900) +else() + target_compile_definitions(pdf_backend_iface INTERFACE QT_DISABLE_DEPRECATED_BEFORE=0x050F00) +endif() diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt new file mode 100644 index 000000000..c754f5523 --- /dev/null +++ b/common/CMakeLists.txt @@ -0,0 +1,197 @@ +# Common libraries for YACReader +# Fine-grained STATIC targets per concern + +# --- yr_global (no GUI, used by all 3 apps) --- +add_library(yr_global STATIC + yacreader_global.h + yacreader_global.cpp +) +target_include_directories(yr_global PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(yr_global PUBLIC Qt::Core) +if(UNIX AND NOT APPLE) + target_compile_definitions(yr_global PRIVATE + "LIBDIR=\"${CMAKE_INSTALL_FULL_LIBDIR}\"") +endif() + +# --- naturalsort --- +add_library(naturalsort STATIC + qnaturalsorting.h + qnaturalsorting.cpp +) +target_include_directories(naturalsort PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(naturalsort PUBLIC Qt::Core) + +# --- concurrent_queue --- +add_library(concurrent_queue STATIC + concurrent_queue.h + concurrent_queue.cpp +) +target_include_directories(concurrent_queue PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(concurrent_queue PUBLIC Qt::Core) + +# --- worker (header-only thread helpers) --- +add_library(worker INTERFACE) +target_include_directories(worker INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +target_sources(worker INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}/worker_thread.h + ${CMAKE_CURRENT_SOURCE_DIR}/release_acquire_atomic.h +) + +# --- common_all (shared non-GUI code used by all 3 apps) --- +add_library(common_all STATIC + comic_db.h + comic_db.cpp + folder.h + folder.cpp + library_item.h + library_item.cpp + bookmarks.h + bookmarks.cpp + http_worker.h + http_worker.cpp + cover_utils.h + cover_utils.cpp + global_info_provider.h + global_info_provider.cpp +) +target_include_directories(common_all PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(common_all PUBLIC + Qt::Core + Qt::Gui + Qt::Sql + Qt::Network + yr_global + naturalsort + pdf_backend_iface +) + +# --- comic_backend (comic file handling + PDF) --- +add_library(comic_backend STATIC + comic.h + comic.cpp + pdf_comic.h +) + +# PDF source depends on backend +if(PDF_BACKEND STREQUAL "pdfkit") + target_sources(comic_backend PRIVATE pdf_comic.mm) +elseif(NOT PDF_BACKEND STREQUAL "no_pdf") + target_sources(comic_backend PRIVATE pdf_comic.cpp) +endif() + +target_include_directories(comic_backend PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(comic_backend PUBLIC + Qt::Core + Qt::Gui + common_all + pdf_backend_iface + cbx_backend + QsLog +) + +# GUI-only targets: not needed for server-standalone builds (Qt 6.4+) which +# lack Qt::Widgets, Qt::ShaderTools, Qt::GuiPrivate, etc. +if(NOT BUILD_SERVER_STANDALONE) + +# --- common_gui (GUI-only code: widgets, version check, themes infrastructure) --- +# NOTE: theme_manager.h/cpp is NOT included here because it depends on app-specific +# theme.h (YACReader vs YACReaderLibrary have different Theme structs). +# Each app includes theme_manager directly alongside its own theme.h/theme_factory. +add_library(common_gui STATIC + custom_widgets.h + custom_widgets.cpp + check_new_version.h + check_new_version.cpp + yacreader_global_gui.h + yacreader_global_gui.cpp + exit_check.h + exit_check.cpp + scroll_management.h + scroll_management.cpp + # themes infrastructure (does NOT depend on app-specific theme.h) + themes/icon_utils.h + themes/icon_utils.cpp + themes/theme_id.h + themes/themable.h + themes/yacreader_icon.h + themes/shared/help_about_dialog_theme.h + themes/shared/whats_new_dialog_theme.h +) +target_include_directories(common_gui PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/themes + ${CMAKE_CURRENT_SOURCE_DIR}/themes/shared +) +target_link_libraries(common_gui PUBLIC + Qt::Core + Qt::Core5Compat + Qt::Widgets + Qt::Network + Qt::Svg + common_all + yr_global + QsLog +) + +# --- RHI flow (3D coverflow) --- +# Compiled twice with different defines, like the old GL flow pattern. +# Shaders are compiled from GLSL 450 source at build time via qt_add_shaders(). + +set(RHI_FLOW_SOURCES + rhi/flow_types.h + rhi/flow_types.cpp + rhi/yacreader_flow_rhi.h + rhi/yacreader_flow_rhi.cpp + rhi/yacreader_comic_flow_rhi.h + rhi/yacreader_comic_flow_rhi.cpp + rhi/yacreader_page_flow_rhi.h + rhi/yacreader_page_flow_rhi.cpp +) + +add_library(rhi_flow_reader STATIC ${RHI_FLOW_SOURCES}) +target_include_directories(rhi_flow_reader PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/rhi +) +target_compile_definitions(rhi_flow_reader PRIVATE YACREADER) +target_link_libraries(rhi_flow_reader PUBLIC + Qt::Core + Qt::Gui + Qt::GuiPrivate + Qt::Widgets +) +qt_add_shaders(rhi_flow_reader "flow_shaders_reader" + BASE rhi/shaders + PREFIX "/shaders" + GLSL "100es,120,150" + HLSL 50 + MSL 12 + FILES + rhi/shaders/flow.vert + rhi/shaders/flow.frag +) + +add_library(rhi_flow_library STATIC ${RHI_FLOW_SOURCES}) +target_include_directories(rhi_flow_library PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/rhi +) +target_compile_definitions(rhi_flow_library PRIVATE YACREADER_LIBRARY) +target_link_libraries(rhi_flow_library PUBLIC + Qt::Core + Qt::Gui + Qt::GuiPrivate + Qt::Widgets +) +qt_add_shaders(rhi_flow_library "flow_shaders_library" + BASE rhi/shaders + PREFIX "/shaders" + GLSL "100es,120,150" + HLSL 50 + MSL 12 + FILES + rhi/shaders/flow.vert + rhi/shaders/flow.frag +) + +endif() # NOT BUILD_SERVER_STANDALONE diff --git a/common/rhi/README.md b/common/rhi/README.md index fd1247976..f3ca057c5 100644 --- a/common/rhi/README.md +++ b/common/rhi/README.md @@ -27,7 +27,7 @@ QRhiWidget (Qt base class) - **yacreader_flow_rhi.h** - Header with class definitions - **yacreader_flow_rhi.cpp** - Implementation -- **shaders/** - GLSL 450 shaders and compiled .qsb files +- **shaders/** - GLSL 450 shader source files (compiled to .qsb at build time by `qt_add_shaders`) - **README.md** - This file ## Key Features @@ -52,7 +52,8 @@ QRhi resources managed: ### Shader System -Shaders are written in **GLSL 4.50** and compiled to `.qsb` format supporting: +Shaders are written in **GLSL 4.50** and compiled to `.qsb` format at build time +via `qt_add_shaders()` in CMake, supporting: - OpenGL ES 2.0, 3.0 - OpenGL 2.1, 3.0+ - HLSL (Direct3D 11/12) @@ -134,36 +135,20 @@ All public methods from `YACReaderFlowGL` are preserved: ### Prerequisites -1. **Qt 6.7 or later** -2. **qsb tool** (Qt Shader Baker) in PATH -3. **C++17 compiler** - -### Compile Shaders - -Before building YACReader, compile the shaders: - -```bash -cd common/rhi/shaders -# Windows -compile_shaders.bat - -# Unix/macOS -chmod +x compile_shaders.sh -./compile_shaders.sh -``` - -This generates `flow.vert.qsb` and `flow.frag.qsb` which are embedded via `shaders.qrc`. +1. **Qt 6.7 or later** (with ShaderTools module) +2. **CMake 3.25+** +3. **C++20 compiler** ### Build YACReader -The `.pro` files automatically include RHI sources for Qt 6.7+: +Shaders are compiled automatically at build time via `qt_add_shaders()`: ```bash -qmake YACReader.pro -make +cmake -B build -DCMAKE_BUILD_TYPE=Release +cmake --build build --parallel ``` -For Qt 5 builds, the OpenGL version is used automatically. +No manual shader compilation step is needed. ## Graphics API Selection @@ -224,7 +209,7 @@ qDebug() << "Driver:" << rhi->driverInfo(); ### Common Issues **Problem**: Shaders fail to load -**Solution**: Ensure `.qsb` files are compiled and included in resources +**Solution**: Ensure Qt ShaderTools module is installed and `qt_add_shaders()` ran during build **Problem**: Black screen on Qt 6.7 **Solution**: Check if `YACREADER_USE_RHI` is defined in build @@ -260,7 +245,7 @@ The RHI version is a **drop-in replacement** requiring no application code chang 1. **Qt Version**: Requires Qt 6.7+ (released April 2024) 2. **QRhi Stability**: QRhi APIs may change in minor Qt releases 3. **Mixed Renderers**: Only one graphics API per window -4. **Shader Compilation**: Must recompile shaders when modifying source +4. **Shader Compilation**: Shaders are recompiled automatically when source files change ## Future Improvements diff --git a/common/rhi/shaders/README.md b/common/rhi/shaders/README.md deleted file mode 100644 index 7b8828201..000000000 --- a/common/rhi/shaders/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# YACReader Flow RHI Shaders - -This directory contains the GLSL 4.50 shaders for the QRhiWidget-based flow implementation. - -## Files - -- `flow.vert` - Vertex shader (GLSL 450) -- `flow.frag` - Fragment shader (GLSL 450) -- `flow.vert.qsb` - Compiled vertex shader (multi-platform) -- `flow.frag.qsb` - Compiled fragment shader (multi-platform) -- `compile_shaders.bat` - Windows compilation script -- `compile_shaders.sh` - Unix/macOS compilation script -- `shaders.qrc` - Qt resource file - -## Compiling Shaders - -The shaders must be compiled to `.qsb` format using Qt's `qsb` tool before building YACReader. - -### Prerequisites - -Ensure `qsb` is in your PATH. It's typically located in: -- Windows: `C:\Qt\6.x.x\msvc2019_64\bin\qsb.exe` -- macOS: `/opt/Qt/6.x.x/macos/bin/qsb` -- Linux: `/opt/Qt/6.x.x/gcc_64/bin/qsb` - -### Compilation - -**Windows:** -```cmd -cd common/rhi/shaders -compile_shaders.bat -``` - -**Unix/macOS:** -```bash -cd common/rhi/shaders -chmod +x compile_shaders.sh -./compile_shaders.sh -``` - -The compiled `.qsb` files contain shader variants for: -- OpenGL ES 2.0, 3.0 -- OpenGL 2.1, 3.0+ -- HLSL (Direct3D 11/12) -- Metal Shading Language (macOS/iOS) - -## Note - -The `.qsb` files are included in the repository for convenience. Recompile only if you modify the shader source. diff --git a/common/rhi/shaders/compile_shaders.bat b/common/rhi/shaders/compile_shaders.bat deleted file mode 100644 index 56ce73818..000000000 --- a/common/rhi/shaders/compile_shaders.bat +++ /dev/null @@ -1,19 +0,0 @@ -@echo off -REM Compile shaders to .qsb format for Qt RHI -REM Requires qsb tool from Qt installation - -echo Compiling flow vertex shader... -qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o flow.vert.qsb flow.vert -if %ERRORLEVEL% NEQ 0 ( - echo Error compiling vertex shader - exit /b 1 -) - -echo Compiling flow fragment shader... -qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o flow.frag.qsb flow.frag -if %ERRORLEVEL% NEQ 0 ( - echo Error compiling fragment shader - exit /b 1 -) - -echo Shader compilation complete! diff --git a/common/rhi/shaders/compile_shaders.sh b/common/rhi/shaders/compile_shaders.sh deleted file mode 100755 index f084121f2..000000000 --- a/common/rhi/shaders/compile_shaders.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -# Compile shaders to .qsb format for Qt RHI -# Requires qsb tool from Qt installation - -echo "Compiling flow vertex shader..." -qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o flow.vert.qsb flow.vert -if [ $? -ne 0 ]; then - echo "Error compiling vertex shader" - exit 1 -fi - -echo "Compiling flow fragment shader..." -qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o flow.frag.qsb flow.frag -if [ $? -ne 0 ]; then - echo "Error compiling fragment shader" - exit 1 -fi - -echo "Shader compilation complete!" diff --git a/common/rhi/shaders/flow.frag.qsb b/common/rhi/shaders/flow.frag.qsb deleted file mode 100644 index e223ca0b7496a235b79bc8620c39d17b60b3e889..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3066 zcmV&D!VIN2HZd%P15FLPe1kakLbsK=%@Y-{WE&{t&ekh+L?RjuI^r~ggGZ6=MZns zT01kpnR{pM+_|%xgfX^@G1d?F0Nk&!b+*VX)?`!6g?~I&25v9h?0OFk=HiXLrUomtQ9z5Z7*Uhz{5AU-T z9W0IK2qHi=R*Q!Sm%qKC68vM>-zN;SZfdQ5~vHs`A&-O#wt$3-;HpM z7CVpXbX?q*;lABTvE|t?jd7xN+Vj`G-XlW@-_2fP-w^jz*i>j>H>lw6<=KVVj31OUqj_9Eh)AC@$R0ij-c{47 z34O-ig!>rWSKz)1w+;6rhAGv@v6!Bh;b|}Y9wJ+kK1}mK8g0EF(tX_S%Orb~WK#DS z(fx$IqF}F(te0e071>pi^^t6ea92RKL}L$ddLX2SnAjdF?+E=$UJvokE4*If%__V; z;>|0(e&Q`EyaD3fR(ONNyFoB`suHVP!gwF@y3CA$_ zn)Y+Q2Wfr={C$aHf%ic;DiS2uvscpZfIS>PLHe>@Aa8=`y~M-u_L03_!oR{=$vr{z ztHeY3ewxc5(FaI2MECBBTXNgt&(mGe8M z;L*;9!u&Z&pHRj}nr|}p_}m1Ie}(iVeU<3_FzPji)ubP4m+-Nl; z|6M$HP)FkAy{N?QCi%5QV(HAuOl15+GXiK9%*64Mj zCxOO2i8XRB(YPM3F|prnK~xa;I$@B179zHbco#s9x%v(h`|Tjv!1a2U_=talXo>$3 z;on#A2JsR99?=qigz$$I{Evx`_(McX{7(pfRKX{SkN6LWmiXh0h3AUIr-}arFi2;J zhx>XDWC`+QJ8+!jxW}_JMvCNej1d|`jnOFai`91q ziitfS>1ihRjI{lcV*4WDr^)sOl1tsoOza;?&oEJIzo3}^lrS@-e~EY!k7qd6;y(i( z>+sKrhimjtz~gz2*M9(yvNx(f6~u+(#KkXZ+SM4 z!w|0}Ys6cnIN`j0N46^@zt87B$az)5>?OIJhfA`Wf|c(J36kUdEaFRl@Vy0jpOGD( zc({IF5wAh~fNXqBJZWQtVj^jLl|qc%x0{4%Dr@k7we~H_)qT58a$Hk9n?9j+-=Z<_ zoO(=r8P_LFoJ(_HALXAC?}-xEUS*D-F;VB|fkOP}#FO_Pvh#(KE04+U=QKAwD}GJm zs;$J8Kzal$K;eD;xmb~8(ub0nji2LbZ?tdCIN0o{;bXjbhy_ zXH|x0*%e`CsUFXtb~kE50+TZw|3)a$4G&KwwqW)RG41H|jpF#2A`{;FX0=|iyxg== zav@lYRx@aL7Qog`Z_}x*qB}Wb9r#nO>y;-Gb_Iq~gb<3Enje_8lC`jAmVrB=>CU<( zvoi1cny#31s61CUOHQ!a0TgjLvF4SZDSH2(U078QgticawMfj zu4382QXSNES29fERogtmjh2W_}c7B^JnCLl@`SgT|h&djE9+{k9~Y50>( z8^f7w#HVJAMzgC1x<`Y9Zq;cfrNe28P}35=nCq}xlQPI!sZ594 z7~Foq{T@li%_5ajpc^pMRwALD1x*%S1Al3q1-a}Gp}y}__MOVUQ`vVa`wLmwf3H;b zKeZ}*{)b)JomzZR7yP(-9%^W%9Qa+UxFV1EI(}ez$(5`uBc8iateW>=uH668<|wXvF|NXc z0Z6#}u5J5PkSs+u(+Jnn{L>UhBMX9fJPdRY_b&=l(^7-yyMTG2(cod);#q=l^*m_< zKZu+0a2t%T2o&i>*;k(tu{;|&T-5jn7`z2>1}y|;U>QXfTBPGiRq;^;PG&Q3O0-sn zx@jgNvd94zRcb%MG{x3ArV3)pjwX(rV$m_xql}u1h54BqH;YrA>-)u-TD=iaLh93p z7%YBtdund(#x!lznhT3(d36^~QCzhSekqE>T@>5=QuK1&^`faGl}08ae#mGlh*1R* zT|@va+$;jx5mDTVkJnry&;q7}SlC!Jy;Up73KP70KtM6lLXf7?M5sxa5&4;n&CD0F zv#@z3w|ObIx7%EFR*Lo)5VZQUHW*yzSvrhxkmuQA*xTwc_|)`jo{lNm-+GhLxyKND zv{RR1$F&)Dd!J!Ht1ShqEF z>vW9RmWM|N+mU?~-9x%Y`wMQXa0^DvVh9s1Cj?04WFkq@I*WM&XhB`CX$H2`_OhQv z{;SlXKOS*vrAh;K^_i*_n3bX*lq=54*+h%)JJs?D{F7Nb3oqS1M!jZMEg!;Q8C(;4X_sT;R<>gfPkxV*;_oVS~E3#gl8ZI$dvTYt|2u9{9{T3p&+j7NWJ9J%f(2k8)9JsCb zvQ0lYeOerHsPGJ*cRH%RnBRHSaJKbfT=-po?NQV2JOAL*y%~G{pM2D8+vbNKS3hb+ zKZXGp$5h-`pp@R05p-K0f|L{76$dw-+ylG-(U&3Z>yY?=jqr;3-z2o7zAKgyt?TgX I|1}P*qWKaC(*OVf diff --git a/common/rhi/shaders/flow.vert.qsb b/common/rhi/shaders/flow.vert.qsb deleted file mode 100644 index 5194219b83f329b3a7900a5f9c35f2526bc6213c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2689 zcmV-{3V!tf059Ztob6icZyU!EUx}3D(5d4%4=ah|oTEI*L}qv-CA(IrIF{{5u2d;{ zxN2mXK9NWHY>Fq4M?D${D9~^H)_&-}(m$;aplD}qXL)mb54H`82CWEOcr){x$Ii^o zt{4j;UJ>$x-yaD_bVN^h!h-LHu*HgSMH9Z;qAt4dek@9W%fd7IclwB!&p%_xBtw}W zYN$+xvOm;Ng$#|Q8M-VE0o(&~9y~4>gC(FKUC9GaCt?8wt3RbUCelod!E;3%iOtycrzQ>6 zmI2-Xk8QE$XI-kLR@wlyrPQ^{m8a%D&Pd$aQ+L6;zLB0-2jvzl!3O1^X;3}2_eXpa zTL5-I9n*Fo?ukCUx4={vq~p-KGolJ_&zRl>Jb7^K0O}a>hRyvVqUyWNs4kA4CQ(vMLEmQg5% z8zJ5Z{?hIng?mnGgN z=4n=>+=o;lw(Tf`Wi0Bcbm$f>q5q*Jjh4sBevK>wL3DM(( zeaf&;MY#TTq9+JzF{~wm-gpBvM*THrd>Y^1hBx$Kz;hMw6XX+Po`nBiAiG%~llAX0 z6SM}TRgWNVj_6m3r|3%>eOaTg5dAsO=v(fXUw@_Ow>?@_g;oAhAZUrzdpm`7G>R|BgbnK;EB$ zGe%hK&m85XM*aK~A$wBMuL;?cihfcT3LiXghU=`Q!HrWu2ca?Y}j5kTVQO0|R zcp1ifmtx@d-Xk8jca3=5-uuMk_O8RvxxL3hC zVt-D&6^ea?^p;6hqj~(Tko*3R5CiV{4dUUP{uAK0NdK>ZM;V^O$iscQNwMRe{)Le9 zXqwsHCjM_IN57;TY%{&@m>$OW9pU~0_LZM45$xw(A?M9Jow>Wr-!ma+%{-m4&zNkF z);UjSD$;+0tlXAY$1L6FkZ6j*eKPyosUy4FbKH($mP)x?&+GOZp0U+&T5k8?Ucc3{ zySeXk27C@IuWB4Q_VHTRePK5|&{?s(u5&Wyi;wI^#n`hNFZa7{ztdcB+iq7%T5Z?z zjQXL~EOAEHZndSEt;2Z!efPK{B~HgPoZk9Cq8m2na%Xe7TwjJA4&SKHR6%BW5bIvw zvoX>tSnPRLr(v(SO}kz1y2lXPFo-!EQXUSeXpo9===L1Bsw1m=>U8#zT{ez3?UM!9 z?KU-qvf&K`VTEP4VYS!X9#@b_Qc*l?JCN*F8(2&g>bgXLjptSqxQWXkxv3eEUItcH z53PpdohHXI0K{4eRXTU%I!y!HH(%hb7)q>B^O<>!H6N{QVcLk7n2C~dqNGwN$o|`J z*Vm|Y;6D$2R*c&p#%JMJ3&8L#tGZ7cX0b#z2So>qL79DtsxC;BX7S{dHb~3J^BNmB zYDNi+`a+qskoDpzSOKrbP0o|H&ZIl7BLE-mfe?^t%7B9^OB^dJ1Id;=%jL8wbs`2I zKBda%Q|f$5olmLrDfQ!+Qh#7m>Q*qNX8xzAl+#HbPl+-!MOIFcRg{d6Ah+*D#*akt zxf7s*nFFZAVMF-1L8FJKO&HWnnl2HK;jzM1&qvDt`A8WR!7q34xwzKYlN&F*4e!9t z-gkPQ-OcZnRC7Ru>Ic>fw=3JJdQ!#hT92*F9RnhK>9$%u+sijp4Sc4FZ}e6YQ+y1IU!pQu547{FwJxWY4NIUQ;;XeAw5 zX3%Onw8Ee>u~3zN2At*lLd!IR-HL}k7u=)(Dk zHA?8RXlY^YD3W8*QKC1>iGhnu5U51sXcA+DeIN|2W? z@uz;0%uJD$Q)CHe|3Sa4!U!GeEii?$ke%to^QiD2xdgO^-U3=brfWcS!^q2DWRe-6 zxNp}Td{^BPGmUB-SByKSVinC{ie`dhd6;53L9sGSkv806(03djoO}rKf)3)Ka5sgT zCEmF#3kMH|XS_nVEA&YkuM=*NU<61;OhZT`u1`o1=M=-6GjwZ-VEJBSmxL&e?L2lj zh~lCfCVDMM)(R38y$!@@h4+$n2k>vhw%6}=w1l1UyEgt`S@sW=#`{xFr_t^=ZR5)W z+q2sBp4V(Ud-J(~-*XO{U*La=&*$M!amV$u=5v(xXvA0utI(J2*ncSFZtq%j!S41=S?lwr#eEN=n^tb~F5 zh-Rp&9w*;CJ3DHsASjXvr;~7-+}RoYmY6T;VR%8d0+gwT5i`j-zC09fhVYf4_;Lsz zNlVPQ=J=T;{9s&i^sH7xeN1xftpuz;v^ns0K@|x{sC^Q&t9;9=qJareRD*bTciL#U zzEN$neu5VjK+3 v8*?maYY81pt~`(MKpOL#ihljkegPW%!%so~G*~;eB67vkasKBYQFraVLAY9G diff --git a/common/rhi/shaders/shaders.qrc b/common/rhi/shaders/shaders.qrc deleted file mode 100644 index 37a0d50b8..000000000 --- a/common/rhi/shaders/shaders.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - flow.vert.qsb - flow.frag.qsb - - diff --git a/common/themes/themes_common.pri b/common/themes/themes_common.pri deleted file mode 100644 index f246882c9..000000000 --- a/common/themes/themes_common.pri +++ /dev/null @@ -1,16 +0,0 @@ -INCLUDEPATH += $$PWD \ - $$PWD/shared - -HEADERS += \ - $$PWD/icon_utils.h \ - $$PWD/theme_id.h \ - $$PWD/theme_manager.h \ - $$PWD/themable.h \ - $$PWD/yacreader_icon.h \ - $$PWD/shared/help_about_dialog_theme.h \ - $$PWD/shared/whats_new_dialog_theme.h \ - - -SOURCES += \ - $$PWD/icon_utils.cpp \ - $$PWD/theme_manager.cpp diff --git a/compileOSX.sh b/compileOSX.sh index bd92627fc..8a5d043dc 100755 --- a/compileOSX.sh +++ b/compileOSX.sh @@ -21,37 +21,30 @@ if [ "$ARCH" == "x86_64" ]; then ARCHS="x86_64" ARCH_NAME="Intel" else - ARCHS="x86_64 arm64" + ARCHS="x86_64;arm64" ARCH_NAME="U" fi echo "Building for $ARCH_NAME" -hash qmake 2>/dev/null || { echo >&2 "Qmake command not available. Please add the bin subfolder of your Qt installation to the PATH environment variable."; exit 1; } +hash cmake 2>/dev/null || { echo >&2 "cmake command not available. Please add cmake to your PATH."; exit 1; } -echo "Compiling YACReader" -cd YACReader -qmake DEFINES+="BUILD_NUMBER=\\\\\\\"${BUILD_NUMBER}\\\\\\\"" QMAKE_APPLE_DEVICE_ARCHS="$ARCHS" -make -cd .. +echo "Configuring and building with CMake" +cmake -B build \ + -G Ninja \ + -DDECOMPRESSION_BACKEND=7zip \ + -DBUILD_NUMBER="${BUILD_NUMBER}" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_OSX_ARCHITECTURES="${ARCHS}" \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=11 -echo "Compiling YACReaderLibrary" -cd YACReaderLibrary -qmake DEFINES+="BUILD_NUMBER=\\\\\\\"${BUILD_NUMBER}\\\\\\\"" QMAKE_APPLE_DEVICE_ARCHS="$ARCHS" -make -cd .. - -echo "Compiling YACReaderLibraryServer" -cd YACReaderLibraryServer -qmake DEFINES+="BUILD_NUMBER=\\\\\\\"${BUILD_NUMBER}\\\\\\\"" QMAKE_APPLE_DEVICE_ARCHS="$ARCHS" -make -cd .. +cmake --build build --parallel echo "Configuring release apps" -cp -R YACReader/YACReader.app YACReader.app -cp -R YACReaderLibrary/YACReaderLibrary.app YACReaderLibrary.app -cp -R YACReaderLibraryServer/YACReaderLibraryServer.app YACReaderLibraryServer.app +cp -R build/bin/YACReader.app YACReader.app +cp -R build/bin/YACReaderLibrary.app YACReaderLibrary.app +cp -R build/bin/YACReaderLibraryServer.app YACReaderLibraryServer.app hash macdeployqt 2>/dev/null || { echo >&2 "macdeployqt command not available. Please add the bin subfolder of your Qt installation to the PATH environment variable."; exit 1; } @@ -71,14 +64,22 @@ cp -R dependencies/7zip/macx/${ARCH}/* YACReaderLibraryServer.app/Contents/MacOS cp -R release/server YACReaderLibrary.app/Contents/MacOS/ cp -R release/server YACReaderLibraryServer.app/Contents/MacOS/ -cp -R release/languages YACReader.app/Contents/MacOS/ -cp -R release/languages YACReaderLibrary.app/Contents/MacOS/ -cp -R release/languages YACReaderLibraryServer.app/Contents/MacOS/ + +# Collect cmake-generated .qm translation files from the build tree +# (release/languages is not tracked in git; cmake generates .qm in build subdirs) +mkdir -p YACReader.app/Contents/MacOS/languages +mkdir -p YACReaderLibrary.app/Contents/MacOS/languages +mkdir -p YACReaderLibraryServer.app/Contents/MacOS/languages +find build -name "*.qm" -exec cp {} YACReader.app/Contents/MacOS/languages/ \; +find build -name "*.qm" -exec cp {} YACReaderLibrary.app/Contents/MacOS/languages/ \; +find build -name "*.qm" -exec cp {} YACReaderLibraryServer.app/Contents/MacOS/languages/ \; /usr/libexec/PlistBuddy -c "Add :CFBundleVersion string ${BUILD_NUMBER}" YACReader.app/Contents/Info.plist /usr/libexec/PlistBuddy -c "Add :CFBundleShortVersionString string ${VERSION}" YACReader.app/Contents/Info.plist /usr/libexec/PlistBuddy -c "Add :CFBundleVersion string ${BUILD_NUMBER}" YACReaderLibrary.app/Contents/Info.plist /usr/libexec/PlistBuddy -c "Add :CFBundleShortVersionString string ${VERSION}" YACReaderLibrary.app/Contents/Info.plist +/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${BUILD_NUMBER}" YACReaderLibraryServer.app/Contents/Info.plist +/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${VERSION}" YACReaderLibraryServer.app/Contents/Info.plist if [ "$SKIP_CODESIGN" = false ]; then ./signapps.sh diff --git a/compressed_archive/CMakeLists.txt b/compressed_archive/CMakeLists.txt new file mode 100644 index 000000000..215f45abd --- /dev/null +++ b/compressed_archive/CMakeLists.txt @@ -0,0 +1,158 @@ +# Comic archive decompression backend (cbx_backend) +# Switched on DECOMPRESSION_BACKEND: unarr | 7zip | libarchive + +add_library(cbx_backend STATIC) + +if(DECOMPRESSION_BACKEND STREQUAL "unarr") + message(STATUS "Decompression backend: unarr") + + target_sources(cbx_backend PRIVATE + unarr/compressed_archive.cpp + unarr/compressed_archive.h + unarr/extract_delegate.h + ) + target_include_directories(cbx_backend PUBLIC unarr) + target_compile_definitions(cbx_backend PUBLIC use_unarr) + + # Try CMake config first, then pkg-config, then system path + find_package(unarr QUIET) + if(unarr_FOUND) + message(STATUS " Found unarr via CMake config") + target_link_libraries(cbx_backend PRIVATE unarr::unarr) + else() + pkg_check_modules(UNARR QUIET IMPORTED_TARGET libunarr) + if(UNARR_FOUND) + message(STATUS " Found unarr via pkg-config") + target_link_libraries(cbx_backend PRIVATE PkgConfig::UNARR) + elseif(APPLE AND EXISTS "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx/libunarr.a") + message(STATUS " Found prebuilt unarr in dependencies (macOS)") + target_include_directories(cbx_backend PRIVATE + "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx") + target_link_directories(cbx_backend PRIVATE + "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx") + target_link_libraries(cbx_backend PRIVATE unarr z bz2) + elseif(WIN32 AND EXISTS "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/unarr.h") + message(STATUS " Found prebuilt unarr in dependencies (Windows)") + target_include_directories(cbx_backend PRIVATE + "${CMAKE_SOURCE_DIR}/dependencies/unarr/win") + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64") + target_link_directories(cbx_backend PRIVATE + "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/arm64") + else() + target_link_directories(cbx_backend PRIVATE + "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/x64") + endif() + target_link_libraries(cbx_backend PRIVATE unarr) + target_compile_definitions(cbx_backend PRIVATE UNARR_IS_SHARED_LIBRARY) + elseif(EXISTS "/usr/include/unarr.h") + message(STATUS " Found system unarr at /usr/include") + target_link_libraries(cbx_backend PRIVATE unarr) + else() + message(FATAL_ERROR + "Could not find unarr. Install libunarr or use a different DECOMPRESSION_BACKEND.") + endif() + endif() + +elseif(DECOMPRESSION_BACKEND STREQUAL "7zip") + message(STATUS "Decompression backend: 7zip (in-tree)") + + # Auto-download 7zip source if not present + if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lib7zip/CPP") + include(FetchContent) + FetchContent_Declare( + lib7zip + URL "https://github.com/YACReader/yacreader-7z-deps/raw/main/7z2301-src.7z" + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib7zip" + DOWNLOAD_EXTRACT_TIMESTAMP ON + ) + message(STATUS " Downloading 7zip source from yacreader-7z-deps...") + FetchContent_MakeAvailable(lib7zip) + endif() + + target_sources(cbx_backend PRIVATE + compressed_archive.cpp + compressed_archive.h + extract_delegate.h + 7z_includes.h + open_callbacks.h + extract_callbacks.h + lib7zip/CPP/Windows/FileIO.cpp + lib7zip/CPP/Windows/PropVariant.cpp + lib7zip/CPP/Windows/PropVariantConv.cpp + lib7zip/CPP/Common/IntToString.cpp + lib7zip/CPP/Common/MyString.cpp + lib7zip/CPP/Common/MyVector.cpp + lib7zip/CPP/Common/Wildcard.cpp + lib7zip/CPP/7zip/Common/FileStreams.cpp + lib7zip/C/Alloc.c + lib7zip/CPP/7zip/Common/StreamObjects.cpp + ) + + if(UNIX) + target_sources(cbx_backend PRIVATE + lib7zip/CPP/Common/NewHandler.cpp + lib7zip/CPP/Windows/DLL.cpp + lib7zip/CPP/Windows/FileDir.cpp + lib7zip/CPP/Windows/FileFind.cpp + lib7zip/CPP/Windows/FileName.cpp + lib7zip/CPP/Windows/TimeUtils.cpp + lib7zip/CPP/Common/UTFConvert.cpp + lib7zip/CPP/Common/MyWindows.cpp + lib7zip/CPP/Common/StringConvert.cpp + ) + endif() + + target_include_directories(cbx_backend + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE lib7zip/CPP + ) + + if(APPLE) + target_compile_definitions(cbx_backend PRIVATE + _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE NDEBUG _REENTRANT + ENV_UNIX _7ZIP_LARGE_PAGES ENV_MACOSX _TCHAR_DEFINED + UNICODE _UNICODE UNIX_USE_WIN_FILE) + target_link_libraries(cbx_backend PRIVATE + "-framework IOKit" "-framework CoreFoundation") + elseif(UNIX) + target_compile_definitions(cbx_backend PRIVATE + _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE NDEBUG _REENTRANT + ENV_UNIX _7ZIP_LARGE_PAGES UNICODE _UNICODE UNIX_USE_WIN_FILE) + endif() + +elseif(DECOMPRESSION_BACKEND STREQUAL "libarchive") + message(STATUS "Decompression backend: libarchive") + + if(WIN32 OR APPLE) + message(FATAL_ERROR "libarchive backend is not supported on Windows or macOS") + endif() + + target_sources(cbx_backend PRIVATE + libarchive/compressed_archive.cpp + libarchive/compressed_archive.h + libarchive/extract_delegate.h + ) + target_include_directories(cbx_backend PUBLIC libarchive) + target_compile_definitions(cbx_backend PUBLIC use_libarchive) + + # Try pkg-config first, then system path + pkg_check_modules(LIBARCHIVE QUIET IMPORTED_TARGET libarchive) + if(LIBARCHIVE_FOUND) + message(STATUS " Found libarchive via pkg-config") + target_link_libraries(cbx_backend PRIVATE PkgConfig::LIBARCHIVE) + elseif(EXISTS "/usr/include/archive.h") + message(STATUS " Found system libarchive at /usr/include") + target_link_libraries(cbx_backend PRIVATE archive) + else() + message(FATAL_ERROR + "Could not find libarchive. Install it or use a different DECOMPRESSION_BACKEND.") + endif() + +else() + message(FATAL_ERROR + "Unknown DECOMPRESSION_BACKEND: '${DECOMPRESSION_BACKEND}'. " + "Use: unarr, 7zip, or libarchive") +endif() + +# Qt, yr_global, and QsLog are needed by all backends +target_link_libraries(cbx_backend PRIVATE Qt::Core yr_global QsLog) diff --git a/compressed_archive/libarchive/README.md b/compressed_archive/libarchive/README.md index 71c8d11aa..759d8639f 100644 --- a/compressed_archive/libarchive/README.md +++ b/compressed_archive/libarchive/README.md @@ -7,9 +7,9 @@ This backend is currently only supported on the Linux platform. ## Using -Enabling this backend is achieved by adding the `libarchive` qmake configuration value: +Enable this backend by setting the `DECOMPRESSION_BACKEND` CMake option: - qmake CONFIG+=libarchive + cmake -B build -DDECOMPRESSION_BACKEND=libarchive Upon success, the application can be built as normal. diff --git a/compressed_archive/libarchive/libarchive-wrapper.pri b/compressed_archive/libarchive/libarchive-wrapper.pri deleted file mode 100644 index c9bcd8254..000000000 --- a/compressed_archive/libarchive/libarchive-wrapper.pri +++ /dev/null @@ -1,31 +0,0 @@ -INCLUDEPATH += $$PWD -DEPENDPATH += $$PWD - -HEADERS += $$PWD/extract_delegate.h \ - $$PWD/compressed_archive.h - -SOURCES += $$PWD/compressed_archive.cpp - -if(mingw|unix):!macx:!contains(QT_CONFIG, no-pkg-config):packagesExist(libarchive) { - message(Using system provided libarchive installation found by pkg-config.) - !system(pkg-config --atleast-version=3.6.0 libarchive) { - LIBARCHIVE_WARNING = "libarchive < 3.6.0 found. Older versions of libarchive DO NOT SUPPORT RARv4 files. This is probably not what you want" - warning($$LIBARCHIVE_WARNING) - message($$LIBARCHIVE_WARNING) - } - - CONFIG += link_pkgconfig - PKGCONFIG += libarchive - DEFINES += use_libarchive - } -else:unix:!macx:exists(/usr/include/archive.h) { - message(Using system provided libarchive installation.) - LIBS += -larchive - DEFINES += use_libarchive -} -else:if(win32|macx) { - error(Unsupported: the libarchive decompression backend is not currently supported on this system.) -} -else { - error(Missing dependency: libarchive decompression backend. Please install libarchive on your system) -} diff --git a/compressed_archive/unarr/unarr-wrapper.pri b/compressed_archive/unarr/unarr-wrapper.pri deleted file mode 100644 index 011526741..000000000 --- a/compressed_archive/unarr/unarr-wrapper.pri +++ /dev/null @@ -1,52 +0,0 @@ -INCLUDEPATH += $$PWD -DEPENDPATH += $$PWD - -HEADERS += $$PWD/extract_delegate.h \ - $$PWD/compressed_archive.h - -SOURCES += $$PWD/compressed_archive.cpp - -if(mingw|unix):!macx:!contains(QT_CONFIG, no-pkg-config):packagesExist(libunarr) { - message(Using system provided unarr installation found by pkg-config.) - CONFIG += link_pkgconfig - PKGCONFIG += libunarr - DEFINES += use_unarr - } -else:unix:!macx:exists(/usr/include/unarr.h) { - message(Using system provided unarr installation.) - LIBS += -lunarr - DEFINES += use_unarr -} - -else:macx:exists(../../dependencies/unarr/macx/libunarr.a) { - message(Found prebuilt unarr library in dependencies directory.) - INCLUDEPATH += $$PWD/../../dependencies/unarr/macx - LIBS += -L$$PWD/../../dependencies/unarr/macx -lunarr -lz -lbz2 - DEFINES += use_unarr - } - -else:win32:exists(../../dependencies/unarr/win/unarr.h) { - message(Found prebuilt unarr library in dependencies directory.) - INCLUDEPATH += $$PWD/../../dependencies/unarr/win - contains(QMAKE_TARGET.arch, x86_64): { - LIBS += -L$$PWD/../../dependencies/unarr/win/x64 -lunarr - } else { - LIBS += -L$$PWD/../../dependencies/unarr/win/x86 -lunarr - } - DEFINES += use_unarr UNARR_IS_SHARED_LIBRARY - } - -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) - } diff --git a/compressed_archive/unarr/unarr.pro b/compressed_archive/unarr/unarr.pro deleted file mode 100644 index d23c3c199..000000000 --- a/compressed_archive/unarr/unarr.pro +++ /dev/null @@ -1,46 +0,0 @@ -INCLUDEPATH += $$PWD/unarr-master/ -DEPENDPATH += $$PWD/unarr-master/ - -unix:QMAKE_CFLAGS_RELEASE -= "-O2" -unix:QMAKE_CFLAGS_RELEASE += "-O3" -unix:QMAKE_CFLAGS_RELEASE += "-DNDEBUG" -unix:QMAKE_CFLAGS += "-D_FILE_OFFSET_BITS=64" - -win32:QMAKE_CFLAGS_RELEASE += "/DNDEBUG" - -HEADERS+=$$PWD/unarr-master/common/allocator.h\ - $$PWD/unarr-master/common/unarr-imp.h\ - $$PWD/unarr-master/lzmasdk/7zTypes.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/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 \ No newline at end of file diff --git a/compressed_archive/wrapper.pri b/compressed_archive/wrapper.pri deleted file mode 100644 index a8d777402..000000000 --- a/compressed_archive/wrapper.pri +++ /dev/null @@ -1,62 +0,0 @@ -INCLUDEPATH += $$PWD -DEPENDPATH += $$PWD - -exists (../compressed_archive/lib7zip) { - message(Using 7zip) -} else { - error(You\'ll need 7zip source code to compile YACReader. \ - Please check the compressed_archive folder for further instructions.) -} - -INCLUDEPATH += \ - $$PWD/lib7zip/CPP \ - -SOURCES += \ - $$PWD/compressed_archive.cpp \ - $$PWD/lib7zip/CPP/Windows/FileIO.cpp \ - $$PWD/lib7zip/CPP/Windows/PropVariant.cpp \ - $$PWD/lib7zip/CPP/Windows/PropVariantConv.cpp \ - $$PWD/lib7zip/CPP/Common/IntToString.cpp \ - $$PWD/lib7zip/CPP/Common/MyString.cpp \ - $$PWD/lib7zip/CPP/Common/MyVector.cpp \ - $$PWD/lib7zip/CPP/Common/Wildcard.cpp \ - $$PWD/lib7zip/CPP/7zip/Common/FileStreams.cpp \ - $$PWD/lib7zip/C/Alloc.c \ - $$PWD/lib7zip/CPP/7zip/Common/StreamObjects.cpp - -unix{ -SOURCES += \ - $$PWD/lib7zip/CPP/Common/NewHandler.cpp \ - $$PWD/lib7zip/CPP/Windows/DLL.cpp \ - $$PWD/lib7zip/CPP/Windows/FileDir.cpp \ - $$PWD/lib7zip/CPP/Windows/FileFind.cpp \ - $$PWD/lib7zip/CPP/Windows/FileName.cpp \ - $$PWD/lib7zip/CPP/Windows/TimeUtils.cpp \ - $$PWD/lib7zip/CPP/Common/UTFConvert.cpp \ - $$PWD/lib7zip/CPP/Common/MyWindows.cpp \ - $$PWD/lib7zip/CPP/Common/StringConvert.cpp \ -} - -HEADERS += \ - $$PWD/lib7zip/CPP/Common/Common.h \ - $$PWD/compressed_archive.h \ - $$PWD/extract_delegate.h \ - $$PWD/7z_includes.h \ - $$PWD/open_callbacks.h \ - $$PWD/extract_callbacks.h \ - -macx{ -LIBS += -framework IOKit -framework CoreFoundation - -DEFINES += _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE \ - NDEBUG _REENTRANT ENV_UNIX \ - _7ZIP_LARGE_PAGES ENV_MACOSX _TCHAR_DEFINED \ - UNICODE _UNICODE UNIX_USE_WIN_FILE -} - -unix:!macx{ -DEFINES += _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE \ - NDEBUG _REENTRANT ENV_UNIX \ - _7ZIP_LARGE_PAGES \ - UNICODE _UNICODE UNIX_USE_WIN_FILE -} diff --git a/config.pri b/config.pri deleted file mode 100644 index 083bef24b..000000000 --- a/config.pri +++ /dev/null @@ -1,101 +0,0 @@ -# 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 - -CONFIG += c++20 - -win32 { - #enable c++20 explicitly in msvc - QMAKE_CXXFLAGS += /std:c++20 /Zc:__cplusplus /permissive- -} - -DEFINES += NOMINMAX - -if(unix|mingw):QMAKE_CXXFLAGS_RELEASE += -DNDEBUG -win32:msvc:QMAKE_CXXFLAGS_RELEASE += /DNDEBUG - -# check Qt version -defineTest(minQtVersion) { - maj = $$1 - min = $$2 - patch = $$3 - isEqual(QT_MAJOR_VERSION, $$maj) { - isEqual(QT_MINOR_VERSION, $$min) { - isEqual(QT_PATCH_VERSION, $$patch) { - return(true) - } - greaterThan(QT_PATCH_VERSION, $$patch) { - return(true) - } - } - greaterThan(QT_MINOR_VERSION, $$min) { - return(true) - } - } - greaterThan(QT_MAJOR_VERSION, $$maj) { - return(true) - } - return(false) -} - -!minQtVersion(6, 0, 0) { - error(YACReader requires Qt 6.0 or newer but $$[QT_VERSION] was detected) -} - -# reduce log pollution -CONFIG += silent - -# Disable coverflow for arm targets -isEmpty(QMAKE_TARGET.arch) { - QMAKE_TARGET.arch = $$QMAKE_HOST.arch -} - -# default value for comic archive decompression backend -unix:!macx:!CONFIG(unarr):!CONFIG(7zip):!CONFIG(libarchive) { - CONFIG += unarr -} - -win32:!CONFIG(unarr):!CONFIG(7zip):!CONFIG(libarchive) { - CONFIG += 7zip -} - -macx:!CONFIG(unarr):!CONFIG(7zip):!CONFIG(libarchive) { - CONFIG += 7zip -} - -# default values for pdf render backend -win32:!CONFIG(poppler):!CONFIG(pdfium):!CONFIG(no_pdf) { - CONFIG += pdfium -} - -unix:!macx:!CONFIG(poppler):!CONFIG(pdfium):!CONFIG(no_pdf) { - CONFIG += poppler -} - -macx:!CONFIG(pdfkit):!CONFIG(pdfium):!CONFIG(no_pdf) { - CONFIG += pdfkit -} - -!CONFIG(poppler) { - DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x050F00 -} else { - DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x050900 -} - -unix:!macx { -# set install prefix if it's empty -isEmpty(PREFIX) { - PREFIX = /usr -} -isEmpty(BINDIR) { - BINDIR = $$PREFIX/bin -} -isEmpty(LIBDIR) { - LIBDIR = $$PREFIX/lib -} -isEmpty(DATADIR) { - DATADIR = $$PREFIX/share -} -} - -DEFINES += QT_DEPRECATED_WARNINGS diff --git a/custom_widgets/CMakeLists.txt b/custom_widgets/CMakeLists.txt new file mode 100644 index 000000000..4e5b6f1d6 --- /dev/null +++ b/custom_widgets/CMakeLists.txt @@ -0,0 +1,106 @@ +# Custom widgets for YACReader +# Shared widgets + app-specific variants + +# Files shared between both YACReader and YACReaderLibrary +set(WIDGETS_COMMON_SOURCES + help_about_dialog.h + help_about_dialog.cpp + yacreader_field_edit.h + yacreader_field_edit.cpp + yacreader_field_plain_text_edit.h + yacreader_field_plain_text_edit.cpp + yacreader_options_dialog.h + yacreader_options_dialog.cpp + yacreader_spin_slider_widget.h + yacreader_spin_slider_widget.cpp + yacreader_tool_bar_stretch.h + yacreader_tool_bar_stretch.cpp + yacreader_busy_widget.h + yacreader_busy_widget.cpp + rounded_corners_dialog.h + rounded_corners_dialog.cpp + whats_new_dialog.h + whats_new_dialog.cpp + whats_new_controller.h + whats_new_controller.cpp + yacreader_3d_flow_config_widget.h + yacreader_3d_flow_config_widget.cpp +) + +# macOS toolbar (shared by both apps) +if(APPLE) + list(APPEND WIDGETS_COMMON_SOURCES + yacreader_macosx_toolbar.h + yacreader_macosx_toolbar.mm + ) +endif() + +# --- custom_widgets_reader (YACReader-specific) --- +add_library(custom_widgets_reader STATIC ${WIDGETS_COMMON_SOURCES}) +target_include_directories(custom_widgets_reader PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +# App-specific theme.h needed because themable.h → theme_manager.h → theme.h +target_include_directories(custom_widgets_reader PRIVATE + ${CMAKE_SOURCE_DIR}/YACReader/themes +) +target_compile_definitions(custom_widgets_reader PRIVATE YACREADER) +target_link_libraries(custom_widgets_reader PUBLIC + Qt::Core + Qt::Widgets + Qt::Network + common_gui + rhi_flow_reader + QsLog +) +if(APPLE) + target_link_libraries(custom_widgets_reader PRIVATE + "-framework Foundation" + "-framework AppKit" + ) +endif() + +# --- custom_widgets_library (YACReaderLibrary-specific) --- +set(LIBRARY_EXTRA_WIDGETS + yacreader_search_line_edit.h + yacreader_search_line_edit.cpp + yacreader_titled_toolbar.h + yacreader_titled_toolbar.cpp + yacreader_table_view.h + yacreader_table_view.cpp + yacreader_sidebar.h + yacreader_sidebar.cpp + yacreader_library_list_widget.h + yacreader_library_list_widget.cpp + yacreader_library_item_widget.h + yacreader_library_item_widget.cpp + yacreader_treeview.h + yacreader_treeview.cpp + yacreader_cover_label.h + yacreader_cover_label.cpp +) + +add_library(custom_widgets_library STATIC + ${WIDGETS_COMMON_SOURCES} + ${LIBRARY_EXTRA_WIDGETS} +) +target_include_directories(custom_widgets_library PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +# App-specific theme.h + YACReaderLibrary headers needed by macosx_toolbar +target_include_directories(custom_widgets_library PRIVATE + ${CMAKE_SOURCE_DIR}/YACReaderLibrary/themes + ${CMAKE_SOURCE_DIR}/YACReaderLibrary + ${CMAKE_SOURCE_DIR}/YACReaderLibrary/db +) +target_compile_definitions(custom_widgets_library PRIVATE YACREADER_LIBRARY) +target_link_libraries(custom_widgets_library PUBLIC + Qt::Core + Qt::Widgets + Qt::Network + common_gui + rhi_flow_library + QsLog +) +if(APPLE) + target_link_libraries(custom_widgets_library PRIVATE + "-framework Foundation" + "-framework AppKit" + ) +endif() diff --git a/custom_widgets/custom_widgets_yacreader.pri b/custom_widgets/custom_widgets_yacreader.pri deleted file mode 100644 index 92e474aee..000000000 --- a/custom_widgets/custom_widgets_yacreader.pri +++ /dev/null @@ -1,34 +0,0 @@ -INCLUDEPATH += $$PWD -DEPENDPATH += $$PWD - -HEADERS += \ - $$PWD/help_about_dialog.h \ - $$PWD/yacreader_field_edit.h \ - $$PWD/yacreader_field_plain_text_edit.h \ - $$PWD/yacreader_options_dialog.h \ - $$PWD/yacreader_spin_slider_widget.h \ - $$PWD/yacreader_tool_bar_stretch.h \ - $$PWD/yacreader_busy_widget.h \ - $$PWD/rounded_corners_dialog.h \ - $$PWD/whats_new_dialog.h \ - $$PWD/whats_new_controller.h \ - $$PWD/yacreader_3d_flow_config_widget.h -macx{ -HEADERS += $$PWD/yacreader_macosx_toolbar.h -} - -SOURCES += \ - $$PWD/help_about_dialog.cpp \ - $$PWD/yacreader_field_edit.cpp \ - $$PWD/yacreader_field_plain_text_edit.cpp \ - $$PWD/yacreader_options_dialog.cpp \ - $$PWD/yacreader_spin_slider_widget.cpp \ - $$PWD/yacreader_tool_bar_stretch.cpp \ - $$PWD/yacreader_busy_widget.cpp \ - $$PWD/rounded_corners_dialog.cpp \ - $$PWD/whats_new_dialog.cpp \ - $$PWD/whats_new_controller.cpp \ - $$PWD/yacreader_3d_flow_config_widget.cpp -macx{ -OBJECTIVE_SOURCES += $$PWD/yacreader_macosx_toolbar.mm -} diff --git a/custom_widgets/custom_widgets_yacreaderlibrary.pri b/custom_widgets/custom_widgets_yacreaderlibrary.pri deleted file mode 100644 index e9f61afd0..000000000 --- a/custom_widgets/custom_widgets_yacreaderlibrary.pri +++ /dev/null @@ -1,50 +0,0 @@ -INCLUDEPATH += $$PWD -DEPENDPATH += $$PWD - -HEADERS += \ - $$PWD/help_about_dialog.h \ - $$PWD/rounded_corners_dialog.h \ - $$PWD/whats_new_dialog.h \ - $$PWD/whats_new_controller.h \ - $$PWD/yacreader_field_edit.h \ - $$PWD/yacreader_field_plain_text_edit.h \ - $$PWD/yacreader_options_dialog.h \ - $$PWD/yacreader_search_line_edit.h \ - $$PWD/yacreader_spin_slider_widget.h \ - $$PWD/yacreader_tool_bar_stretch.h \ - $$PWD/yacreader_titled_toolbar.h \ - $$PWD/yacreader_table_view.h \ - $$PWD/yacreader_sidebar.h \ - $$PWD/yacreader_library_list_widget.h \ - $$PWD/yacreader_library_item_widget.h \ - $$PWD/yacreader_treeview.h \ - $$PWD/yacreader_busy_widget.h \ - $$PWD/yacreader_cover_label.h \ - $$PWD/yacreader_3d_flow_config_widget.h -macx{ -HEADERS += $$PWD/yacreader_macosx_toolbar.h -} - -SOURCES += \ - $$PWD/help_about_dialog.cpp \ - $$PWD/rounded_corners_dialog.cpp \ - $$PWD/whats_new_dialog.cpp \ - $$PWD/whats_new_controller.cpp \ - $$PWD/yacreader_field_edit.cpp \ - $$PWD/yacreader_field_plain_text_edit.cpp \ - $$PWD/yacreader_options_dialog.cpp \ - $$PWD/yacreader_search_line_edit.cpp \ - $$PWD/yacreader_spin_slider_widget.cpp \ - $$PWD/yacreader_tool_bar_stretch.cpp \ - $$PWD/yacreader_titled_toolbar.cpp \ - $$PWD/yacreader_table_view.cpp \ - $$PWD/yacreader_sidebar.cpp \ - $$PWD/yacreader_library_list_widget.cpp \ - $$PWD/yacreader_library_item_widget.cpp \ - $$PWD/yacreader_treeview.cpp \ - $$PWD/yacreader_busy_widget.cpp \ - $$PWD/yacreader_cover_label.cpp \ - $$PWD/yacreader_3d_flow_config_widget.cpp -macx{ -OBJECTIVE_SOURCES += $$PWD/yacreader_macosx_toolbar.mm -} diff --git a/dependencies/pdf_backend.pri b/dependencies/pdf_backend.pri deleted file mode 100644 index 1402b9e20..000000000 --- a/dependencies/pdf_backend.pri +++ /dev/null @@ -1,75 +0,0 @@ -CONFIG(no_pdf) { - DEFINES += "NO_PDF" -} - -CONFIG(pdfium) { - message(Using pdfium.) - DEFINES += "USE_PDFIUM" - SOURCES += ../common/pdf_comic.cpp - msvc { - INCLUDEPATH += $$PWD/pdfium/win/public - contains(QMAKE_TARGET.arch, x86_64): { - LIBS += -L$$PWD/pdfium/win/x64 -lpdfium - } else:contains(QMAKE_TARGET.arch, arm64): { - LIBS += -L$$PWD/pdfium/win/arm64 -lpdfium - } else { - LIBS += -L$$PWD/pdfium/win/x86 -lpdfium - } - } - unix|mingw { - macx { - LIBS += -L$$PWD/pdfium/macx/bin -lpdfium - INCLUDEPATH += $$PWD/pdfium/macx/include - } - else:!contains(QT_CONFIG, no-pkg-config):packagesExist(libpdfium) { - message(Using system provided installation of libpdfium found by pkg-config.) - CONFIG += link_pkgconfig - PKGCONFIG += libpdfium - } else:exists(/usr/include/pdfium) { - message(Using libpdfium found at /usr/lib/pdfium) - INCLUDEPATH += /usr/include/pdfium - LIBS += -lpdfium - } else { - error(Could not find libpdfium.) - } - } -} - -CONFIG(pdfkit) { - !macx { - error (Pdfkit is macOS only) - } else { - DEFINES += "USE_PDFKIT" - OBJECTIVE_SOURCES += ../common/pdf_comic.mm - } -} - -CONFIG(poppler) { - msvc { - contains(QMAKE_TARGET.arch, x86_64): { - error ("We currently don't ship precompiled poppler libraries for 64 bit builds on Windows") - } - INCLUDEPATH += $$PWD/poppler/include/qt6 - LIBS += -L$$PWD/poppler/lib -lpoppler-qt6 - # Add extra paths for dll dependencies so the executables don't crash when launching - # from QtCreator - LIBS += -L$$PWD/poppler/bin - LIBS += -L$$PWD/poppler/dependencies/bin - } - if(unix|mingw):!macx { - !contains(QT_CONFIG, no-pkg-config):packagesExist(poppler-qt6) { - message("Using system provided installation of poppler-qt6 found by pkg-config.") - CONFIG += link_pkgconfig - PKGCONFIG += poppler-qt6 - } else:!macx:exists(/usr/include/poppler/qt6) { - message("Using system provided installation of poppler-qt6.") - INCLUDEPATH += /usr/include/poppler/qt6 - LIBS += -lpoppler-qt6 - } else { - error("Could not find poppler-qt6") - } - } - unix:macx { - error (Poppler backend is currently not supported on macOS) - } -} diff --git a/docker/Dockerfile b/docker/Dockerfile index 12c5ed4b5..60bad055a 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -14,14 +14,13 @@ RUN \ apt-get update && \ apt-get install -y --no-install-recommends \ build-essential \ + cmake \ desktop-file-utils \ gcc \ g++ \ git \ qt6-tools-dev \ qt6-base-dev-tools \ - qmake6 \ - qmake6-bin \ qt6-base-dev \ qt6-multimedia-dev \ qt6-tools-dev-tools \ @@ -60,24 +59,22 @@ RUN git clone https://github.com/YACReader/yacreader.git /src/git && \ cd /src/git && \ git checkout $YACR_VERSION -# get 7zip source -RUN cd /src/git/compressed_archive && \ - wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O /src/git/compressed_archive/7z2301-src.7z && \ - 7z x /src/git/compressed_archive/7z2301-src.7z -o/src/git/compressed_archive/lib7zip - -# build yacreaderlibraryserver -RUN cd /src/git/YACReaderLibraryServer && \ - qmake6 PREFIX=/app CONFIG+="7zip server_standalone" YACReaderLibraryServer.pro && \ - qmake6 -v && \ - make && \ - make install +# build yacreaderlibraryserver (7zip source is auto-downloaded by CMake FetchContent) +RUN cd /src/git && \ + cmake -B build \ + -DCMAKE_INSTALL_PREFIX=/app \ + -DDECOMPRESSION_BACKEND=7zip \ + -DBUILD_SERVER_STANDALONE=ON \ + -DCMAKE_BUILD_TYPE=Release && \ + cmake --build build --parallel && \ + cmake --install build # install 7z.so with RAR support RUN echo "Building and installing 7z.so with RAR support..." && \ cd "/src/git/compressed_archive/lib7zip/CPP/7zip/Bundles/Format7zF" && \ make -f makefile.gcc && \ mkdir -p /app/lib/7zip && \ - cp ./_o/7z.so /app/lib/7zip + cp ./_o/7z.so /app/lib/7zip # Stage 2: Runtime stage FROM ghcr.io/linuxserver/baseimage-ubuntu:noble @@ -95,7 +92,7 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends \ libqt6core5compat6 \ libpoppler-qt6-3t64 \ - qt6-image-formats-plugins \ + qt6-image-formats-plugins \ libqt6network6t64 \ libqt6sql6-sqlite && \ apt-get clean && \ diff --git a/docker/Dockerfile.aarch64 b/docker/Dockerfile.aarch64 index bd4660c7a..922c490ea 100644 --- a/docker/Dockerfile.aarch64 +++ b/docker/Dockerfile.aarch64 @@ -14,15 +14,17 @@ RUN \ apt-get update && \ apt-get install -y --no-install-recommends \ build-essential \ + cmake \ desktop-file-utils \ + gcc \ g++ \ git \ qt6-tools-dev \ qt6-base-dev-tools \ - qmake6 \ qt6-base-dev \ qt6-multimedia-dev \ qt6-tools-dev-tools \ + libgl-dev \ qt6-l10n-tools \ qt6-declarative-dev \ libqt6svg6-dev \ @@ -54,16 +56,15 @@ RUN git clone https://github.com/YACReader/yacreader.git /src/git && \ cd /src/git && \ git checkout $YACR_VERSION -# get 7zip source -RUN cd /src/git/compressed_archive && \ - wget "https://github.com/YACReader/yacreader-7z-deps/blob/main/7z2301-src.7z?raw=true" -O /src/git/compressed_archive/7z2301-src.7z && \ - 7z x /src/git/compressed_archive/7z2301-src.7z -o/src/git/compressed_archive/lib7zip - -# build yacreaderlibraryserver -RUN cd /src/git/YACReaderLibraryServer && \ - qmake6 PREFIX=/app CONFIG+="7zip server_standalone" YACReaderLibraryServer.pro && \ - make && \ - make install +# build yacreaderlibraryserver (7zip source is auto-downloaded by CMake FetchContent) +RUN cd /src/git && \ + cmake -B build \ + -DCMAKE_INSTALL_PREFIX=/app \ + -DDECOMPRESSION_BACKEND=7zip \ + -DBUILD_SERVER_STANDALONE=ON \ + -DCMAKE_BUILD_TYPE=Release && \ + cmake --build build --parallel && \ + cmake --install build # install 7z.so with RAR support RUN echo "Building and installing 7z.so with RAR support..." && \ diff --git a/shortcuts_management/CMakeLists.txt b/shortcuts_management/CMakeLists.txt new file mode 100644 index 000000000..a658e4128 --- /dev/null +++ b/shortcuts_management/CMakeLists.txt @@ -0,0 +1,34 @@ +# Shortcuts management for YACReader +# Two targets: reader-specific, library-specific (compiled with different defines) + +set(SHORTCUTS_SOURCES + edit_shortcuts_dialog.h + edit_shortcuts_dialog.cpp + actions_groups_model.h + actions_groups_model.cpp + actions_shortcuts_model.h + actions_shortcuts_model.cpp + edit_shortcut_item_delegate.h + edit_shortcut_item_delegate.cpp + shortcuts_manager.h + shortcuts_manager.cpp +) + +# --- shortcuts_reader (YACREADER define) --- +add_library(shortcuts_reader STATIC ${SHORTCUTS_SOURCES}) +target_include_directories(shortcuts_reader PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +# App-specific theme.h needed because themable.h → theme_manager.h → theme.h +target_include_directories(shortcuts_reader PRIVATE + ${CMAKE_SOURCE_DIR}/YACReader/themes +) +target_compile_definitions(shortcuts_reader PRIVATE YACREADER) +target_link_libraries(shortcuts_reader PUBLIC Qt::Core Qt::Widgets yr_global common_gui) + +# --- shortcuts_library (YACREADER_LIBRARY define) --- +add_library(shortcuts_library STATIC ${SHORTCUTS_SOURCES}) +target_include_directories(shortcuts_library PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(shortcuts_library PRIVATE + ${CMAKE_SOURCE_DIR}/YACReaderLibrary/themes +) +target_compile_definitions(shortcuts_library PRIVATE YACREADER_LIBRARY) +target_link_libraries(shortcuts_library PUBLIC Qt::Core Qt::Widgets yr_global common_gui) diff --git a/shortcuts_management/shortcuts_management.pri b/shortcuts_management/shortcuts_management.pri deleted file mode 100644 index b70a60da3..000000000 --- a/shortcuts_management/shortcuts_management.pri +++ /dev/null @@ -1,16 +0,0 @@ -INCLUDEPATH += $$PWD -DEPENDPATH += $$PWD - -HEADERS += \ - $$PWD/edit_shortcuts_dialog.h \ - $$PWD/actions_groups_model.h \ - $$PWD/actions_shortcuts_model.h \ - $$PWD/edit_shortcut_item_delegate.h \ - $$PWD/shortcuts_manager.h - -SOURCES += \ - $$PWD/edit_shortcuts_dialog.cpp \ - $$PWD/actions_groups_model.cpp \ - $$PWD/actions_shortcuts_model.cpp \ - $$PWD/edit_shortcut_item_delegate.cpp \ - $$PWD/shortcuts_manager.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 000000000..03bacbc14 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,4 @@ +# YACReader tests + +add_subdirectory(concurrent_queue_test) +add_subdirectory(compressed_archive_test) diff --git a/tests/compressed_archive_test/CMakeLists.txt b/tests/compressed_archive_test/CMakeLists.txt new file mode 100644 index 000000000..7b3e40b03 --- /dev/null +++ b/tests/compressed_archive_test/CMakeLists.txt @@ -0,0 +1,13 @@ +# Compressed archive test + +qt_add_executable(compressed_archive_test + main.cpp +) +target_link_libraries(compressed_archive_test PRIVATE + Qt::Core + cbx_backend +) +if(WIN32) + target_link_libraries(compressed_archive_test PRIVATE oleaut32 ole32) +endif() +add_test(NAME compressed_archive_test COMMAND compressed_archive_test) diff --git a/tests/compressed_archive_test/compressed_archive_test.pro b/tests/compressed_archive_test/compressed_archive_test.pro deleted file mode 100644 index b48980144..000000000 --- a/tests/compressed_archive_test/compressed_archive_test.pro +++ /dev/null @@ -1,26 +0,0 @@ -TEMPLATE = app -CONFIG += console - -SOURCES += \ - main.cpp \ - -QT += core - -win32 { - LIBS += -loleaut32 -lole32 - msvc { - QMAKE_CXXFLAGS_RELEASE += /MP /Ob2 /Oi /Ot /GT - QMAKE_LFLAGS_RELEASE += /LTCG - } - CONFIG -= embed_manifest_exe -} - -CONFIG(7zip) { -include(../../compressed_archive/wrapper.pri) -} else:CONFIG(unarr) { -include(../../compressed_archive/unarr/unarr-wrapper.pri) -} else:CONFIG(libarchive) { -include(../../compressed_archive/libarchive/libarchive-wrapper.pri) -} else { -include(../../compressed_archive/wrapper.pri) -} diff --git a/tests/concurrent_queue_test/CMakeLists.txt b/tests/concurrent_queue_test/CMakeLists.txt new file mode 100644 index 000000000..b6c490937 --- /dev/null +++ b/tests/concurrent_queue_test/CMakeLists.txt @@ -0,0 +1,12 @@ +# Concurrent queue test + +qt_add_executable(concurrent_queue_test + concurrent_queue_test.cpp +) +target_link_libraries(concurrent_queue_test PRIVATE + Qt::Core + Qt::Test + concurrent_queue +) +add_test(NAME concurrent_queue_test + COMMAND concurrent_queue_test -maxwarnings 100000) diff --git a/tests/concurrent_queue_test/concurrent_queue_test.pro b/tests/concurrent_queue_test/concurrent_queue_test.pro deleted file mode 100644 index 714039115..000000000 --- a/tests/concurrent_queue_test/concurrent_queue_test.pro +++ /dev/null @@ -1,9 +0,0 @@ -include(../qt_test.pri) - -PATH_TO_common = ../../common - -INCLUDEPATH += $$PATH_TO_common -HEADERS += $${PATH_TO_common}/concurrent_queue.h -SOURCES += \ - $${PATH_TO_common}/concurrent_queue.cpp \ - concurrent_queue_test.cpp diff --git a/tests/qt_test.pri b/tests/qt_test.pri deleted file mode 100644 index 1005fa030..000000000 --- a/tests/qt_test.pri +++ /dev/null @@ -1,9 +0,0 @@ -QT += testlib -QT -= gui - -CONFIG += qt console warn_on testcase no_testcase_installs -CONFIG -= app_bundle - -TEMPLATE = app - -include(../config.pri) diff --git a/tests/tests.pro b/tests/tests.pro deleted file mode 100644 index 15317f23f..000000000 --- a/tests/tests.pro +++ /dev/null @@ -1,2 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS += concurrent_queue_test diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt new file mode 100644 index 000000000..d4804f55b --- /dev/null +++ b/third_party/CMakeLists.txt @@ -0,0 +1,80 @@ +# Third-party libraries for YACReader + +# --- QsLog (logging) --- +add_library(QsLog STATIC + QsLog/QsLogDest.cpp + QsLog/QsLog.cpp + QsLog/QsLogDestConsole.cpp + QsLog/QsLogDestFile.cpp + QsLog/QsLogDestFunctor.cpp + QsLog/QsLogMessage.cpp + QsLog/QsLogLevel.cpp + QsLog/QsLogDest.h + QsLog/QsLog.h + QsLog/QsLogDestConsole.h + QsLog/QsLogLevel.h + QsLog/QsLogDestFile.h + QsLog/QsLogDisableForThisFile.h + QsLog/QsLogDestFunctor.h + QsLog/QsLogMessage.h + QsLog/QsLogSharedLibrary.h +) +target_include_directories(QsLog PUBLIC QsLog) +target_compile_definitions(QsLog PUBLIC QS_LOG_SEPARATE_THREAD) +target_link_libraries(QsLog PUBLIC Qt::Core) + +# --- QrCode (QR code generation, no Qt dependency) --- +add_library(QrCode STATIC + QrCode/qrcodegen.cpp + QrCode/qrcodegen.hpp +) +target_include_directories(QrCode PUBLIC QrCode) + +# --- QtWebApp HTTP server --- +add_library(QtWebApp_httpserver STATIC + QtWebApp/httpserver/httpglobal.cpp + QtWebApp/httpserver/httplistener.cpp + QtWebApp/httpserver/httpconnectionhandler.cpp + QtWebApp/httpserver/httpconnectionhandlerpool.cpp + QtWebApp/httpserver/httprequest.cpp + QtWebApp/httpserver/httpresponse.cpp + QtWebApp/httpserver/httpcookie.cpp + QtWebApp/httpserver/httprequesthandler.cpp + QtWebApp/httpserver/httpsession.cpp + QtWebApp/httpserver/httpsessionstore.cpp + QtWebApp/httpserver/staticfilecontroller.cpp + QtWebApp/httpserver/httpglobal.h + QtWebApp/httpserver/httplistener.h + QtWebApp/httpserver/httpconnectionhandler.h + QtWebApp/httpserver/httpconnectionhandlerpool.h + QtWebApp/httpserver/httprequest.h + QtWebApp/httpserver/httpresponse.h + QtWebApp/httpserver/httpcookie.h + QtWebApp/httpserver/httprequesthandler.h + QtWebApp/httpserver/httpsession.h + QtWebApp/httpserver/httpsessionstore.h + QtWebApp/httpserver/staticfilecontroller.h +) +target_include_directories(QtWebApp_httpserver PUBLIC QtWebApp/httpserver) +target_link_libraries(QtWebApp_httpserver PUBLIC Qt::Network) + +# --- QtWebApp template engine --- +add_library(QtWebApp_templateengine STATIC + QtWebApp/templateengine/template.cpp + QtWebApp/templateengine/templateloader.cpp + QtWebApp/templateengine/templatecache.cpp + QtWebApp/templateengine/templateglobal.h + QtWebApp/templateengine/template.h + QtWebApp/templateengine/templateloader.h + QtWebApp/templateengine/templatecache.h +) +target_include_directories(QtWebApp_templateengine PUBLIC QtWebApp/templateengine) +target_link_libraries(QtWebApp_templateengine PUBLIC Qt::Core5Compat) + +# --- KDSignalThrottler (from KDToolBox) --- +add_library(KDSignalThrottler STATIC + KDToolBox/KDSignalThrottler.cpp + KDToolBox/KDSignalThrottler.h +) +target_include_directories(KDSignalThrottler PUBLIC KDToolBox) +target_link_libraries(KDSignalThrottler PUBLIC Qt::Core) diff --git a/third_party/KDToolBox/KDToolBox.pri b/third_party/KDToolBox/KDToolBox.pri deleted file mode 100644 index 1cfbb745d..000000000 --- a/third_party/KDToolBox/KDToolBox.pri +++ /dev/null @@ -1,4 +0,0 @@ -INCLUDEPATH += $$PWD - -SOURCES += $$PWD/KDSignalThrottler.cpp -HEADERS += $$PWD/KDSignalThrottler.h diff --git a/third_party/QrCode/QrCode.pri b/third_party/QrCode/QrCode.pri deleted file mode 100644 index 091426110..000000000 --- a/third_party/QrCode/QrCode.pri +++ /dev/null @@ -1,4 +0,0 @@ -INCLUDEPATH += $$PWD - -SOURCES += $$PWD/qrcodegen.cpp -HEADERS += $$PWD/qrcodegen.hpp diff --git a/third_party/QsLog/QsLog.pri b/third_party/QsLog/QsLog.pri deleted file mode 100644 index 20363e1c9..000000000 --- a/third_party/QsLog/QsLog.pri +++ /dev/null @@ -1,41 +0,0 @@ -INCLUDEPATH += $$PWD -#DEFINES += QS_LOG_LINE_NUMBERS # automatically writes the file and line for each log message -#DEFINES += QS_LOG_DISABLE # logging code is replaced with a no-op -DEFINES += QS_LOG_SEPARATE_THREAD # messages are queued and written from a separate thread -#DEFINES += QS_LOG_WIN_PRINTF_CONSOLE # Use fprintf instead of OutputDebugString on Windows -#DEFINES += QS_LOG_WINDOW # allows easily showing log messages in a UI - -contains(DEFINES, QS_LOG_WINDOW) { - message("Will include log window destination") - QT += gui - greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - SOURCES += $$PWD/QsLogWindow.cpp \ - $$PWD/QsLogWindowModel.cpp - HEADERS += $$PWD/QsLogWindow.h \ - $$PWD/QsLogWindowModel.h - FORMS += $$PWD/QsLogWindow.ui - RESOURCES += $$PWD/QsLogWindow.qrc -} - -SOURCES += $$PWD/QsLogDest.cpp \ - $$PWD/QsLog.cpp \ - $$PWD/QsLogDestConsole.cpp \ - $$PWD/QsLogDestFile.cpp \ - $$PWD/QsLogDestFunctor.cpp \ - $$PWD/QsLogMessage.cpp \ - $$PWD/QsLogLevel.cpp - -HEADERS += $$PWD/QsLogDest.h \ - $$PWD/QsLog.h \ - $$PWD/QsLogDestConsole.h \ - $$PWD/QsLogLevel.h \ - $$PWD/QsLogDestFile.h \ - $$PWD/QsLogDisableForThisFile.h \ - $$PWD/QsLogDestFunctor.h \ - $$PWD/QsLogMessage.h \ - $$PWD/QsLogSharedLibrary.h - -OTHER_FILES += \ - $$PWD/QsLogChanges.txt \ - $$PWD/README.md \ - $$PWD/LICENSE.txt diff --git a/third_party/QsLog/QsLogSharedLibrary.pro b/third_party/QsLog/QsLogSharedLibrary.pro deleted file mode 100644 index 8d34111d0..000000000 --- a/third_party/QsLog/QsLogSharedLibrary.pro +++ /dev/null @@ -1,46 +0,0 @@ -# This pro file will build QsLog as a shared library -TARGET = QsLog -VERSION = "2.1.0" -QT -= gui -CONFIG -= console -CONFIG -= app_bundle -CONFIG += shared -CONFIG += c++11 -TEMPLATE = lib - -QSLOG_DESTDIR=$$(QSLOG_DESTDIR) -!isEmpty(QSLOG_DESTDIR) { - message(Will use $${QSLOG_DESTDIR} as destdir.) - DESTDIR = $${QSLOG_DESTDIR}/bin - OBJECTS_DIR = $${QSLOG_DESTDIR} - MOC_DIR = $${QSLOG_DESTDIR} - UI_DIR = $${QSLOG_DESTDIR} - RCC_DIR = $${QSLOG_DESTDIR} -} - -win32 { - DEFINES += QSLOG_IS_SHARED_LIBRARY -} - -include(QsLog.pri) - -unix:!macx { - DISTRO = $$system(uname -a) - - # make install will install the shared object in the appropriate folders - headers.files = QsLog.h QsLogDest.h QsLogLevel.h - headers.path = /usr/include/$(QMAKE_TARGET) - - other_files.files = LICENSE.txt QsLogChanges.txt README.md - other_files.path = /usr/local/share/$(QMAKE_TARGET) - contains(DISTRO, .*ARCH): other_files.path = /usr/share/$(QMAKE_TARGET) - - contains(QT_ARCH, x86_64) { - target.path = /usr/lib64 - contains(DISTRO, .*ARCH): target.path = /usr/lib - } else { - target.path = /usr/lib - } - - INSTALLS += headers target other_files -} diff --git a/third_party/QsLog/unittest/unittest.pro b/third_party/QsLog/unittest/unittest.pro deleted file mode 100644 index b59b8a93a..000000000 --- a/third_party/QsLog/unittest/unittest.pro +++ /dev/null @@ -1,29 +0,0 @@ -QT += core - -TARGET = QsLogUnitTest -CONFIG += console qtestlib c++11 -CONFIG -= app_bundle -TEMPLATE = app - -# optionally enable address sanitizer -linux-g++|macx { - QMAKE_CXXFLAGS += -fsanitize=address - QMAKE_LFLAGS += -fsanitize=address -} - -# test-case sources -SOURCES += TestLog.cpp - -HEADERS += TestLog.h - -# component sources -include(../QsLog.pri) - -SOURCES += \ - ./QtTestUtil/TestRegistry.cpp \ - ./QtTestUtil/SimpleChecker.cpp - -HEADERS += \ - ./QtTestUtil/TestRegistry.h \ - ./QtTestUtil/TestRegistration.h \ - ./QtTestUtil/QtTestUtil.h diff --git a/third_party/QtWebApp/httpserver/httpserver.pri b/third_party/QtWebApp/httpserver/httpserver.pri deleted file mode 100644 index 9bfabd24e..000000000 --- a/third_party/QtWebApp/httpserver/httpserver.pri +++ /dev/null @@ -1,33 +0,0 @@ -INCLUDEPATH += $$PWD -DEPENDPATH += $$PWD - -QT += network - -# Enable very detailed debug messages when compiling the debug version -CONFIG(debug, debug|release) { - DEFINES += SUPERVERBOSE -} - -HEADERS += $$PWD/httpglobal.h \ - $$PWD/httplistener.h \ - $$PWD/httpconnectionhandler.h \ - $$PWD/httpconnectionhandlerpool.h \ - $$PWD/httprequest.h \ - $$PWD/httpresponse.h \ - $$PWD/httpcookie.h \ - $$PWD/httprequesthandler.h \ - $$PWD/httpsession.h \ - $$PWD/httpsessionstore.h \ - $$PWD/staticfilecontroller.h - -SOURCES += $$PWD/httpglobal.cpp \ - $$PWD/httplistener.cpp \ - $$PWD/httpconnectionhandler.cpp \ - $$PWD/httpconnectionhandlerpool.cpp \ - $$PWD/httprequest.cpp \ - $$PWD/httpresponse.cpp \ - $$PWD/httpcookie.cpp \ - $$PWD/httprequesthandler.cpp \ - $$PWD/httpsession.cpp \ - $$PWD/httpsessionstore.cpp \ - $$PWD/staticfilecontroller.cpp diff --git a/third_party/QtWebApp/templateengine/templateengine.pri b/third_party/QtWebApp/templateengine/templateengine.pri deleted file mode 100644 index faca956ac..000000000 --- a/third_party/QtWebApp/templateengine/templateengine.pri +++ /dev/null @@ -1,15 +0,0 @@ -INCLUDEPATH += $$PWD -DEPENDPATH += $$PWD - -greaterThan(QT_VERSION,6) { - QT += core5compat -} - -HEADERS += $$PWD/templateglobal.h -HEADERS += $$PWD/template.h -HEADERS += $$PWD/templateloader.h -HEADERS += $$PWD/templatecache.h - -SOURCES += $$PWD/template.cpp -SOURCES += $$PWD/templateloader.cpp -SOURCES += $$PWD/templatecache.cpp From cd0d89d46b910de17bafb7755ad0bddba229b395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20A=CC=81ngel=20San=20Marti=CC=81n=20Rodri=CC=81guez?= Date: Wed, 25 Feb 2026 18:04:05 +0100 Subject: [PATCH 087/187] Enable ninja in docker builds --- docker/Dockerfile | 3 ++- docker/Dockerfile.aarch64 | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 60bad055a..50629fc77 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -15,6 +15,7 @@ RUN \ apt-get install -y --no-install-recommends \ build-essential \ cmake \ + ninja-build \ desktop-file-utils \ gcc \ g++ \ @@ -61,7 +62,7 @@ RUN git clone https://github.com/YACReader/yacreader.git /src/git && \ # build yacreaderlibraryserver (7zip source is auto-downloaded by CMake FetchContent) RUN cd /src/git && \ - cmake -B build \ + cmake -B build -G Ninja \ -DCMAKE_INSTALL_PREFIX=/app \ -DDECOMPRESSION_BACKEND=7zip \ -DBUILD_SERVER_STANDALONE=ON \ diff --git a/docker/Dockerfile.aarch64 b/docker/Dockerfile.aarch64 index 922c490ea..aa75208bc 100644 --- a/docker/Dockerfile.aarch64 +++ b/docker/Dockerfile.aarch64 @@ -15,6 +15,7 @@ RUN \ apt-get install -y --no-install-recommends \ build-essential \ cmake \ + ninja-build \ desktop-file-utils \ gcc \ g++ \ @@ -58,7 +59,7 @@ RUN git clone https://github.com/YACReader/yacreader.git /src/git && \ # build yacreaderlibraryserver (7zip source is auto-downloaded by CMake FetchContent) RUN cd /src/git && \ - cmake -B build \ + cmake -B build -G Ninja \ -DCMAKE_INSTALL_PREFIX=/app \ -DDECOMPRESSION_BACKEND=7zip \ -DBUILD_SERVER_STANDALONE=ON \ From 0bd291ba98dcbd2cdac35b211fa68db1af1fcc44 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 26 Feb 2026 16:19:58 +0100 Subject: [PATCH 088/187] Extract the layout logic to a view model to simplify the update logic in continuous scroll mode --- YACReader/CMakeLists.txt | 2 + YACReader/continuous_page_widget.cpp | 316 +++------------------------ YACReader/continuous_page_widget.h | 52 +---- YACReader/continuous_view_model.cpp | 299 +++++++++++++++++++++++++ YACReader/continuous_view_model.h | 79 +++++++ YACReader/viewer.cpp | 115 ++++++---- YACReader/viewer.h | 8 +- 7 files changed, 501 insertions(+), 370 deletions(-) create mode 100644 YACReader/continuous_view_model.cpp create mode 100644 YACReader/continuous_view_model.h diff --git a/YACReader/CMakeLists.txt b/YACReader/CMakeLists.txt index 3f4010cdb..51c55b615 100644 --- a/YACReader/CMakeLists.txt +++ b/YACReader/CMakeLists.txt @@ -11,6 +11,8 @@ qt_add_executable(YACReader WIN32 main_window_viewer.cpp continuous_page_widget.h continuous_page_widget.cpp + continuous_view_model.h + continuous_view_model.cpp mouse_handler.h mouse_handler.cpp viewer.h diff --git a/YACReader/continuous_page_widget.cpp b/YACReader/continuous_page_widget.cpp index 59a148aec..0f825cfb2 100644 --- a/YACReader/continuous_page_widget.cpp +++ b/YACReader/continuous_page_widget.cpp @@ -1,10 +1,9 @@ #include "continuous_page_widget.h" +#include "continuous_view_model.h" #include "render.h" #include #include -#include -#include ContinuousPageWidget::ContinuousPageWidget(QWidget *parent) : QWidget(parent) @@ -26,82 +25,34 @@ void ContinuousPageWidget::setRender(Render *r) render = r; } -void ContinuousPageWidget::setNumPages(int count) +void ContinuousPageWidget::setViewModel(ContinuousViewModel *viewModel) { - numPages = count; - defaultPageSize = QSize(800, 1200); - pageSizes.fill(QSize(0, 0), count); - relayout(false); -} - -void ContinuousPageWidget::setZoomFactor(int zoom) -{ - if (zoomFactor == zoom) { + if (continuousViewModel == viewModel) { return; } - zoomFactor = zoom; - relayout(true); - update(); -} -void ContinuousPageWidget::probeBufferedPages() -{ - if (!render || numPages == 0) { - return; + if (continuousViewModel) { + disconnect(continuousViewModel, &ContinuousViewModel::stateChanged, this, QOverload<>::of(&ContinuousPageWidget::update)); } - bool changed = false; - for (int i = 0; i < numPages; ++i) { - const QImage *img = render->bufferedImage(i); - bool hasKnownSize = pageSizes[i].width() > 0 && pageSizes[i].height() > 0; - if (img && !img->isNull() && !hasKnownSize) { - pageSizes[i] = img->size(); - if (defaultPageSize == QSize(800, 1200)) { - defaultPageSize = img->size(); - } - changed = true; - } - } + continuousViewModel = viewModel; - if (changed) { - relayout(true); - update(); + if (continuousViewModel) { + connect(continuousViewModel, &ContinuousViewModel::stateChanged, this, QOverload<>::of(&ContinuousPageWidget::update)); } + + updateGeometry(); + update(); } void ContinuousPageWidget::reset() { - numPages = 0; - pageSizes.clear(); - yPositions.clear(); - currentTotalHeight = 0; - layoutSnapshot = LayoutSnapshot(); - defaultPageSize = QSize(800, 1200); setMinimumHeight(0); setMaximumHeight(QWIDGETSIZE_MAX); updateGeometry(); update(); } -int ContinuousPageWidget::centerPage(int scrollY, int viewportHeight) const -{ - const int centerY = scrollY + std::max(0, viewportHeight / 2); - return pageAtY(centerY); -} - -int ContinuousPageWidget::yPositionForPage(int pageIndex) const -{ - if (pageIndex < 0 || pageIndex >= yPositions.size()) { - return 0; - } - return yPositions[pageIndex]; -} - -int ContinuousPageWidget::totalHeight() const -{ - return currentTotalHeight; -} - bool ContinuousPageWidget::hasHeightForWidth() const { return true; @@ -109,26 +60,24 @@ bool ContinuousPageWidget::hasHeightForWidth() const int ContinuousPageWidget::heightForWidth(int w) const { - if (numPages == 0 || w <= 0) { + if (!continuousViewModel || w <= 0) { return 0; } - - int h = 0; - for (int i = 0; i < numPages; ++i) { - QSize scaled = scaledPageSize(i, w); - h += scaled.height(); - } - return h; + Q_UNUSED(w) + return continuousViewModel->totalHeight(); } QSize ContinuousPageWidget::sizeHint() const { - return QSize(defaultPageSize.width(), currentTotalHeight > 0 ? currentTotalHeight : 0); + if (!continuousViewModel) { + return QSize(800, 0); + } + return QSize(width(), continuousViewModel->totalHeight()); } void ContinuousPageWidget::onPageAvailable(int absolutePageIndex) { - if (!render || absolutePageIndex < 0 || absolutePageIndex >= numPages) { + if (!render || !continuousViewModel || absolutePageIndex < 0 || absolutePageIndex >= continuousViewModel->numPages()) { return; } @@ -137,45 +86,35 @@ void ContinuousPageWidget::onPageAvailable(int absolutePageIndex) return; } - QSize naturalSize = img->size(); - - // update default page size from the first real page we see - if (defaultPageSize == QSize(800, 1200) && !naturalSize.isNull()) { - defaultPageSize = naturalSize; - } - - bool sizeChanged = (pageSizes[absolutePageIndex] != naturalSize); - pageSizes[absolutePageIndex] = naturalSize; - - if (sizeChanged) { - // keep anchor page visually stable while refined page sizes arrive - relayout(true); - } - // repaint the region where this page lives - if (absolutePageIndex < yPositions.size()) { - QSize scaled = scaledPageSize(absolutePageIndex, width()); - QRect pageRect(0, yPositions[absolutePageIndex], scaled.width(), scaled.height()); + if (absolutePageIndex < continuousViewModel->numPages()) { + QSize scaled = continuousViewModel->scaledPageSize(absolutePageIndex); + const int y = continuousViewModel->yPositionForPage(absolutePageIndex); + int x = (width() - scaled.width()) / 2; + if (x < 0) { + x = 0; + } + QRect pageRect(x, y, scaled.width(), scaled.height()); update(pageRect); } } void ContinuousPageWidget::paintEvent(QPaintEvent *event) { - if (numPages == 0 || !render) { + if (!continuousViewModel || continuousViewModel->numPages() == 0 || !render) { return; } QPainter painter(this); QRect visibleRect = event->rect(); - int firstPage = pageAtY(visibleRect.top()); - int lastPage = pageAtY(visibleRect.bottom()); + int firstPage = continuousViewModel->pageAtY(visibleRect.top()); + int lastPage = continuousViewModel->pageAtY(visibleRect.bottom()); int w = width(); - for (int i = firstPage; i <= lastPage && i < numPages; ++i) { - int y = yPositions[i]; - QSize scaled = scaledPageSize(i, w); + for (int i = firstPage; i <= lastPage && i < continuousViewModel->numPages(); ++i) { + int y = continuousViewModel->yPositionForPage(i); + QSize scaled = continuousViewModel->scaledPageSize(i); // center horizontally if page is narrower than widget int x = (w - scaled.width()) / 2; if (x < 0) { @@ -202,192 +141,7 @@ void ContinuousPageWidget::paintEvent(QPaintEvent *event) void ContinuousPageWidget::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); - relayout(true); -} - -void ContinuousPageWidget::setAnchorPage(int page) -{ - anchorPage = page; -} - -void ContinuousPageWidget::setViewportState(int scrollY, int viewportHeight) -{ - viewportScrollY = std::max(0, scrollY); - currentViewportHeight = std::max(0, viewportHeight); - hasViewportState = true; -} - -void ContinuousPageWidget::updateLayout() -{ - relayout(false); -} - -void ContinuousPageWidget::updateLayoutWithAnchor() -{ - relayout(true); -} - -void ContinuousPageWidget::relayout(bool preserveAnchor) -{ - int w = width(); - if (w <= 0) { - w = parentWidget() ? parentWidget()->width() : 0; - } - if (w <= 0) { - w = defaultPageSize.width(); - } - - const LayoutSnapshot oldSnapshot = layoutSnapshot; - - ViewportAnchor anchor; - if (preserveAnchor && hasViewportState && !oldSnapshot.yPositions.isEmpty()) { - anchor = anchorFromViewport(oldSnapshot, viewportScrollY, currentViewportHeight); - } else if (preserveAnchor && anchorPage >= 0) { - anchor.pageIndex = anchorPage; - anchor.offsetRatio = 0.5f; - anchor.valid = true; - } - - layoutSnapshot = buildLayoutSnapshot(w); - -#ifndef NDEBUG - Q_ASSERT(layoutSnapshot.yPositions.size() == numPages); - Q_ASSERT(layoutSnapshot.scaledSizes.size() == numPages); - for (int i = 0; i < layoutSnapshot.scaledSizes.size(); ++i) { - Q_ASSERT(layoutSnapshot.scaledSizes[i].width() > 0); - Q_ASSERT(layoutSnapshot.scaledSizes[i].height() > 0); - if (i > 0) { - Q_ASSERT(layoutSnapshot.yPositions[i] >= layoutSnapshot.yPositions[i - 1]); - } - } -#endif - - yPositions = layoutSnapshot.yPositions; - currentTotalHeight = layoutSnapshot.totalHeight; - - setFixedHeight(currentTotalHeight); - updateGeometry(); - - if (!preserveAnchor || !anchor.valid || currentViewportHeight <= 0) { - return; - } - - const int newScrollForAnchor = resolveAnchorToScrollY(layoutSnapshot, anchor, currentViewportHeight); - emit layoutScrollPositionRequested(newScrollForAnchor); -} - -ContinuousPageWidget::LayoutSnapshot ContinuousPageWidget::buildLayoutSnapshot(int w) const -{ - LayoutSnapshot snapshot; - - if (numPages <= 0 || w <= 0) { - return snapshot; + if (continuousViewModel) { + continuousViewModel->setViewportSize(width(), continuousViewModel->viewportHeight()); } - - snapshot.yPositions.resize(numPages); - snapshot.scaledSizes.resize(numPages); - - qint64 y = 0; - for (int i = 0; i < numPages; ++i) { - snapshot.yPositions[i] = static_cast(std::min(y, std::numeric_limits::max())); - QSize scaled = scaledPageSize(i, w); - scaled.setWidth(std::max(1, scaled.width())); - scaled.setHeight(std::max(1, scaled.height())); - snapshot.scaledSizes[i] = scaled; - y += scaled.height(); - } - - snapshot.totalHeight = static_cast(std::min(y, static_cast(QWIDGETSIZE_MAX))); - return snapshot; -} - -int ContinuousPageWidget::pageAtY(const LayoutSnapshot &snapshot, int y) const -{ - if (snapshot.yPositions.isEmpty()) { - return 0; - } - - auto it = std::upper_bound(snapshot.yPositions.constBegin(), snapshot.yPositions.constEnd(), y); - if (it == snapshot.yPositions.constBegin()) { - return 0; - } - --it; - return static_cast(it - snapshot.yPositions.constBegin()); -} - -ContinuousPageWidget::ViewportAnchor ContinuousPageWidget::anchorFromViewport(const LayoutSnapshot &snapshot, int scrollY, int viewportHeight) const -{ - ViewportAnchor anchor; - - if (snapshot.yPositions.isEmpty() || viewportHeight <= 0) { - return anchor; - } - - const int maxScroll = std::max(0, snapshot.totalHeight - viewportHeight); - const int clampedScroll = qBound(0, scrollY, maxScroll); - const int anchorY = clampedScroll + viewportHeight / 2; - const int page = pageAtY(snapshot, anchorY); - - if (page < 0 || page >= snapshot.scaledSizes.size()) { - return anchor; - } - - const int pageTop = snapshot.yPositions[page]; - const int pageHeight = std::max(1, snapshot.scaledSizes[page].height()); - const float ratio = static_cast(anchorY - pageTop) / static_cast(pageHeight); - - anchor.pageIndex = page; - anchor.offsetRatio = qBound(0.0f, ratio, 1.0f); - anchor.valid = true; - return anchor; -} - -int ContinuousPageWidget::resolveAnchorToScrollY(const LayoutSnapshot &snapshot, const ViewportAnchor &anchor, int viewportHeight) const -{ - if (!anchor.valid || viewportHeight <= 0 || snapshot.yPositions.isEmpty()) { - return 0; - } - - if (anchor.pageIndex < 0 || anchor.pageIndex >= snapshot.yPositions.size() || anchor.pageIndex >= snapshot.scaledSizes.size()) { - return 0; - } - - const int pageTop = snapshot.yPositions[anchor.pageIndex]; - const int pageHeight = std::max(1, snapshot.scaledSizes[anchor.pageIndex].height()); - const int anchorY = pageTop + qRound(anchor.offsetRatio * pageHeight); - const int maxScroll = std::max(0, snapshot.totalHeight - viewportHeight); - const int target = anchorY - viewportHeight / 2; - return qBound(0, target, maxScroll); -} - -int ContinuousPageWidget::pageAtY(int y) const -{ - return pageAtY(layoutSnapshot, y); -} - -QSize ContinuousPageWidget::scaledPageSize(int pageIndex, int forWidth) const -{ - QSize natural = (pageIndex < pageSizes.size() && pageSizes[pageIndex].width() > 0 && pageSizes[pageIndex].height() > 0) - ? pageSizes[pageIndex] - : defaultPageSize; - - float scale = scaleForPage(pageIndex, forWidth); - int scaledW = std::max(1, qRound(natural.width() * scale)); - int scaledH = std::max(1, qRound(natural.height() * scale)); - return QSize(scaledW, scaledH); -} - -float ContinuousPageWidget::scaleForPage(int pageIndex, int forWidth) const -{ - QSize natural = (pageIndex < pageSizes.size() && pageSizes[pageIndex].width() > 0 && pageSizes[pageIndex].height() > 0) - ? pageSizes[pageIndex] - : defaultPageSize; - - if (natural.width() <= 0 || forWidth <= 0) { - return 1.0f; - } - - float baseScale = static_cast(forWidth) / natural.width(); - float zoomMultiplier = zoomFactor / 100.0f; - return baseScale * zoomMultiplier; } diff --git a/YACReader/continuous_page_widget.h b/YACReader/continuous_page_widget.h index 55393a5b9..d40d4bd62 100644 --- a/YACReader/continuous_page_widget.h +++ b/YACReader/continuous_page_widget.h @@ -8,6 +8,7 @@ #include "themable.h" class Render; +class ContinuousViewModel; class ContinuousPageWidget : public QWidget, protected Themable { @@ -16,27 +17,13 @@ class ContinuousPageWidget : public QWidget, protected Themable explicit ContinuousPageWidget(QWidget *parent = nullptr); void setRender(Render *r); - void setNumPages(int count); - void setZoomFactor(int zoom); - void probeBufferedPages(); + void setViewModel(ContinuousViewModel *viewModel); void reset(); - int centerPage(int scrollY, int viewportHeight) const; - int yPositionForPage(int pageIndex) const; - int totalHeight() const; - bool hasHeightForWidth() const override; int heightForWidth(int w) const override; QSize sizeHint() const override; - void setAnchorPage(int page); - void setViewportState(int scrollY, int viewportHeight); - -signals: - // emitted after layout recomputation when the preserved viewport anchor - // resolves to an absolute scroll position - void layoutScrollPositionRequested(int scrollY); - public slots: void onPageAvailable(int absolutePageIndex); @@ -46,41 +33,8 @@ public slots: void applyTheme(const Theme &theme) override; private: - struct LayoutSnapshot { - QVector yPositions; - QVector scaledSizes; - int totalHeight = 0; - }; - - struct ViewportAnchor { - int pageIndex = -1; - float offsetRatio = 0.0f; - bool valid = false; - }; - - void updateLayout(); - void updateLayoutWithAnchor(); - void relayout(bool preserveAnchor); - LayoutSnapshot buildLayoutSnapshot(int w) const; - int pageAtY(const LayoutSnapshot &snapshot, int y) const; - ViewportAnchor anchorFromViewport(const LayoutSnapshot &snapshot, int scrollY, int viewportHeight) const; - int resolveAnchorToScrollY(const LayoutSnapshot &snapshot, const ViewportAnchor &anchor, int viewportHeight) const; - int pageAtY(int y) const; - QSize scaledPageSize(int pageIndex, int forWidth) const; - float scaleForPage(int pageIndex, int forWidth) const; - Render *render = nullptr; - int numPages = 0; - QVector pageSizes; - QVector yPositions; - int currentTotalHeight = 0; - LayoutSnapshot layoutSnapshot; - QSize defaultPageSize { 800, 1200 }; - int zoomFactor = 100; - int anchorPage = -1; - int viewportScrollY = 0; - int currentViewportHeight = 0; - bool hasViewportState = false; + ContinuousViewModel *continuousViewModel = nullptr; }; #endif // CONTINUOUS_PAGE_WIDGET_H diff --git a/YACReader/continuous_view_model.cpp b/YACReader/continuous_view_model.cpp new file mode 100644 index 000000000..8d88443d3 --- /dev/null +++ b/YACReader/continuous_view_model.cpp @@ -0,0 +1,299 @@ +#include "continuous_view_model.h" + +#include +#include + +#include +#include + +ContinuousViewModel::ContinuousViewModel(QObject *parent) + : QObject(parent) +{ +} + +void ContinuousViewModel::reset() +{ + numPagesValue = 0; + pageSizes.clear(); + defaultPageSize = QSize(800, 1200); + scrollYValue = 0; + anchorPage = -1; + layoutSnapshot = LayoutSnapshot(); + emit stateChanged(); +} + +void ContinuousViewModel::setNumPages(int count) +{ + numPagesValue = std::max(0, count); + pageSizes.fill(QSize(0, 0), numPagesValue); + defaultPageSize = QSize(800, 1200); + recompute(RecomputePolicy::PreserveScrollClamped); +} + +void ContinuousViewModel::setZoomFactor(int zoom) +{ + if (zoomFactorValue == zoom) { + return; + } + + zoomFactorValue = zoom; + recompute(RecomputePolicy::PreserveViewportAnchor); +} + +void ContinuousViewModel::setViewportSize(int width, int height) +{ + width = std::max(0, width); + height = std::max(0, height); + + if (viewportWidth == width && viewportHeightValue == height) { + return; + } + + viewportWidth = width; + viewportHeightValue = height; + recompute(RecomputePolicy::PreserveViewportAnchor); +} + +void ContinuousViewModel::setScrollYFromUser(int scrollY) +{ + scrollYValue = std::max(0, scrollY); + recompute(RecomputePolicy::PreserveScrollClamped); +} + +void ContinuousViewModel::setAnchorPage(int page) +{ + if (page < 0 || page >= numPagesValue) { + return; + } + + anchorPage = page; +} + +void ContinuousViewModel::setCurrentPage(int page) +{ + if (page < 0 || page >= numPagesValue) { + return; + } + + anchorPage = page; + recompute(RecomputePolicy::ScrollToPageTop, page); +} + +void ContinuousViewModel::setPageNaturalSize(int pageIndex, const QSize &size) +{ + if (pageIndex < 0 || pageIndex >= numPagesValue || size.isEmpty()) { + return; + } + + if (defaultPageSize == QSize(800, 1200)) { + defaultPageSize = size; + } + + if (pageSizes[pageIndex] == size) { + return; + } + + pageSizes[pageIndex] = size; + recompute(RecomputePolicy::PreserveViewportAnchor); +} + +int ContinuousViewModel::numPages() const +{ + return numPagesValue; +} + +int ContinuousViewModel::totalHeight() const +{ + return layoutSnapshot.totalHeight; +} + +int ContinuousViewModel::scrollY() const +{ + return scrollYValue; +} + +int ContinuousViewModel::viewportHeight() const +{ + return viewportHeightValue; +} + +int ContinuousViewModel::zoomFactor() const +{ + return zoomFactorValue; +} + +int ContinuousViewModel::centerPage() const +{ + const int centerY = scrollYValue + std::max(0, viewportHeightValue / 2); + return pageAtY(centerY); +} + +int ContinuousViewModel::yPositionForPage(int pageIndex) const +{ + if (pageIndex < 0 || pageIndex >= layoutSnapshot.yPositions.size()) { + return 0; + } + + return layoutSnapshot.yPositions[pageIndex]; +} + +int ContinuousViewModel::pageAtY(int y) const +{ + return pageAtY(layoutSnapshot, y); +} + +QSize ContinuousViewModel::scaledPageSize(int pageIndex) const +{ + if (pageIndex < 0 || pageIndex >= layoutSnapshot.scaledSizes.size()) { + return QSize(); + } + + return layoutSnapshot.scaledSizes[pageIndex]; +} + +void ContinuousViewModel::recompute(RecomputePolicy policy, int targetPage) +{ + const LayoutSnapshot oldSnapshot = layoutSnapshot; + + const int effectiveWidth = viewportWidth > 0 ? viewportWidth : defaultPageSize.width(); + + ViewportAnchor anchor; + if (policy == RecomputePolicy::PreserveViewportAnchor) { + if (!oldSnapshot.yPositions.isEmpty() && viewportHeightValue > 0) { + anchor = anchorFromViewport(oldSnapshot, scrollYValue, viewportHeightValue); + } else if (anchorPage >= 0) { + anchor.pageIndex = anchorPage; + anchor.offsetRatio = 0.5f; + anchor.valid = true; + } + } + + layoutSnapshot = buildLayoutSnapshot(effectiveWidth); + + if (policy == RecomputePolicy::ScrollToPageTop) { + scrollYValue = yPositionForPage(targetPage); + } else if (policy == RecomputePolicy::PreserveViewportAnchor && anchor.valid && viewportHeightValue > 0) { + scrollYValue = resolveAnchorToScrollY(layoutSnapshot, anchor, viewportHeightValue); + } + + scrollYValue = qBound(0, scrollYValue, maxScrollFor(layoutSnapshot)); + + emit stateChanged(); +} + +ContinuousViewModel::LayoutSnapshot ContinuousViewModel::buildLayoutSnapshot(int width) const +{ + LayoutSnapshot snapshot; + + if (numPagesValue <= 0 || width <= 0) { + return snapshot; + } + + snapshot.yPositions.resize(numPagesValue); + snapshot.scaledSizes.resize(numPagesValue); + + qint64 y = 0; + for (int i = 0; i < numPagesValue; ++i) { + snapshot.yPositions[i] = static_cast(std::min(y, std::numeric_limits::max())); + QSize scaled = scaledPageSizeForWidth(i, width); + scaled.setWidth(std::max(1, scaled.width())); + scaled.setHeight(std::max(1, scaled.height())); + snapshot.scaledSizes[i] = scaled; + y += scaled.height(); + } + + snapshot.totalHeight = static_cast(std::min(y, static_cast(QWIDGETSIZE_MAX))); + return snapshot; +} + +ContinuousViewModel::ViewportAnchor ContinuousViewModel::anchorFromViewport(const LayoutSnapshot &snapshot, int scrollY, int viewportHeight) const +{ + ViewportAnchor anchor; + + if (snapshot.yPositions.isEmpty() || viewportHeight <= 0) { + return anchor; + } + + const int maxScroll = std::max(0, snapshot.totalHeight - viewportHeight); + const int clampedScroll = qBound(0, scrollY, maxScroll); + const int anchorY = clampedScroll + viewportHeight / 2; + const int page = pageAtY(snapshot, anchorY); + + if (page < 0 || page >= snapshot.scaledSizes.size()) { + return anchor; + } + + const int pageTop = snapshot.yPositions[page]; + const int pageHeight = std::max(1, snapshot.scaledSizes[page].height()); + const float ratio = static_cast(anchorY - pageTop) / static_cast(pageHeight); + + anchor.pageIndex = page; + anchor.offsetRatio = qBound(0.0f, ratio, 1.0f); + anchor.valid = true; + return anchor; +} + +int ContinuousViewModel::resolveAnchorToScrollY(const LayoutSnapshot &snapshot, const ViewportAnchor &anchor, int viewportHeight) const +{ + if (!anchor.valid || viewportHeight <= 0 || snapshot.yPositions.isEmpty()) { + return 0; + } + + if (anchor.pageIndex < 0 || anchor.pageIndex >= snapshot.yPositions.size() || anchor.pageIndex >= snapshot.scaledSizes.size()) { + return 0; + } + + const int pageTop = snapshot.yPositions[anchor.pageIndex]; + const int pageHeight = std::max(1, snapshot.scaledSizes[anchor.pageIndex].height()); + const int anchorY = pageTop + qRound(anchor.offsetRatio * pageHeight); + const int maxScroll = std::max(0, snapshot.totalHeight - viewportHeight); + const int target = anchorY - viewportHeight / 2; + return qBound(0, target, maxScroll); +} + +int ContinuousViewModel::pageAtY(const LayoutSnapshot &snapshot, int y) const +{ + if (snapshot.yPositions.isEmpty()) { + return 0; + } + + auto it = std::upper_bound(snapshot.yPositions.constBegin(), snapshot.yPositions.constEnd(), y); + if (it == snapshot.yPositions.constBegin()) { + return 0; + } + + --it; + return static_cast(it - snapshot.yPositions.constBegin()); +} + +int ContinuousViewModel::maxScrollFor(const LayoutSnapshot &snapshot) const +{ + return std::max(0, snapshot.totalHeight - viewportHeightValue); +} + +QSize ContinuousViewModel::scaledPageSizeForWidth(int pageIndex, int width) const +{ + QSize natural = (pageIndex < pageSizes.size() && pageSizes[pageIndex].width() > 0 && pageSizes[pageIndex].height() > 0) + ? pageSizes[pageIndex] + : defaultPageSize; + + const float scale = scaleForPage(pageIndex, width); + const int scaledW = std::max(1, qRound(natural.width() * scale)); + const int scaledH = std::max(1, qRound(natural.height() * scale)); + return QSize(scaledW, scaledH); +} + +float ContinuousViewModel::scaleForPage(int pageIndex, int width) const +{ + QSize natural = (pageIndex < pageSizes.size() && pageSizes[pageIndex].width() > 0 && pageSizes[pageIndex].height() > 0) + ? pageSizes[pageIndex] + : defaultPageSize; + + if (natural.width() <= 0 || width <= 0) { + return 1.0f; + } + + const float baseScale = static_cast(width) / natural.width(); + const float zoomMultiplier = zoomFactorValue / 100.0f; + return baseScale * zoomMultiplier; +} diff --git a/YACReader/continuous_view_model.h b/YACReader/continuous_view_model.h new file mode 100644 index 000000000..228de7ac5 --- /dev/null +++ b/YACReader/continuous_view_model.h @@ -0,0 +1,79 @@ +#ifndef CONTINUOUS_VIEW_MODEL_H +#define CONTINUOUS_VIEW_MODEL_H + +#include +#include +#include + +class ContinuousViewModel : public QObject +{ + Q_OBJECT +public: + explicit ContinuousViewModel(QObject *parent = nullptr); + + void reset(); + + void setNumPages(int count); + void setZoomFactor(int zoom); + void setViewportSize(int width, int height); + void setScrollYFromUser(int scrollY); + void setAnchorPage(int page); + void setCurrentPage(int page); + void setPageNaturalSize(int pageIndex, const QSize &size); + + int numPages() const; + int totalHeight() const; + int scrollY() const; + int viewportHeight() const; + int zoomFactor() const; + + int centerPage() const; + int yPositionForPage(int pageIndex) const; + int pageAtY(int y) const; + QSize scaledPageSize(int pageIndex) const; + +signals: + void stateChanged(); + +private: + struct LayoutSnapshot { + QVector yPositions; + QVector scaledSizes; + int totalHeight = 0; + }; + + struct ViewportAnchor { + int pageIndex = -1; + float offsetRatio = 0.0f; + bool valid = false; + }; + + enum class RecomputePolicy { + PreserveViewportAnchor, + PreserveScrollClamped, + ScrollToPageTop + }; + + void recompute(RecomputePolicy policy, int targetPage = -1); + LayoutSnapshot buildLayoutSnapshot(int width) const; + ViewportAnchor anchorFromViewport(const LayoutSnapshot &snapshot, int scrollY, int viewportHeight) const; + int resolveAnchorToScrollY(const LayoutSnapshot &snapshot, const ViewportAnchor &anchor, int viewportHeight) const; + int pageAtY(const LayoutSnapshot &snapshot, int y) const; + int maxScrollFor(const LayoutSnapshot &snapshot) const; + QSize scaledPageSizeForWidth(int pageIndex, int width) const; + float scaleForPage(int pageIndex, int width) const; + + int numPagesValue = 0; + QVector pageSizes; + QSize defaultPageSize { 800, 1200 }; + + int zoomFactorValue = 100; + int viewportWidth = 0; + int viewportHeightValue = 0; + int scrollYValue = 0; + int anchorPage = -1; + + LayoutSnapshot layoutSnapshot; +}; + +#endif // CONTINUOUS_VIEW_MODEL_H diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index 32c9911be..6eae05adf 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -1,5 +1,6 @@ #include "viewer.h" #include "continuous_page_widget.h" +#include "continuous_view_model.h" #include "configuration.h" #include "magnifying_glass.h" #include "goto_flow_widget.h" @@ -65,6 +66,8 @@ Viewer::Viewer(QWidget *parent) setAlignment(Qt::AlignCenter); continuousWidget = new ContinuousPageWidget(); + continuousViewModel = new ContinuousViewModel(this); + continuousWidget->setViewModel(continuousViewModel); continuousWidget->installEventFilter(this); //--------------------------------------- mglass = new MagnifyingGlass( @@ -153,6 +156,7 @@ Viewer::~Viewer() if (widget() != continuousWidget) { delete continuousWidget; } + delete continuousViewModel; delete hideCursorTimer; delete informationLabel; delete verticalScroller; @@ -204,7 +208,8 @@ void Viewer::createConnections() connect(render, QOverload::of(&Render::imageLoaded), goToFlow, &GoToFlowWidget::setImageReady); connect(render, &Render::currentPageReady, this, &Viewer::updatePage); connect(render, &Render::pageRendered, continuousWidget, &ContinuousPageWidget::onPageAvailable); - connect(continuousWidget, &ContinuousPageWidget::layoutScrollPositionRequested, this, &Viewer::onContinuousLayoutScrollRequested); + connect(render, &Render::pageRendered, this, &Viewer::onContinuousPageRendered); + connect(continuousViewModel, &ContinuousViewModel::stateChanged, this, &Viewer::onContinuousViewModelChanged); connect(render, qOverload(&Render::numPages), this, &Viewer::onNumPagesReady); connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &Viewer::onContinuousScroll); connect(render, &Render::processingPage, this, &Viewer::setLoadingMessage); @@ -342,7 +347,7 @@ void Viewer::goTo(unsigned int page) if (continuousScroll) { lastCenterPage = page; - continuousWidget->setAnchorPage(page); + continuousViewModel->setAnchorPage(static_cast(page)); render->goTo(page); scrollToCurrentContinuousPage(); return; @@ -448,7 +453,7 @@ void Viewer::increaseZoomFactor() zoom = std::min(zoom + 10, 500); if (continuousScroll) { - continuousWidget->setZoomFactor(zoom); + continuousViewModel->setZoomFactor(zoom); } else { updateContentSize(); } @@ -462,7 +467,7 @@ void Viewer::decreaseZoomFactor() zoom = std::max(zoom - 10, 30); if (continuousScroll) { - continuousWidget->setZoomFactor(zoom); + continuousViewModel->setZoomFactor(zoom); } else { updateContentSize(); } @@ -831,7 +836,7 @@ void Viewer::resizeEvent(QResizeEvent *event) QScrollArea::resizeEvent(event); if (continuousScroll) { - continuousWidget->setViewportState(verticalScrollBar()->value(), viewport()->height()); + continuousViewModel->setViewportSize(viewport()->width(), viewport()->height()); } updateContentSize(); @@ -1019,15 +1024,15 @@ void Viewer::setContinuousScroll(bool enabled) Configuration::getConfiguration().setContinuousScroll(continuousScroll); if (continuousScroll) { - continuousWidget->setZoomFactor(zoom); + continuousViewModel->setZoomFactor(zoom); if (render->hasLoadedComic()) { - continuousWidget->setViewportState(verticalScrollBar()->value(), viewport()->height()); - continuousWidget->setNumPages(render->numPages()); + continuousViewModel->setViewportSize(viewport()->width(), viewport()->height()); + continuousViewModel->setNumPages(render->numPages()); // set the current page as model state before any layout/scroll happens lastCenterPage = render->getIndex(); - continuousWidget->setAnchorPage(lastCenterPage); + continuousViewModel->setAnchorPage(lastCenterPage); // pick up sizes of pages already in the buffer - continuousWidget->probeBufferedPages(); + probeContinuousBufferedPages(); // trigger a render cycle so new pages arrive via pageRendered signal render->update(); setActiveWidget(continuousWidget); @@ -1047,17 +1052,17 @@ void Viewer::setContinuousScroll(bool enabled) void Viewer::onContinuousScroll(int value) { - if (!continuousScroll || !render->hasLoadedComic()) { + if (!continuousScroll || !render->hasLoadedComic() || applyingContinuousModelState) { return; } - continuousWidget->setViewportState(value, viewport()->height()); + continuousViewModel->setScrollYFromUser(value); - int center = continuousWidget->centerPage(value, viewport()->height()); + int center = continuousViewModel->centerPage(); if (center != lastCenterPage && center >= 0) { lastCenterPage = center; - continuousWidget->setAnchorPage(center); + continuousViewModel->setAnchorPage(center); syncingRenderFromContinuousScroll = true; render->goTo(center); syncingRenderFromContinuousScroll = false; @@ -1065,20 +1070,65 @@ void Viewer::onContinuousScroll(int value) } } -void Viewer::onContinuousLayoutScrollRequested(int scrollY) +void Viewer::onContinuousViewModelChanged() { if (!continuousScroll) { return; } - auto *sb = verticalScrollBar(); - const int target = qBound(sb->minimum(), scrollY, sb->maximum()); + applyContinuousStateToUi(); +} + +void Viewer::onContinuousPageRendered(int absolutePageIndex) +{ + if (!continuousScroll || !render->hasLoadedComic()) { + return; + } + + const QImage *img = render->bufferedImage(absolutePageIndex); + if (!img || img->isNull()) { + return; + } + + continuousViewModel->setPageNaturalSize(absolutePageIndex, img->size()); +} + +void Viewer::probeContinuousBufferedPages() +{ + if (!render->hasLoadedComic()) { + return; + } + const int totalPages = static_cast(render->numPages()); + for (int i = 0; i < totalPages; ++i) { + const QImage *img = render->bufferedImage(i); + if (img && !img->isNull()) { + continuousViewModel->setPageNaturalSize(i, img->size()); + } + } +} + +void Viewer::applyContinuousStateToUi() +{ + if (!continuousScroll) { + return; + } + + applyingContinuousModelState = true; + + continuousWidget->setFixedHeight(continuousViewModel->totalHeight()); + continuousWidget->updateGeometry(); + + auto *sb = verticalScrollBar(); + const int target = qBound(sb->minimum(), continuousViewModel->scrollY(), sb->maximum()); sb->blockSignals(true); sb->setValue(target); sb->blockSignals(false); - continuousWidget->setViewportState(target, viewport()->height()); + applyingContinuousModelState = false; + + continuousWidget->update(); + viewport()->update(); } void Viewer::scrollToCurrentContinuousPage() @@ -1087,22 +1137,7 @@ void Viewer::scrollToCurrentContinuousPage() return; } - auto applyPosition = [this]() { - auto *sb = verticalScrollBar(); - int targetY = continuousWidget->yPositionForPage(lastCenterPage); - targetY = qBound(sb->minimum(), targetY, sb->maximum()); - - sb->blockSignals(true); - sb->setValue(targetY); - sb->blockSignals(false); - - continuousWidget->setViewportState(targetY, viewport()->height()); - - continuousWidget->update(); - viewport()->update(); - }; - - applyPosition(); + continuousViewModel->setCurrentPage(lastCenterPage); } void Viewer::onNumPagesReady(unsigned int numPages) @@ -1110,8 +1145,9 @@ void Viewer::onNumPagesReady(unsigned int numPages) if (continuousScroll && numPages > 0) { setActiveWidget(continuousWidget); - continuousWidget->setViewportState(verticalScrollBar()->value(), viewport()->height()); - continuousWidget->setNumPages(numPages); + continuousViewModel->setViewportSize(viewport()->width(), viewport()->height()); + continuousViewModel->setNumPages(numPages); + probeContinuousBufferedPages(); int page = lastCenterPage; if (page < 0) { @@ -1119,7 +1155,7 @@ void Viewer::onNumPagesReady(unsigned int numPages) } page = qBound(0, page, static_cast(numPages) - 1); lastCenterPage = page; - continuousWidget->setAnchorPage(page); + continuousViewModel->setAnchorPage(page); scrollToCurrentContinuousPage(); } @@ -1132,7 +1168,7 @@ void Viewer::onRenderPageChanged(int page) } lastCenterPage = page; - continuousWidget->setAnchorPage(page); + continuousViewModel->setAnchorPage(page); scrollToCurrentContinuousPage(); } @@ -1157,6 +1193,7 @@ void Viewer::resetContent() { configureContent(tr("Press 'O' to open comic.")); goToFlow->reset(); + continuousViewModel->reset(); continuousWidget->reset(); lastCenterPage = -1; emit reset(); @@ -1316,7 +1353,7 @@ void Viewer::updateZoomRatio(int ratio) { zoom = ratio; if (continuousScroll) { - continuousWidget->setZoomFactor(zoom); + continuousViewModel->setZoomFactor(zoom); } else { updateContentSize(); } diff --git a/YACReader/viewer.h b/YACReader/viewer.h index d5b852f56..99e6b60aa 100644 --- a/YACReader/viewer.h +++ b/YACReader/viewer.h @@ -31,6 +31,7 @@ class YACReaderTranslator; class GoToFlowWidget; class Bookmarks; class ContinuousPageWidget; +class ContinuousViewModel; class PageLabelWidget; class NotificationsLabelWidget; @@ -149,8 +150,10 @@ public slots: QLabel *content; QLabel *messageLabel; ContinuousPageWidget *continuousWidget; + ContinuousViewModel *continuousViewModel; int lastCenterPage = -1; bool syncingRenderFromContinuousScroll = false; + bool applyingContinuousModelState = false; YACReaderTranslator *translator; int translatorXPos; @@ -191,7 +194,10 @@ public slots: int animationDuration() const; void animateScroll(QPropertyAnimation &scroller, const QScrollBar &scrollBar, int delta); void onContinuousScroll(int value); - void onContinuousLayoutScrollRequested(int scrollY); + void onContinuousViewModelChanged(); + void onContinuousPageRendered(int absolutePageIndex); + void probeContinuousBufferedPages(); + void applyContinuousStateToUi(); void scrollToCurrentContinuousPage(); void onNumPagesReady(unsigned int numPages); void onRenderPageChanged(int page); From edbbc3c5775bc8ea08275966e8ae8d82721bf534 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 26 Feb 2026 16:41:43 +0100 Subject: [PATCH 089/187] Implement a small cache to avoid scaling continuously while painting --- YACReader/continuous_page_widget.cpp | 54 +++++++++++++++++++++++++-- YACReader/continuous_page_widget.h | 55 ++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 4 deletions(-) diff --git a/YACReader/continuous_page_widget.cpp b/YACReader/continuous_page_widget.cpp index 0f825cfb2..fb509a7f7 100644 --- a/YACReader/continuous_page_widget.cpp +++ b/YACReader/continuous_page_widget.cpp @@ -42,6 +42,7 @@ void ContinuousPageWidget::setViewModel(ContinuousViewModel *viewModel) } updateGeometry(); + scaledPageCache.invalidateAll(); update(); } @@ -49,6 +50,7 @@ void ContinuousPageWidget::reset() { setMinimumHeight(0); setMaximumHeight(QWIDGETSIZE_MAX); + scaledPageCache.invalidateAll(); updateGeometry(); update(); } @@ -86,6 +88,8 @@ void ContinuousPageWidget::onPageAvailable(int absolutePageIndex) return; } + scaledPageCache.invalidatePage(absolutePageIndex); + // repaint the region where this page lives if (absolutePageIndex < continuousViewModel->numPages()) { QSize scaled = continuousViewModel->scaledPageSize(absolutePageIndex); @@ -106,10 +110,17 @@ void ContinuousPageWidget::paintEvent(QPaintEvent *event) } QPainter painter(this); + scaledPageCache.invalidateForWidth(width()); QRect visibleRect = event->rect(); int firstPage = continuousViewModel->pageAtY(visibleRect.top()); int lastPage = continuousViewModel->pageAtY(visibleRect.bottom()); + firstPage = qBound(0, firstPage, continuousViewModel->numPages() - 1); + lastPage = qBound(0, lastPage, continuousViewModel->numPages() - 1); + + const int cacheMin = std::max(0, firstPage - 1); + const int cacheMax = std::min(continuousViewModel->numPages() - 1, lastPage + 1); + scaledPageCache.keepOnlyRange(cacheMin, cacheMax); int w = width(); for (int i = firstPage; i <= lastPage && i < continuousViewModel->numPages(); ++i) { @@ -124,10 +135,9 @@ void ContinuousPageWidget::paintEvent(QPaintEvent *event) const QImage *img = render->bufferedImage(i); if (img && !img->isNull()) { - if (img->size() != scaled) { - painter.drawImage(pageRect, img->scaled(scaled, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); - } else { - painter.drawImage(pageRect, *img); + const QImage *drawable = scaledImageForPaint(i, img, scaled, width()); + if (drawable) { + painter.drawImage(pageRect, *drawable); } } else { // placeholder @@ -145,3 +155,39 @@ void ContinuousPageWidget::resizeEvent(QResizeEvent *event) continuousViewModel->setViewportSize(width(), continuousViewModel->viewportHeight()); } } + +const QImage *ContinuousPageWidget::scaledImageForPaint(int pageIndex, const QImage *source, const QSize &targetSize, int effectiveWidth) +{ + if (!source || source->isNull() || targetSize.isEmpty()) { + return nullptr; + } + + if (source->size() == targetSize) { + return source; + } + + scaledPageCache.invalidateForWidth(effectiveWidth); + + auto it = scaledPageCache.pages.find(pageIndex); + const qint64 sourceKey = source->cacheKey(); + + if (it != scaledPageCache.pages.end()) { + const ScaledPageCacheEntry &entry = it.value(); + const bool validEntry = entry.sourceCacheKey == sourceKey + && entry.sourceSize == source->size() + && entry.targetSize == targetSize + && !entry.scaledImage.isNull(); + if (validEntry) { + return &it.value().scaledImage; + } + } + + ScaledPageCacheEntry entry; + entry.sourceCacheKey = sourceKey; + entry.sourceSize = source->size(); + entry.targetSize = targetSize; + entry.scaledImage = source->scaled(targetSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + scaledPageCache.pages.insert(pageIndex, std::move(entry)); + + return &scaledPageCache.pages[pageIndex].scaledImage; +} diff --git a/YACReader/continuous_page_widget.h b/YACReader/continuous_page_widget.h index d40d4bd62..819d7a191 100644 --- a/YACReader/continuous_page_widget.h +++ b/YACReader/continuous_page_widget.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include "themable.h" @@ -33,8 +35,61 @@ public slots: void applyTheme(const Theme &theme) override; private: + struct ScaledPageCacheEntry { + qint64 sourceCacheKey = 0; + QSize sourceSize; + QSize targetSize; + QImage scaledImage; + }; + + struct ScaledPageCache { + int effectiveWidth = -1; + QHash pages; + + void invalidateAll() + { + effectiveWidth = -1; + pages.clear(); + } + + void invalidateForWidth(int width) + { + if (effectiveWidth != width) { + effectiveWidth = width; + pages.clear(); + } + } + + void invalidatePage(int pageIndex) + { + pages.remove(pageIndex); + } + + void keepOnlyRange(int minPageIndex, int maxPageIndex) + { + if (pages.isEmpty()) { + return; + } + + QList keysToRemove; + keysToRemove.reserve(pages.size()); + for (auto it = pages.constBegin(); it != pages.constEnd(); ++it) { + if (it.key() < minPageIndex || it.key() > maxPageIndex) { + keysToRemove.append(it.key()); + } + } + + for (int key : keysToRemove) { + pages.remove(key); + } + } + }; + + const QImage *scaledImageForPaint(int pageIndex, const QImage *source, const QSize &targetSize, int effectiveWidth); + Render *render = nullptr; ContinuousViewModel *continuousViewModel = nullptr; + ScaledPageCache scaledPageCache; }; #endif // CONTINUOUS_PAGE_WIDGET_H From a936c23cdce7988778d1db46e7ad7f45350e3c7e Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 26 Feb 2026 20:45:50 +0100 Subject: [PATCH 090/187] Format --- YACReader/continuous_page_widget.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/YACReader/continuous_page_widget.cpp b/YACReader/continuous_page_widget.cpp index fb509a7f7..65e1361b1 100644 --- a/YACReader/continuous_page_widget.cpp +++ b/YACReader/continuous_page_widget.cpp @@ -173,10 +173,7 @@ const QImage *ContinuousPageWidget::scaledImageForPaint(int pageIndex, const QIm if (it != scaledPageCache.pages.end()) { const ScaledPageCacheEntry &entry = it.value(); - const bool validEntry = entry.sourceCacheKey == sourceKey - && entry.sourceSize == source->size() - && entry.targetSize == targetSize - && !entry.scaledImage.isNull(); + const bool validEntry = entry.sourceCacheKey == sourceKey && entry.sourceSize == source->size() && entry.targetSize == targetSize && !entry.scaledImage.isNull(); if (validEntry) { return &it.value().scaledImage; } From 2157f668d9d15d61388b461bd8c25686009677df Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 26 Feb 2026 19:28:45 +0100 Subject: [PATCH 091/187] Keep what's new dialog up to date for users trying YACReader 10 --- custom_widgets/whats_new_dialog.cpp | 36 ++++------------------------- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/custom_widgets/whats_new_dialog.cpp b/custom_widgets/whats_new_dialog.cpp index 6f9689d94..d3c694076 100644 --- a/custom_widgets/whats_new_dialog.cpp +++ b/custom_widgets/whats_new_dialog.cpp @@ -37,40 +37,14 @@ YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent) versionLabel->setAlignment(Qt::AlignCenter); textLabel = new QLabel(); - htmlTemplate = "This version brings exciting new features, improved functionality, enhanced customization options, bug fixes, and performance improvements across all apps:
" + htmlTemplate = "YACReader 10 is finally here!! This is all the exciting new features and improvements:
" "
" "YACReader
" - " • Don't use scroll animations on macOS by default, where hdpi scroll is most likely to be used
" - " • New toolbar on macOS
" - " • New mouse modes to turn pages - you can setup the app to use the left/right buttons to turn pages directly or click on the left/right part of the screen to turn pages
" - " • Fix current page/time label content when the content is too long. (new in 9.16.3)
" + " • Add support for continuous scroll mode
" "
" - "YACReaderLibrary
" - " • Improve flexibility of the open comic in third party app setting so more complex commands can be used, e.g. `open -a \"/Applications/My Reader.app\" \"{comic_file_path}\"`
" - " • Fix setting the comic rating in the table view
" - " • Log libraries validation when the app starts
" - " • New toolbar on macOS
" - " • New setting in Comic Vine scraper to force exact volume matches
" - " • Better default search query in the Comic Vine scraper
" - " • Improved navigation in Comic Vine scraper, including keeping the current query around to make edits and refined searches easier
" - " • Add support for custom covers for any folder using the context menu
" - " • The edit cover buttons now support looping through pages, going forward from the last returns to the first, and going backward from the first jumps to the last
" - " • Add support for custom covers for comics using the edit metadata dialog, you can use a pick file button or drag&drop an image into the cover view in the dialog
" - " • Covers can be set in bulk for various comics at once
" - " • New button to reset to the default cover of a comic
" - " • Support for storing the new image filters from iOS and Android apps
" - " • Fixed cover loading in Comic Vine scraper (new in 9.16.1)
" - " • Added a customizable User Agent string to use it with Comic Vine. It can be set in YACReaderLibrary.ini in the [ComicVine] section using the COMIC_VINE_USER_AGENT key (new in 9.16.2)
" - " • Prevent crash when opening the folders context menu if a folder is not selected. (new in 9.16.2)
" - " • Fix crash when using the `Set type` menu on libraries. (new in 9.16.2)
" - " • Fix table view last section stretch. Before it was only working randomly. (new in 9.16.3)
" - " • Fix empty table view caused by wront state being saved. You'll need to reconfigure the table view headers to your liking after this udpate. (new in 9.16.3)
" - "
" - "YACReaderLibraryServer
" - " • Log libraries validation when the app starts
" - "
" - "All apps
" - " • PDF support has been updated in all Windows apps
" + "All GUI Apps
" + " • Migrate Flow implementation from OpenGL to QRhi. This is a full new implementation with better performance and compatibility with operating systems and hardware
" + " • Add light/dark themes support that follow the system configuration
" "
" "I hope you enjoy the new update. Please, if you like YACReader consider to become a patron in Patreon " "or donate some money using Pay-Pal and help keeping the project alive. " From 7ab7aaf09a41ae415ed3ebf5d77299194c14ccd5 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 26 Feb 2026 22:02:12 +0100 Subject: [PATCH 092/187] Minimum Qt version required is 6.7 --- common/themes/theme_manager.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/common/themes/theme_manager.cpp b/common/themes/theme_manager.cpp index e39554be9..094000c2e 100644 --- a/common/themes/theme_manager.cpp +++ b/common/themes/theme_manager.cpp @@ -21,8 +21,6 @@ ThemeManager &ThemeManager::instance() void ThemeManager::initialize() { - // QStyleHints::colorScheme is only 6.5+ -#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) auto *styleHints = qGuiApp->styleHints(); auto colorScheme = styleHints->colorScheme(); @@ -35,15 +33,6 @@ void ThemeManager::initialize() applyColorScheme(colorScheme); connect(styleHints, &QStyleHints::colorSchemeChanged, this, applyColorScheme, Qt::QueuedConnection); -#else - auto applyPalette = [this](const QPalette &palette) { - setTheme(palette.color(QPalette::Window).lightness() < 128 ? ThemeId::Dark : ThemeId::Light); - }; - - applyPalette(qGuiApp->palette()); - - connect(qGuiApp, &QGuiApplication::paletteChanged, this, applyPalette, Qt::QueuedConnection); -#endif } void ThemeManager::setTheme(ThemeId themeId) From 392e4a0643086bbbf19a76817dbfacbe46730a61 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 27 Feb 2026 13:26:25 +0100 Subject: [PATCH 093/187] Move check button svgs paths out from theme params --- YACReaderLibrary/themes/theme_factory.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 5f7c49691..f6fda6ca7 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -33,10 +33,8 @@ struct ComicVineParams { QColor buttonTextColor; QColor buttonBorderColor; - QString radioUncheckedPath; QColor radioUncheckedColor; - QString radioCheckedPath; QColor radioCheckedBackgroundColor; QColor radioCheckedIndicatorColor; @@ -335,7 +333,7 @@ Theme makeTheme(const ThemeParams ¶ms) theme.comicVine.defaultLabelQSS = t.defaultLabelQSS.arg(cv.labelTextColor.name()); theme.comicVine.titleLabelQSS = t.titleLabelQSS.arg(cv.labelTextColor.name()); theme.comicVine.coverLabelQSS = t.coverLabelQSS.arg(cv.labelBackgroundColor.name(), cv.labelTextColor.name()); - theme.comicVine.radioButtonQSS = t.radioButtonQSS.arg(cv.buttonTextColor.name(), recolor(cv.radioUncheckedPath, cv.radioUncheckedColor), recoloredSvgToThemeFile(cv.radioCheckedPath, cv.radioCheckedBackgroundColor, cv.radioCheckedIndicatorColor, params.themeName)); + theme.comicVine.radioButtonQSS = t.radioButtonQSS.arg(cv.buttonTextColor.name(), recolor(":/images/comic_vine/radioUnchecked.svg", cv.radioUncheckedColor), recoloredSvgToThemeFile(":/images/comic_vine/radioChecked.svg", cv.radioCheckedBackgroundColor, cv.radioCheckedIndicatorColor, params.themeName)); theme.comicVine.checkBoxQSS = t.checkBoxQSS.arg(cv.buttonTextColor.name(), cv.buttonBorderColor.name(), cv.buttonBackgroundColor.name(), recolor(":/images/comic_vine/checkBoxTick.svg", cv.checkBoxTickColor)); theme.comicVine.scraperLineEditTitleLabelQSS = t.scraperLineEditTitleLabelQSS.arg(cv.contentTextColor.name()); @@ -885,10 +883,8 @@ ThemeParams classicThemeParams() cv.buttonTextColor = Qt::white; cv.buttonBorderColor = QColor(0x242424); - cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.svg"; cv.radioUncheckedColor = QColor(0xE5E5E5); - cv.radioCheckedPath = ":/images/comic_vine/radioChecked.svg"; cv.radioCheckedBackgroundColor = QColor(0xE5E5E5); cv.radioCheckedIndicatorColor = QColor(0x5F5F5F); @@ -1140,10 +1136,8 @@ ThemeParams lightThemeParams() cv.buttonTextColor = Qt::black; cv.buttonBorderColor = QColor(0xCCCCCC); - cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.svg"; cv.radioUncheckedColor = QColor(0xE0E0E0); - cv.radioCheckedPath = ":/images/comic_vine/radioChecked.svg"; cv.radioCheckedBackgroundColor = QColor(0xE0E0E0); cv.radioCheckedIndicatorColor = QColor(0x222222); @@ -1395,10 +1389,8 @@ ThemeParams darkThemeParams() cv.buttonTextColor = Qt::white; cv.buttonBorderColor = QColor(0x242424); - cv.radioUncheckedPath = ":/images/comic_vine/radioUnchecked.svg"; cv.radioUncheckedColor = QColor(0xE5E5E5); - cv.radioCheckedPath = ":/images/comic_vine/radioChecked.svg"; cv.radioCheckedBackgroundColor = QColor(0xE5E5E5); cv.radioCheckedIndicatorColor = QColor(0x5F5F5F); From 084146995b5eec2c32e1ed5a700970788976773a Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 27 Feb 2026 15:18:51 +0100 Subject: [PATCH 094/187] Replace the info shadow pngs with svg versions and make them themable --- YACReaderLibrary/folder_content_view.cpp | 3 -- YACReaderLibrary/grid_comics_view.cpp | 3 -- YACReaderLibrary/info_comics_view.cpp | 6 ++-- YACReaderLibrary/qml.qrc | 10 ++----- YACReaderLibrary/qml/info-indicator-light.png | Bin 361 -> 0 bytes .../qml/info-indicator-light@2x.png | Bin 526 -> 0 bytes YACReaderLibrary/qml/info-indicator.png | Bin 652 -> 0 bytes YACReaderLibrary/qml/info-indicator.svg | 24 ++++++++++++++++ YACReaderLibrary/qml/info-shadow-light.png | Bin 120 -> 0 bytes YACReaderLibrary/qml/info-shadow-light@2x.png | Bin 125 -> 0 bytes YACReaderLibrary/qml/info-shadow.png | Bin 135 -> 0 bytes YACReaderLibrary/qml/info-shadow.svg | 24 ++++++++++++++++ YACReaderLibrary/qml/info-top-shadow.png | Bin 121 -> 0 bytes YACReaderLibrary/qml/info-top-shadow.svg | 19 +++++++++++++ YACReaderLibrary/themes/theme.h | 6 ++-- YACReaderLibrary/themes/theme_factory.cpp | 26 ++++++++---------- 16 files changed, 87 insertions(+), 34 deletions(-) delete mode 100644 YACReaderLibrary/qml/info-indicator-light.png delete mode 100644 YACReaderLibrary/qml/info-indicator-light@2x.png delete mode 100644 YACReaderLibrary/qml/info-indicator.png create mode 100644 YACReaderLibrary/qml/info-indicator.svg delete mode 100644 YACReaderLibrary/qml/info-shadow-light.png delete mode 100644 YACReaderLibrary/qml/info-shadow-light@2x.png delete mode 100644 YACReaderLibrary/qml/info-shadow.png create mode 100644 YACReaderLibrary/qml/info-shadow.svg delete mode 100644 YACReaderLibrary/qml/info-top-shadow.png create mode 100644 YACReaderLibrary/qml/info-top-shadow.svg diff --git a/YACReaderLibrary/folder_content_view.cpp b/YACReaderLibrary/folder_content_view.cpp index 79d87fa3c..485032bf7 100644 --- a/YACReaderLibrary/folder_content_view.cpp +++ b/YACReaderLibrary/folder_content_view.cpp @@ -283,9 +283,6 @@ void FolderContentView::applyTheme(const Theme &theme) // Info panel colors ctxt->setContextProperty("infoBackgroundColor", qv.infoBackgroundColor); - ctxt->setContextProperty("topShadow", qv.topShadow.isEmpty() ? QUrl() : QUrl(qv.topShadow)); - ctxt->setContextProperty("infoShadow", qv.infoShadow); - ctxt->setContextProperty("infoIndicator", qv.infoIndicator); ctxt->setContextProperty("infoTextColor", qv.infoTextColor); ctxt->setContextProperty("infoTitleColor", qv.infoTitleColor); diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index f30e4f906..262fb1ccc 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -501,9 +501,6 @@ void GridComicsView::applyTheme(const Theme &theme) // Info panel colors ctxt->setContextProperty("infoBackgroundColor", qv.infoBackgroundColor); - ctxt->setContextProperty("topShadow", qv.topShadow.isEmpty() ? QUrl() : QUrl(qv.topShadow)); - ctxt->setContextProperty("infoShadow", qv.infoShadow); - ctxt->setContextProperty("infoIndicator", qv.infoIndicator); ctxt->setContextProperty("infoTextColor", qv.infoTextColor); ctxt->setContextProperty("infoTitleColor", qv.infoTitleColor); diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp index 87e35a534..ce442f1f9 100644 --- a/YACReaderLibrary/info_comics_view.cpp +++ b/YACReaderLibrary/info_comics_view.cpp @@ -228,9 +228,9 @@ void InfoComicsView::applyTheme(const Theme &theme) // Info panel colors ctxt->setContextProperty("infoBackgroundColor", qv.infoBackgroundColor); - ctxt->setContextProperty("topShadow", qv.topShadow.isEmpty() ? QUrl() : QUrl(qv.topShadow)); - ctxt->setContextProperty("infoShadow", qv.infoShadow); - ctxt->setContextProperty("infoIndicator", qv.infoIndicator); + ctxt->setContextProperty("topShadow", QUrl::fromLocalFile(qv.topShadow)); + ctxt->setContextProperty("infoShadow", QUrl::fromLocalFile(qv.infoShadow)); + ctxt->setContextProperty("infoIndicator", QUrl::fromLocalFile(qv.infoIndicator)); ctxt->setContextProperty("infoTextColor", qv.infoTextColor); ctxt->setContextProperty("infoTitleColor", qv.infoTitleColor); diff --git a/YACReaderLibrary/qml.qrc b/YACReaderLibrary/qml.qrc index d216b4f83..2d767d062 100644 --- a/YACReaderLibrary/qml.qrc +++ b/YACReaderLibrary/qml.qrc @@ -11,13 +11,9 @@ qml/reading.svg qml/star.svg qml/page.svg - qml/info-indicator.png - qml/info-shadow.png - qml/info-indicator-light.png - qml/info-shadow-light.png - qml/info-indicator-light@2x.png - qml/info-shadow-light@2x.png - qml/info-top-shadow.png + qml/info-indicator.svg + qml/info-shadow.svg + qml/info-top-shadow.svg qml/ComicInfoView.qml qml/info-favorites.svg qml/info-rating.svg diff --git a/YACReaderLibrary/qml/info-indicator-light.png b/YACReaderLibrary/qml/info-indicator-light.png deleted file mode 100644 index b08a8ead6088a2ecb22b8981ff0fa104a6f884e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 361 zcmV-v0ha!WP)pzj>j+n0002s zkIky88W_W9dp*bXI~(=BoxYWf@M6GdZQBkySmhgG+{j+s%y}ipQ%cFT(*aX2gmD#y z;a2wIhCqHuk|c)j`v)B~=ZP>bf*@$(IA(AJayms(IF@A{9)!_xUAM`y%wb{#a#E&g z8hM_pOHsMYw(V`2rb^a=Ku*r{JUPD0dnHFoOcX_>tO0@iYRRF*JZC0Vn=wqIuIp3R zbxV2HCFZD)bN(CoLVmyG$VG|a3;7fJzQ6ukf6U|9y^y%(CiBST;w?>u# zKtKWrNB{u|ARqw*B!GYf5Rd=@5};omR;$&)GSC8V;kWp5kBP&)oA6kA1=vB-R?84n zHxH>W=c{n!><;n}SO)H`s;XqS+r{Bi2(9Wy;rJXLmUWt@ z`FuXN;0Q>%BZT8IB$F$ZHnEfmb1Y*x#<@U1(kbDXeLQXln-FM?T@co#%sL*c;~XF$ z>7=Gh8>I{al3r=5v{A|+AnB!sN*kpN0+RmuZ)u~HK|s=Le=Tj4G6+Zp;kTuYQU(FZ zpj=woC}j|k4AOoL?}&f|aKr|L!_ssyE?5Y2##^GTm} z?VW8te%?Q5rIZ0{u%rG+lSMBpWi5JbwW(F3Sf-lUv081_?wwrl0k}Y+I1EfK0rUwh z{+t1rP(NYL#(8!bcm-yMS`OykW{*I6;3D-4TfSBSauZ0tG9r8{@FRJ}tf_{>=rR{2 z`%NGZY1=jwPWI&rh%bX_!x)2?%rRw`uz6XoMcS1N^T8`n?iG+eLFq9l9qUXf+FT)R z7$3+HwVGB;hpmv9ZHcljQ|oPka&K2iJsb{GVQn`>QFJ?*OnyN3o;e~|SJrtQL9ApR z3#celoWQ9F=o{3_3ozA=}&8id9Z-=2*e}sCzx}Yrs+t2gXgzC(T-X! zm#R{!T(#Tnb9fBERf5iEtD#Tta4f)DoP%>k&(Dye_t~~ptJS)m&*$N6Hv2^%yGz@) zqU{>b>PJBkoMP=_v5??oh0GO7uhZ$=c%F9*kF{;aF|5H_Nlbvu_Zpt2DvsmN-EQ|A zJl4St%XJ*X8mtuwkhv>K66Lz?8GtvophOtQIEFPM0rEpHIn`?QYopQlk^$LlHqY># zTw(;se|E`%v*ML8rs@0s3FrdfiT*C#@Au^}lUKM}t5T^HuGeckTh`><_`2k8pZqU5 mwX81^ApeU?j_B?BEx-V$gtq!VC4%_?0000 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/YACReaderLibrary/qml/info-shadow-light.png b/YACReaderLibrary/qml/info-shadow-light.png deleted file mode 100644 index e52f2c7adc9c18c721468d254e5dfbf68d116418..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{N!3HE{4j&T&Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JiljVU978H@B_$kSm6DSBXZ(kqNll<%g-PK6LsA3Vgs%q- R`hlt#JYD@<);T3K0RW_cAdUb4 diff --git a/YACReaderLibrary/qml/info-shadow-light@2x.png b/YACReaderLibrary/qml/info-shadow-light@2x.png deleted file mode 100644 index 3abb75afe4aa0de03b37b22e5c2bc9ccd3bac58b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^OhBx}!3HEtr8tCulw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6JlB6&|2$B>F!NeK%?6LK;#e()z59CZE1%-D4zAccWNg268U}fi7AzZCsS>JiZnf4978H@B_$*zJV;~`x})I4;L_2+!O6zX-u~a`{k^@( g427P`3`{%>Lfcq=>s0O!25MsPboFyt=akR{0L+Uei2wiq diff --git a/YACReaderLibrary/qml/info-shadow.svg b/YACReaderLibrary/qml/info-shadow.svg new file mode 100644 index 000000000..679574287 --- /dev/null +++ b/YACReaderLibrary/qml/info-shadow.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/YACReaderLibrary/qml/info-top-shadow.png b/YACReaderLibrary/qml/info-top-shadow.png deleted file mode 100644 index 1fd60281510ee5b3e065c60f6f2824a35cd796f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrF!3HE-TH59VDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9Mbe%wjv*Ddk`fXUIM|ZdvIQ3MDIIZS;df|YWZ=2Ya5Lb8 RZ#7UEgQu&X%Q~loCIH7%ARGVy diff --git a/YACReaderLibrary/qml/info-top-shadow.svg b/YACReaderLibrary/qml/info-top-shadow.svg new file mode 100644 index 000000000..f8092b2a2 --- /dev/null +++ b/YACReaderLibrary/qml/info-top-shadow.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index bf3b7a1dc..11dd94ad5 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -226,9 +226,9 @@ struct QmlViewTheme { // Info panel colors QColor infoBackgroundColor; - QString topShadow; // Image filename - QString infoShadow; // Image filename - QString infoIndicator; // Image filename + QString topShadow; // Recolored SVG path + QString infoShadow; // Recolored SVG path + QString infoIndicator; // Recolored SVG path QColor infoTextColor; QColor infoTitleColor; diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index f6fda6ca7..75cb914a0 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -149,9 +149,8 @@ struct QmlViewParams { // Info panel colors QColor infoBackgroundColor; - QString topShadow; // Image filename - QString infoShadow; // Image filename - QString infoIndicator; // Image filename + QColor infoBorderColor; + QColor infoShadowColor; QColor infoTextColor; QColor infoTitleColor; @@ -494,9 +493,9 @@ Theme makeTheme(const ThemeParams ¶ms) theme.qmlView.textColor = qv.textColor; theme.qmlView.showDropShadow = qv.showDropShadow; theme.qmlView.infoBackgroundColor = qv.infoBackgroundColor; - theme.qmlView.topShadow = qv.topShadow; - theme.qmlView.infoShadow = qv.infoShadow; - theme.qmlView.infoIndicator = qv.infoIndicator; + theme.qmlView.topShadow = recoloredSvgToThemeFile(":/qml/info-top-shadow.svg", qv.infoBackgroundColor, qv.infoBorderColor, qv.infoShadowColor, params.themeName); + theme.qmlView.infoShadow = recoloredSvgToThemeFile(":/qml/info-shadow.svg", qv.infoBackgroundColor, qv.infoBorderColor, qv.infoShadowColor, params.themeName); + theme.qmlView.infoIndicator = recoloredSvgToThemeFile(":/qml/info-indicator.svg", qv.infoBackgroundColor, qv.infoBorderColor, qv.infoShadowColor, params.themeName); theme.qmlView.infoTextColor = qv.infoTextColor; theme.qmlView.infoTitleColor = qv.infoTitleColor; theme.qmlView.ratingUnselectedColor = qv.ratingUnselectedColor; @@ -991,9 +990,8 @@ ThemeParams classicThemeParams() qv.textColor = QColor(0xA8A8A8); qv.showDropShadow = true; qv.infoBackgroundColor = QColor(0x2E2E2E); - qv.topShadow = "info-top-shadow.png"; - qv.infoShadow = "info-shadow.png"; - qv.infoIndicator = "info-indicator.png"; + qv.infoBorderColor = QColor(0x404040); + qv.infoShadowColor = Qt::black; qv.infoTextColor = QColor(0xB0B0B0); qv.infoTitleColor = QColor(0xFFFFFF); qv.ratingUnselectedColor = QColor(0x1C1C1C); @@ -1244,9 +1242,8 @@ ThemeParams lightThemeParams() qv.textColor = QColor(0x636363); qv.showDropShadow = true; qv.infoBackgroundColor = QColor(0xFFFFFF); - qv.topShadow = ""; - qv.infoShadow = "info-shadow-light.png"; - qv.infoIndicator = "info-indicator-light.png"; + qv.infoBorderColor = QColor(0x808080); + qv.infoShadowColor = QColor(0x444444); qv.infoTextColor = QColor(0x404040); qv.infoTitleColor = QColor(0x2E2E2E); qv.ratingUnselectedColor = QColor(0xDEDEDE); @@ -1497,9 +1494,8 @@ ThemeParams darkThemeParams() qv.textColor = QColor(0xA8A8A8); qv.showDropShadow = true; qv.infoBackgroundColor = QColor(0x2E2E2E); - qv.topShadow = "info-top-shadow.png"; - qv.infoShadow = "info-shadow.png"; - qv.infoIndicator = "info-indicator.png"; + qv.infoBorderColor = QColor(0x404040); + qv.infoShadowColor = Qt::black; qv.infoTextColor = QColor(0xB0B0B0); qv.infoTitleColor = QColor(0xFFFFFF); qv.ratingUnselectedColor = QColor(0x1C1C1C); From 0e9117620060bbc47af44223471901d2d0ead893 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 27 Feb 2026 16:12:59 +0100 Subject: [PATCH 095/187] Remove unused images and server v1 files --- YACReaderLibrary/images.qrc | 2 - YACReaderLibraryServer/CMakeLists.txt | 2 - images/f.png | Bin 710 -> 0 bytes images/f_overlayed.png | Bin 597 -> 0 bytes images/f_overlayed_retina.png | Bin 1224 -> 0 bytes release/server/docroot/css/reset.css | 46 -- release/server/docroot/css/styles_ipad.css | 466 ------------------ release/server/docroot/css/styles_iphone.css | 463 ----------------- release/server/docroot/images/browse.png | Bin 134 -> 0 bytes release/server/docroot/images/browse@2x.png | Bin 185 -> 0 bytes release/server/docroot/images/combo.png | Bin 120 -> 0 bytes release/server/docroot/images/combo@2x.png | Bin 167 -> 0 bytes release/server/docroot/images/download.png | Bin 155 -> 0 bytes release/server/docroot/images/download@2x.png | Bin 203 -> 0 bytes release/server/docroot/images/f.png | Bin 621 -> 0 bytes release/server/docroot/images/f@2x.png | Bin 1262 -> 0 bytes release/server/docroot/images/imported.png | Bin 158 -> 0 bytes release/server/docroot/images/imported@2x.png | Bin 214 -> 0 bytes release/server/docroot/images/indicator.png | Bin 118 -> 0 bytes .../server/docroot/images/indicator@2x.png | Bin 220 -> 0 bytes release/server/docroot/images/library.png | Bin 201 -> 0 bytes release/server/docroot/images/library@2x.png | Bin 284 -> 0 bytes release/server/docroot/images/next.png | Bin 137 -> 0 bytes release/server/docroot/images/next@2x.png | Bin 339 -> 0 bytes release/server/docroot/images/prev.png | Bin 154 -> 0 bytes release/server/docroot/images/prev@2x.png | Bin 345 -> 0 bytes release/server/docroot/images/read.png | Bin 152 -> 0 bytes release/server/docroot/images/read@2x.png | Bin 201 -> 0 bytes release/server/docroot/images/readMark.png | Bin 196 -> 0 bytes release/server/docroot/images/readMark@2x.png | Bin 296 -> 0 bytes release/server/docroot/images/readingMark.png | Bin 206 -> 0 bytes .../server/docroot/images/readingMark@2x.png | Bin 296 -> 0 bytes release/server/docroot/images/up.png | Bin 163 -> 0 bytes release/server/docroot/images/up@2x.png | Bin 271 -> 0 bytes release/server/docroot/login.html | 26 - release/server/templates/folder.tpl | 117 ----- release/server/templates/libraries.tpl | 27 - 37 files changed, 1149 deletions(-) delete mode 100644 images/f.png delete mode 100644 images/f_overlayed.png delete mode 100644 images/f_overlayed_retina.png delete mode 100644 release/server/docroot/css/reset.css delete mode 100644 release/server/docroot/css/styles_ipad.css delete mode 100644 release/server/docroot/css/styles_iphone.css delete mode 100644 release/server/docroot/images/browse.png delete mode 100644 release/server/docroot/images/browse@2x.png delete mode 100644 release/server/docroot/images/combo.png delete mode 100644 release/server/docroot/images/combo@2x.png delete mode 100644 release/server/docroot/images/download.png delete mode 100644 release/server/docroot/images/download@2x.png delete mode 100644 release/server/docroot/images/f.png delete mode 100644 release/server/docroot/images/f@2x.png delete mode 100644 release/server/docroot/images/imported.png delete mode 100644 release/server/docroot/images/imported@2x.png delete mode 100644 release/server/docroot/images/indicator.png delete mode 100644 release/server/docroot/images/indicator@2x.png delete mode 100644 release/server/docroot/images/library.png delete mode 100644 release/server/docroot/images/library@2x.png delete mode 100644 release/server/docroot/images/next.png delete mode 100644 release/server/docroot/images/next@2x.png delete mode 100644 release/server/docroot/images/prev.png delete mode 100644 release/server/docroot/images/prev@2x.png delete mode 100644 release/server/docroot/images/read.png delete mode 100644 release/server/docroot/images/read@2x.png delete mode 100644 release/server/docroot/images/readMark.png delete mode 100644 release/server/docroot/images/readMark@2x.png delete mode 100644 release/server/docroot/images/readingMark.png delete mode 100644 release/server/docroot/images/readingMark@2x.png delete mode 100644 release/server/docroot/images/up.png delete mode 100644 release/server/docroot/images/up@2x.png delete mode 100644 release/server/docroot/login.html delete mode 100644 release/server/templates/folder.tpl delete mode 100644 release/server/templates/libraries.tpl diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index d0749b7f5..788d45d96 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -36,8 +36,6 @@ ../images/empty_container/empty_reading_list.svg ../images/library_dialogs/exportComicsInfo.svg ../images/library_dialogs/exportLibrary.svg - ../images/f_overlayed.png - ../images/f_overlayed_retina.png ../images/find_folder.svg ../images/flow1.png ../images/flow2.png diff --git a/YACReaderLibraryServer/CMakeLists.txt b/YACReaderLibraryServer/CMakeLists.txt index 619f10a82..fd70e77ef 100644 --- a/YACReaderLibraryServer/CMakeLists.txt +++ b/YACReaderLibraryServer/CMakeLists.txt @@ -19,8 +19,6 @@ target_compile_definitions(YACReaderLibraryServer PRIVATE YACREADER_LIBRARY ) -# Resources -qt_add_resources(yacreaderlibraryserver_images_rcc "${CMAKE_CURRENT_SOURCE_DIR}/images.qrc") target_sources(YACReaderLibraryServer PRIVATE ${yacreaderlibraryserver_images_rcc}) # Translations diff --git a/images/f.png b/images/f.png deleted file mode 100644 index 232a785d75767e8fae82aae15cf36213ecec1598..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 710 zcmeAS@N?(olHy`uVBq!ia0vp^0YF^A!3HE#-<5s?Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07??6VT^vIyZoRp?F|Wx%=6In&AK%@WTIO07-ooXZUtUl* z=zZxkL;CU$mRgpXt6k(5?rU5v-CSLLea^|&5(Yl4@|t?i#EaQKf9x+RDEhkJ)h5W& zmV<#sz=46Yfq{ubff2}JQ~|LXSR5E~J@&ugUVnYHxa-DptGRR7B>RuY$++K3Fwpo? zwg1JEOIcrE+05(P5x4(pbfe`Smz>!qcV%N4xSM{4yqT87{omqR6+@{FI$`{63> zfOAt%wZ)##joXp&XA{5lsY`J>^X446{odYt|MD+e($;Nxs^T+e+3q8k_SY`7(hQS} zoYBX;_UPom{na(w8@HUTi0X^!oFVGSrf~fb*gY4HeR==2`Do|?k2iKl%+@B#eAj7H zets@w!GUUl-Ojuf^RgZ{QL&CicNKr?l_(xm9QL7*^%keCEkd%VK^x^JT5=>vb+yrXKE@%#ogm z5*nB>!^kp$0T@RN&lb=7vCV4P@r08U}fi7AzZCsS=07#P2Mx;TbZ+=nBHH#?)tcPPQU#n9&pQ?~$NilYd-YPszK%?ZVB=$&jOBv%7t6LY_$aga z>}FES<$mos$;94`XUDoI!MJs6?HE4HZ}k*+c8bs5{vO@8dfM3=I^4+` z)j?C788>sN#hI}fyey8h*u)k4Jm^^~>w){~k?{`Emeq+M`wplw<*nK#pZI?lf9+k> z?@{dQ4vS^2X?z}9z4lh7=IaCJC#IiO`?7O}WJF7(McS*I-)mk=R`4H4dvAHPWy93Z zVtHRft$nY&Pnu>JZ~XGIk=nKN1ltSSSIN4)crEbDN;i|uE^1HfUt>lE2SyG7e8i84 zhK({i-pyx~{~5o2UEiPWdtaq|nD}2J|NV=it0xl<+*s%Evg+!|2iC$zq9qg@8km5l lH88Lu5eH^Ib#Gu~kmFl)@v?G$8ZezOc)I$ztaD0e0swUy@gx8M diff --git a/images/f_overlayed_retina.png b/images/f_overlayed_retina.png deleted file mode 100644 index d613de82913baa10606c85d4c22e2bd45684f3ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1224 zcmeAS@N?(olHy`uVBq!ia0vp^3xN0o2OE%Vcg(*9q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~;1FtB8Kx;TbZ+gV-o|An$T-;E=8g(`TqCg+j1{ksvKi-pS9bhJyY+wk$1!Izi}1X+=gdg zDlz%k>pqH3Zz*2WqRwxids8iEuJYNpD@~W%X}^2(MyKcTk6ZQo`XB4{9sZL4s!-Bh z{P@=|@6#V?Nyy2|zuw33^Q?bBexLZ_`dqoy_nVGxf5!o&W-qJEyuH_Ge)pE&rPg*| zU+%NabGbkB_|aLl?}}I|4EnoGf8Tj}qe=Snj)+{D{^GoYOi%jFy{7$>Lh~}jBT)Zf zqppZQ*txuNqaLe==UpkLJ!bvgrF+{LE*ssOefsFj;+%thnGd%9*d%lL!2+pCWmRkM zwJwzpdAvf;z0`8eg&Xe@Tl=z0W3oRo$VR+9@G41Maed{(A8cCFG`Zii28X?5xcqlk z|HGFChmW1GTDRPsjKQ{kZ^}*om(P!Hd-nU#? zd?RMcou*i^>&f4O4Ovgfzu&WixB0e#f&&W&lS=~{b)bH-9do(#ae-5RUp+RkZ7W+n zdBfH7%=@|@d%FtHud{!q*0-Kj-g)AA<~+j#bzSS--gCQY9N^hy@l7T`kGPno7HC>>4Lu}8>)eoAFXL0MjTzy>Yz@&FJVT{wJ z+>6{1f8g;Re(7I_=i2oI+`qbuUwO?RrzguE9WUR!lzW0M+mFYr|9%Ht-+Rz-%3qxY zx;q-S@YZwq=l>~Z4S!N{@Z-uRd5-t2oA)yO4U>suR&o$fU}9k;k-`W&tN{ua{BdUK z^8HfNnNlV*njP0T{eMMf-QP` z=GM!_b-#mZ^v_(a>6`hbc7ENG9@ZX{@SQ2QoA}$EckI}~@z^4&J}XY@@vH6k-#cF~ zeSNFxviX+VZ$Ih1|5I9%*;jOQdMWq6M2WWd-Zg*Ha?7Xon22ZkUApsRS}u3nt#{0z mY)QJ;L16_?J(9J;2@I**cC54P%a;NcO$?r{elF{r5}E)%Z}4sa diff --git a/release/server/docroot/css/reset.css b/release/server/docroot/css/reset.css deleted file mode 100644 index b1f6c072a..000000000 --- a/release/server/docroot/css/reset.css +++ /dev/null @@ -1,46 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-weight: inherit; - font-style: inherit; - font-size: 100%; - font-family: inherit; - vertical-align: baseline; -} -/* remember to define focus styles! */ -:focus -{ - outline: 0; -} -body -{ - line-height: 1; - color: black; -} -ol, ul -{ - list-style: none; -} -/* tables still need 'cellspacing="0"' in the markup */ -table, td, tr -{ - border: 0; - border-collapse: separate; - border-spacing: 0; -} -caption, th, td -{ - text-align: left; - font-weight: normal; -} -blockquote:before, blockquote:after, q:before, q:after -{ - content: ""; -} -blockquote, q -{ - quotes: "" ""; -} diff --git a/release/server/docroot/css/styles_ipad.css b/release/server/docroot/css/styles_ipad.css deleted file mode 100644 index d14b3cfb7..000000000 --- a/release/server/docroot/css/styles_ipad.css +++ /dev/null @@ -1,466 +0,0 @@ -body{ - background-color: #F5F5F5; - font-family: Arial, Helvetica, sans-serif; -} - -/* libraries */ -#contentLibraries{ - width: 400px; - border: 1px solid #C6C6C6; - background-color: white; - margin-left: auto; - margin-right: auto; - margin-top: 9px; -} - -#contentLibraries .library-icon -{ - float: left; - background-color: white; - height: 18px; - padding: 11px 19px 10px 19px; - display:block; -} - -#contentLibraries li -{ - border-bottom: 1px solid #e2e2e2; - position: relative; - list-style: none; -} - -#contentLibraries li:last-child -{ - border: none; -} - -#contentLibraries .library-link -{ - width: 311px; - height: 28px; - border: none; - padding: 11px 0 0 0px; - background-color: white; - display: block; - float:left; - font-family: Arial; - font-size: 16px; - text-decoration: none; - color: #525252 ; - overflow: hidden; -} - - #contentLibraries a -{ - position: absolute; - height: 39px; - width: 100%; - z-index: 10; - display: block; - top 0; - text-decoration: none; -} - -#contentLibraries .library-indicator -{ - float: left; - background-color: white; - height: 8px; - padding: 16px 16px 15px 16px; - display:block; -} - - -#content h1 -{ - color: #292929; - text-align: center; - font-size: 21px; -} - -#contentLibraries h1{ - color: #292929; - text-align: center; - border-bottom: 1px solid #C6C6C6; - font-size: 21px; - padding: 15px 0 16px 0; -} - -#folder-header -{ - position: fixed; - width: 100%; - height: 88px; - background-color: rgba(255,255,255,0.9); - border-bottom: 1px solid #C6C6C6; - z-index: 999; -} - -#folder-subheader1 -{ - width: 100%; - height: 40px; - margin-top: 18px; - -} - -#folder-subheader2 -{ - width: 100%; - padding-left: 16px; -} - -#topIndex -{ - position: absolute; - left: 16px; - top: 19px; -} - -#topIndex a -{ - float: left; -} - -.indicator { - margin: 0 9px; -} - -.path { - text-decoration: none; - color: #5C5C5C; - font-family: Arial, Helvetica; - font-size: 15px; - -} - -#header-combos -{ - position: absolute; - right: 15px; - top: 15px; - color: #a3a3a3; - width: 160px; -} - -#topIndex .next{ - width: 25px; - height: 19px; - border: none; - margin: 0 21px 4px 0; - padding: 5px 0 0 0; - display: block; - background: url("/images/next.png") no-repeat scroll 0 0 transparent; - background-size: 25px 19px; - padding: 0; - text-indent: -99999px; -} - -#topIndex .previous{ - width: 25px; - height: 19px; - border: none; - margin: 0 14px 4px 0; - padding: 5px 0 0 0; - display: block; - background: url("/images/prev.png") no-repeat scroll 0 0 transparent; - background-size: 25px 19px; - padding: 0; - text-indent: -99999px; -} - -#topIndex .up{ - width: 15px; - height: 19px; - border: none; - background: url("/images/up.png") no-repeat scroll 0 0 transparent; - background-size: 15px 19px; - color: #FFF; - display: block; - text-indent: -99999px; -} - -#itemContainer li -{ -float: left; -width: 242px; -height: 120px; -border: 1px solid #E2E2E2; -margin: 9px 9px 0px 0; -background-color: white; -overflow: hidden; -position: relative; -} - -.folderContent -{ - padding-top: 90px; - padding-left: 9px; -} -/* hasta aquí */ - -.folder -{ -float: left; - -} - -.cover -{ -float: left; -overflow: hidden; -} - -.mark -{ - position: absolute; - top: 0px; - margin-left: 55px; -} - -.info -{ -padding: 8px 0px 0px 0px; -float: left; -position: relative; -height: 115px; -width: 158px; - -} - -.buttons -{ - position:absolute; - bottom:0px; - left:0px; - border-top: 1px solid #e2e2e2; - padding-top: 3px; - height: 25px; - width: 162px; - font-family: Arial; - color: #6e6e6e; - font-size: 10px; -} - -.elementInfo -{ - position:absolute; - bottom:24px; - padding-top: 3px; - height: 25px; - width: 162px; - font-family: Arial; - color: #adadad; - font-size: 10px; -} - -.numPages -{ - float: left; - padding-left:8px; -} - -.comicSize -{ - float: right; - padding-right: 9px; -} - - - -#itemContainer a -{ - text-decoration: none; - - -} - -.browseButton -{ - width: 60px; - background: url("/images/browse.png") no-repeat scroll 0 0 transparent; - background-position: 1px 6px; - background-size: 7px 7px; - border: none; - text-align:right; - display: block; - float: right; - padding: 4px 10px 0 0; - color: #6e6e6e; -} - -.importButton -{ - width: 60px; - background: url("/images/download.png") no-repeat scroll 0 0 transparent; - background-position: 3px 5px; - background-size: 7px 8px; - border: none; - text-align:left; - display: block; - float: left; - margin: 0 0 0 4px; - padding: 4px 0 0 16px; - color: #6e6e6e; -} - -.readButton -{ - width: 60px; - background: url("/images/read.png") no-repeat scroll 0 0 transparent; - background-position: 18px 5px; - background-size: 7px 9px; - border: none; - text-align:right; - display: block; - float: right; - padding: 4px 10px 0 0; - color: #6e6e6e; -} - -.importedButton -{ - width: 60px; - background: url("/images/imported.png") no-repeat scroll 0 0 transparent; - background-position: 2px 6px; - background-size: 8px 6px; - border: none; - text-align:left; - display: block; - float: left; - margin: 0 0 0 4px; - padding: 4px 0 0 16px; - color: #6e6e6e; -} - - -#indexes{ - border-top: 1px solid #C6C6C6; - background-color: white; - padding: 0px; - margin: 9px 0 0 0; -} - -.index{ - background-color: white; - margin: 9px 0 9px 0; -} - - -#alphaIndex a, #pageIndex a{ - width: 29px; - height: 24px; - border: none; - margin: 0 0 9px 9px; - padding: 5px 0 0 0px; - color: #5C5C5C; - font-size: 20px; - text-align: center; - display: block; - text-decoration: none; - font-family: Arial; - border: 1px solid #E2E2E2; - text-align:center; -} - -#alphaIndex li, #pageIndex li{ - float: left; -} - -#pageIndex .current{ - color: white; - background-color: #A2A2A2; - border: 1px solid #A2A2A2; - -} - - #content h2, #contentLibraries h2{ - color: #000; - font-weight: bold; - font-size: 12px; - margin: 0 0 16px 0; - } - - .inputs_login{ - width: 256px; - height: 64px; - background: url("/images/fnd_inputs.jpg") no-repeat scroll 0 0 #FFF; - margin: 0 0 18px 0; - } - .username{ - width: 200px; - height: 24px; - background: url("/images/fnd_input_username.jpg") no-repeat scroll 0 0 #2b2b2b; - border: none; - padding: 0 0 0 44px; - margin: 5px 0 6px 8px; - font-size: 14px; - color: #6e6e6e; - } - .pass{ - width: 200px; - height: 24px; - background: url("/images/fnd_input_pass.jpg") no-repeat scroll 0 0 #2b2b2b; - border: none; - padding: 0 0 0 44px; - margin: 0 0 0 8px; - font-size: 14px; - color: #6e6e6e; - } - .button_sign{ - width: 86px; - height: 30px; - background: url("/images/bt_login.jpg") no-repeat scroll 0 0 transparent; - border: none; - margin: 0; - padding: 0; - color: #FFF; - font-size: 14px; - float: left; - } - .infor{ - color: #666; - font-size: 8px; - float: left; - width: 112px; - margin: 0 0 0 8px; - line-height: 120%; - } - -.clear{ - height: 2px; - clear: both; -} - -.title{ - font-family: Arial; - font-size: 12px; - margin: 0 0 0 6px; - color: #555555 ; - overflow: hidden; - word-wrap: break-word; - height: 80px; - text-decoration: none; -} - -#indexalpha, #indexnumber{ - - -webkit-appearance: none; - background-color: rgba(255,255,255,0); - border-radius: 0px; - border: none; - color: #a3a3a3; - font-size: 16px; - font-family: Arial, Helvetica; - height: 30px; - margin: 0 0 0 10px; - padding:0; - float: right; -} - -.comboIndicator { - float: right; - padding: 14px 0 0 0; - margin: 0 0 0 4px; - width: 5px; -} \ No newline at end of file diff --git a/release/server/docroot/css/styles_iphone.css b/release/server/docroot/css/styles_iphone.css deleted file mode 100644 index 109b11554..000000000 --- a/release/server/docroot/css/styles_iphone.css +++ /dev/null @@ -1,463 +0,0 @@ -body{ - background-color: #F5F5F5; - font-family: Arial, Helvetica, sans-serif; -} - -/* libraries */ -#contentLibraries{ - border: 1px solid #C6C6C6; - background-color: white; - margin-left: 20px; - margin-right: 20px; - margin-top: 9px; -} - -#contentLibraries .library-icon -{ - float: left; - background-color: white; - height: 18px; - padding: 11px 19px 10px 19px; - display:block; -} - -#contentLibraries li -{ - border-bottom: 1px solid #e2e2e2; - position: relative; - list-style: none; -} - -#contentLibraries li:last-child -{ - border: none; -} - -#contentLibraries .library-link -{ - width: 65%; - height: 28px; - border: none; - padding: 11px 0 0 0px; - background-color: white; - display: block; - float:left; - font-family: Arial; - font-size: 16px; - text-decoration: none; - color: #525252 ; - overflow: hidden; -} - - #contentLibraries a -{ - position: absolute; - height: 39px; - width: 100%; - z-index: 10; - display: block; - top 0; - text-decoration: none; -} - -#contentLibraries .library-indicator -{ - float: right; - background-color: white; - height: 8px; - padding: 16px 16px 15px 16px; - display:block; -} - - -#content h1 -{ - color: #292929; - text-align: center; - font-size: 21px; -} - -#contentLibraries h1{ - color: #292929; - text-align: center; - border-bottom: 1px solid #C6C6C6; - font-size: 21px; - padding: 15px 0 16px 0; -} - -#folder-header -{ - position: fixed; - width: 100%; - height: 88px; - background-color: rgba(255,255,255,0.9); - border-bottom: 1px solid #C6C6C6; - z-index: 999; -} - -#folder-subheader1 -{ - width: 100%; - height: 40px; - margin-top: 18px; - -} - -#folder-subheader2 -{ - width: 100%; - padding-left: 16px; -} - -#topIndex -{ - position: absolute; - left: 16px; - top: 19px; -} - -#topIndex a -{ - float: left; -} - -.indicator { - margin: 0 5px; -} - -.path { - text-decoration: none; - color: #5C5C5C; - font-family: Arial, Helvetica; - font-size: 15px; - -} - -#header-combos -{ - position: absolute; - right: 10px; - top: 15px; - color: #a3a3a3; - width: 160px; -} - -#topIndex .next{ - width: 25px; - height: 19px; - border: none; - margin: 0 21px 4px 0; - padding: 5px 0 0 0; - display: block; - background: url("/images/next.png") no-repeat scroll 0 0 transparent; - background-size: 25px 19px; - padding: 0; - text-indent: -99999px; -} - -#topIndex .previous{ - width: 25px; - height: 19px; - border: none; - margin: 0 14px 4px 0; - padding: 5px 0 0 0; - display: block; - background: url("/images/prev.png") no-repeat scroll 0 0 transparent; - background-size: 25px 19px; - padding: 0; - text-indent: -99999px; -} - -#topIndex .up{ - width: 15px; - height: 19px; - border: none; - background: url("/images/up.png") no-repeat scroll 0 0 transparent; - background-size: 15px 19px; - color: #FFF; - display: block; - text-indent: -99999px; -} - -#itemContainer li -{ - -height: 120px; -border: 1px solid #E2E2E2; -margin: 9px 10px 0px 10px; -background-color: white; -overflow: hidden; -position: relative; -} - -.folderContent -{ - padding-top: 90px; -} -/* hasta aquí */ - -.folder -{ -float: left; - -} - -.cover -{ -float: left; -overflow: hidden; -} - -.mark -{ - position: absolute; - top: 0px; - margin-left: 55px; -} - -.info -{ -padding: 8px 0px 0px 0px; - -position: relative; -height: 115px; - -padding-left: 82px; -} - -.buttons -{ - position:absolute; - bottom:0px; - left:80px; - right: 0px; - border-top: 1px solid #e2e2e2; - padding-top: 3px; - height: 25px; - font-family: Arial; - color: #6e6e6e; - font-size: 10px; -} - -.elementInfo -{ - position:absolute; - bottom:24px; - padding-top: 3px; - height: 25px; - width: 100%; - font-family: Arial; - color: #adadad; - font-size: 10px; -} - -.numPages -{ - float: left; - padding-left:8px; -} - -.comicSize -{ - float: right; - padding-right: 9px; -} - - - -#itemContainer a -{ - text-decoration: none; - - -} - -.browseButton -{ - width: 60px; - background: url("/images/browse.png") no-repeat scroll 0 0 transparent; - background-position: 1px 6px; - background-size: 7px 7px; - border: none; - text-align:right; - display: block; - float: right; - padding: 4px 10px 0 0; - color: #6e6e6e; -} - -.importButton -{ - width: 60px; - background: url("/images/download.png") no-repeat scroll 0 0 transparent; - background-position: 3px 5px; - background-size: 7px 8px; - border: none; - text-align:left; - display: block; - float: left; - margin: 0 0 0 4px; - padding: 4px 0 0 16px; - color: #6e6e6e; -} - -.readButton -{ - width: 60px; - background: url("/images/read.png") no-repeat scroll 0 0 transparent; - background-position: 18px 5px; - background-size: 7px 9px; - border: none; - text-align:right; - display: block; - float: right; - padding: 4px 10px 0 0; - color: #6e6e6e; -} - -.importedButton -{ - width: 60px; - background: url("/images/imported.png") no-repeat scroll 0 0 transparent; - background-position: 2px 6px; - background-size: 8px 6px; - border: none; - text-align:left; - display: block; - float: left; - margin: 0 0 0 4px; - padding: 4px 0 0 16px; - color: #6e6e6e; -} - - -#indexes{ - border-top: 1px solid #C6C6C6; - background-color: white; - padding: 0px; - margin: 9px 0 0 0; -} - -.index{ - background-color: white; - margin: 9px 0 9px 0; -} - - -#alphaIndex a, #pageIndex a{ - width: 29px; - height: 24px; - border: none; - margin: 0 0 9px 9px; - padding: 5px 0 0 0px; - color: #5C5C5C; - font-size: 20px; - text-align: center; - display: block; - text-decoration: none; - font-family: Arial; - border: 1px solid #E2E2E2; - text-align:center; -} - -#alphaIndex li, #pageIndex li{ - float: left; -} - -#pageIndex .current{ - color: white; - background-color: #A2A2A2; - border: 1px solid #A2A2A2; - -} - - #content h2, #contentLibraries h2{ - color: #000; - font-weight: bold; - font-size: 12px; - margin: 0 0 16px 0; - } - - .inputs_login{ - width: 256px; - height: 64px; - background: url("/images/fnd_inputs.jpg") no-repeat scroll 0 0 #FFF; - margin: 0 0 18px 0; - } - .username{ - width: 200px; - height: 24px; - background: url("/images/fnd_input_username.jpg") no-repeat scroll 0 0 #2b2b2b; - border: none; - padding: 0 0 0 44px; - margin: 5px 0 6px 8px; - font-size: 14px; - color: #6e6e6e; - } - .pass{ - width: 200px; - height: 24px; - background: url("/images/fnd_input_pass.jpg") no-repeat scroll 0 0 #2b2b2b; - border: none; - padding: 0 0 0 44px; - margin: 0 0 0 8px; - font-size: 14px; - color: #6e6e6e; - } - .button_sign{ - width: 86px; - height: 30px; - background: url("/images/bt_login.jpg") no-repeat scroll 0 0 transparent; - border: none; - margin: 0; - padding: 0; - color: #FFF; - font-size: 14px; - float: left; - } - .infor{ - color: #666; - font-size: 8px; - float: left; - width: 112px; - margin: 0 0 0 8px; - line-height: 120%; - } - -.clear{ - height: 2px; - clear: both; -} - -.title{ - font-family: Arial; - font-size: 12px; - margin: 0 0 0 6px; - color: #555555 ; - overflow: hidden; - word-wrap: break-word; - height: 65px; - text-decoration: none; -} - -#indexalpha, #indexnumber{ - - -webkit-appearance: none; - background-color: rgba(255,255,255,0); - border-radius: 0px; - border: none; - color: #a3a3a3; - font-size: 16px; - font-family: Arial, Helvetica; - height: 30px; - margin: 0 0 0 10px; - padding:0; - float: right; -} - -.comboIndicator { - float: right; - padding: 14px 0 0 0; - margin: 0 0 0 4px; - width: 5px; -} \ No newline at end of file diff --git a/release/server/docroot/images/browse.png b/release/server/docroot/images/browse.png deleted file mode 100644 index 9043aa9d9858598d9af07bdc6c95e402680c6a0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^>>$j+1|*LJg}1oj85^_xT291H%W55|cF45{<>wj&+>(Tf?xN eErqjzftle=sQ{~F>Xc-l9tKZWKbLh*2~7Yv@h24k diff --git a/release/server/docroot/images/browse@2x.png b/release/server/docroot/images/browse@2x.png deleted file mode 100644 index 06d5f0580720bdc26a2e67ebe314626eabd6a77c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1G(Vi}jAr-fhPMkjdoBt4x3X>X}(LseP9ojq{+XPos+Ivc= z`_4MTv4oFdBlD)SE;l)@yy?g@R<tDnm{r-UW|^CCGT diff --git a/release/server/docroot/images/combo.png b/release/server/docroot/images/combo.png deleted file mode 100644 index 54edc9fafbde3c37c4dde5aeff80382e495eccbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1n!3HFw&5r&6Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JiljVU978H@B}MG1_*l=T!tngC#0#zf76v9B29|ujPR>k* QEkIQap00i_>zopr0NbA+CjbBd diff --git a/release/server/docroot/images/combo@2x.png b/release/server/docroot/images/combo@2x.png deleted file mode 100644 index 39e5c700937a7e8ec1599760de64dc3bcc4e412c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^AT}EZ8<70WD#W6a5s#(4CSmdKI;Vst0A>O+1ONa4 diff --git a/release/server/docroot/images/download.png b/release/server/docroot/images/download.png deleted file mode 100644 index 10b43d66be328c5f946556e772f54a078d35d982..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PI@$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1Gww^AIAr-fh5*(N+D=Ys`{OQ9}!N5A{#W#i9{Fh#KtYbJ; zp3+hz({QCurSiDvWHs3YmmuC?hG`6)j4Toi#?7LC94^ZQ01aaBboFyt=akR{0Kum( AbpQYW diff --git a/release/server/docroot/images/download@2x.png b/release/server/docroot/images/download@2x.png deleted file mode 100644 index 98c6ae38f9d448b10db872feb999e0a3a341bcac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^d_XL~!3HGNrubO_DajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MY*0Xjv*Ddk`fLue){z3U$cQ;r5c;j!4+;%87YlNuP*VN zEYW$9A^3cY%7*zIz6GW}0kioSHZt#x1XkcXcci*_{_;RZNpv4THu6{1-oD!M<1rbIJ diff --git a/release/server/docroot/images/f.png b/release/server/docroot/images/f.png deleted file mode 100644 index 32fb386772d76990a4c8c17858db498aa475f95f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 621 zcmeAS@N?(olHy`uVBq!ia0vp^0YF^A!3HE#-<5s?Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS=07?}7yT^vIyZoRp?(eIFhOvA@!1EU>NuZnNjtt0V>`2&N| zX`V#Zur0>telXZDWWH&tu4QuHWw{~yf3L5B+LG%*x8nB4Uz#wX>dC$s=YJ_KD8||I#gLI<{#=ua956cEaTu ztBzYAm$Be~;xelNXa@(-vTMPsSFrOnIp|J5f9m^RpT{@0tzCAxbCb?$J8gqHclB%= z#pDwa?(%0%?H^=)UG&%SSa6Dtq#xZ~<8foCRa%s=OK=2Z4X z&lbJ$_Fh=hnM-Uky>eUk_ZN2cs3u=iTOgCy_gQ8xOS&r1L|55Et$T$ghV%7(J~El( z{2>LPhdmqwfF6c83oQ&l!O{ehV=R2v5V=n)UM%wYgm3QZ_oh_-pK+l0?%TUd!xm)P nH$Kwroo@w?vK6!C8QB=RUbpTEy|;TCC>A|k{an^LB{Ts5f)NB~ diff --git a/release/server/docroot/images/f@2x.png b/release/server/docroot/images/f@2x.png deleted file mode 100644 index e388d804f336a4d6c0f783ecbfc194d5e13f826c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1262 zcmeAS@N?(olHy`uVBq!ia0vp^3xN0o2OE%Vcg(*9q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~;1FtAMUba4!+xb^1lMt_k=nFAjMHGOV0@p&Ek$9QLJwrfZB z>zgw*K3Z-4x*>L(Xl~=I>@6QNj!sy;;OmPV0q<>#7wn%cUv$#-p_7vF`?KesPxcAm zs@%Q*z1@MNBNKTZ-(>b`}!YApXR9F_ik>%qNY~9Bj(eVolmb`tEL_CVsH07 zOKa<39esPPs=aX+UzYS3J1<|p{OG@bbsM*StuCyw*_E?x|FeC}b=!ZJ?!KE;T)g;h<-Cg-~ z_rNQKY^Pk)($l-@_Q&7Z|KA%Jk8c`s1^2gn{_ybA&6oZwA8~)&n9RFz+LZkgDhH&F z_L)npNh|dTTBCaH$}x^;(FfP#o$s6}tIf_{f9{&b0YlN{#ZPN&V%Dt9RqxoUcEIBO zy9W;xewQAT(zl%L-{AZ0-`~EiTn2O1WT)L*)_gZwIN{X)Jjv%?%B#!z_YjF zWAwHA6OPfOgF8C)pz;*{4u=Dw|4-#)or#hz{N zh7C{MKe5gzyB--=S5o#c*nm(9!k)-jK%uPQKmrvZ)$8`|ug{V>uA3OHUpM!$6V^-* zOm9&C|M&F0dv%5qYi@B0zppWDo^ka5*;QVXP4C@%`>EvS3X{vmcgJ+ymv>AhWx7oR`=`SacFPvw`N&IYBkO0$Q1HP^GJ m*37>ni?vVy3L3=y6HH*(A!Ao{RJ*4Nq{`FP&t;ucLK6V+vM6`} diff --git a/release/server/docroot/images/imported.png b/release/server/docroot/images/imported.png deleted file mode 100644 index 1eaf45d4e2d320c021d077b173883b656a00a82d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^96-#*!3HG%vEKg;q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6*+jiIEGZ*N=i7u7+1k!-H_oXGl|n7%TB=BNO85>WS=QF zHhyDJ4k@ztU|7Ybwv!=`b&?)iiYJe|Vl*o=10x&5_h*t{U7hXufo3syy85}Sb4q9e E0R1m4egFUf diff --git a/release/server/docroot/images/imported@2x.png b/release/server/docroot/images/imported@2x.png deleted file mode 100644 index 41b9ad4e96532b047eac146c38c66e37dc9817ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~e!3HF=pW8M9DajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MHQYdjv*Ddk`fe{_k7?GV|c_SFnglRS%)lp0cnOpWo6b` z`V1SDl~re{maX}FfMse3U6Ni2|d@-Vg$+o0KU z>haYcq236dM1>`i%CZY24>@=kUu$78UBYl`ZiByZD1$=-BSXwAkG2i#7iR+9z~JfX K=d#Wzp$Pyl_d)dl diff --git a/release/server/docroot/images/indicator.png b/release/server/docroot/images/indicator.png deleted file mode 100644 index 138c77a84bb3339a5c1092bd83b6104481688dfc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 118 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1k!3HFMt$j8RNJ*BsMwA5SrbP0l+XkK8S^5> diff --git a/release/server/docroot/images/indicator@2x.png b/release/server/docroot/images/indicator@2x.png deleted file mode 100644 index 9f30e70415f7715ee848411d4ad9b6b5a82f3ee5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr+(8<0%e?(YqxBuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrH1%)p@!&hE&{2I&=E;?(+u@EMPdot>!yx%83SM1I9uHfqI5V zEDM(X+#zDr#Ib;hSz)Vu2W!F1GaShRL1#M799%v_@Ge(Om*hrEnb}EhG5cJ?&$M_e zUYNq|a7s|D#6mQQyI|28wfn{{to(tDejy@4Q#CpQS-9tYZ4qf?aA;s;2#WA!+@DuD Q9q1AUPgg&ebxsLQ0BK`La{vGU diff --git a/release/server/docroot/images/library.png b/release/server/docroot/images/library.png deleted file mode 100644 index 1a185057a328c0aa1c1dc75cd86edc7c57fd4449..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^d_XM3!3HF=W8NDADajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_c!wVp1HAr-ftOmgIFFyLU(e7N_E?uSI)z{yz+LAF-Q#Ujcs zZ#l?moIhc~s3=UPDKl(yc`FJ7UWr@xi3r@U9dp;?^CGY#a--2Ix*DcPSV;QVE x>$v=)BoWiD-3w0*^-~1kIcOQ#E#f}N(&!?EHl96Qx+=389HzTS%zdO zichKTL#W}7xO~clq>vGWX>BPj;t;Q;EY!9LPnrN(`krP!#09A4Lqho$mQU&K!{Kis z(Q$}YR+1g3gV%?o)*d4_(Tt|j(NsEWA@x!zxp6w0O6liAQcISh<3nn-zG3ZCbn^zz ihcxI#4URYj2rvMR$xk-q0jcBw0000{( zJaZG%Q-e|yQz{EjrrH1%X?wajhE&{2N?5?KW!tuY=?mB;wq{&eB$yzmd^bmClcQPI i!4<5BPcStwFf(Md8T7mf@@N5SWAJqKb6Mw<&;$UgGbzdd diff --git a/release/server/docroot/images/next@2x.png b/release/server/docroot/images/next@2x.png deleted file mode 100644 index ec4feb220534dfd6107e93a2b65fb7ef17ad94b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 339 zcmV-Z0j&OsP)MwIvpFaV2?%kdd*&=&vz002ovPDHLkV1i%%fOr4^ diff --git a/release/server/docroot/images/prev.png b/release/server/docroot/images/prev.png deleted file mode 100644 index 43e4805e3916fdecdebc1a9dc8fc3a31521c50b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^l0YoX!3HE#i{( zJaZG%Q-e|yQz{EjrrH1%*?77*hE&{2N>E^kijJ0T_+ihy_P`3(#bP~C3~W7HwlT0o zG~5vE_#Pe}ZhYyAS{2L96|RfLcoVxBn0Od&TlgCvd$uA8Xbyv?tDnm{r-UW|QRgn` diff --git a/release/server/docroot/images/prev@2x.png b/release/server/docroot/images/prev@2x.png deleted file mode 100644 index d505f4f51dff9bd246dd7948942d507848d9341e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 345 zcmV-f0jBYnD$VQWAX zL68vH5Hv&<1QC%8K}94%kP*=kbVL+{0dWXnLF_`95StJ-L=eJ=SV3433kWk}hOi?h zNDT-djpm&l@tF~km#H8cQ%RgOd(CcMT8?vR`5Ae95q_Txy3|_AJu)4?5;(cYX6E-p zB*!eTD8!icrI8d9zQz+`wjWkxnEj_N5$3q~K!S-Y2N7W63v}R^w2~<>CcTIaipgs$ r0AlhRJz$u!)*BGUmJWb|c?&QABjnXf3&W2300000NkvXXu0mjf*A#>Z diff --git a/release/server/docroot/images/read.png b/release/server/docroot/images/read.png deleted file mode 100644 index 9465a7d5f4727667be0605a7591744bf0dcc14c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)P!3HG%MVKuHQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JimW_c978H@C7n5a`uF(;7B$~lM>w76b4UMKbLh*2~7aVH!tk~ diff --git a/release/server/docroot/images/read@2x.png b/release/server/docroot/images/read@2x.png deleted file mode 100644 index 68ed871530b0ffc5740ec6f6336ab2690ad2dbec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^d_XM3!3HF=W8NDADajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_c!wVp1HAr-fh&YV8|`+S3Z3`5d!&&g`F4q_=u3Oqaw74{dH z7*ibGX7oA;OHNds5L3jsO7du0Qcj7>C7$gw7r3q9m6+AJQE+vdnA5C+mR*d2W=YIC w6?2YvoM%nBZLw;im{cUk5`kB@IRp|IN*0AX-jET)X7KQ01>=#%OA)*d*Z(j?D)T5veqeAlU2&)F(Psyp2K@$y sPXVO~wme6&j-)X#Yf4?@W#BMiDDE)I+JE*$8qh`tPgg&ebxsLQ0Ful_p#T5? diff --git a/release/server/docroot/images/readMark@2x.png b/release/server/docroot/images/readMark@2x.png deleted file mode 100644 index 1d9d0d3e3a3dab8d7259402b47f02d5172ec407e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^azJdx!3HERoY(vbq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6`k^QaSW-r_2$My&SnDv)(73fH+)}l+&v&@3tme#bd9y_{rM!qFj5E+OD_+S8&|VT6^}zU*3J!?nxxH n6qK4ADKy%4PbhI8s{}&@XA@`A!!uPtUom*P`njxgN@xNA$RK!! diff --git a/release/server/docroot/images/readingMark.png b/release/server/docroot/images/readingMark.png deleted file mode 100644 index e37f3c80cd812942ac988e20df154626baba7ae7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+t!3HE3PrP~@NJ*BsMwA5SrL11q z;e{rivmB*lBz+~s8Zu(o3?5#rU_8=zDT3GG`X7c!WgZ2|4-C`OCNMdd^k%S0I9*+s zv5#TvN9KJOT2EOY;$^rd@w_pjVTuORO7@q`90m+?jwnqyx_IMSpxq3fu6{1-oD!M< D)h9`8 diff --git a/release/server/docroot/images/readingMark@2x.png b/release/server/docroot/images/readingMark@2x.png deleted file mode 100644 index 589e2e9bf8474511263dd76023add1e2358d48e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^azJdx!3HERoY(vbq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6`k^QaSW-r_2$M~&K3h6wg)$QS;PyPr4LFU>^v7J^PtY6 zNqL9kdP^mb9h>E^z3SgCpk?|*QA}scru?>Q?DRqy2wTV(w^AtCwe m3XxTXbrn2&x2 diff --git a/release/server/docroot/images/up.png b/release/server/docroot/images/up.png deleted file mode 100644 index b039b35f6f26beee4034541f13a226488f7d603a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+s!3HG#4~4G+Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jid;Qi978H@B_$kSj*5={|9En`id%ANsi`vaMuugAbJe1h z?aTt}RE`|icAO%iC(POP_%rv;A{Whsqy-E;S#no>1Q=K(7;f2_>xnB$^Z^ZI@O1Ta JS?83{1OPAQFaiJo diff --git a/release/server/docroot/images/up@2x.png b/release/server/docroot/images/up@2x.png deleted file mode 100644 index d990ce0d8fb2cf6386608432f9a5e8cf48161078..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 271 zcmV+q0r38bP)ug1}Ww%}+*tvEbT3l1+-i^CJu;P6JT z;)p=6;D|!ca73d2a73fOaMW)t6g|L4^C9w1pEcI~=x!>)gb5QSOqeiX!twPLU;r+0 Vp{p>?rG@|i002ovPDHLkV1h>9Zu - - - - - Login - - -
- -

LOGIN

-

YACREADER LIBRARY

- -
- - -

If you have forgotten your login information, please reset it on the YACReaderLibrary

-
 
-
-
-
 
- - \ No newline at end of file diff --git a/release/server/templates/folder.tpl b/release/server/templates/folder.tpl deleted file mode 100644 index cb13a1648..000000000 --- a/release/server/templates/folder.tpl +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - Folder - - -
-
- -
-
{if pageIndex} {end pageIndex} up
- - -
- {if device.ipad} -

{folder.name}

- {end device.ipad} -
- -
- Libraries {library.name} {loop path} {path.name} {end path} -
-
- {if pageIndex} - - - {end pageIndex} - - {if alphaIndex} - - - {end alphaIndex} - -
-
- - -
-
    - {loop element} -
  • -
    - {element.cover.browse} {element.cover.browse.end} -
    -
    -

    {element.name}

    -
    -
    {element.pages} {element.size} -
    -
    {element.download} {element.read} {element.browse} -
    -
    - {element.status} -
  • - {end element} -
-
 
-
-
- - {if index} -
- {if alphaIndex} - -
- -
 
-
- - {end alphaIndex} - - - {if pageIndex} - -
- -
 
-
- {end pageIndex} -
- {end index} - - - - - diff --git a/release/server/templates/libraries.tpl b/release/server/templates/libraries.tpl deleted file mode 100644 index 0de6f4d95..000000000 --- a/release/server/templates/libraries.tpl +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - Libraries - - -
-

Libraries

-

-

    - {loop library} -
  • -
    - -
    -   -
     
    -
  • - {end library} -
-

-
- - From 4720705cf6b764fd45aec96fe5f0543e9242a7e4 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 27 Feb 2026 16:22:06 +0100 Subject: [PATCH 096/187] Remove useStyledTemplate --- YACReaderLibrary/themes/theme.h | 7 ------ YACReaderLibrary/themes/theme_factory.cpp | 29 +++++++---------------- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index 11dd94ad5..42017d81b 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -197,13 +197,6 @@ struct TreeViewThemeTemplates { "QTreeView::branch:has-children:selected:!has-siblings:closed,QTreeView::branch:closed:selected:has-children:has-siblings {border-image: none;image: url('%6');}" "QTreeView::branch:open:has-children:!has-siblings,QTreeView::branch:open:has-children:has-siblings {border-image: none;image: url('%7');}" "QTreeView::branch:open:has-children:selected:!has-siblings,QTreeView::branch:open:has-children:selected:has-siblings {border-image: none;image: url('%7');}"; - - // Native tree view template (uses system scroll bars) - for macOS - QString nativeTreeViewQSS = "QTreeView {background-color:transparent; border: none;}" - "QTreeView::item:selected {background-color:%1; border-top: 1px solid %1; border-left:none;border-right:none;border-bottom:1px solid %1;}" - "QTreeView::branch:selected {background-color:%1; border-top: 1px solid %1; border-left:none;border-right:none;border-bottom:1px solid %1;}" - "QTreeView::branch:open:selected:has-children {image: url(':/images/sidebar/expanded_branch_osx.png');}" - "QTreeView::branch:closed:selected:has-children {image: url(':/images/sidebar/collapsed_branch_osx.png');}"; }; struct TreeViewTheme { diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 75cb914a0..0d8aaa373 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -101,18 +101,12 @@ struct ImportWidgetParams { struct TreeViewParams { TreeViewThemeTemplates t; - bool useStyledTemplate; // true for non-macOS themes, false for macOS themes - // For styled template: %1=text, %2=selection bg, %3=scroll bg, %4=scroll handle, %5=selected text QColor textColor; QColor selectionBackgroundColor; QColor scrollBackgroundColor; QColor scrollHandleColor; QColor selectedTextColor; - - // For native (macOS) template: %1=selection color - QColor nativeSelectionColor; - QColor folderIndicatorColor; }; @@ -642,18 +636,14 @@ Theme makeTheme(const ThemeParams ¶ms) // TreeView (must come after SidebarIcons for branch icon paths) const auto &tv = params.treeViewParams; - if (tv.useStyledTemplate) { - theme.treeView.treeViewQSS = tv.t.styledTreeViewQSS - .arg(tv.textColor.name(), - tv.selectionBackgroundColor.name(), - tv.scrollBackgroundColor.name(), - tv.scrollHandleColor.name(), - tv.selectedTextColor.name(), - theme.sidebarIcons.branchClosedIconPath, - theme.sidebarIcons.branchOpenIconPath); - } else { - theme.treeView.treeViewQSS = tv.t.nativeTreeViewQSS.arg(tv.nativeSelectionColor.name()); - } + theme.treeView.treeViewQSS = tv.t.styledTreeViewQSS + .arg(tv.textColor.name(), + tv.selectionBackgroundColor.name(), + tv.scrollBackgroundColor.name(), + tv.scrollHandleColor.name(), + tv.selectedTextColor.name(), + theme.sidebarIcons.branchClosedIconPath, + theme.sidebarIcons.branchOpenIconPath); theme.treeView.folderIndicatorColor = tv.folderIndicatorColor; // end TreeView @@ -953,7 +943,6 @@ ThemeParams classicThemeParams() params.importWidgetParams = iw; TreeViewParams tv; - tv.useStyledTemplate = true; tv.textColor = QColor(0xDDDFDF); tv.selectionBackgroundColor = QColor(0x2E2E2E); tv.scrollBackgroundColor = QColor(0x404040); @@ -1205,7 +1194,6 @@ ThemeParams lightThemeParams() params.importWidgetParams = iw; TreeViewParams tv; - tv.useStyledTemplate = true; tv.textColor = Qt::black; tv.selectionBackgroundColor = QColor(0xD0D0D0); tv.scrollBackgroundColor = QColor(0xE0E0E0); @@ -1457,7 +1445,6 @@ ThemeParams darkThemeParams() params.importWidgetParams = iw; TreeViewParams tv; - tv.useStyledTemplate = true; tv.textColor = QColor(0xDDDFDF); tv.selectionBackgroundColor = QColor(0x2E2E2E); tv.scrollBackgroundColor = QColor(0x404040); From d71048b15275899b70974421c536d50f647eb2b0 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 27 Feb 2026 18:35:39 +0100 Subject: [PATCH 097/187] Fully customize the content views toolbar --- YACReaderLibrary/themes/theme.h | 7 +++---- YACReaderLibrary/themes/theme_factory.cpp | 13 ++++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index 42017d81b..f02f13b61 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -255,10 +255,9 @@ struct ContentSplitterThemeTemplates { }; struct ComicsViewToolbarThemeTemplates { - QString toolbarQSS = R"( - QToolBar { border: none; } - QToolButton:checked { background-color: %1; } - )"; + QString toolbarQSS = "QToolBar { border: none; background: %1; }\n" + "QToolBar::separator { background: %2; width: 1px; margin: 5px 4px; }\n" + "QToolButton:checked { background-color: %3; }\n"; }; struct SearchLineEditThemeTemplates { diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 0d8aaa373..80f2ee09b 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -213,6 +213,8 @@ struct LibraryItemParams { struct ComicsViewToolbarParams { ComicsViewToolbarThemeTemplates t; + QColor backgroundColor; + QColor separatorColor; QColor checkedBackgroundColor; QColor iconColor; // Main icon color (replaces #f0f) }; @@ -669,7 +671,10 @@ Theme makeTheme(const ThemeParams ¶ms) return icon; }; - theme.comicsViewToolbar.toolbarQSS = cvt.t.toolbarQSS.arg(cvt.checkedBackgroundColor.name()); + theme.comicsViewToolbar.toolbarQSS = cvt.t.toolbarQSS + .arg(cvt.backgroundColor.name()) + .arg(cvt.separatorColor.name()) + .arg(cvt.checkedBackgroundColor.name()); theme.comicsViewToolbar.openInYACReaderIcon = makeComicsViewIcon(":/images/comics_view_toolbar/openInYACReader.svg"); theme.comicsViewToolbar.setAsReadIcon = makeComicsViewIcon(":/images/comics_view_toolbar/setReadButton.svg"); theme.comicsViewToolbar.setAsUnreadIcon = makeComicsViewIcon(":/images/comics_view_toolbar/setUnread.svg"); @@ -1024,6 +1029,8 @@ ThemeParams classicThemeParams() params.libraryItemParams = li; ComicsViewToolbarParams cvt; + cvt.backgroundColor = QColor(0xF0F0F0); + cvt.separatorColor = QColor(0xCCCCCC); cvt.checkedBackgroundColor = QColor(0xCCCCCC); cvt.iconColor = QColor(0x404040); params.comicsViewToolbarParams = cvt; @@ -1275,6 +1282,8 @@ ThemeParams lightThemeParams() params.libraryItemParams = li; ComicsViewToolbarParams cvt; + cvt.backgroundColor = QColor(0xF0F0F0); + cvt.separatorColor = QColor(0xCCCCCC); cvt.checkedBackgroundColor = QColor(0xCCCCCC); cvt.iconColor = QColor(0x404040); params.comicsViewToolbarParams = cvt; @@ -1526,6 +1535,8 @@ ThemeParams darkThemeParams() params.libraryItemParams = li; ComicsViewToolbarParams cvt; + cvt.backgroundColor = QColor(0x2A2A2A); + cvt.separatorColor = QColor(0x444444); cvt.checkedBackgroundColor = QColor(0x555555); cvt.iconColor = QColor(0xDDDDDD); params.comicsViewToolbarParams = cvt; From b62ce07b15efadbe695bd7efe71638f592b26283 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 28 Feb 2026 09:13:20 +0100 Subject: [PATCH 098/187] Simplify the sidebar splitter theming --- YACReaderLibrary/themes/theme.h | 12 ++--------- YACReaderLibrary/themes/theme_factory.cpp | 25 ----------------------- 2 files changed, 2 insertions(+), 35 deletions(-) diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index f02f13b61..403394d8a 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -136,20 +136,12 @@ struct EmptyContainerTheme { QMap emptyLabelIcons; // Keyed by YACReader::LabelColors enum value }; -struct SidebarThemeTemplates { - // Non-macOS splitter template: %1 = background color, %2 = height - QString styledSplitterQSS = "QSplitter::handle { image: none; background-color: %1; }" - "QSplitter::handle:vertical { height: %2px;}"; - - // macOS splitter template: %1 = height, %2 = background color - QString nativeSplitterQSS = "QSplitter::handle:vertical { height: %1px; background-color: %2;}"; -}; - struct SidebarTheme { QColor backgroundColor; QColor separatorColor; QColor sectionSeparatorColor; // Horizontal separators between sidebar sections - QString splitterQSS; + QString splitterQSS = "QSplitter::handle { image: none; background-color: transparent; }" + "QSplitter::handle:vertical { height: 39px; }"; // When true, section title strings are uppercased after translation bool uppercaseLabels; diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 80f2ee09b..1da37a49c 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -64,17 +64,10 @@ struct EmptyContainerParams { }; struct SidebarParams { - SidebarThemeTemplates t; - bool useStyledSplitter; // true for non-macOS, false for macOS - QColor backgroundColor; QColor separatorColor; QColor sectionSeparatorColor; // Horizontal separators between sidebar sections - // Splitter parameters - QColor splitterBackgroundColor; - int splitterHeight; - bool uppercaseLabels; // Title bar colors @@ -420,15 +413,6 @@ Theme makeTheme(const ThemeParams ¶ms) theme.sidebar.backgroundColor = sb.backgroundColor; theme.sidebar.separatorColor = sb.separatorColor; theme.sidebar.sectionSeparatorColor = sb.sectionSeparatorColor; - if (sb.useStyledSplitter) { - theme.sidebar.splitterQSS = sb.t.styledSplitterQSS - .arg(sb.splitterBackgroundColor.name()) - .arg(sb.splitterHeight); - } else { - theme.sidebar.splitterQSS = sb.t.nativeSplitterQSS - .arg(sb.splitterHeight) - .arg(sb.splitterBackgroundColor.name()); - } theme.sidebar.uppercaseLabels = sb.uppercaseLabels; theme.sidebar.titleTextColor = sb.titleTextColor; theme.sidebar.titleDropShadowColor = sb.titleDropShadowColor; @@ -921,12 +905,9 @@ ThemeParams classicThemeParams() params.emptyContainerParams = ec; SidebarParams sb; - sb.useStyledSplitter = true; sb.backgroundColor = QColor(0x454545); sb.separatorColor = QColor(0xBDBFBF); sb.sectionSeparatorColor = QColor(0x575757); - sb.splitterBackgroundColor = QColor(0x454545); - sb.splitterHeight = 39; sb.uppercaseLabels = true; sb.titleTextColor = QColor(0xBDBFBF); sb.titleDropShadowColor = Qt::black; @@ -1174,12 +1155,9 @@ ThemeParams lightThemeParams() params.emptyContainerParams = ec; SidebarParams sb; - sb.useStyledSplitter = true; sb.backgroundColor = QColor(0xF1F1F1); sb.separatorColor = QColor(0x808080); sb.sectionSeparatorColor = QColor(0xD0D0D0); - sb.splitterBackgroundColor = QColor(0xF1F1F1); - sb.splitterHeight = 39; sb.uppercaseLabels = true; sb.titleTextColor = QColor(0x808080); sb.titleDropShadowColor = QColor(0xFFFFFF); @@ -1427,12 +1405,9 @@ ThemeParams darkThemeParams() params.emptyContainerParams = ec; SidebarParams sb; - sb.useStyledSplitter = true; sb.backgroundColor = QColor(0x454545); sb.separatorColor = QColor(0xBDBFBF); sb.sectionSeparatorColor = QColor(0x575757); - sb.splitterBackgroundColor = QColor(0x454545); - sb.splitterHeight = 39; sb.uppercaseLabels = true; sb.titleTextColor = QColor(0xBDBFBF); sb.titleDropShadowColor = Qt::black; From 61a0b590eddb61243f71c871e0ba3c8b1be289d0 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 28 Feb 2026 09:53:48 +0100 Subject: [PATCH 099/187] Add more parameters to control library item style --- YACReaderLibrary/themes/theme_factory.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 1da37a49c..989aaf8db 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -199,7 +199,9 @@ struct LibraryItemParams { QColor textColor; QColor selectedTextColor; QColor selectedBackgroundColor; - QColor libraryIconSelectedColor; // Color for the library icon when selected + QColor libraryIconColor; + QColor libraryIconShadowColor; + QColor libraryIconSelectedColor; QColor libraryOptionsIconColor; // Color for the options icon (shown only when selected) }; @@ -209,7 +211,7 @@ struct ComicsViewToolbarParams { QColor backgroundColor; QColor separatorColor; QColor checkedBackgroundColor; - QColor iconColor; // Main icon color (replaces #f0f) + QColor iconColor; }; struct SearchLineEditParams { @@ -586,8 +588,15 @@ Theme makeTheme(const ThemeParams ¶ms) theme.sidebarIcons.folderIcon = makeSidebarIcon(":/images/sidebar/folder.svg"); theme.sidebarIcons.folderFinishedIcon = makeSidebarIconWithExtra(":/images/sidebar/folder_finished.svg"); - // Library icon (unselected state uses sidebar colors) - theme.sidebarIcons.libraryIcon = makeSidebarIcon(":/images/sidebar/libraryIcon.svg"); + // Library icon (unselected state, two-color: #f0f main, #0ff shadow) + { + const auto &li = params.libraryItemParams; + const QString libraryIconPath = recoloredSvgToThemeFile(":/images/sidebar/libraryIcon.svg", li.libraryIconColor, li.libraryIconShadowColor, params.themeName); + QIcon icon; + icon.addFile(libraryIconPath, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(libraryIconPath, QSize(), QIcon::Selected, QIcon::Off); + theme.sidebarIcons.libraryIcon = icon; + } // Action icons theme.sidebarIcons.newLibraryIcon = makeSidebarIcon(":/images/sidebar/newLibraryIcon.svg"); @@ -1003,6 +1012,8 @@ ThemeParams classicThemeParams() LibraryItemParams li; li.textColor = QColor(0xDDDFDF); + li.libraryIconColor = QColor(0xDDDFDF); + li.libraryIconShadowColor = QColor(0xFF000000); li.selectedTextColor = Qt::white; li.selectedBackgroundColor = QColor(0x2E2E2E); li.libraryIconSelectedColor = Qt::white; @@ -1253,6 +1264,8 @@ ThemeParams lightThemeParams() LibraryItemParams li; li.textColor = QColor(0x404040); + li.libraryIconColor = QColor(0x404040); + li.libraryIconShadowColor = QColor(0xFFFFFF); li.selectedTextColor = QColor(0x1A1A1A); li.selectedBackgroundColor = QColor(0xD0D0D0); li.libraryIconSelectedColor = QColor(0x404040); @@ -1503,6 +1516,8 @@ ThemeParams darkThemeParams() LibraryItemParams li; li.textColor = QColor(0xDDDFDF); + li.libraryIconColor = QColor(0xDDDFDF); + li.libraryIconShadowColor = QColor(0xFF000000); li.selectedTextColor = Qt::white; li.selectedBackgroundColor = QColor(0x2E2E2E); li.libraryIconSelectedColor = Qt::white; From 7e7c6a979c472e86252259c8ea328624fb4d56f1 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 28 Feb 2026 18:20:13 +0100 Subject: [PATCH 100/187] Add TODO to document bug in recolorSvgXML --- common/themes/icon_utils.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/themes/icon_utils.cpp b/common/themes/icon_utils.cpp index f0ca5f9d6..680a78a86 100644 --- a/common/themes/icon_utils.cpp +++ b/common/themes/icon_utils.cpp @@ -66,6 +66,9 @@ QString recolorSvgXML(QString &svg, const QString &placeHolder, const QColor &color) { + // TODO: svg colors can work without ;, we need to update all the svg files to inlude ; + // Include the trailing ';' so e.g. "#ff0;" never accidentally matches + // inside a previously-substituted value like "#ff0000;". return svg.replace(placeHolder, color.name(QColor::HexRgb), Qt::CaseInsensitive); } From 2beb00c65f05474ff999aed53cce5c8e7e020634 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 28 Feb 2026 18:30:51 +0100 Subject: [PATCH 101/187] Add more custom colors to the side bar elements so we can theme selected items --- YACReaderLibrary/db/folder_model.cpp | 4 +- YACReaderLibrary/db/reading_list_item.cpp | 2 +- YACReaderLibrary/themes/theme.h | 23 +-- YACReaderLibrary/themes/theme_factory.cpp | 168 +++++++++++++----- YACReaderLibrary/yacreader_folders_view.cpp | 12 +- .../yacreader_reading_lists_view.cpp | 8 +- 6 files changed, 156 insertions(+), 61 deletions(-) diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index d659a19cd..8a71c9c2a 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -144,8 +144,8 @@ void FolderModel::applyTheme(const Theme &theme) folderIcon = QFileIconProvider().icon(QFileIconProvider::Folder); folderFinishedIcon = drawFinishedFolderIcon(sidebarIcons.folderReadOverlay); } else { - folderIcon = sidebarIcons.folderIcon; - folderFinishedIcon = sidebarIcons.folderFinishedIcon; + folderIcon = theme.treeView.folderIcon; + folderFinishedIcon = theme.treeView.folderFinishedIcon; } } diff --git a/YACReaderLibrary/db/reading_list_item.cpp b/YACReaderLibrary/db/reading_list_item.cpp index 98e3bf57f..e403f2edb 100644 --- a/YACReaderLibrary/db/reading_list_item.cpp +++ b/YACReaderLibrary/db/reading_list_item.cpp @@ -153,7 +153,7 @@ QIcon ReadingListItem::getIcon() const else if (theme.sidebarIcons.useSystemFolderIcons) return QFileIconProvider().icon(QFileIconProvider::Folder); else - return theme.sidebarIcons.folderIcon; // sublist + return theme.treeView.folderIcon; // sublist } int ReadingListItem::childCount() const diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index 403394d8a..a755d3869 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -186,14 +186,24 @@ struct TreeViewThemeTemplates { "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none; }" "QTreeView::branch:has-children:!has-siblings:closed,QTreeView::branch:closed:has-children:has-siblings {border-image: none;image: url('%6');}" - "QTreeView::branch:has-children:selected:!has-siblings:closed,QTreeView::branch:closed:selected:has-children:has-siblings {border-image: none;image: url('%6');}" + "QTreeView::branch:has-children:selected:!has-siblings:closed,QTreeView::branch:closed:selected:has-children:has-siblings {border-image: none;image: url('%8');}" "QTreeView::branch:open:has-children:!has-siblings,QTreeView::branch:open:has-children:has-siblings {border-image: none;image: url('%7');}" - "QTreeView::branch:open:has-children:selected:!has-siblings,QTreeView::branch:open:has-children:selected:has-siblings {border-image: none;image: url('%7');}"; + "QTreeView::branch:open:has-children:selected:!has-siblings,QTreeView::branch:open:has-children:selected:has-siblings {border-image: none;image: url('%9');}"; }; struct TreeViewTheme { QString treeViewQSS; QColor folderIndicatorColor; // For incomplete folders and recently updated folders + + // Branch indicator icon paths (used by QSS url()) + QString branchClosedIconPath; + QString branchOpenIconPath; + QString branchClosedIconSelectedPath; + QString branchOpenIconSelectedPath; + + // Folder icons (normal and selected states, including finished/read tick variant) + QIcon folderIcon; + QIcon folderFinishedIcon; }; // QML view theme colors (used by GridComicsView, FolderContentView, InfoComicsView) @@ -266,14 +276,10 @@ struct ContentSplitterTheme { struct SidebarIconsTheme { // When true, use QFileIconProvider for folder icons and overlay folderReadOverlay for finished folders - // When false, use the themed folderIcon and folderFinishedIcon SVGs + // When false, use the themed folderIcon and folderFinishedIcon from TreeViewTheme bool useSystemFolderIcons; QPixmap folderReadOverlay; // Tick overlay drawn on system folder icons when useSystemFolderIcons is true - // Folder icons (for FolderModel, ReadingListItem) - QIcon folderIcon; - QIcon folderFinishedIcon; - // Library icon (for YACReaderLibraryItemWidget - unselected state) QIcon libraryIcon; @@ -288,9 +294,6 @@ struct SidebarIconsTheme { QIcon addLabelIcon; QIcon renameListIcon; - // Branch icons (for TreeView QSS) - QString branchClosedIconPath; - QString branchOpenIconPath; }; struct LibraryItemTheme { diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 989aaf8db..1dc4c077f 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -101,6 +101,18 @@ struct TreeViewParams { QColor scrollHandleColor; QColor selectedTextColor; QColor folderIndicatorColor; + + // Branch indicator icon colors (independent of sidebarIcons.iconColor) + QColor branchIndicatorColor; + QColor branchIndicatorSelectedColor; + + // Folder icon colors (own parameters, independent of sidebarIcons) + QColor folderIconColor; // Main color for unselected folder (#f0f) + QColor folderIconShadowColor; // Shadow color for unselected folder (#0ff) + QColor folderIconSelectedColor; // Main color for selected folder (#f0f) + QColor folderIconSelectedShadowColor; // Shadow color for selected folder (#0ff) + QColor folderReadOverlayColor; // Tick/checkmark color for unselected folder (#ff0 in folder_finished, #f0f in folder_read_overlay.svg) + QColor folderReadOverlaySelectedColor; // Tick/checkmark color for selected folder }; struct TableViewParams { @@ -179,11 +191,9 @@ struct SidebarIconsParams { // Icon colors - #f0f placeholder gets replaced with these QColor iconColor; // Main icon color (replaces #f0f) QColor shadowColor; // Shadow color (replaces #0ff) - QColor extraColor; // Extra info like ticks (replaces #ff0) // When true, use QFileIconProvider for folder icons and overlay a tick for finished folders bool useSystemFolderIcons; - QColor folderReadOverlayColor; // Color for the tick overlay (replaces #f0f in folder_read_overlay.svg) }; struct ServerConfigDialogThemeTemplates { @@ -225,18 +235,27 @@ struct SearchLineEditParams { struct ReadingListIconsParams { QMap labelColors; // Label colors by name (e.g., "red" -> #f67a7b) QColor labelShadowColor; // Shadow color for labels (replaces #0ff) + QColor labelShadowSelectedColor; // Shadow color for labels when selected/hovered // Special list icon colors QColor readingListMainColor; // default_0 main color (replaces #f0f) + QColor readingListMainSelectedColor; // default_0 main color when selected/hovered QColor favoritesMainColor; // default_1 main color (replaces #f0f) + QColor favoritesMainSelectedColor; // default_1 main color when selected/hovered QColor currentlyReadingMainColor; // default_2 main color (replaces #f0f) + QColor currentlyReadingMainSelectedColor; // default_2 main color when selected/hovered QColor currentlyReadingOuterColor; // default_2 outer circle (replaces #ff0) + QColor currentlyReadingOuterSelectedColor; // default_2 outer circle when selected/hovered QColor specialListShadowColor; // Shadow color for special lists (replaces #0ff) + QColor specialListShadowSelectedColor; // Shadow color for special lists when selected/hovered // List icon colors QColor listMainColor; // main color (replaces #f0f) + QColor listMainSelectedColor; // main color when selected/hovered QColor listShadowColor; // shadow color (replaces #0ff) + QColor listShadowSelectedColor; // shadow color when selected/hovered QColor listDetailColor; // detail/checkbox color (replaces #ff0) + QColor listDetailSelectedColor; // detail/checkbox color when selected/hovered }; struct DialogIconsParams { @@ -559,15 +578,6 @@ Theme makeTheme(const ThemeParams ¶ms) return icon; }; - // Helper for icons with extra color (three-color: #f0f main, #0ff shadow, #ff0 extra) - auto makeSidebarIconWithExtra = [&](const QString &basePath) { - const QString path = recoloredSvgToThemeFile(basePath, si.iconColor, si.shadowColor, si.extraColor, params.themeName); - QIcon icon; - icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); - icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); - return icon; - }; - // Helper for single-color icons (only #f0f main) auto makeSingleColorIcon = [&](const QString &basePath) { const QString path = recoloredSvgToThemeFile(basePath, si.iconColor, params.themeName); @@ -580,14 +590,10 @@ Theme makeTheme(const ThemeParams ¶ms) // System folder icons flag and overlay theme.sidebarIcons.useSystemFolderIcons = si.useSystemFolderIcons; if (si.useSystemFolderIcons) { - const QString overlayPath = recoloredSvgToThemeFile(":/images/sidebar/folder_read_overlay.svg", si.folderReadOverlayColor, params.themeName); + const QString overlayPath = recoloredSvgToThemeFile(":/images/sidebar/folder_read_overlay.svg", params.treeViewParams.folderReadOverlayColor, params.themeName); theme.sidebarIcons.folderReadOverlay = QPixmap(overlayPath); } - // Folder icons - theme.sidebarIcons.folderIcon = makeSidebarIcon(":/images/sidebar/folder.svg"); - theme.sidebarIcons.folderFinishedIcon = makeSidebarIconWithExtra(":/images/sidebar/folder_finished.svg"); - // Library icon (unselected state, two-color: #f0f main, #0ff shadow) { const auto &li = params.libraryItemParams; @@ -609,9 +615,6 @@ Theme makeTheme(const ThemeParams ¶ms) theme.sidebarIcons.addLabelIcon = makeSidebarIcon(":/images/sidebar/addLabelIcon.svg"); theme.sidebarIcons.renameListIcon = makeSidebarIcon(":/images/sidebar/renameListIcon.svg"); - // Branch icons (paths for QSS) - theme.sidebarIcons.branchClosedIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-closed.svg", si.iconColor, params.themeName); - theme.sidebarIcons.branchOpenIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", si.iconColor, params.themeName); // end SidebarIcons // LibraryItem @@ -629,17 +632,42 @@ Theme makeTheme(const ThemeParams ¶ms) theme.libraryItem.libraryOptionsIcon = QIcon(libraryOptionsPath); // end LibraryItem - // TreeView (must come after SidebarIcons for branch icon paths) + // TreeView const auto &tv = params.treeViewParams; + + // Branch indicator icons — own colors, independent of the sidebar icon color + theme.treeView.branchClosedIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-closed.svg", tv.branchIndicatorColor, params.themeName); + theme.treeView.branchOpenIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", tv.branchIndicatorColor, params.themeName); + theme.treeView.branchClosedIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/branch-closed.svg", tv.branchIndicatorSelectedColor, params.themeName, { .suffix = "_selected" }); + theme.treeView.branchOpenIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", tv.branchIndicatorSelectedColor, params.themeName, { .suffix = "_selected" }); + theme.treeView.treeViewQSS = tv.t.styledTreeViewQSS .arg(tv.textColor.name(), tv.selectionBackgroundColor.name(), tv.scrollBackgroundColor.name(), tv.scrollHandleColor.name(), tv.selectedTextColor.name(), - theme.sidebarIcons.branchClosedIconPath, - theme.sidebarIcons.branchOpenIconPath); + theme.treeView.branchClosedIconPath, + theme.treeView.branchOpenIconPath, + theme.treeView.branchClosedIconSelectedPath, + theme.treeView.branchOpenIconSelectedPath); theme.treeView.folderIndicatorColor = tv.folderIndicatorColor; + + // Folder icon — normal and selected states with independent colors + { + const QString normalPath = recoloredSvgToThemeFile(":/images/sidebar/folder.svg", tv.folderIconColor, tv.folderIconShadowColor, params.themeName); + const QString selectedPath = recoloredSvgToThemeFile(":/images/sidebar/folder.svg", tv.folderIconSelectedColor, tv.folderIconSelectedShadowColor, params.themeName, { .suffix = "_selected" }); + theme.treeView.folderIcon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); + theme.treeView.folderIcon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); + } + + // Folder finished icon — same but with tick (#ff0) recolored independently for each state + { + const QString normalPath = recoloredSvgToThemeFile(":/images/sidebar/folder_finished.svg", tv.folderIconColor, tv.folderIconShadowColor, tv.folderReadOverlayColor, params.themeName); + const QString selectedPath = recoloredSvgToThemeFile(":/images/sidebar/folder_finished.svg", tv.folderIconSelectedColor, tv.folderIconSelectedShadowColor, tv.folderReadOverlaySelectedColor, params.themeName, { .suffix = "_selected" }); + theme.treeView.folderFinishedIcon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); + theme.treeView.folderFinishedIcon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); + } // end TreeView // ContentSplitter @@ -664,10 +692,10 @@ Theme makeTheme(const ThemeParams ¶ms) return icon; }; - theme.comicsViewToolbar.toolbarQSS = cvt.t.toolbarQSS - .arg(cvt.backgroundColor.name()) - .arg(cvt.separatorColor.name()) - .arg(cvt.checkedBackgroundColor.name()); + theme.comicsViewToolbar.toolbarQSS = cvt.t.toolbarQSS.arg( + cvt.backgroundColor.name(), + cvt.separatorColor.name(), + cvt.checkedBackgroundColor.name()); theme.comicsViewToolbar.openInYACReaderIcon = makeComicsViewIcon(":/images/comics_view_toolbar/openInYACReader.svg"); theme.comicsViewToolbar.setAsReadIcon = makeComicsViewIcon(":/images/comics_view_toolbar/setReadButton.svg"); theme.comicsViewToolbar.setAsUnreadIcon = makeComicsViewIcon(":/images/comics_view_toolbar/setUnread.svg"); @@ -705,10 +733,11 @@ Theme makeTheme(const ThemeParams ¶ms) // Helper to create label icons from template (uses color name to generate label_.svg files) auto makeLabelIcon = [&](const QString &colorName, const QColor &mainColor) { - const QString path = recoloredSvgToThemeFile(":/images/lists/label_template.svg", mainColor, rli.labelShadowColor, params.themeName, { .fileName = "label_" + colorName }); + const QString normalPath = recoloredSvgToThemeFile(":/images/lists/label_template.svg", mainColor, rli.labelShadowColor, params.themeName, { .fileName = "label_" + colorName }); + const QString selectedPath = recoloredSvgToThemeFile(":/images/lists/label_template.svg", mainColor, rli.labelShadowSelectedColor, params.themeName, { .suffix = "_selected", .fileName = "label_" + colorName }); QIcon icon; - icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); - icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); return icon; }; @@ -717,32 +746,35 @@ Theme makeTheme(const ThemeParams ¶ms) } // Special list icons - auto makeSpecialIcon = [&](const QString &basePath, const QColor &mainColor) { - const QString path = recoloredSvgToThemeFile(basePath, mainColor, rli.specialListShadowColor, params.themeName); + auto makeSpecialIcon = [&](const QString &basePath, const QColor &mainColor, const QColor &mainSelectedColor) { + const QString normalPath = recoloredSvgToThemeFile(basePath, mainColor, rli.specialListShadowColor, params.themeName); + const QString selectedPath = recoloredSvgToThemeFile(basePath, mainSelectedColor, rli.specialListShadowSelectedColor, params.themeName, { .suffix = "_selected" }); QIcon icon; - icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); - icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); return icon; }; - theme.readingListIcons.readingListIcon = makeSpecialIcon(":/images/lists/default_0.svg", rli.readingListMainColor); - theme.readingListIcons.favoritesIcon = makeSpecialIcon(":/images/lists/default_1.svg", rli.favoritesMainColor); + theme.readingListIcons.readingListIcon = makeSpecialIcon(":/images/lists/default_0.svg", rli.readingListMainColor, rli.readingListMainSelectedColor); + theme.readingListIcons.favoritesIcon = makeSpecialIcon(":/images/lists/default_1.svg", rli.favoritesMainColor, rli.favoritesMainSelectedColor); // Currently reading has 3 colors { - const QString path = recoloredSvgToThemeFile(":/images/lists/default_2.svg", rli.currentlyReadingMainColor, rli.specialListShadowColor, rli.currentlyReadingOuterColor, params.themeName); + const QString normalPath = recoloredSvgToThemeFile(":/images/lists/default_2.svg", rli.currentlyReadingMainColor, rli.specialListShadowColor, rli.currentlyReadingOuterColor, params.themeName); + const QString selectedPath = recoloredSvgToThemeFile(":/images/lists/default_2.svg", rli.currentlyReadingMainSelectedColor, rli.specialListShadowSelectedColor, rli.currentlyReadingOuterSelectedColor, params.themeName, { .suffix = "_selected" }); QIcon icon; - icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); - icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); theme.readingListIcons.currentlyReadingIcon = icon; } // List icon (3 colors) { - const QString path = recoloredSvgToThemeFile(":/images/lists/list.svg", rli.listMainColor, rli.listShadowColor, rli.listDetailColor, params.themeName); + const QString normalPath = recoloredSvgToThemeFile(":/images/lists/list.svg", rli.listMainColor, rli.listShadowColor, rli.listDetailColor, params.themeName); + const QString selectedPath = recoloredSvgToThemeFile(":/images/lists/list.svg", rli.listMainSelectedColor, rli.listShadowSelectedColor, rli.listDetailSelectedColor, params.themeName, { .suffix = "_selected" }); QIcon icon; - icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); - icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); + icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); theme.readingListIcons.listIcon = icon; } // end ReadingListIcons @@ -944,6 +976,14 @@ ThemeParams classicThemeParams() tv.scrollHandleColor = QColor(0xDDDDDD); tv.selectedTextColor = Qt::white; tv.folderIndicatorColor = QColor(237, 197, 24); + tv.branchIndicatorColor = QColor(0xE0E0E0); + tv.branchIndicatorSelectedColor = QColor(0xFFFFFF); + tv.folderIconColor = QColor(0xE0E0E0); + tv.folderIconShadowColor = QColor(0xFF000000); + tv.folderIconSelectedColor = QColor(0xE0E0E0); + tv.folderIconSelectedShadowColor = QColor(0xFF000000); + tv.folderReadOverlayColor = QColor(0x464646); + tv.folderReadOverlaySelectedColor = QColor(0x464646); params.treeViewParams = tv; TableViewParams tav; @@ -1006,7 +1046,6 @@ ThemeParams classicThemeParams() SidebarIconsParams si; si.iconColor = QColor(0xE0E0E0); si.shadowColor = QColor(0xFF000000); - si.extraColor = QColor(0x464646); si.useSystemFolderIcons = false; params.sidebarIconsParams = si; @@ -1049,14 +1088,23 @@ ThemeParams classicThemeParams() { "dark", QColor(0xb7b7b7) } }; rli.labelShadowColor = Qt::black; + rli.labelShadowSelectedColor = Qt::black; rli.readingListMainColor = QColor(0xe7e7e7); + rli.readingListMainSelectedColor = QColor(0xe7e7e7); rli.favoritesMainColor = QColor(0xe15055); + rli.favoritesMainSelectedColor = QColor(0xe15055); rli.currentlyReadingMainColor = QColor(0xffcc00); + rli.currentlyReadingMainSelectedColor = QColor(0xffcc00); rli.currentlyReadingOuterColor = Qt::black; + rli.currentlyReadingOuterSelectedColor = Qt::black; rli.specialListShadowColor = Qt::black; + rli.specialListShadowSelectedColor = Qt::black; rli.listMainColor = QColor(0xe7e7e7); + rli.listMainSelectedColor = QColor(0xe7e7e7); rli.listShadowColor = Qt::black; + rli.listShadowSelectedColor = Qt::black; rli.listDetailColor = QColor(0x464646); + rli.listDetailSelectedColor = QColor(0x464646); params.readingListIconsParams = rli; MenuIconsParams mi; @@ -1196,6 +1244,14 @@ ThemeParams lightThemeParams() tv.scrollHandleColor = QColor(0x888888); tv.selectedTextColor = QColor(0x1A1A1A); tv.folderIndicatorColor = QColor(85, 95, 127); + tv.branchIndicatorColor = QColor(0x606060); + tv.branchIndicatorSelectedColor = QColor(0x1A1A1A); + tv.folderIconColor = QColor(0x606060); + tv.folderIconShadowColor = QColor(0xFFFFFF); + tv.folderIconSelectedColor = QColor(0x606060); + tv.folderIconSelectedShadowColor = QColor(0xFFFFFF); + tv.folderReadOverlayColor = QColor(0xFFFFFF); + tv.folderReadOverlaySelectedColor = QColor(0xFFFFFF); params.treeViewParams = tv; TableViewParams tav; @@ -1258,7 +1314,6 @@ ThemeParams lightThemeParams() SidebarIconsParams si; si.iconColor = QColor(0x606060); si.shadowColor = QColor(0xFFFFFF); - si.extraColor = QColor(0xFFFFFF); si.useSystemFolderIcons = false; params.sidebarIconsParams = si; @@ -1301,14 +1356,23 @@ ThemeParams lightThemeParams() { "dark", QColor(0xb7b7b7) } }; rli.labelShadowColor = QColor(0xa0a0a0); + rli.labelShadowSelectedColor = QColor(0xa0a0a0); rli.readingListMainColor = QColor(0x808080); + rli.readingListMainSelectedColor = QColor(0x808080); rli.favoritesMainColor = QColor(0xe15055); + rli.favoritesMainSelectedColor = QColor(0xe15055); rli.currentlyReadingMainColor = QColor(0xffcc00); + rli.currentlyReadingMainSelectedColor = QColor(0xffcc00); rli.currentlyReadingOuterColor = Qt::black; + rli.currentlyReadingOuterSelectedColor = Qt::black; rli.specialListShadowColor = QColor(0xa0a0a0); + rli.specialListShadowSelectedColor = QColor(0xa0a0a0); rli.listMainColor = QColor(0x808080); + rli.listMainSelectedColor = QColor(0x808080); rli.listShadowColor = QColor(0xc0c0c0); + rli.listShadowSelectedColor = QColor(0xc0c0c0); rli.listDetailColor = QColor(0xFFFFFF); + rli.listDetailSelectedColor = QColor(0xFFFFFF); params.readingListIconsParams = rli; MenuIconsParams mi; @@ -1448,6 +1512,14 @@ ThemeParams darkThemeParams() tv.scrollHandleColor = QColor(0xDDDDDD); tv.selectedTextColor = Qt::white; tv.folderIndicatorColor = QColor(237, 197, 24); + tv.branchIndicatorColor = QColor(0xE0E0E0); + tv.branchIndicatorSelectedColor = QColor(0xFFFFFF); + tv.folderIconColor = QColor(0xE0E0E0); + tv.folderIconShadowColor = QColor(0xFF000000); + tv.folderIconSelectedColor = QColor(0xE0E0E0); + tv.folderIconSelectedShadowColor = QColor(0xFF000000); + tv.folderReadOverlayColor = QColor(0x222222); + tv.folderReadOverlaySelectedColor = QColor(0x222222); params.treeViewParams = tv; TableViewParams tav; @@ -1510,7 +1582,6 @@ ThemeParams darkThemeParams() SidebarIconsParams si; si.iconColor = QColor(0xE0E0E0); si.shadowColor = QColor(0xFF000000); - si.extraColor = QColor(0x222222); si.useSystemFolderIcons = false; params.sidebarIconsParams = si; @@ -1553,14 +1624,23 @@ ThemeParams darkThemeParams() { "dark", QColor(0xb7b7b7) } }; rli.labelShadowColor = Qt::black; + rli.labelShadowSelectedColor = Qt::black; rli.readingListMainColor = QColor(0xe7e7e7); + rli.readingListMainSelectedColor = QColor(0xe7e7e7); rli.favoritesMainColor = QColor(0xe15055); + rli.favoritesMainSelectedColor = QColor(0xe15055); rli.currentlyReadingMainColor = QColor(0xffcc00); + rli.currentlyReadingMainSelectedColor = QColor(0xffcc00); rli.currentlyReadingOuterColor = Qt::black; + rli.currentlyReadingOuterSelectedColor = Qt::black; rli.specialListShadowColor = Qt::black; + rli.specialListShadowSelectedColor = Qt::black; rli.listMainColor = QColor(0xe7e7e7); + rli.listMainSelectedColor = QColor(0xe7e7e7); rli.listShadowColor = Qt::black; + rli.listShadowSelectedColor = Qt::black; rli.listDetailColor = QColor(0x464646); + rli.listDetailSelectedColor = QColor(0x464646); params.readingListIconsParams = rli; MenuIconsParams mi; diff --git a/YACReaderLibrary/yacreader_folders_view.cpp b/YACReaderLibrary/yacreader_folders_view.cpp index 57f6f5b84..ce116bf69 100644 --- a/YACReaderLibrary/yacreader_folders_view.cpp +++ b/YACReaderLibrary/yacreader_folders_view.cpp @@ -81,6 +81,12 @@ YACReaderFoldersViewItemDeletegate::YACReaderFoldersViewItemDeletegate(QObject * void YACReaderFoldersViewItemDeletegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { + // Promote hover to selected so QIcon::Selected mode activates on mouse-over, + // matching the QSS which already uses the same background for hover and selected. + QStyleOptionViewItem opt = option; + if (opt.state & QStyle::State_MouseOver) + opt.state |= QStyle::State_Selected; + // Get indicator color from parent tree view QColor indicatorColor(237, 197, 24); // Default fallback if (auto treeView = qobject_cast(parent())) { @@ -91,11 +97,11 @@ void YACReaderFoldersViewItemDeletegate::paint(QPainter *painter, const QStyleOp painter->save(); painter->setBrush(QBrush(indicatorColor)); painter->setPen(QPen(QBrush(), 0)); - painter->drawRect(0, option.rect.y(), 2, option.rect.height()); + painter->drawRect(0, opt.rect.y(), 2, opt.rect.height()); painter->restore(); } - QStyledItemDelegate::paint(painter, option, index); + QStyledItemDelegate::paint(painter, opt, index); auto showRecent = index.data(FolderModel::ShowRecentRole).toBool(); @@ -110,7 +116,7 @@ void YACReaderFoldersViewItemDeletegate::paint(QPainter *painter, const QStyleOp painter->setRenderHint(QPainter::Antialiasing); painter->setBrush(QBrush(indicatorColor)); painter->setPen(QPen(QBrush(), 0)); - painter->drawEllipse(option.rect.x() + 13, option.rect.y() + 2, 7, 7); + painter->drawEllipse(opt.rect.x() + 13, opt.rect.y() + 2, 7, 7); painter->restore(); } } diff --git a/YACReaderLibrary/yacreader_reading_lists_view.cpp b/YACReaderLibrary/yacreader_reading_lists_view.cpp index 6d3d3b401..62b4aea28 100644 --- a/YACReaderLibrary/yacreader_reading_lists_view.cpp +++ b/YACReaderLibrary/yacreader_reading_lists_view.cpp @@ -50,7 +50,13 @@ void YACReaderReadingListsViewItemDeletegate::paint(QPainter *painter, const QSt return; } - QStyledItemDelegate::paint(painter, option, index); + // Promote hover to selected so QIcon::Selected mode activates on mouse-over, + // matching the QSS which already uses the same background for hover and selected. + QStyleOptionViewItem opt = option; + if (opt.state & QStyle::State_MouseOver) + opt.state |= QStyle::State_Selected; + + QStyledItemDelegate::paint(painter, opt, index); } QSize YACReaderReadingListsViewItemDeletegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const From e10e6dcc88884d2f3faf647cd240ff803af58e79 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 28 Feb 2026 19:05:42 +0100 Subject: [PATCH 102/187] Rename comics table view header parameters --- YACReaderLibrary/themes/theme_factory.cpp | 30 +++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 1dc4c077f..383b54851 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -120,9 +120,9 @@ struct TableViewParams { QColor alternateBackgroundColor; QColor backgroundColor; - QColor cornerButtonBackgroundColor; - QColor cornerButtonBorderColor; - QColor cornerButtonGradientColor; + QColor headerBackgroundColor; + QColor headerBorderColor; + QColor headerGradientColor; QColor itemBorderBottomColor; QColor itemBorderTopColor; QColor itemTextColor; @@ -469,9 +469,9 @@ Theme makeTheme(const ThemeParams ¶ms) theme.tableView.tableViewQSS = tavt.tableViewQSS .arg(tav.alternateBackgroundColor.name(), tav.backgroundColor.name(), - tav.cornerButtonBackgroundColor.name(), - tav.cornerButtonBorderColor.name(), - tav.cornerButtonGradientColor.name(), + tav.headerBackgroundColor.name(), + tav.headerBorderColor.name(), + tav.headerGradientColor.name(), tav.itemBorderBottomColor.name(), tav.itemBorderTopColor.name(), tav.itemTextColor.name(), @@ -989,9 +989,9 @@ ThemeParams classicThemeParams() TableViewParams tav; tav.alternateBackgroundColor = QColor(0xF2F2F2); tav.backgroundColor = QColor(0xFAFAFA); - tav.cornerButtonBackgroundColor = QColor(0xF5F5F5); - tav.cornerButtonBorderColor = QColor(0xB8BDC4); - tav.cornerButtonGradientColor = QColor(0xD1D1D1); + tav.headerBackgroundColor = QColor(0xF5F5F5); + tav.headerBorderColor = QColor(0xB8BDC4); + tav.headerGradientColor = QColor(0xD1D1D1); tav.itemBorderBottomColor = QColor(0xDFDFDF); tav.itemBorderTopColor = QColor(0xFEFEFE); tav.itemTextColor = QColor(0x252626); @@ -1257,9 +1257,9 @@ ThemeParams lightThemeParams() TableViewParams tav; tav.alternateBackgroundColor = QColor(0xF2F2F2); tav.backgroundColor = QColor(0xFAFAFA); - tav.cornerButtonBackgroundColor = QColor(0xF5F5F5); - tav.cornerButtonBorderColor = QColor(0xB8BDC4); - tav.cornerButtonGradientColor = QColor(0xD1D1D1); + tav.headerBackgroundColor = QColor(0xF5F5F5); + tav.headerBorderColor = QColor(0xB8BDC4); + tav.headerGradientColor = QColor(0xD1D1D1); tav.itemBorderBottomColor = QColor(0xDFDFDF); tav.itemBorderTopColor = QColor(0xFEFEFE); tav.itemTextColor = QColor(0x252626); @@ -1525,9 +1525,9 @@ ThemeParams darkThemeParams() TableViewParams tav; tav.alternateBackgroundColor = QColor(0x2E2E2E); tav.backgroundColor = QColor(0x2A2A2A); - tav.cornerButtonBackgroundColor = QColor(0x2A2A2A); - tav.cornerButtonBorderColor = QColor(0x1F1F1F); - tav.cornerButtonGradientColor = QColor(0x252525); + tav.headerBackgroundColor = QColor(0x2A2A2A); + tav.headerBorderColor = QColor(0x1F1F1F); + tav.headerGradientColor = QColor(0x252525); tav.itemBorderBottomColor = QColor(0x1F1F1F); tav.itemBorderTopColor = QColor(0x353535); tav.itemTextColor = QColor(0xDDDDDD); From 368b3bd35e56092fe43c3922627e8a7e9cfc414f Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 28 Feb 2026 20:27:44 +0100 Subject: [PATCH 103/187] Add control over comics table view item top/bottom borders size --- YACReaderLibrary/themes/theme.h | 5 ++--- YACReaderLibrary/themes/theme_factory.cpp | 12 +++++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index a755d3869..f5824c391 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -99,8 +99,8 @@ struct ComicFlowColors { struct TableViewThemeTemplates { QString tableViewQSS = "QTableView {alternate-background-color: %1; background-color: %2; outline: 0px; border: none;}" "QTableCornerButton::section {background-color:%3; border:none; border-bottom:1px solid %4; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %5, stop: 1 %4);}" - "QTableView::item {outline: 0px; border-bottom: 1px solid %6; border-top: 1px solid %7; padding-bottom:1px; color:%8;}" - "QTableView::item:selected {outline: 0px; border-bottom: 1px solid %9; border-top: 1px solid %9; padding-bottom:1px; background-color: %9; color: %10; }" + "QTableView::item {outline: 0px; border-bottom: %12px solid %6; border-top: %13px solid %7; padding-bottom:1px; color:%8;}" + "QTableView::item:selected {outline: 0px; border-bottom: %12px solid %9; border-top: %13px solid %9; padding-bottom:1px; background-color: %9; color: %10; }" "QHeaderView::section:horizontal {background-color:%3; border-bottom:1px solid %4; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %5, stop: 1 %4); border-left:none; border-top:none; padding:4px; color:%11;}" "QHeaderView::section:vertical {border-bottom: 1px solid %6; border-top: 1px solid %7;}"; }; @@ -293,7 +293,6 @@ struct SidebarIconsTheme { QIcon colapseIcon; QIcon addLabelIcon; QIcon renameListIcon; - }; struct LibraryItemTheme { diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 383b54851..30ca4e3f1 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -125,6 +125,8 @@ struct TableViewParams { QColor headerGradientColor; QColor itemBorderBottomColor; QColor itemBorderTopColor; + int itemBorderBottomWidth; // px + int itemBorderTopWidth; // px QColor itemTextColor; QColor selectedColor; QColor selectedTextColor; @@ -477,7 +479,9 @@ Theme makeTheme(const ThemeParams ¶ms) tav.itemTextColor.name(), tav.selectedColor.name(), tav.selectedTextColor.name(), - tav.headerTextColor.name()); + tav.headerTextColor.name(), + QString::number(tav.itemBorderBottomWidth), + QString::number(tav.itemBorderTopWidth)); theme.tableView.starRatingColor = tav.starRatingColor; theme.tableView.starRatingSelectedColor = tav.starRatingSelectedColor; // end TableView @@ -994,6 +998,8 @@ ThemeParams classicThemeParams() tav.headerGradientColor = QColor(0xD1D1D1); tav.itemBorderBottomColor = QColor(0xDFDFDF); tav.itemBorderTopColor = QColor(0xFEFEFE); + tav.itemBorderBottomWidth = 1; + tav.itemBorderTopWidth = 1; tav.itemTextColor = QColor(0x252626); tav.selectedColor = QColor(0xD4D4D4); tav.selectedTextColor = QColor(0x252626); @@ -1262,6 +1268,8 @@ ThemeParams lightThemeParams() tav.headerGradientColor = QColor(0xD1D1D1); tav.itemBorderBottomColor = QColor(0xDFDFDF); tav.itemBorderTopColor = QColor(0xFEFEFE); + tav.itemBorderBottomWidth = 1; + tav.itemBorderTopWidth = 1; tav.itemTextColor = QColor(0x252626); tav.selectedColor = QColor(0x3875D7); tav.selectedTextColor = QColor(0xFFFFFF); @@ -1530,6 +1538,8 @@ ThemeParams darkThemeParams() tav.headerGradientColor = QColor(0x252525); tav.itemBorderBottomColor = QColor(0x1F1F1F); tav.itemBorderTopColor = QColor(0x353535); + tav.itemBorderBottomWidth = 1; + tav.itemBorderTopWidth = 1; tav.itemTextColor = QColor(0xDDDDDD); tav.selectedColor = QColor(0x555555); tav.selectedTextColor = QColor(0xFFFFFF); From 6466739fd75e96b9fb06fb44f2627814dc73010c Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 28 Feb 2026 20:29:00 +0100 Subject: [PATCH 104/187] Add a explicit parameter to control the top gradient value in the comic vine table header --- YACReaderLibrary/themes/theme.h | 2 +- YACReaderLibrary/themes/theme_factory.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index f5824c391..55771d833 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -63,7 +63,7 @@ struct ComicVineThemeTemplates { QString scraperTableViewQSS = "QTableView {color:%1; border:0px;alternate-background-color: %2;background-color: %3; outline: 0px;}" "QTableView::item {outline: 0px; border: 0px; color:%1;}" "QTableView::item:selected {outline: 0px; background-color: %4; }" - "QHeaderView::section:horizontal {background-color:%5; border-bottom:1px solid %6; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %5, stop: 1 %6); border-left:none; border-top:none; padding:4px; color:%7;}" + "QHeaderView::section:horizontal {background-color:%5; border-bottom:1px solid %6; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %14, stop: 1 %6); border-left:none; border-top:none; padding:4px; color:%7;}" "QHeaderView::section:vertical {border-bottom: 1px solid %8;border-top: 1px solid %9;}" "QHeaderView::down-arrow {image: url('%12');width: 8px;height: 7px;padding-right: 10px;}" "QHeaderView::up-arrow {image: url('%13');width: 8px;height: 7px; padding-right: 10px;}" diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 30ca4e3f1..6696cdfa7 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -18,6 +18,7 @@ struct ComicVineParams { QColor tableBorderColor; QColor tableSelectedColor; QColor tableHeaderBackgroundColor; + QColor tableHeaderGradientColor; QColor tableHeaderBorderColor; QColor tableHeaderTextColor; QColor tableScrollHandleColor; @@ -370,7 +371,8 @@ Theme makeTheme(const ThemeParams ¶ms) cv.tableScrollHandleColor.name(), cv.tableScrollBackgroundColor.name(), recolor(":/images/comic_vine/downArrow.svg", cv.downArrowColor), - recolor(":/images/comic_vine/upArrow.svg", cv.upArrowColor)); + recolor(":/images/comic_vine/upArrow.svg", cv.upArrowColor), + cv.tableHeaderGradientColor.name()); theme.comicVine.dialogQSS = t.dialogQSS.arg(cv.dialogBackgroundColor.name()); theme.comicVine.dialogButtonsQSS = t.dialogButtonsQSS.arg(cv.buttonBorderColor.name(), cv.buttonBackgroundColor.name(), cv.buttonTextColor.name()); @@ -891,6 +893,7 @@ ThemeParams classicThemeParams() cv.tableBorderColor = QColor(0x242424); cv.tableSelectedColor = QColor(0x555555); cv.tableHeaderBackgroundColor = QColor(0x292929); + cv.tableHeaderGradientColor = QColor(0x292929); cv.tableHeaderBorderColor = QColor(0x1F1F1F); cv.tableHeaderTextColor = QColor(0xEBEBEB); cv.tableScrollHandleColor = QColor(0xDDDDDD); @@ -1161,6 +1164,7 @@ ThemeParams lightThemeParams() cv.tableBorderColor = QColor(0xCCCCCC); cv.tableSelectedColor = QColor(0xDDDDDD); cv.tableHeaderBackgroundColor = QColor(0xE0E0E0); + cv.tableHeaderGradientColor = QColor(0xE0E0E0); cv.tableHeaderBorderColor = QColor(0xC0C0C0); cv.tableHeaderTextColor = QColor(0x333333); cv.tableScrollHandleColor = QColor(0x888888); @@ -1431,6 +1435,7 @@ ThemeParams darkThemeParams() cv.tableBorderColor = QColor(0x242424); cv.tableSelectedColor = QColor(0x555555); cv.tableHeaderBackgroundColor = QColor(0x292929); + cv.tableHeaderGradientColor = QColor(0x292929); cv.tableHeaderBorderColor = QColor(0x1F1F1F); cv.tableHeaderTextColor = QColor(0xEBEBEB); cv.tableScrollHandleColor = QColor(0xDDDDDD); From 66c9047be4377ba7a5bae07120df2819098d9e17 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 1 Mar 2026 14:13:51 +0100 Subject: [PATCH 105/187] Update some of the light theme values --- YACReaderLibrary/themes/theme_factory.cpp | 74 +++++++++++------------ 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 6696cdfa7..99009d759 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -1150,8 +1150,8 @@ ThemeParams lightThemeParams() params.defaultContentBackgroundColor = QColor(0xFFFFFF); ComicFlowColors cf; - cf.backgroundColor = Qt::white; - cf.textColor = Qt::black; + cf.backgroundColor = QColor(0xDCDCDC); + cf.textColor = QColor(0x303030); ComicVineParams cv; cv.contentTextColor = Qt::black; @@ -1224,11 +1224,11 @@ ThemeParams lightThemeParams() params.emptyContainerParams = ec; SidebarParams sb; - sb.backgroundColor = QColor(0xF1F1F1); + sb.backgroundColor = QColor(0xFBFBFB); sb.separatorColor = QColor(0x808080); - sb.sectionSeparatorColor = QColor(0xD0D0D0); + sb.sectionSeparatorColor = QColor(0xE0E0E0); sb.uppercaseLabels = true; - sb.titleTextColor = QColor(0x808080); + sb.titleTextColor = QColor(0x4A494A); sb.titleDropShadowColor = QColor(0xFFFFFF); sb.busyIndicatorColor = QColor(0x808080); params.sidebarParams = sb; @@ -1249,19 +1249,19 @@ ThemeParams lightThemeParams() TreeViewParams tv; tv.textColor = Qt::black; - tv.selectionBackgroundColor = QColor(0xD0D0D0); + tv.selectionBackgroundColor = QColor(0x333133); tv.scrollBackgroundColor = QColor(0xE0E0E0); tv.scrollHandleColor = QColor(0x888888); - tv.selectedTextColor = QColor(0x1A1A1A); + tv.selectedTextColor = QColor(0xFFFFFF); tv.folderIndicatorColor = QColor(85, 95, 127); tv.branchIndicatorColor = QColor(0x606060); - tv.branchIndicatorSelectedColor = QColor(0x1A1A1A); + tv.branchIndicatorSelectedColor = QColor(0xFFFFFF); tv.folderIconColor = QColor(0x606060); tv.folderIconShadowColor = QColor(0xFFFFFF); - tv.folderIconSelectedColor = QColor(0x606060); - tv.folderIconSelectedShadowColor = QColor(0xFFFFFF); + tv.folderIconSelectedColor = QColor(0xFFFFFF); + tv.folderIconSelectedShadowColor = QColor(0x161616); tv.folderReadOverlayColor = QColor(0xFFFFFF); - tv.folderReadOverlaySelectedColor = QColor(0xFFFFFF); + tv.folderReadOverlaySelectedColor = QColor(0x161616); params.treeViewParams = tv; TableViewParams tav; @@ -1269,13 +1269,13 @@ ThemeParams lightThemeParams() tav.backgroundColor = QColor(0xFAFAFA); tav.headerBackgroundColor = QColor(0xF5F5F5); tav.headerBorderColor = QColor(0xB8BDC4); - tav.headerGradientColor = QColor(0xD1D1D1); + tav.headerGradientColor = QColor(0xF5F5F5); tav.itemBorderBottomColor = QColor(0xDFDFDF); tav.itemBorderTopColor = QColor(0xFEFEFE); - tav.itemBorderBottomWidth = 1; - tav.itemBorderTopWidth = 1; + tav.itemBorderBottomWidth = 0; + tav.itemBorderTopWidth = 0; tav.itemTextColor = QColor(0x252626); - tav.selectedColor = QColor(0x3875D7); + tav.selectedColor = QColor(0x595959); tav.selectedTextColor = QColor(0xFFFFFF); tav.headerTextColor = QColor(0x313232); tav.starRatingColor = QColor(0xE9BE0F); @@ -1311,32 +1311,32 @@ ThemeParams lightThemeParams() MainToolbarParams mt; mt.backgroundColor = QColor(0xF0F0F0); - mt.folderNameColor = QColor(0x404040); + mt.folderNameColor = QColor(0x333133); mt.dividerColor = QColor(0xB8BDC4); - mt.iconColor = QColor(0x404040); + mt.iconColor = QColor(0x333133); mt.iconDisabledColor = QColor(0xB0B0B0); params.mainToolbarParams = mt; ContentSplitterParams cs; - cs.handleColor = QColor(0xB8B8B8); + cs.handleColor = QColor(0xF0F0F0); cs.horizontalHandleHeight = 4; cs.verticalHandleWidth = 4; params.contentSplitterParams = cs; SidebarIconsParams si; - si.iconColor = QColor(0x606060); - si.shadowColor = QColor(0xFFFFFF); + si.iconColor = QColor(0x4F4E4F); + si.shadowColor = QColor(0xFBFBFB); si.useSystemFolderIcons = false; params.sidebarIconsParams = si; LibraryItemParams li; - li.textColor = QColor(0x404040); - li.libraryIconColor = QColor(0x404040); + li.textColor = Qt::black; + li.libraryIconColor = QColor(0x606060); li.libraryIconShadowColor = QColor(0xFFFFFF); - li.selectedTextColor = QColor(0x1A1A1A); - li.selectedBackgroundColor = QColor(0xD0D0D0); - li.libraryIconSelectedColor = QColor(0x404040); - li.libraryOptionsIconColor = QColor(0x404040); + li.selectedTextColor = QColor(0xFFFFFF); + li.selectedBackgroundColor = QColor(0x333133); + li.libraryIconSelectedColor = QColor(0xFFFFFF); + li.libraryOptionsIconColor = QColor(0xFFFFFF); params.libraryItemParams = li; ComicsViewToolbarParams cvt; @@ -1347,9 +1347,9 @@ ThemeParams lightThemeParams() params.comicsViewToolbarParams = cvt; SearchLineEditParams sle; - sle.textColor = QColor(0x606060); - sle.backgroundColor = QColor(0xE0E0E0); - sle.iconColor = QColor(0x808080); + sle.textColor = QColor(0xFFFFFF); + sle.backgroundColor = QColor(0x333133); + sle.iconColor = QColor(0xEFEFEF); params.searchLineEditParams = sle; ReadingListIconsParams rli; @@ -1367,8 +1367,8 @@ ThemeParams lightThemeParams() { "light", QColor(0xcbcbcb) }, { "dark", QColor(0xb7b7b7) } }; - rli.labelShadowColor = QColor(0xa0a0a0); - rli.labelShadowSelectedColor = QColor(0xa0a0a0); + rli.labelShadowColor = QColor(0x8F8F8F); + rli.labelShadowSelectedColor = QColor(0x161616); rli.readingListMainColor = QColor(0x808080); rli.readingListMainSelectedColor = QColor(0x808080); rli.favoritesMainColor = QColor(0xe15055); @@ -1377,14 +1377,14 @@ ThemeParams lightThemeParams() rli.currentlyReadingMainSelectedColor = QColor(0xffcc00); rli.currentlyReadingOuterColor = Qt::black; rli.currentlyReadingOuterSelectedColor = Qt::black; - rli.specialListShadowColor = QColor(0xa0a0a0); - rli.specialListShadowSelectedColor = QColor(0xa0a0a0); + rli.specialListShadowColor = QColor(0x8F8F8F); + rli.specialListShadowSelectedColor = QColor(0x161616); rli.listMainColor = QColor(0x808080); - rli.listMainSelectedColor = QColor(0x808080); - rli.listShadowColor = QColor(0xc0c0c0); - rli.listShadowSelectedColor = QColor(0xc0c0c0); + rli.listMainSelectedColor = QColor(0xFFFFFF); + rli.listShadowColor = QColor(0x8F8F8F); + rli.listShadowSelectedColor = QColor(0x161616); rli.listDetailColor = QColor(0xFFFFFF); - rli.listDetailSelectedColor = QColor(0xFFFFFF); + rli.listDetailSelectedColor = QColor(0x161616); params.readingListIconsParams = rli; MenuIconsParams mi; From 52e43192c4b9acae7df0374356d52990acfb6261 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 1 Mar 2026 15:17:45 +0100 Subject: [PATCH 106/187] Fix blur background setting FastBlur -> MultiEffect broke it. --- YACReaderLibrary/qml/FlowView.qml | 2 +- YACReaderLibrary/qml/GridComicsView.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/YACReaderLibrary/qml/FlowView.qml b/YACReaderLibrary/qml/FlowView.qml index 9ece421a2..b27961583 100644 --- a/YACReaderLibrary/qml/FlowView.qml +++ b/YACReaderLibrary/qml/FlowView.qml @@ -48,7 +48,7 @@ Rectangle { source: backgroundImg blurEnabled: true blur: 1.0 - blurMax: 64 + blurMax: Math.max(2, mainFlowContainer.backgroundBlurRadius) opacity: backgroundBlurOpacity visible: backgroundBlurVisible } diff --git a/YACReaderLibrary/qml/GridComicsView.qml b/YACReaderLibrary/qml/GridComicsView.qml index 1c5edc01b..95ef165ac 100644 --- a/YACReaderLibrary/qml/GridComicsView.qml +++ b/YACReaderLibrary/qml/GridComicsView.qml @@ -43,7 +43,7 @@ SplitView { source: backgroundImg blurEnabled: true blur: 1.0 - blurMax: 64 + blurMax: Math.max(2, backgroundBlurRadius) opacity: backgroundBlurOpacity visible: backgroundBlurVisible } From 87fada611d7da01166e3312fed1cc34128107640 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 1 Mar 2026 15:22:54 +0100 Subject: [PATCH 107/187] Make the blur backgroud color overlay themable This also fixes the hardcoded color in FlowView.qml --- YACReaderLibrary/grid_comics_view.cpp | 2 ++ YACReaderLibrary/info_comics_view.cpp | 1 + YACReaderLibrary/qml/FlowView.qml | 2 +- YACReaderLibrary/themes/theme.h | 3 +++ YACReaderLibrary/themes/theme_factory.cpp | 7 +++++++ 5 files changed, 14 insertions(+), 1 deletion(-) diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index 262fb1ccc..39b67f017 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -220,6 +220,7 @@ void GridComicsView::updateBackgroundConfig() // Use theme colors for cell and selected colors const auto &qv = theme.qmlView; + ctxt->setContextProperty("backgroundColor", useBackgroundImage ? qv.backgroundBlurOverlayColor : qv.backgroundColor); ctxt->setContextProperty("cellColor", useBackgroundImage ? qv.cellColorWithBackground : qv.cellColor); ctxt->setContextProperty("selectedColor", qv.selectedColor); } @@ -491,6 +492,7 @@ void GridComicsView::applyTheme(const Theme &theme) // Grid colors ctxt->setContextProperty("backgroundColor", qv.backgroundColor); + ctxt->setContextProperty("backgroundBlurOverlayColor", qv.backgroundBlurOverlayColor); ctxt->setContextProperty("cellColor", qv.cellColor); ctxt->setContextProperty("selectedColor", qv.selectedColor); ctxt->setContextProperty("selectedBorderColor", qv.selectedBorderColor); diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp index ce442f1f9..a93aeb16c 100644 --- a/YACReaderLibrary/info_comics_view.cpp +++ b/YACReaderLibrary/info_comics_view.cpp @@ -243,4 +243,5 @@ void InfoComicsView::applyTheme(const Theme &theme) ctxt->setContextProperty("readTickCheckedColor", qv.readTickCheckedColor); ctxt->setContextProperty("showDropShadow", QVariant(qv.showDropShadow)); + ctxt->setContextProperty("backgroundBlurOverlayColor", qv.backgroundBlurOverlayColor); } diff --git a/YACReaderLibrary/qml/FlowView.qml b/YACReaderLibrary/qml/FlowView.qml index b27961583..6ebc35a76 100644 --- a/YACReaderLibrary/qml/FlowView.qml +++ b/YACReaderLibrary/qml/FlowView.qml @@ -25,7 +25,7 @@ Rectangle { Rectangle { id: background - color: "#2A2A2A" + color: backgroundBlurOverlayColor anchors.fill: backgroundImg } diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index 55771d833..0d98c0adc 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -241,6 +241,9 @@ struct QmlViewTheme { // Continue reading section (FolderContentView) QColor continueReadingBackgroundColor; QColor continueReadingColor; + + // Blur overlay background (FlowView always, GridView when background image enabled) + QColor backgroundBlurOverlayColor; }; struct MainToolbarThemeTemplates { diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 99009d759..b9e103e2c 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -170,6 +170,9 @@ struct QmlViewParams { // Continue reading section (FolderContentView) QColor continueReadingBackgroundColor; QColor continueReadingColor; + + // Blur overlay background (FlowView always, GridView when background image enabled) + QColor backgroundBlurOverlayColor; }; struct MainToolbarParams { @@ -514,6 +517,7 @@ Theme makeTheme(const ThemeParams ¶ms) theme.qmlView.currentComicBackgroundColor = qv.currentComicBackgroundColor; theme.qmlView.continueReadingBackgroundColor = qv.continueReadingBackgroundColor; theme.qmlView.continueReadingColor = qv.continueReadingColor; + theme.qmlView.backgroundBlurOverlayColor = qv.backgroundBlurOverlayColor; // end QmlView // MainToolbar @@ -1036,6 +1040,7 @@ ThemeParams classicThemeParams() qv.currentComicBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); qv.continueReadingBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); qv.continueReadingColor = QColor(0xFFFFFF); + qv.backgroundBlurOverlayColor = QColor(0x2A2A2A); params.qmlViewParams = qv; MainToolbarParams mt; @@ -1307,6 +1312,7 @@ ThemeParams lightThemeParams() qv.currentComicBackgroundColor = QColor(0xFF, 0xFF, 0xFF, 0x88); qv.continueReadingBackgroundColor = QColor(0xE8E8E8); qv.continueReadingColor = QColor::fromRgb(0x000000); + qv.backgroundBlurOverlayColor = QColor(0x9E9E9E); params.qmlViewParams = qv; MainToolbarParams mt; @@ -1578,6 +1584,7 @@ ThemeParams darkThemeParams() qv.currentComicBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); qv.continueReadingBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); qv.continueReadingColor = QColor(0xFFFFFF); + qv.backgroundBlurOverlayColor = QColor(0x2A2A2A); params.qmlViewParams = qv; MainToolbarParams mt; From 547e48cc049e677dc30bda6e11ff527673344a06 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 2 Mar 2026 21:23:39 +0100 Subject: [PATCH 108/187] Use json file based themes instead of code to create them (theme editor + theme mode settings) --- YACReader/CMakeLists.txt | 4 + YACReader/main.cpp | 9 +- YACReader/options_dialog.cpp | 14 + YACReader/options_dialog.h | 2 + YACReader/render.cpp | 2 +- YACReader/themes/builtin_classic.json | 51 + YACReader/themes/builtin_dark.json | 51 + YACReader/themes/builtin_light.json | 51 + YACReader/themes/theme.h | 5 + YACReader/themes/theme_factory.cpp | 299 ++-- YACReader/themes/theme_factory.h | 5 +- YACReader/themes/themes.qrc | 7 + YACReaderLibrary/CMakeLists.txt | 4 + YACReaderLibrary/info_comics_view.cpp | 14 +- YACReaderLibrary/main.cpp | 8 +- YACReaderLibrary/options_dialog.cpp | 17 + YACReaderLibrary/options_dialog.h | 1 + YACReaderLibrary/themes/builtin_classic.json | 238 ++++ YACReaderLibrary/themes/builtin_dark.json | 238 ++++ YACReaderLibrary/themes/builtin_light.json | 238 ++++ YACReaderLibrary/themes/theme.h | 5 + YACReaderLibrary/themes/theme_factory.cpp | 1248 +++++------------ YACReaderLibrary/themes/theme_factory.h | 5 +- YACReaderLibrary/themes/themes.qrc | 7 + common/CMakeLists.txt | 12 +- common/themes/appearance_config_images.qrc | 7 + common/themes/appearance_configuration.cpp | 96 ++ common/themes/appearance_configuration.h | 48 + common/themes/appearance_tab_widget.cpp | 98 ++ common/themes/appearance_tab_widget.h | 29 + common/themes/theme_editor_dialog.cpp | 477 +++++++ common/themes/theme_editor_dialog.h | 63 + common/themes/theme_id.h | 10 - common/themes/theme_manager.cpp | 109 +- common/themes/theme_manager.h | 20 +- common/themes/theme_meta.h | 14 + common/themes/theme_repository.cpp | 206 +++ common/themes/theme_repository.h | 57 + common/themes/theme_variant.h | 9 + images/appearance_config/theme-mode-dark.svg | 29 + images/appearance_config/theme-mode-light.svg | 29 + .../appearance_config/theme-mode-system.svg | 55 + 42 files changed, 2761 insertions(+), 1130 deletions(-) create mode 100644 YACReader/themes/builtin_classic.json create mode 100644 YACReader/themes/builtin_dark.json create mode 100644 YACReader/themes/builtin_light.json create mode 100644 YACReader/themes/themes.qrc create mode 100644 YACReaderLibrary/themes/builtin_classic.json create mode 100644 YACReaderLibrary/themes/builtin_dark.json create mode 100644 YACReaderLibrary/themes/builtin_light.json create mode 100644 YACReaderLibrary/themes/themes.qrc create mode 100644 common/themes/appearance_config_images.qrc create mode 100644 common/themes/appearance_configuration.cpp create mode 100644 common/themes/appearance_configuration.h create mode 100644 common/themes/appearance_tab_widget.cpp create mode 100644 common/themes/appearance_tab_widget.h create mode 100644 common/themes/theme_editor_dialog.cpp create mode 100644 common/themes/theme_editor_dialog.h delete mode 100644 common/themes/theme_id.h create mode 100644 common/themes/theme_meta.h create mode 100644 common/themes/theme_repository.cpp create mode 100644 common/themes/theme_repository.h create mode 100644 common/themes/theme_variant.h create mode 100644 images/appearance_config/theme-mode-dark.svg create mode 100644 images/appearance_config/theme-mode-light.svg create mode 100644 images/appearance_config/theme-mode-system.svg diff --git a/YACReader/CMakeLists.txt b/YACReader/CMakeLists.txt index 51c55b615..62cf58643 100644 --- a/YACReader/CMakeLists.txt +++ b/YACReader/CMakeLists.txt @@ -56,9 +56,13 @@ target_compile_definitions(YACReader PRIVATE YACREADER) # Resources qt_add_resources(yacreader_images_rcc "${CMAKE_CURRENT_SOURCE_DIR}/yacreader_images.qrc") qt_add_resources(yacreader_files_rcc "${CMAKE_CURRENT_SOURCE_DIR}/yacreader_files.qrc") +qt_add_resources(yacreader_themes_rcc "${CMAKE_CURRENT_SOURCE_DIR}/themes/themes.qrc") +qt_add_resources(yacreader_common_images_rcc "${CMAKE_SOURCE_DIR}/common/themes/appearance_config_images.qrc") target_sources(YACReader PRIVATE ${yacreader_images_rcc} ${yacreader_files_rcc} + ${yacreader_themes_rcc} + ${yacreader_common_images_rcc} ) # Translations diff --git a/YACReader/main.cpp b/YACReader/main.cpp index e71f6791b..d1c98e224 100644 --- a/YACReader/main.cpp +++ b/YACReader/main.cpp @@ -7,7 +7,10 @@ #include "main_window_viewer.h" #include "configuration.h" #include "exit_check.h" +#include "appearance_configuration.h" #include "theme_manager.h" +#include "theme_repository.h" +#include "yacreader_global.h" #include "QsLog.h" #include "QsLogDest.h" @@ -114,7 +117,11 @@ int main(int argc, char *argv[]) app.setApplicationName("YACReader"); app.setOrganizationName("YACReader"); - ThemeManager::instance().initialize(); + auto *appearanceConfig = new AppearanceConfiguration( + YACReader::getSettingsPath() + "/YACReader.ini", qApp); + auto *themeRepo = new ThemeRepository( + ":/themes", YACReader::getSettingsPath() + "/themes/user"); + ThemeManager::instance().initialize(appearanceConfig, themeRepo); if (QIcon::hasThemeIcon("YACReader")) { app.setWindowIcon(QIcon::fromTheme("YACReader")); diff --git a/YACReader/options_dialog.cpp b/YACReader/options_dialog.cpp index 4df071c36..c39e71155 100644 --- a/YACReader/options_dialog.cpp +++ b/YACReader/options_dialog.cpp @@ -12,7 +12,10 @@ #include #include #include +#include #include "theme_manager.h" +#include "theme_factory.h" +#include "appearance_tab_widget.h" #include "yacreader_spin_slider_widget.h" #include "yacreader_3d_flow_config_widget.h" @@ -203,9 +206,20 @@ OptionsDialog::OptionsDialog(QWidget *parent) pageFlow->setLayout(layoutFlow); pageImage->setLayout(layoutImageV); + // APPEARANCE ---------------------------------------- + + auto *pageAppearance = new AppearanceTabWidget( + ThemeManager::instance().getAppearanceConfiguration(), + []() { return ThemeManager::instance().getCurrentTheme().sourceJson; }, + [](const QJsonObject &json) { ThemeManager::instance().setTheme(makeTheme(json)); }, + this); + + // APPEARANCE END ------------------------------------ + tabWidget->addTab(pageGeneral, tr("General")); tabWidget->addTab(pageFlow, tr("Page Flow")); tabWidget->addTab(pageImage, tr("Image adjustment")); + tabWidget->addTab(pageAppearance, tr("Appearance")); layout->addWidget(tabWidget); diff --git a/YACReader/options_dialog.h b/YACReader/options_dialog.h index 7c2ef6cc9..20467f773 100644 --- a/YACReader/options_dialog.h +++ b/YACReader/options_dialog.h @@ -4,6 +4,8 @@ #include "yacreader_options_dialog.h" #include "themable.h" +#include + class QDialog; class QLabel; class QLineEdit; diff --git a/YACReader/render.cpp b/YACReader/render.cpp index 595df27c4..59996fea4 100644 --- a/YACReader/render.cpp +++ b/YACReader/render.cpp @@ -1000,7 +1000,7 @@ void Render::fillBuffer() pageRenders[currentPageBufferedIndex + i]->start(); } - if ((currentIndex - i > 0) && + if ((currentIndex - i >= 0) && buffer[currentPageBufferedIndex - i]->isNull() && i <= numLeftPages && pageRenders[currentPageBufferedIndex - i] == 0 && diff --git a/YACReader/themes/builtin_classic.json b/YACReader/themes/builtin_classic.json new file mode 100644 index 000000000..74dff6b4a --- /dev/null +++ b/YACReader/themes/builtin_classic.json @@ -0,0 +1,51 @@ +{ + "meta": { + "id": "builtin/classic", + "displayName": "Default Classic", + "variant": "dark" + }, + "toolbar": { + "iconColor": "#404040", + "iconDisabledColor": "#858585", + "iconCheckedColor": "#5a5a5a", + "backgroundColor": "#f3f3f3", + "separatorColor": "#cccccc", + "checkedButtonColor": "#cccccc", + "menuIndicatorColor": "#404040" + }, + "viewer": { + "defaultBackgroundColor": "#282828", + "defaultTextColor": "#ffffff", + "infoBackgroundColor": "#bb000000", + "infoTextColor": "#ffffff" + }, + "goToFlowWidget": { + "flowBackgroundColor": "#282828", + "flowTextColor": "#ffffff", + "toolbarBackgroundColor": "#99000000", + "sliderBorderColor": "#22ffffff", + "sliderGrooveColor": "#77000000", + "sliderHandleColor": "#55ffffff", + "editBorderColor": "#77000000", + "editBackgroundColor": "#55000000", + "editTextColor": "#ffffff", + "labelTextColor": "#ffffff", + "iconColor": "#ffffff" + }, + "helpAboutDialog": { + "headingColor": "#302f2d", + "linkColor": "#c19441" + }, + "whatsNewDialog": { + "backgroundColor": "#ffffff", + "headerTextColor": "#0a0a0a", + "versionTextColor": "#858585", + "contentTextColor": "#0a0a0a", + "linkColor": "#e8b800", + "closeButtonColor": "#444444", + "headerDecorationColor": "#e8b800" + }, + "shortcutsIcons": { + "iconColor": "#404040" + } +} diff --git a/YACReader/themes/builtin_dark.json b/YACReader/themes/builtin_dark.json new file mode 100644 index 000000000..01085ca9c --- /dev/null +++ b/YACReader/themes/builtin_dark.json @@ -0,0 +1,51 @@ +{ + "meta": { + "id": "builtin/dark", + "displayName": "Default Dark", + "variant": "dark" + }, + "toolbar": { + "iconColor": "#cccccc", + "iconDisabledColor": "#444444", + "iconCheckedColor": "#dadada", + "backgroundColor": "#202020", + "separatorColor": "#444444", + "checkedButtonColor": "#3a3a3a", + "menuIndicatorColor": "#cccccc" + }, + "viewer": { + "defaultBackgroundColor": "#282828", + "defaultTextColor": "#ffffff", + "infoBackgroundColor": "#bb000000", + "infoTextColor": "#b0b0b0" + }, + "goToFlowWidget": { + "flowBackgroundColor": "#282828", + "flowTextColor": "#ffffff", + "toolbarBackgroundColor": "#99000000", + "sliderBorderColor": "#22ffffff", + "sliderGrooveColor": "#77000000", + "sliderHandleColor": "#55ffffff", + "editBorderColor": "#77000000", + "editBackgroundColor": "#55000000", + "editTextColor": "#ffffff", + "labelTextColor": "#ffffff", + "iconColor": "#cccccc" + }, + "helpAboutDialog": { + "headingColor": "#e0e0e0", + "linkColor": "#d4a84b" + }, + "whatsNewDialog": { + "backgroundColor": "#2a2a2a", + "headerTextColor": "#e0e0e0", + "versionTextColor": "#858585", + "contentTextColor": "#e0e0e0", + "linkColor": "#e8b800", + "closeButtonColor": "#dddddd", + "headerDecorationColor": "#e8b800" + }, + "shortcutsIcons": { + "iconColor": "#d0d0d0" + } +} diff --git a/YACReader/themes/builtin_light.json b/YACReader/themes/builtin_light.json new file mode 100644 index 000000000..979057911 --- /dev/null +++ b/YACReader/themes/builtin_light.json @@ -0,0 +1,51 @@ +{ + "meta": { + "id": "builtin/light", + "displayName": "Default Light", + "variant": "light" + }, + "toolbar": { + "iconColor": "#404040", + "iconDisabledColor": "#b0b0b0", + "iconCheckedColor": "#5a5a5a", + "backgroundColor": "#f3f3f3", + "separatorColor": "#cccccc", + "checkedButtonColor": "#cccccc", + "menuIndicatorColor": "#404040" + }, + "viewer": { + "defaultBackgroundColor": "#f6f6f6", + "defaultTextColor": "#202020", + "infoBackgroundColor": "#bbffffff", + "infoTextColor": "#404040" + }, + "goToFlowWidget": { + "flowBackgroundColor": "#f6f6f6", + "flowTextColor": "#202020", + "toolbarBackgroundColor": "#bbffffff", + "sliderBorderColor": "#22000000", + "sliderGrooveColor": "#33000000", + "sliderHandleColor": "#55000000", + "editBorderColor": "#33000000", + "editBackgroundColor": "#22000000", + "editTextColor": "#202020", + "labelTextColor": "#202020", + "iconColor": "#404040" + }, + "helpAboutDialog": { + "headingColor": "#302f2d", + "linkColor": "#c19441" + }, + "whatsNewDialog": { + "backgroundColor": "#ffffff", + "headerTextColor": "#0a0a0a", + "versionTextColor": "#858585", + "contentTextColor": "#0a0a0a", + "linkColor": "#e8b800", + "closeButtonColor": "#444444", + "headerDecorationColor": "#e8b800" + }, + "shortcutsIcons": { + "iconColor": "#606060" + } +} diff --git a/YACReader/themes/theme.h b/YACReader/themes/theme.h index 2cc5e8cf8..964e619f5 100644 --- a/YACReader/themes/theme.h +++ b/YACReader/themes/theme.h @@ -2,9 +2,11 @@ #define THEME_H #include +#include #include "help_about_dialog_theme.h" #include "whats_new_dialog_theme.h" +#include "theme_meta.h" struct ToolbarThemeTemplates { QString toolbarQSS = "QToolBar { border: none; background: %1; }\n" @@ -142,6 +144,9 @@ struct DialogIconsTheme { }; struct Theme { + ThemeMeta meta; + QJsonObject sourceJson; + ToolbarTheme toolbar; ViewerTheme viewer; GoToFlowWidgetTheme goToFlowWidget; diff --git a/YACReader/themes/theme_factory.cpp b/YACReader/themes/theme_factory.cpp index d798a5a43..7a19d4f85 100644 --- a/YACReader/themes/theme_factory.cpp +++ b/YACReader/themes/theme_factory.cpp @@ -3,6 +3,7 @@ #include #include "icon_utils.h" +#include "theme_meta.h" struct ToolbarParams { ToolbarThemeTemplates t; @@ -56,7 +57,7 @@ struct ShortcutsIconsParams { }; struct ThemeParams { - QString themeName; + ThemeMeta meta; ToolbarParams toolbarParams; ViewerParams viewerParams; @@ -72,7 +73,7 @@ void setToolbarIconPair(QIcon &icon, const QColor &iconColor, const QColor &disabledColor, const QColor &checkedColor, - const QString &themeName) + const QString &themeId) { QString path18 = basePath; if (path18.endsWith(".svg")) @@ -81,14 +82,14 @@ void setToolbarIconPair(QIcon &icon, path18.append("_18x18"); // Normal - const QString normalPath = recoloredSvgToThemeFile(basePath, iconColor, themeName); - const QString normalPath18 = recoloredSvgToThemeFile(path18, iconColor, themeName); + const QString normalPath = recoloredSvgToThemeFile(basePath, iconColor, themeId); + const QString normalPath18 = recoloredSvgToThemeFile(path18, iconColor, themeId); // Disabled - const QString disabledPath = recoloredSvgToThemeFile(basePath, disabledColor, themeName, { .suffix = "_disabled" }); - const QString disabledPath18 = recoloredSvgToThemeFile(path18, disabledColor, themeName, { .suffix = "_disabled" }); + const QString disabledPath = recoloredSvgToThemeFile(basePath, disabledColor, themeId, { .suffix = "_disabled" }); + const QString disabledPath18 = recoloredSvgToThemeFile(path18, disabledColor, themeId, { .suffix = "_disabled" }); // Checked (On state) - const QString checkedPath = recoloredSvgToThemeFile(basePath, checkedColor, themeName, { .suffix = "_checked" }); - const QString checkedPath18 = recoloredSvgToThemeFile(path18, checkedColor, themeName, { .suffix = "_checked" }); + const QString checkedPath = recoloredSvgToThemeFile(basePath, checkedColor, themeId, { .suffix = "_checked" }); + const QString checkedPath18 = recoloredSvgToThemeFile(path18, checkedColor, themeId, { .suffix = "_checked" }); icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); icon.addFile(disabledPath, QSize(), QIcon::Disabled, QIcon::Off); @@ -105,11 +106,13 @@ Theme makeTheme(const ThemeParams ¶ms) { Theme theme; + theme.meta = params.meta; + // Toolbar & actions - theme.toolbar.toolbarQSS = params.toolbarParams.t.toolbarQSS.arg(params.toolbarParams.backgroundColor.name(), params.toolbarParams.separatorColor.name(), params.toolbarParams.checkedButtonColor.name(), recoloredSvgToThemeFile(params.toolbarParams.t.menuArrowPath, params.toolbarParams.menuIndicatorColor, params.themeName)); + theme.toolbar.toolbarQSS = params.toolbarParams.t.toolbarQSS.arg(params.toolbarParams.backgroundColor.name(), params.toolbarParams.separatorColor.name(), params.toolbarParams.checkedButtonColor.name(), recoloredSvgToThemeFile(params.toolbarParams.t.menuArrowPath, params.toolbarParams.menuIndicatorColor, params.meta.id)); auto setToolbarIconPairT = [&](QIcon &icon, QIcon &icon18, const QString &basePath) { - setToolbarIconPair(icon, icon18, basePath, params.toolbarParams.iconColor, params.toolbarParams.iconDisabledColor, params.toolbarParams.iconCheckedColor, params.themeName); + setToolbarIconPair(icon, icon18, basePath, params.toolbarParams.iconColor, params.toolbarParams.iconDisabledColor, params.toolbarParams.iconCheckedColor, params.meta.id); }; setToolbarIconPairT(theme.toolbar.openAction, theme.toolbar.openAction18x18, ":/images/viewer_toolbar/open.svg"); @@ -166,8 +169,8 @@ Theme makeTheme(const ThemeParams ¶ms) theme.goToFlowWidget.buttonQSS = gotoParams.t.buttonQSS; theme.goToFlowWidget.labelQSS = gotoParams.t.labelQSS.arg(gotoParams.labelTextColor.name()); - const QString centerIconPath = recoloredSvgToThemeFile(":/images/centerFlow.svg", gotoParams.iconColor, params.themeName); - const QString goToIconPath = recoloredSvgToThemeFile(":/images/gotoFlow.svg", gotoParams.iconColor, params.themeName); + const QString centerIconPath = recoloredSvgToThemeFile(":/images/centerFlow.svg", gotoParams.iconColor, params.meta.id); + const QString goToIconPath = recoloredSvgToThemeFile(":/images/gotoFlow.svg", gotoParams.iconColor, params.meta.id); theme.goToFlowWidget.centerIcon = QIcon(centerIconPath); theme.goToFlowWidget.goToIcon = QIcon(goToIconPath); // end GoToFlowWidget @@ -183,14 +186,14 @@ Theme makeTheme(const ThemeParams ¶ms) theme.whatsNewDialog.versionTextColor = wn.versionTextColor; theme.whatsNewDialog.contentTextColor = wn.contentTextColor; theme.whatsNewDialog.linkColor = wn.linkColor; - theme.whatsNewDialog.closeButtonIcon = QPixmap(recoloredSvgToThemeFile(":/images/custom_dialog/custom_close_button.svg", wn.closeButtonColor, params.themeName)); - theme.whatsNewDialog.headerDecoration = QPixmap(recoloredSvgToThemeFile(":/images/whats_new/whatsnew_header.svg", wn.headerDecorationColor, params.themeName)); + theme.whatsNewDialog.closeButtonIcon = QPixmap(recoloredSvgToThemeFile(":/images/custom_dialog/custom_close_button.svg", wn.closeButtonColor, params.meta.id)); + theme.whatsNewDialog.headerDecoration = QPixmap(recoloredSvgToThemeFile(":/images/whats_new/whatsnew_header.svg", wn.headerDecorationColor, params.meta.id)); // end WhatsNewDialog // ShortcutsIcons const auto &sci = params.shortcutsIconsParams; auto makeShortcutsIcon = [&](const QString &basePath) { - const QString path = recoloredSvgToThemeFile(basePath, sci.iconColor, params.themeName); + const QString path = recoloredSvgToThemeFile(basePath, sci.iconColor, params.meta.id); return QIcon(path); }; @@ -203,7 +206,7 @@ Theme makeTheme(const ThemeParams ¶ms) // FindFolder icon (used in OptionsDialog) { - const QString path = recoloredSvgToThemeFile(":/images/find_folder.svg", params.toolbarParams.iconColor, params.themeName); + const QString path = recoloredSvgToThemeFile(":/images/find_folder.svg", params.toolbarParams.iconColor, params.meta.id); const qreal dpr = qApp->devicePixelRatio(); theme.dialogIcons.findFolderIcon = QIcon(renderSvgToPixmap(path, 13, 13, dpr)); } @@ -211,204 +214,92 @@ Theme makeTheme(const ThemeParams ¶ms) return theme; } -ThemeParams classicThemeParams(); -ThemeParams lightThemeParams(); -ThemeParams darkThemeParams(); +// JSON helpers --------------------------------------------------------------- -Theme makeTheme(ThemeId themeId) +static QColor colorFromJson(const QJsonObject &obj, const QString &key, const QColor &fallback) { - switch (themeId) { - case ThemeId::Classic: - return makeTheme(classicThemeParams()); - case ThemeId::Light: - return makeTheme(lightThemeParams()); - case ThemeId::Dark: - return makeTheme(darkThemeParams()); - } + if (!obj.contains(key)) + return fallback; + QColor c(obj[key].toString()); + return c.isValid() ? c : fallback; } -ThemeParams classicThemeParams() +Theme makeTheme(const QJsonObject &json) { - ThemeParams params; - params.themeName = "classic"; - - ToolbarParams toolbarParams; - toolbarParams.iconColor = QColor(0x404040); - toolbarParams.iconDisabledColor = QColor(0x858585); - toolbarParams.iconCheckedColor = QColor(0x5A5A5A); - toolbarParams.backgroundColor = QColor(0xF3F3F3); - toolbarParams.separatorColor = QColor(0xCCCCCC); - toolbarParams.checkedButtonColor = QColor(0xCCCCCC); - toolbarParams.menuIndicatorColor = QColor(0x404040); - - params.toolbarParams = toolbarParams; - - ViewerParams viewerParams; - viewerParams.defaultBackgroundColor = QColor(0x282828); - viewerParams.defaultTextColor = Qt::white; - viewerParams.infoBackgroundColor = QColor::fromRgba(0xBB000000); - viewerParams.infoTextColor = Qt::white; - viewerParams.t = ViewerThemeTemplates(); - - params.viewerParams = viewerParams; - - GoToFlowWidgetParams goToFlowWidgetParams; - goToFlowWidgetParams.flowBackgroundColor = QColor(0x282828); - goToFlowWidgetParams.flowTextColor = Qt::white; - goToFlowWidgetParams.toolbarBackgroundColor = QColor::fromRgba(0x99000000); - goToFlowWidgetParams.sliderBorderColor = QColor::fromRgba(0x22FFFFFF); - goToFlowWidgetParams.sliderGrooveColor = QColor::fromRgba(0x77000000); - goToFlowWidgetParams.sliderHandleColor = QColor::fromRgba(0x55FFFFFF); - goToFlowWidgetParams.editBorderColor = QColor::fromRgba(0x77000000); - goToFlowWidgetParams.editBackgroundColor = QColor::fromRgba(0x55000000); - goToFlowWidgetParams.editTextColor = Qt::white; - goToFlowWidgetParams.labelTextColor = Qt::white; - goToFlowWidgetParams.iconColor = Qt::white; - goToFlowWidgetParams.t = GoToFlowWidgetThemeTemplates(); - - params.goToFlowWidgetParams = goToFlowWidgetParams; - - params.helpAboutDialogParams.headingColor = QColor(0x302f2d); - params.helpAboutDialogParams.linkColor = QColor(0xC19441); - - params.whatsNewDialogParams.backgroundColor = QColor(0xFFFFFF); - params.whatsNewDialogParams.headerTextColor = QColor(0x0A0A0A); - params.whatsNewDialogParams.versionTextColor = QColor(0x858585); - params.whatsNewDialogParams.contentTextColor = QColor(0x0A0A0A); - params.whatsNewDialogParams.linkColor = QColor(0xE8B800); - params.whatsNewDialogParams.closeButtonColor = QColor(0x444444); - params.whatsNewDialogParams.headerDecorationColor = QColor(0xE8B800); - - // ShortcutsIcons - ShortcutsIconsParams sci; - sci.iconColor = QColor(0x404040); // Dark icons for light background - params.shortcutsIconsParams = sci; - - return params; -} - -ThemeParams lightThemeParams() -{ - ThemeParams params; - params.themeName = "light"; - - ToolbarParams toolbarParams; - toolbarParams.iconColor = QColor(0x404040); - toolbarParams.iconDisabledColor = QColor(0xB0B0B0); - toolbarParams.iconCheckedColor = QColor(0x5A5A5A); - toolbarParams.backgroundColor = QColor(0xF3F3F3); - toolbarParams.separatorColor = QColor(0xCCCCCC); - toolbarParams.checkedButtonColor = QColor(0xCCCCCC); - toolbarParams.menuIndicatorColor = QColor(0x404040); - - params.toolbarParams = toolbarParams; - - ViewerParams viewerParams; - viewerParams.defaultBackgroundColor = QColor(0xF6F6F6); - viewerParams.defaultTextColor = QColor(0x202020); - viewerParams.infoBackgroundColor = QColor::fromRgba(0xBBFFFFFF); - viewerParams.infoTextColor = QColor(0x404040); - viewerParams.t = ViewerThemeTemplates(); - - params.viewerParams = viewerParams; - - GoToFlowWidgetParams goToFlowWidgetParams; - goToFlowWidgetParams.flowBackgroundColor = QColor(0xF6F6F6); - goToFlowWidgetParams.flowTextColor = QColor(0x202020); - goToFlowWidgetParams.toolbarBackgroundColor = QColor::fromRgba(0xBBFFFFFF); - goToFlowWidgetParams.sliderBorderColor = QColor::fromRgba(0x22000000); - goToFlowWidgetParams.sliderGrooveColor = QColor::fromRgba(0x33000000); - goToFlowWidgetParams.sliderHandleColor = QColor::fromRgba(0x55000000); - goToFlowWidgetParams.editBorderColor = QColor::fromRgba(0x33000000); - goToFlowWidgetParams.editBackgroundColor = QColor::fromRgba(0x22000000); - goToFlowWidgetParams.editTextColor = QColor(0x202020); - goToFlowWidgetParams.labelTextColor = QColor(0x202020); - goToFlowWidgetParams.iconColor = QColor(0x404040); - goToFlowWidgetParams.t = GoToFlowWidgetThemeTemplates(); - - params.goToFlowWidgetParams = goToFlowWidgetParams; - - params.helpAboutDialogParams.headingColor = QColor(0x302f2d); - params.helpAboutDialogParams.linkColor = QColor(0xC19441); - - params.whatsNewDialogParams.backgroundColor = QColor(0xFFFFFF); - params.whatsNewDialogParams.headerTextColor = QColor(0x0A0A0A); - params.whatsNewDialogParams.versionTextColor = QColor(0x858585); - params.whatsNewDialogParams.contentTextColor = QColor(0x0A0A0A); - params.whatsNewDialogParams.linkColor = QColor(0xE8B800); - params.whatsNewDialogParams.closeButtonColor = QColor(0x444444); - params.whatsNewDialogParams.headerDecorationColor = QColor(0xE8B800); - - // ShortcutsIcons - ShortcutsIconsParams sci; - sci.iconColor = QColor(0x606060); // Dark icons for light background - params.shortcutsIconsParams = sci; - - return params; -} - -ThemeParams darkThemeParams() -{ - ThemeParams params; - params.themeName = "dark"; - - ToolbarParams toolbarParams; - toolbarParams.iconColor = QColor(0xCCCCCC); - toolbarParams.iconDisabledColor = QColor(0x444444); - toolbarParams.iconCheckedColor = QColor(0xDADADA); - toolbarParams.backgroundColor = QColor(0x202020); - toolbarParams.separatorColor = QColor(0x444444); - toolbarParams.checkedButtonColor = QColor(0x3A3A3A); - toolbarParams.menuIndicatorColor = QColor(0xCCCCCC); + ThemeParams p; + + if (json.contains("toolbar")) { + const auto t = json["toolbar"].toObject(); + auto &tp = p.toolbarParams; + tp.iconColor = colorFromJson(t, "iconColor", tp.iconColor); + tp.iconDisabledColor = colorFromJson(t, "iconDisabledColor", tp.iconDisabledColor); + tp.iconCheckedColor = colorFromJson(t, "iconCheckedColor", tp.iconCheckedColor); + tp.backgroundColor = colorFromJson(t, "backgroundColor", tp.backgroundColor); + tp.separatorColor = colorFromJson(t, "separatorColor", tp.separatorColor); + tp.checkedButtonColor = colorFromJson(t, "checkedButtonColor", tp.checkedButtonColor); + tp.menuIndicatorColor = colorFromJson(t, "menuIndicatorColor", tp.menuIndicatorColor); + } - params.toolbarParams = toolbarParams; + if (json.contains("viewer")) { + const auto v = json["viewer"].toObject(); + auto &vp = p.viewerParams; + vp.defaultBackgroundColor = colorFromJson(v, "defaultBackgroundColor", vp.defaultBackgroundColor); + vp.defaultTextColor = colorFromJson(v, "defaultTextColor", vp.defaultTextColor); + vp.infoBackgroundColor = colorFromJson(v, "infoBackgroundColor", vp.infoBackgroundColor); + vp.infoTextColor = colorFromJson(v, "infoTextColor", vp.infoTextColor); + } - ViewerParams viewerParams; - viewerParams.defaultBackgroundColor = QColor(40, 40, 40); - viewerParams.defaultTextColor = Qt::white; - viewerParams.infoBackgroundColor = QColor::fromRgba(0xBB000000); - viewerParams.infoTextColor = QColor(0xB0B0B0); - viewerParams.t = ViewerThemeTemplates(); + if (json.contains("goToFlowWidget")) { + const auto g = json["goToFlowWidget"].toObject(); + auto &gp = p.goToFlowWidgetParams; + gp.flowBackgroundColor = colorFromJson(g, "flowBackgroundColor", gp.flowBackgroundColor); + gp.flowTextColor = colorFromJson(g, "flowTextColor", gp.flowTextColor); + gp.toolbarBackgroundColor = colorFromJson(g, "toolbarBackgroundColor", gp.toolbarBackgroundColor); + gp.sliderBorderColor = colorFromJson(g, "sliderBorderColor", gp.sliderBorderColor); + gp.sliderGrooveColor = colorFromJson(g, "sliderGrooveColor", gp.sliderGrooveColor); + gp.sliderHandleColor = colorFromJson(g, "sliderHandleColor", gp.sliderHandleColor); + gp.editBorderColor = colorFromJson(g, "editBorderColor", gp.editBorderColor); + gp.editBackgroundColor = colorFromJson(g, "editBackgroundColor", gp.editBackgroundColor); + gp.editTextColor = colorFromJson(g, "editTextColor", gp.editTextColor); + gp.labelTextColor = colorFromJson(g, "labelTextColor", gp.labelTextColor); + gp.iconColor = colorFromJson(g, "iconColor", gp.iconColor); + } - params.viewerParams = viewerParams; + if (json.contains("helpAboutDialog")) { + const auto h = json["helpAboutDialog"].toObject(); + p.helpAboutDialogParams.headingColor = colorFromJson(h, "headingColor", p.helpAboutDialogParams.headingColor); + p.helpAboutDialogParams.linkColor = colorFromJson(h, "linkColor", p.helpAboutDialogParams.linkColor); + } - GoToFlowWidgetParams goToFlowWidgetParams; - goToFlowWidgetParams.flowBackgroundColor = QColor(40, 40, 40); - goToFlowWidgetParams.flowTextColor = Qt::white; - goToFlowWidgetParams.toolbarBackgroundColor = QColor::fromRgba(0x99000000); - goToFlowWidgetParams.sliderBorderColor = QColor::fromRgba(0x22FFFFFF); - goToFlowWidgetParams.sliderGrooveColor = QColor::fromRgba(0x77000000); - goToFlowWidgetParams.sliderHandleColor = QColor::fromRgba(0x55FFFFFF); - goToFlowWidgetParams.editBorderColor = QColor::fromRgba(0x77000000); - goToFlowWidgetParams.editBackgroundColor = QColor::fromRgba(0x55000000); - goToFlowWidgetParams.editTextColor = Qt::white; - goToFlowWidgetParams.labelTextColor = Qt::white; - goToFlowWidgetParams.iconColor = QColor(0xCCCCCC); - goToFlowWidgetParams.t = GoToFlowWidgetThemeTemplates(); - - params.goToFlowWidgetParams = goToFlowWidgetParams; - - params.helpAboutDialogParams.headingColor = QColor(0xE0E0E0); - params.helpAboutDialogParams.linkColor = QColor(0xD4A84B); - - params.whatsNewDialogParams.backgroundColor = QColor(0x2A2A2A); - params.whatsNewDialogParams.headerTextColor = QColor(0xE0E0E0); - params.whatsNewDialogParams.versionTextColor = QColor(0x858585); - params.whatsNewDialogParams.contentTextColor = QColor(0xE0E0E0); - params.whatsNewDialogParams.linkColor = QColor(0xE8B800); - params.whatsNewDialogParams.closeButtonColor = QColor(0xDDDDDD); - params.whatsNewDialogParams.headerDecorationColor = QColor(0xE8B800); + if (json.contains("whatsNewDialog")) { + const auto w = json["whatsNewDialog"].toObject(); + auto &wn = p.whatsNewDialogParams; + wn.backgroundColor = colorFromJson(w, "backgroundColor", wn.backgroundColor); + wn.headerTextColor = colorFromJson(w, "headerTextColor", wn.headerTextColor); + wn.versionTextColor = colorFromJson(w, "versionTextColor", wn.versionTextColor); + wn.contentTextColor = colorFromJson(w, "contentTextColor", wn.contentTextColor); + wn.linkColor = colorFromJson(w, "linkColor", wn.linkColor); + wn.closeButtonColor = colorFromJson(w, "closeButtonColor", wn.closeButtonColor); + wn.headerDecorationColor = colorFromJson(w, "headerDecorationColor",wn.headerDecorationColor); + } - // ShortcutsIcons - ShortcutsIconsParams sci; - sci.iconColor = QColor(0xD0D0D0); // Light icons for dark background - params.shortcutsIconsParams = sci; + if (json.contains("shortcutsIcons")) { + const auto s = json["shortcutsIcons"].toObject(); + p.shortcutsIconsParams.iconColor = colorFromJson(s, "iconColor", p.shortcutsIconsParams.iconColor); + } - return params; -} + if (json.contains("meta")) { + const auto o = json["meta"].toObject(); + p.meta.id = o["id"].toString(p.meta.id); + p.meta.displayName = o["displayName"].toString(p.meta.displayName); + const QString variantStr = o["variant"].toString(); + if (variantStr == "light") + p.meta.variant = ThemeVariant::Light; + else if (variantStr == "dark") + p.meta.variant = ThemeVariant::Dark; + } -// TODO -ThemeParams paramsFromFile(const QString &filePath) -{ - return {}; + Theme theme = makeTheme(p); + theme.sourceJson = json; + return theme; } diff --git a/YACReader/themes/theme_factory.h b/YACReader/themes/theme_factory.h index 72cb4ca28..ebed9bbb1 100644 --- a/YACReader/themes/theme_factory.h +++ b/YACReader/themes/theme_factory.h @@ -2,8 +2,9 @@ #define THEME_FACTORY_H #include "theme.h" -#include "theme_id.h" -Theme makeTheme(ThemeId themeId); +#include + +Theme makeTheme(const QJsonObject &json); #endif // THEME_FACTORY_H diff --git a/YACReader/themes/themes.qrc b/YACReader/themes/themes.qrc new file mode 100644 index 000000000..62ec21fee --- /dev/null +++ b/YACReader/themes/themes.qrc @@ -0,0 +1,7 @@ + + + builtin_classic.json + builtin_light.json + builtin_dark.json + + diff --git a/YACReaderLibrary/CMakeLists.txt b/YACReaderLibrary/CMakeLists.txt index cae71e34f..485c11916 100644 --- a/YACReaderLibrary/CMakeLists.txt +++ b/YACReaderLibrary/CMakeLists.txt @@ -203,10 +203,14 @@ target_compile_definitions(YACReaderLibrary PRIVATE qt_add_resources(yacreaderlibrary_images_rcc "${CMAKE_CURRENT_SOURCE_DIR}/images.qrc") qt_add_resources(yacreaderlibrary_files_rcc "${CMAKE_CURRENT_SOURCE_DIR}/files.qrc") qt_add_resources(yacreaderlibrary_qml_rcc "${CMAKE_CURRENT_SOURCE_DIR}/qml.qrc") +qt_add_resources(yacreaderlibrary_themes_rcc "${CMAKE_CURRENT_SOURCE_DIR}/themes/themes.qrc") +qt_add_resources(yacreaderlibrary_common_images_rcc "${CMAKE_SOURCE_DIR}/common/themes/appearance_config_images.qrc") target_sources(YACReaderLibrary PRIVATE ${yacreaderlibrary_images_rcc} ${yacreaderlibrary_files_rcc} ${yacreaderlibrary_qml_rcc} + ${yacreaderlibrary_themes_rcc} + ${yacreaderlibrary_common_images_rcc} ) if(WIN32 OR (UNIX AND NOT APPLE)) qt_add_resources(yacreaderlibrary_images_win_rcc "${CMAKE_CURRENT_SOURCE_DIR}/images_win.qrc") diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp index a93aeb16c..bb58b5bfa 100644 --- a/YACReaderLibrary/info_comics_view.cpp +++ b/YACReaderLibrary/info_comics_view.cpp @@ -227,10 +227,18 @@ void InfoComicsView::applyTheme(const Theme &theme) const auto &qv = theme.qmlView; // Info panel colors + // Cache-bust the SVG file URLs so QML's image cache doesn't serve stale + // files when the theme is updated (the same file path is rewritten each time). + const QString bust = QString::number(QDateTime::currentMSecsSinceEpoch()); + auto svgUrl = [&bust](const QString &path) { + QUrl url = QUrl::fromLocalFile(path); + url.setQuery(bust); + return url; + }; ctxt->setContextProperty("infoBackgroundColor", qv.infoBackgroundColor); - ctxt->setContextProperty("topShadow", QUrl::fromLocalFile(qv.topShadow)); - ctxt->setContextProperty("infoShadow", QUrl::fromLocalFile(qv.infoShadow)); - ctxt->setContextProperty("infoIndicator", QUrl::fromLocalFile(qv.infoIndicator)); + ctxt->setContextProperty("topShadow", svgUrl(qv.topShadow)); + ctxt->setContextProperty("infoShadow", svgUrl(qv.infoShadow)); + ctxt->setContextProperty("infoIndicator", svgUrl(qv.infoIndicator)); ctxt->setContextProperty("infoTextColor", qv.infoTextColor); ctxt->setContextProperty("infoTitleColor", qv.infoTitleColor); diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index 5507e25ea..4d82ea863 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -21,7 +21,9 @@ #include "db_helper.h" #include "yacreader_libraries.h" #include "exit_check.h" +#include "appearance_configuration.h" #include "theme_manager.h" +#include "theme_repository.h" #ifdef Q_OS_MACOS #include "trayhandler.h" #endif @@ -140,7 +142,11 @@ int main(int argc, char **argv) app.setApplicationVersion(VERSION); // Theme initialization - ThemeManager::instance().initialize(); + auto *appearanceConfig = new AppearanceConfiguration( + YACReader::getSettingsPath() + "/YACReaderLibrary.ini", qApp); + auto *themeRepo = new ThemeRepository( + ":/themes", YACReader::getSettingsPath() + "/themes/user"); + ThemeManager::instance().initialize(appearanceConfig, themeRepo); // Set window icon according to Freedesktop icon specification // This is mostly relevant for Linux and other Unix systems diff --git a/YACReaderLibrary/options_dialog.cpp b/YACReaderLibrary/options_dialog.cpp index 53210ac8f..1087d8ada 100644 --- a/YACReaderLibrary/options_dialog.cpp +++ b/YACReaderLibrary/options_dialog.cpp @@ -4,6 +4,11 @@ #include "api_key_dialog.h" #include "yacreader_global_gui.h" +#include "theme_manager.h" +#include "theme_factory.h" +#include "appearance_tab_widget.h" + +#include FlowType flowType = Strip; @@ -15,11 +20,14 @@ OptionsDialog::OptionsDialog(QWidget *parent) auto comicFlowW = createFlowTab(); auto gridViewW = createGridTab(); + auto appearanceW = createAppearanceTab(); + auto tabWidget = new QTabWidget(); tabWidget->addTab(generalW, tr("General")); tabWidget->addTab(librariesW, tr("Libraries")); tabWidget->addTab(comicFlowW, tr("Comic Flow")); tabWidget->addTab(gridViewW, tr("Grid view")); + tabWidget->addTab(appearanceW, tr("Appearance")); auto buttons = new QHBoxLayout(); buttons->addStretch(); @@ -406,3 +414,12 @@ QWidget *OptionsDialog::createGridTab() return gridViewW; } + +QWidget *OptionsDialog::createAppearanceTab() +{ + return new AppearanceTabWidget( + ThemeManager::instance().getAppearanceConfiguration(), + []() { return ThemeManager::instance().getCurrentTheme().sourceJson; }, + [](const QJsonObject &json) { ThemeManager::instance().setTheme(makeTheme(json)); }, + this); +} diff --git a/YACReaderLibrary/options_dialog.h b/YACReaderLibrary/options_dialog.h index ccf8a2ffb..84caae53c 100644 --- a/YACReaderLibrary/options_dialog.h +++ b/YACReaderLibrary/options_dialog.h @@ -61,6 +61,7 @@ private slots: QWidget *createLibrariesTab(); QWidget *createFlowTab(); QWidget *createGridTab(); + QWidget *createAppearanceTab(); }; #endif diff --git a/YACReaderLibrary/themes/builtin_classic.json b/YACReaderLibrary/themes/builtin_classic.json new file mode 100644 index 000000000..a365fbb87 --- /dev/null +++ b/YACReaderLibrary/themes/builtin_classic.json @@ -0,0 +1,238 @@ +{ + "meta": { + "id": "builtin/classic", + "displayName": "Default Classic", + "variant": "dark" + }, + "defaultContentBackgroundColor": "#2a2a2a", + "comicFlow": { + "backgroundColor": "#000000", + "textColor": "#4c4c4c" + }, + "comicVine": { + "contentTextColor": "#ffffff", + "contentBackgroundColor": "#2b2b2b", + "contentAltBackgroundColor": "#2b2b2b", + "dialogBackgroundColor": "#404040", + "tableBackgroundColor": "#2b2b2b", + "tableAltBackgroundColor": "#2e2e2e", + "tableBorderColor": "#242424", + "tableSelectedColor": "#555555", + "tableHeaderBackgroundColor": "#292929", + "tableHeaderGradientColor": "#292929", + "tableHeaderBorderColor": "#1f1f1f", + "tableHeaderTextColor": "#ebebeb", + "tableScrollHandleColor": "#dddddd", + "tableScrollBackgroundColor": "#404040", + "tableSectionBorderLight": "#fefefe", + "tableSectionBorderDark": "#dfdfdf", + "labelTextColor": "#ffffff", + "labelBackgroundColor": "#2b2b2b", + "hyperlinkColor": "#ffcc00", + "buttonBackgroundColor": "#2e2e2e", + "buttonTextColor": "#ffffff", + "buttonBorderColor": "#242424", + "radioUncheckedColor": "#e5e5e5", + "radioCheckedBackgroundColor": "#e5e5e5", + "radioCheckedIndicatorColor": "#5f5f5f", + "checkBoxTickColor": "#ffffff", + "toolButtonAccentColor": "#282828", + "downArrowColor": "#9f9f9f", + "upArrowColor": "#9f9f9f", + "busyIndicatorColor": "#ffffff", + "navIconColor": "#ffffff", + "rowIconColor": "#e5e5e5" + }, + "helpAboutDialog": { + "headingColor": "#302f2d", + "linkColor": "#c19441" + }, + "whatsNewDialog": { + "backgroundColor": "#2a2a2a", + "headerTextColor": "#e0e0e0", + "versionTextColor": "#858585", + "contentTextColor": "#e0e0e0", + "linkColor": "#e8b800", + "closeButtonColor": "#dddddd", + "headerDecorationColor": "#e8b800" + }, + "emptyContainer": { + "backgroundColor": "#2a2a2a", + "titleTextColor": "#cccccc", + "textColor": "#cccccc", + "descriptionTextColor": "#aaaaaa", + "searchIconColor": "#4c4c4c" + }, + "sidebar": { + "backgroundColor": "#454545", + "separatorColor": "#bdbfbf", + "sectionSeparatorColor": "#575757", + "uppercaseLabels": true, + "titleTextColor": "#bdbfbf", + "titleDropShadowColor": "#000000", + "busyIndicatorColor": "#ffffff" + }, + "sidebarIcons": { + "iconColor": "#e0e0e0", + "shadowColor": "#000000", + "useSystemFolderIcons": false + }, + "libraryItem": { + "textColor": "#dddfdf", + "libraryIconColor": "#dddfdf", + "libraryIconShadowColor": "#000000", + "selectedTextColor": "#ffffff", + "selectedBackgroundColor": "#2e2e2e", + "libraryIconSelectedColor": "#ffffff", + "libraryOptionsIconColor": "#ffffff" + }, + "importWidget": { + "backgroundColor": "#2a2a2a", + "titleTextColor": "#cccccc", + "descriptionTextColor": "#aaaaaa", + "currentComicTextColor": "#aaaaaa", + "coversViewBackgroundColor": "#3a3a3a", + "coversLabelColor": "#aaaaaa", + "coversDecorationBgColor": "#3a3a3a", + "coversDecorationShadowColor": "#1a1a1a", + "modeIconColor": "#4a4a4a", + "iconColor": "#cccccc", + "iconCheckedColor": "#aaaaaa" + }, + "serverConfigDialog": { + "backgroundColor": "#2a2a2a", + "titleTextColor": "#474747", + "qrMessageTextColor": "#a3a3a3", + "propagandaTextColor": "#4d4d4d", + "labelTextColor": "#575757", + "checkBoxTextColor": "#262626", + "qrBackgroundColor": "#2a2a2a", + "qrForegroundColor": "#ffffff", + "decorationColor": "#f7f7f7" + }, + "mainToolbar": { + "backgroundColor": "#f0f0f0", + "folderNameColor": "#404040", + "dividerColor": "#b8bdc4", + "iconColor": "#404040", + "iconDisabledColor": "#b0b0b0" + }, + "contentSplitter": { + "handleColor": "#b8b8b8", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "treeView": { + "textColor": "#dddfdf", + "selectionBackgroundColor": "#2e2e2e", + "scrollBackgroundColor": "#404040", + "scrollHandleColor": "#dddddd", + "selectedTextColor": "#ffffff", + "folderIndicatorColor": "#edc518", + "branchIndicatorColor": "#e0e0e0", + "branchIndicatorSelectedColor": "#ffffff", + "folderIconColor": "#e0e0e0", + "folderIconShadowColor": "#000000", + "folderIconSelectedColor": "#e0e0e0", + "folderIconSelectedShadowColor": "#000000", + "folderReadOverlayColor": "#464646", + "folderReadOverlaySelectedColor": "#464646" + }, + "tableView": { + "alternateBackgroundColor": "#f2f2f2", + "backgroundColor": "#fafafa", + "headerBackgroundColor": "#f5f5f5", + "headerBorderColor": "#b8bdc4", + "headerGradientColor": "#d1d1d1", + "itemBorderBottomColor": "#dfdfdf", + "itemBorderTopColor": "#fefefe", + "itemBorderBottomWidth": 1, + "itemBorderTopWidth": 1, + "itemTextColor": "#252626", + "selectedColor": "#d4d4d4", + "selectedTextColor": "#252626", + "headerTextColor": "#313232", + "starRatingColor": "#e9be0f", + "starRatingSelectedColor": "#ffffff" + }, + "qmlView": { + "backgroundColor": "#2a2a2a", + "cellColor": "#212121", + "cellColorWithBackground": "#99212121", + "selectedColor": "#121212", + "selectedBorderColor": "#ffcc00", + "borderColor": "#121212", + "titleColor": "#ffffff", + "textColor": "#a8a8a8", + "showDropShadow": true, + "infoBackgroundColor": "#2e2e2e", + "infoBorderColor": "#404040", + "infoShadowColor": "#000000", + "infoTextColor": "#b0b0b0", + "infoTitleColor": "#ffffff", + "ratingUnselectedColor": "#1c1c1c", + "ratingSelectedColor": "#ffffff", + "favUncheckedColor": "#1c1c1c", + "favCheckedColor": "#e84852", + "readTickUncheckedColor": "#1c1c1c", + "readTickCheckedColor": "#e84852", + "currentComicBackgroundColor": "#88000000", + "continueReadingBackgroundColor": "#88000000", + "continueReadingColor": "#ffffff", + "backgroundBlurOverlayColor": "#2a2a2a" + }, + "comicsViewToolbar": { + "backgroundColor": "#f0f0f0", + "separatorColor": "#cccccc", + "checkedBackgroundColor": "#cccccc", + "iconColor": "#404040" + }, + "searchLineEdit": { + "textColor": "#ababab", + "backgroundColor": "#404040", + "iconColor": "#f7f7f7" + }, + "readingListIcons": { + "labelColors": { + "red": "#f67a7b", + "orange": "#f5c240", + "yellow": "#f2e446", + "green": "#ade738", + "cyan": "#a0fddb", + "blue": "#82c7ff", + "violet": "#8f95ff", + "purple": "#d692fc", + "pink": "#fd9cda", + "white": "#fcfcfc", + "light": "#cbcbcb", + "dark": "#b7b7b7" + }, + "labelShadowColor": "#000000", + "labelShadowSelectedColor": "#000000", + "readingListMainColor": "#e7e7e7", + "readingListMainSelectedColor": "#e7e7e7", + "favoritesMainColor": "#e15055", + "favoritesMainSelectedColor": "#e15055", + "currentlyReadingMainColor": "#ffcc00", + "currentlyReadingMainSelectedColor": "#ffcc00", + "currentlyReadingOuterColor": "#000000", + "currentlyReadingOuterSelectedColor": "#000000", + "specialListShadowColor": "#000000", + "specialListShadowSelectedColor": "#000000", + "listMainColor": "#e7e7e7", + "listMainSelectedColor": "#e7e7e7", + "listShadowColor": "#000000", + "listShadowSelectedColor": "#000000", + "listDetailColor": "#464646", + "listDetailSelectedColor": "#464646" + }, + "dialogIcons": { + "iconColor": "#f7f7f7" + }, + "menuIcons": { + "iconColor": "#f7f7f7" + }, + "shortcutsIcons": { + "iconColor": "#f7f7f7" + } +} diff --git a/YACReaderLibrary/themes/builtin_dark.json b/YACReaderLibrary/themes/builtin_dark.json new file mode 100644 index 000000000..21855acaf --- /dev/null +++ b/YACReaderLibrary/themes/builtin_dark.json @@ -0,0 +1,238 @@ +{ + "meta": { + "id": "builtin/dark", + "displayName": "Default Dark", + "variant": "dark" + }, + "defaultContentBackgroundColor": "#2a2a2a", + "comicFlow": { + "backgroundColor": "#111111", + "textColor": "#888888" + }, + "comicVine": { + "contentTextColor": "#ffffff", + "contentBackgroundColor": "#2b2b2b", + "contentAltBackgroundColor": "#2e2e2e", + "dialogBackgroundColor": "#404040", + "tableBackgroundColor": "#2b2b2b", + "tableAltBackgroundColor": "#2e2e2e", + "tableBorderColor": "#242424", + "tableSelectedColor": "#555555", + "tableHeaderBackgroundColor": "#292929", + "tableHeaderGradientColor": "#292929", + "tableHeaderBorderColor": "#1f1f1f", + "tableHeaderTextColor": "#ebebeb", + "tableScrollHandleColor": "#dddddd", + "tableScrollBackgroundColor": "#404040", + "tableSectionBorderLight": "#fefefe", + "tableSectionBorderDark": "#dfdfdf", + "labelTextColor": "#ffffff", + "labelBackgroundColor": "#2b2b2b", + "hyperlinkColor": "#ffcc00", + "buttonBackgroundColor": "#2e2e2e", + "buttonTextColor": "#ffffff", + "buttonBorderColor": "#242424", + "radioUncheckedColor": "#e5e5e5", + "radioCheckedBackgroundColor": "#e5e5e5", + "radioCheckedIndicatorColor": "#5f5f5f", + "checkBoxTickColor": "#ffffff", + "toolButtonAccentColor": "#282828", + "downArrowColor": "#9f9f9f", + "upArrowColor": "#9f9f9f", + "busyIndicatorColor": "#ffffff", + "navIconColor": "#ffffff", + "rowIconColor": "#e5e5e5" + }, + "helpAboutDialog": { + "headingColor": "#e0e0e0", + "linkColor": "#d4a84b" + }, + "whatsNewDialog": { + "backgroundColor": "#2a2a2a", + "headerTextColor": "#e0e0e0", + "versionTextColor": "#858585", + "contentTextColor": "#e0e0e0", + "linkColor": "#e8b800", + "closeButtonColor": "#dddddd", + "headerDecorationColor": "#e8b800" + }, + "emptyContainer": { + "backgroundColor": "#2a2a2a", + "titleTextColor": "#cccccc", + "textColor": "#cccccc", + "descriptionTextColor": "#aaaaaa", + "searchIconColor": "#4c4c4c" + }, + "sidebar": { + "backgroundColor": "#454545", + "separatorColor": "#bdbfbf", + "sectionSeparatorColor": "#575757", + "uppercaseLabels": true, + "titleTextColor": "#bdbfbf", + "titleDropShadowColor": "#000000", + "busyIndicatorColor": "#ffffff" + }, + "sidebarIcons": { + "iconColor": "#e0e0e0", + "shadowColor": "#000000", + "useSystemFolderIcons": false + }, + "libraryItem": { + "textColor": "#dddfdf", + "libraryIconColor": "#dddfdf", + "libraryIconShadowColor": "#000000", + "selectedTextColor": "#ffffff", + "selectedBackgroundColor": "#2e2e2e", + "libraryIconSelectedColor": "#ffffff", + "libraryOptionsIconColor": "#ffffff" + }, + "importWidget": { + "backgroundColor": "#2a2a2a", + "titleTextColor": "#cccccc", + "descriptionTextColor": "#aaaaaa", + "currentComicTextColor": "#aaaaaa", + "coversViewBackgroundColor": "#3a3a3a", + "coversLabelColor": "#aaaaaa", + "coversDecorationBgColor": "#3a3a3a", + "coversDecorationShadowColor": "#1a1a1a", + "modeIconColor": "#4a4a4a", + "iconColor": "#cccccc", + "iconCheckedColor": "#aaaaaa" + }, + "serverConfigDialog": { + "backgroundColor": "#2a2a2a", + "titleTextColor": "#d0d0d0", + "qrMessageTextColor": "#a3a3a3", + "propagandaTextColor": "#b0b0b0", + "labelTextColor": "#c0c0c0", + "checkBoxTextColor": "#dddddd", + "qrBackgroundColor": "#2a2a2a", + "qrForegroundColor": "#ffffff", + "decorationColor": "#f7f7f7" + }, + "mainToolbar": { + "backgroundColor": "#2a2a2a", + "folderNameColor": "#dddddd", + "dividerColor": "#555555", + "iconColor": "#dddddd", + "iconDisabledColor": "#666666" + }, + "contentSplitter": { + "handleColor": "#1f1f1f", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "treeView": { + "textColor": "#dddfdf", + "selectionBackgroundColor": "#2e2e2e", + "scrollBackgroundColor": "#404040", + "scrollHandleColor": "#dddddd", + "selectedTextColor": "#ffffff", + "folderIndicatorColor": "#edc518", + "branchIndicatorColor": "#e0e0e0", + "branchIndicatorSelectedColor": "#ffffff", + "folderIconColor": "#e0e0e0", + "folderIconShadowColor": "#000000", + "folderIconSelectedColor": "#e0e0e0", + "folderIconSelectedShadowColor": "#000000", + "folderReadOverlayColor": "#222222", + "folderReadOverlaySelectedColor": "#222222" + }, + "tableView": { + "alternateBackgroundColor": "#2e2e2e", + "backgroundColor": "#2a2a2a", + "headerBackgroundColor": "#2a2a2a", + "headerBorderColor": "#1f1f1f", + "headerGradientColor": "#252525", + "itemBorderBottomColor": "#1f1f1f", + "itemBorderTopColor": "#353535", + "itemBorderBottomWidth": 1, + "itemBorderTopWidth": 1, + "itemTextColor": "#dddddd", + "selectedColor": "#555555", + "selectedTextColor": "#ffffff", + "headerTextColor": "#dddddd", + "starRatingColor": "#e9be0f", + "starRatingSelectedColor": "#ffffff" + }, + "qmlView": { + "backgroundColor": "#2a2a2a", + "cellColor": "#212121", + "cellColorWithBackground": "#99212121", + "selectedColor": "#121212", + "selectedBorderColor": "#ffcc00", + "borderColor": "#121212", + "titleColor": "#ffffff", + "textColor": "#a8a8a8", + "showDropShadow": true, + "infoBackgroundColor": "#2e2e2e", + "infoBorderColor": "#404040", + "infoShadowColor": "#000000", + "infoTextColor": "#b0b0b0", + "infoTitleColor": "#ffffff", + "ratingUnselectedColor": "#1c1c1c", + "ratingSelectedColor": "#ffffff", + "favUncheckedColor": "#1c1c1c", + "favCheckedColor": "#e84852", + "readTickUncheckedColor": "#1c1c1c", + "readTickCheckedColor": "#e84852", + "currentComicBackgroundColor": "#88000000", + "continueReadingBackgroundColor": "#88000000", + "continueReadingColor": "#ffffff", + "backgroundBlurOverlayColor": "#2a2a2a" + }, + "comicsViewToolbar": { + "backgroundColor": "#2a2a2a", + "separatorColor": "#444444", + "checkedBackgroundColor": "#555555", + "iconColor": "#dddddd" + }, + "searchLineEdit": { + "textColor": "#ababab", + "backgroundColor": "#404040", + "iconColor": "#f7f7f7" + }, + "readingListIcons": { + "labelColors": { + "red": "#f67a7b", + "orange": "#f5c240", + "yellow": "#f2e446", + "green": "#ade738", + "cyan": "#a0fddb", + "blue": "#82c7ff", + "violet": "#8f95ff", + "purple": "#d692fc", + "pink": "#fd9cda", + "white": "#fcfcfc", + "light": "#cbcbcb", + "dark": "#b7b7b7" + }, + "labelShadowColor": "#000000", + "labelShadowSelectedColor": "#000000", + "readingListMainColor": "#e7e7e7", + "readingListMainSelectedColor": "#e7e7e7", + "favoritesMainColor": "#e15055", + "favoritesMainSelectedColor": "#e15055", + "currentlyReadingMainColor": "#ffcc00", + "currentlyReadingMainSelectedColor": "#ffcc00", + "currentlyReadingOuterColor": "#000000", + "currentlyReadingOuterSelectedColor": "#000000", + "specialListShadowColor": "#000000", + "specialListShadowSelectedColor": "#000000", + "listMainColor": "#e7e7e7", + "listMainSelectedColor": "#e7e7e7", + "listShadowColor": "#000000", + "listShadowSelectedColor": "#000000", + "listDetailColor": "#464646", + "listDetailSelectedColor": "#464646" + }, + "dialogIcons": { + "iconColor": "#f7f7f7" + }, + "menuIcons": { + "iconColor": "#f7f7f7" + }, + "shortcutsIcons": { + "iconColor": "#f7f7f7" + } +} diff --git a/YACReaderLibrary/themes/builtin_light.json b/YACReaderLibrary/themes/builtin_light.json new file mode 100644 index 000000000..4d9c8744a --- /dev/null +++ b/YACReaderLibrary/themes/builtin_light.json @@ -0,0 +1,238 @@ +{ + "meta": { + "id": "builtin/light", + "displayName": "Default Light", + "variant": "light" + }, + "defaultContentBackgroundColor": "#ffffff", + "comicFlow": { + "backgroundColor": "#dcdcdc", + "textColor": "#303030" + }, + "comicVine": { + "contentTextColor": "#000000", + "contentBackgroundColor": "#ececec", + "contentAltBackgroundColor": "#e0e0e0", + "dialogBackgroundColor": "#fbfbfb", + "tableBackgroundColor": "#f4f4f4", + "tableAltBackgroundColor": "#fafafa", + "tableBorderColor": "#cccccc", + "tableSelectedColor": "#dddddd", + "tableHeaderBackgroundColor": "#e0e0e0", + "tableHeaderGradientColor": "#e0e0e0", + "tableHeaderBorderColor": "#c0c0c0", + "tableHeaderTextColor": "#333333", + "tableScrollHandleColor": "#888888", + "tableScrollBackgroundColor": "#d0d0d0", + "tableSectionBorderLight": "#ffffff", + "tableSectionBorderDark": "#cccccc", + "labelTextColor": "#000000", + "labelBackgroundColor": "#ececec", + "hyperlinkColor": "#ffcc00", + "buttonBackgroundColor": "#e0e0e0", + "buttonTextColor": "#000000", + "buttonBorderColor": "#cccccc", + "radioUncheckedColor": "#e0e0e0", + "radioCheckedBackgroundColor": "#e0e0e0", + "radioCheckedIndicatorColor": "#222222", + "checkBoxTickColor": "#000000", + "toolButtonAccentColor": "#a0a0a0", + "downArrowColor": "#222222", + "upArrowColor": "#222222", + "busyIndicatorColor": "#000000", + "navIconColor": "#222222", + "rowIconColor": "#222222" + }, + "helpAboutDialog": { + "headingColor": "#302f2d", + "linkColor": "#c19441" + }, + "whatsNewDialog": { + "backgroundColor": "#ffffff", + "headerTextColor": "#0a0a0a", + "versionTextColor": "#858585", + "contentTextColor": "#0a0a0a", + "linkColor": "#e8b800", + "closeButtonColor": "#444444", + "headerDecorationColor": "#e8b800" + }, + "emptyContainer": { + "backgroundColor": "#ffffff", + "titleTextColor": "#888888", + "textColor": "#495252", + "descriptionTextColor": "#565959", + "searchIconColor": "#cccccc" + }, + "sidebar": { + "backgroundColor": "#fbfbfb", + "separatorColor": "#808080", + "sectionSeparatorColor": "#e0e0e0", + "uppercaseLabels": true, + "titleTextColor": "#4a494a", + "titleDropShadowColor": "#ffffff", + "busyIndicatorColor": "#808080" + }, + "sidebarIcons": { + "iconColor": "#4f4e4f", + "shadowColor": "#fbfbfb", + "useSystemFolderIcons": false + }, + "libraryItem": { + "textColor": "#000000", + "libraryIconColor": "#606060", + "libraryIconShadowColor": "#ffffff", + "selectedTextColor": "#ffffff", + "selectedBackgroundColor": "#333133", + "libraryIconSelectedColor": "#ffffff", + "libraryOptionsIconColor": "#ffffff" + }, + "importWidget": { + "backgroundColor": "#fafafa", + "titleTextColor": "#495252", + "descriptionTextColor": "#565959", + "currentComicTextColor": "#565959", + "coversViewBackgroundColor": "#e6e6e6", + "coversLabelColor": "#565959", + "coversDecorationBgColor": "#e6e6e6", + "coversDecorationShadowColor": "#a1a1a1", + "modeIconColor": "#e6e6e6", + "iconColor": "#495252", + "iconCheckedColor": "#565959" + }, + "serverConfigDialog": { + "backgroundColor": "#ffffff", + "titleTextColor": "#474747", + "qrMessageTextColor": "#a3a3a3", + "propagandaTextColor": "#4d4d4d", + "labelTextColor": "#575757", + "checkBoxTextColor": "#262626", + "qrBackgroundColor": "#ffffff", + "qrForegroundColor": "#606060", + "decorationColor": "#606060" + }, + "mainToolbar": { + "backgroundColor": "#f0f0f0", + "folderNameColor": "#333133", + "dividerColor": "#b8bdc4", + "iconColor": "#333133", + "iconDisabledColor": "#b0b0b0" + }, + "contentSplitter": { + "handleColor": "#f0f0f0", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "treeView": { + "textColor": "#000000", + "selectionBackgroundColor": "#333133", + "scrollBackgroundColor": "#e0e0e0", + "scrollHandleColor": "#888888", + "selectedTextColor": "#ffffff", + "folderIndicatorColor": "#555f7f", + "branchIndicatorColor": "#606060", + "branchIndicatorSelectedColor": "#ffffff", + "folderIconColor": "#606060", + "folderIconShadowColor": "#ffffff", + "folderIconSelectedColor": "#ffffff", + "folderIconSelectedShadowColor": "#161616", + "folderReadOverlayColor": "#ffffff", + "folderReadOverlaySelectedColor": "#161616" + }, + "tableView": { + "alternateBackgroundColor": "#f2f2f2", + "backgroundColor": "#fafafa", + "headerBackgroundColor": "#f5f5f5", + "headerBorderColor": "#b8bdc4", + "headerGradientColor": "#f5f5f5", + "itemBorderBottomColor": "#dfdfdf", + "itemBorderTopColor": "#fefefe", + "itemBorderBottomWidth": 0, + "itemBorderTopWidth": 0, + "itemTextColor": "#252626", + "selectedColor": "#595959", + "selectedTextColor": "#ffffff", + "headerTextColor": "#313232", + "starRatingColor": "#e9be0f", + "starRatingSelectedColor": "#ffffff" + }, + "qmlView": { + "backgroundColor": "#f6f6f6", + "cellColor": "#ffffff", + "cellColorWithBackground": "#99ffffff", + "selectedColor": "#ffffff", + "selectedBorderColor": "#ffcc00", + "borderColor": "#dbdbdb", + "titleColor": "#121212", + "textColor": "#636363", + "showDropShadow": true, + "infoBackgroundColor": "#ffffff", + "infoBorderColor": "#808080", + "infoShadowColor": "#444444", + "infoTextColor": "#404040", + "infoTitleColor": "#2e2e2e", + "ratingUnselectedColor": "#dedede", + "ratingSelectedColor": "#2b2b2b", + "favUncheckedColor": "#dedede", + "favCheckedColor": "#e84852", + "readTickUncheckedColor": "#dedede", + "readTickCheckedColor": "#e84852", + "currentComicBackgroundColor": "#88ffffff", + "continueReadingBackgroundColor": "#e8e8e8", + "continueReadingColor": "#000000", + "backgroundBlurOverlayColor": "#9e9e9e" + }, + "comicsViewToolbar": { + "backgroundColor": "#f0f0f0", + "separatorColor": "#cccccc", + "checkedBackgroundColor": "#cccccc", + "iconColor": "#404040" + }, + "searchLineEdit": { + "textColor": "#ffffff", + "backgroundColor": "#333133", + "iconColor": "#efefef" + }, + "readingListIcons": { + "labelColors": { + "red": "#f67a7b", + "orange": "#f5c240", + "yellow": "#f2e446", + "green": "#ade738", + "cyan": "#a0fddb", + "blue": "#82c7ff", + "violet": "#8f95ff", + "purple": "#d692fc", + "pink": "#fd9cda", + "white": "#fcfcfc", + "light": "#cbcbcb", + "dark": "#b7b7b7" + }, + "labelShadowColor": "#8f8f8f", + "labelShadowSelectedColor": "#161616", + "readingListMainColor": "#808080", + "readingListMainSelectedColor": "#808080", + "favoritesMainColor": "#e15055", + "favoritesMainSelectedColor": "#e15055", + "currentlyReadingMainColor": "#ffcc00", + "currentlyReadingMainSelectedColor": "#ffcc00", + "currentlyReadingOuterColor": "#000000", + "currentlyReadingOuterSelectedColor": "#000000", + "specialListShadowColor": "#8f8f8f", + "specialListShadowSelectedColor": "#161616", + "listMainColor": "#808080", + "listMainSelectedColor": "#ffffff", + "listShadowColor": "#8f8f8f", + "listShadowSelectedColor": "#161616", + "listDetailColor": "#ffffff", + "listDetailSelectedColor": "#161616" + }, + "dialogIcons": { + "iconColor": "#606060" + }, + "menuIcons": { + "iconColor": "#606060" + }, + "shortcutsIcons": { + "iconColor": "#606060" + } +} diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index 0d98c0adc..b0254429b 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -2,10 +2,12 @@ #define THEME_H #include +#include #include "yacreader_icon.h" #include "help_about_dialog_theme.h" #include "whats_new_dialog_theme.h" +#include "theme_meta.h" struct ComicVineThemeTemplates { QString defaultLabelQSS = "QLabel {color:%1; font-size:12px;font-family:Arial;}"; @@ -452,6 +454,9 @@ struct ComicVineTheme { }; struct Theme { + ThemeMeta meta; + QJsonObject sourceJson; + QColor defaultContentBackgroundColor; ComicFlowColors comicFlow; diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index b9e103e2c..1e0818cd5 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -300,7 +300,7 @@ struct WhatsNewDialogParams { }; struct ThemeParams { - QString themeName; + ThemeMeta meta; QColor defaultContentBackgroundColor; ComicFlowColors comicFlowColors; @@ -342,13 +342,13 @@ Theme makeTheme(const ThemeParams ¶ms) const auto &t = cv.t; auto recolor = [&](const QString &path, const QColor &color) { - return recoloredSvgToThemeFile(path, color, params.themeName); + return recoloredSvgToThemeFile(path, color, params.meta.id); }; theme.comicVine.defaultLabelQSS = t.defaultLabelQSS.arg(cv.labelTextColor.name()); theme.comicVine.titleLabelQSS = t.titleLabelQSS.arg(cv.labelTextColor.name()); theme.comicVine.coverLabelQSS = t.coverLabelQSS.arg(cv.labelBackgroundColor.name(), cv.labelTextColor.name()); - theme.comicVine.radioButtonQSS = t.radioButtonQSS.arg(cv.buttonTextColor.name(), recolor(":/images/comic_vine/radioUnchecked.svg", cv.radioUncheckedColor), recoloredSvgToThemeFile(":/images/comic_vine/radioChecked.svg", cv.radioCheckedBackgroundColor, cv.radioCheckedIndicatorColor, params.themeName)); + theme.comicVine.radioButtonQSS = t.radioButtonQSS.arg(cv.buttonTextColor.name(), recolor(":/images/comic_vine/radioUnchecked.svg", cv.radioUncheckedColor), recoloredSvgToThemeFile(":/images/comic_vine/radioChecked.svg", cv.radioCheckedBackgroundColor, cv.radioCheckedIndicatorColor, params.meta.id)); theme.comicVine.checkBoxQSS = t.checkBoxQSS.arg(cv.buttonTextColor.name(), cv.buttonBorderColor.name(), cv.buttonBackgroundColor.name(), recolor(":/images/comic_vine/checkBoxTick.svg", cv.checkBoxTickColor)); theme.comicVine.scraperLineEditTitleLabelQSS = t.scraperLineEditTitleLabelQSS.arg(cv.contentTextColor.name()); @@ -399,8 +399,8 @@ Theme makeTheme(const ThemeParams ¶ms) theme.whatsNewDialog.versionTextColor = wn.versionTextColor; theme.whatsNewDialog.contentTextColor = wn.contentTextColor; theme.whatsNewDialog.linkColor = wn.linkColor; - theme.whatsNewDialog.closeButtonIcon = QPixmap(recoloredSvgToThemeFile(":/images/custom_dialog/custom_close_button.svg", wn.closeButtonColor, params.themeName)); - theme.whatsNewDialog.headerDecoration = QPixmap(recoloredSvgToThemeFile(":/images/whats_new/whatsnew_header.svg", wn.headerDecorationColor, params.themeName)); + theme.whatsNewDialog.closeButtonIcon = QPixmap(recoloredSvgToThemeFile(":/images/custom_dialog/custom_close_button.svg", wn.closeButtonColor, params.meta.id)); + theme.whatsNewDialog.headerDecoration = QPixmap(recoloredSvgToThemeFile(":/images/whats_new/whatsnew_header.svg", wn.headerDecorationColor, params.meta.id)); // end WhatsNewDialog // EmptyContainer @@ -411,16 +411,16 @@ Theme makeTheme(const ThemeParams ¶ms) theme.emptyContainer.titleLabelQSS = ect.titleLabelQSS.arg(ec.titleTextColor.name()); theme.emptyContainer.textColor = ec.textColor; theme.emptyContainer.descriptionTextColor = ec.descriptionTextColor; - theme.emptyContainer.noLibrariesIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/noLibrariesIcon.svg", ec.searchIconColor, params.themeName), 165, 160, qApp->devicePixelRatio()); + theme.emptyContainer.noLibrariesIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/noLibrariesIcon.svg", ec.searchIconColor, params.meta.id), 165, 160, qApp->devicePixelRatio()); { const qreal dpr = qApp->devicePixelRatio(); - theme.emptyContainer.searchingIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/search_result.svg", ec.searchIconColor, params.themeName, { .suffix = "_searching" }), 97, dpr); - theme.emptyContainer.noSearchResultsIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/search_result.svg", ec.searchIconColor, params.themeName, { .suffix = "_no_results" }), 239, dpr); + theme.emptyContainer.searchingIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/search_result.svg", ec.searchIconColor, params.meta.id, { .suffix = "_searching" }), 97, dpr); + theme.emptyContainer.noSearchResultsIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/search_result.svg", ec.searchIconColor, params.meta.id, { .suffix = "_no_results" }), 239, dpr); - theme.emptyContainer.emptyFolderIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_folder.svg", ec.searchIconColor, params.themeName), 319, 243, dpr); - theme.emptyContainer.emptyFavoritesIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_favorites.svg", QColor(0xe84853), params.themeName), 238, 223, dpr); - theme.emptyContainer.emptyCurrentReadingsIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_current_readings.svg", ec.searchIconColor, params.themeName), 167, 214, dpr); - theme.emptyContainer.emptyReadingListIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_reading_list.svg", ec.searchIconColor, params.themeName), 248, 187, dpr); + theme.emptyContainer.emptyFolderIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_folder.svg", ec.searchIconColor, params.meta.id), 319, 243, dpr); + theme.emptyContainer.emptyFavoritesIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_favorites.svg", QColor(0xe84853), params.meta.id), 238, 223, dpr); + theme.emptyContainer.emptyCurrentReadingsIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_current_readings.svg", ec.searchIconColor, params.meta.id), 167, 214, dpr); + theme.emptyContainer.emptyReadingListIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_reading_list.svg", ec.searchIconColor, params.meta.id), 248, 187, dpr); // Generate empty label icons for each label color const auto &rli = params.readingListIconsParams; @@ -430,7 +430,7 @@ Theme makeTheme(const ThemeParams ¶ms) auto it = rli.labelColors.find(colorName); if (it != rli.labelColors.end()) { theme.emptyContainer.emptyLabelIcons[c] = renderSvgToPixmap( - recoloredSvgToThemeFile(":/images/empty_container/empty_label.svg", it.value(), params.themeName, { .suffix = "_" + colorName }), 243, 243, dpr); + recoloredSvgToThemeFile(":/images/empty_container/empty_label.svg", it.value(), params.meta.id, { .suffix = "_" + colorName }), 243, 243, dpr); } } } @@ -456,14 +456,14 @@ Theme makeTheme(const ThemeParams ¶ms) theme.importWidget.currentComicTextColor = iw.currentComicTextColor; theme.importWidget.coversViewBackgroundColor = iw.coversViewBackgroundColor; theme.importWidget.coversLabelColor = iw.coversLabelColor; - theme.importWidget.topCoversDecoration = QPixmap(recoloredSvgToThemeFile(":/images/import/importTopCoversDecoration.svg", iw.coversDecorationBgColor, iw.coversDecorationShadowColor, params.themeName)); - theme.importWidget.bottomCoversDecoration = QPixmap(recoloredSvgToThemeFile(":/images/import/importBottomCoversDecoration.svg", iw.coversDecorationBgColor, iw.coversDecorationShadowColor, params.themeName)); - theme.importWidget.importingIcon = QPixmap(recoloredSvgToThemeFile(":/images/import/importingIcon.svg", iw.modeIconColor, params.themeName)); - theme.importWidget.updatingIcon = QPixmap(recoloredSvgToThemeFile(":/images/import/updatingIcon.svg", iw.modeIconColor, params.themeName)); + theme.importWidget.topCoversDecoration = QPixmap(recoloredSvgToThemeFile(":/images/import/importTopCoversDecoration.svg", iw.coversDecorationBgColor, iw.coversDecorationShadowColor, params.meta.id)); + theme.importWidget.bottomCoversDecoration = QPixmap(recoloredSvgToThemeFile(":/images/import/importBottomCoversDecoration.svg", iw.coversDecorationBgColor, iw.coversDecorationShadowColor, params.meta.id)); + theme.importWidget.importingIcon = QPixmap(recoloredSvgToThemeFile(":/images/import/importingIcon.svg", iw.modeIconColor, params.meta.id)); + theme.importWidget.updatingIcon = QPixmap(recoloredSvgToThemeFile(":/images/import/updatingIcon.svg", iw.modeIconColor, params.meta.id)); { QIcon coversToggle; - const QString normalPath = recoloredSvgToThemeFile(":/images/import/coversToggle.svg", iw.iconColor, params.themeName); - const QString checkedPath = recoloredSvgToThemeFile(":/images/import/coversToggle.svg", iw.iconCheckedColor, params.themeName, { .suffix = "_checked" }); + const QString normalPath = recoloredSvgToThemeFile(":/images/import/coversToggle.svg", iw.iconColor, params.meta.id); + const QString checkedPath = recoloredSvgToThemeFile(":/images/import/coversToggle.svg", iw.iconCheckedColor, params.meta.id, { .suffix = "_checked" }); coversToggle.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); coversToggle.addFile(checkedPath, QSize(), QIcon::Normal, QIcon::On); theme.importWidget.coversToggleIcon = coversToggle; @@ -503,9 +503,9 @@ Theme makeTheme(const ThemeParams ¶ms) theme.qmlView.textColor = qv.textColor; theme.qmlView.showDropShadow = qv.showDropShadow; theme.qmlView.infoBackgroundColor = qv.infoBackgroundColor; - theme.qmlView.topShadow = recoloredSvgToThemeFile(":/qml/info-top-shadow.svg", qv.infoBackgroundColor, qv.infoBorderColor, qv.infoShadowColor, params.themeName); - theme.qmlView.infoShadow = recoloredSvgToThemeFile(":/qml/info-shadow.svg", qv.infoBackgroundColor, qv.infoBorderColor, qv.infoShadowColor, params.themeName); - theme.qmlView.infoIndicator = recoloredSvgToThemeFile(":/qml/info-indicator.svg", qv.infoBackgroundColor, qv.infoBorderColor, qv.infoShadowColor, params.themeName); + theme.qmlView.topShadow = recoloredSvgToThemeFile(":/qml/info-top-shadow.svg", qv.infoBackgroundColor, qv.infoBorderColor, qv.infoShadowColor, params.meta.id); + theme.qmlView.infoShadow = recoloredSvgToThemeFile(":/qml/info-shadow.svg", qv.infoBackgroundColor, qv.infoBorderColor, qv.infoShadowColor, params.meta.id); + theme.qmlView.infoIndicator = recoloredSvgToThemeFile(":/qml/info-indicator.svg", qv.infoBackgroundColor, qv.infoBorderColor, qv.infoShadowColor, params.meta.id); theme.qmlView.infoTextColor = qv.infoTextColor; theme.qmlView.infoTitleColor = qv.infoTitleColor; theme.qmlView.ratingUnselectedColor = qv.ratingUnselectedColor; @@ -557,8 +557,8 @@ Theme makeTheme(const ThemeParams ¶ms) // Build icons with Normal and Disabled states auto makeToolbarIcon = [&](const QString &basePath) { QIcon icon; - const QString normalPath = recoloredSvgToThemeFile(basePath, mt.iconColor, params.themeName); - const QString disabledPath = recoloredSvgToThemeFile(basePath, mt.iconDisabledColor, params.themeName, { .suffix = "_disabled" }); + const QString normalPath = recoloredSvgToThemeFile(basePath, mt.iconColor, params.meta.id); + const QString disabledPath = recoloredSvgToThemeFile(basePath, mt.iconDisabledColor, params.meta.id, { .suffix = "_disabled" }); icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); icon.addFile(disabledPath, QSize(), QIcon::Disabled, QIcon::Off); return icon; @@ -581,7 +581,7 @@ Theme makeTheme(const ThemeParams ¶ms) // Helper to create icons with shadow (two-color: #f0f main, #0ff shadow) // Adds both Normal and Selected modes to prevent Qt from applying a selection tint auto makeSidebarIcon = [&](const QString &basePath) { - const QString path = recoloredSvgToThemeFile(basePath, si.iconColor, si.shadowColor, params.themeName); + const QString path = recoloredSvgToThemeFile(basePath, si.iconColor, si.shadowColor, params.meta.id); QIcon icon; icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); @@ -590,7 +590,7 @@ Theme makeTheme(const ThemeParams ¶ms) // Helper for single-color icons (only #f0f main) auto makeSingleColorIcon = [&](const QString &basePath) { - const QString path = recoloredSvgToThemeFile(basePath, si.iconColor, params.themeName); + const QString path = recoloredSvgToThemeFile(basePath, si.iconColor, params.meta.id); QIcon icon; icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); @@ -600,14 +600,14 @@ Theme makeTheme(const ThemeParams ¶ms) // System folder icons flag and overlay theme.sidebarIcons.useSystemFolderIcons = si.useSystemFolderIcons; if (si.useSystemFolderIcons) { - const QString overlayPath = recoloredSvgToThemeFile(":/images/sidebar/folder_read_overlay.svg", params.treeViewParams.folderReadOverlayColor, params.themeName); + const QString overlayPath = recoloredSvgToThemeFile(":/images/sidebar/folder_read_overlay.svg", params.treeViewParams.folderReadOverlayColor, params.meta.id); theme.sidebarIcons.folderReadOverlay = QPixmap(overlayPath); } // Library icon (unselected state, two-color: #f0f main, #0ff shadow) { const auto &li = params.libraryItemParams; - const QString libraryIconPath = recoloredSvgToThemeFile(":/images/sidebar/libraryIcon.svg", li.libraryIconColor, li.libraryIconShadowColor, params.themeName); + const QString libraryIconPath = recoloredSvgToThemeFile(":/images/sidebar/libraryIcon.svg", li.libraryIconColor, li.libraryIconShadowColor, params.meta.id); QIcon icon; icon.addFile(libraryIconPath, QSize(), QIcon::Normal, QIcon::Off); icon.addFile(libraryIconPath, QSize(), QIcon::Selected, QIcon::Off); @@ -634,11 +634,11 @@ Theme makeTheme(const ThemeParams ¶ms) theme.libraryItem.selectedBackgroundColor = li.selectedBackgroundColor; // Library icon when selected (uses its own color to contrast with selected background) - const QString libraryIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/libraryIconSelected.svg", li.libraryIconSelectedColor, params.themeName); + const QString libraryIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/libraryIconSelected.svg", li.libraryIconSelectedColor, params.meta.id); theme.libraryItem.libraryIconSelected = QIcon(libraryIconSelectedPath); // Library options icon (shown only when selected, uses its own color) - const QString libraryOptionsPath = recoloredSvgToThemeFile(":/images/sidebar/libraryOptions.svg", li.libraryOptionsIconColor, params.themeName); + const QString libraryOptionsPath = recoloredSvgToThemeFile(":/images/sidebar/libraryOptions.svg", li.libraryOptionsIconColor, params.meta.id); theme.libraryItem.libraryOptionsIcon = QIcon(libraryOptionsPath); // end LibraryItem @@ -646,10 +646,10 @@ Theme makeTheme(const ThemeParams ¶ms) const auto &tv = params.treeViewParams; // Branch indicator icons — own colors, independent of the sidebar icon color - theme.treeView.branchClosedIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-closed.svg", tv.branchIndicatorColor, params.themeName); - theme.treeView.branchOpenIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", tv.branchIndicatorColor, params.themeName); - theme.treeView.branchClosedIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/branch-closed.svg", tv.branchIndicatorSelectedColor, params.themeName, { .suffix = "_selected" }); - theme.treeView.branchOpenIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", tv.branchIndicatorSelectedColor, params.themeName, { .suffix = "_selected" }); + theme.treeView.branchClosedIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-closed.svg", tv.branchIndicatorColor, params.meta.id); + theme.treeView.branchOpenIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", tv.branchIndicatorColor, params.meta.id); + theme.treeView.branchClosedIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/branch-closed.svg", tv.branchIndicatorSelectedColor, params.meta.id, { .suffix = "_selected" }); + theme.treeView.branchOpenIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", tv.branchIndicatorSelectedColor, params.meta.id, { .suffix = "_selected" }); theme.treeView.treeViewQSS = tv.t.styledTreeViewQSS .arg(tv.textColor.name(), @@ -665,16 +665,16 @@ Theme makeTheme(const ThemeParams ¶ms) // Folder icon — normal and selected states with independent colors { - const QString normalPath = recoloredSvgToThemeFile(":/images/sidebar/folder.svg", tv.folderIconColor, tv.folderIconShadowColor, params.themeName); - const QString selectedPath = recoloredSvgToThemeFile(":/images/sidebar/folder.svg", tv.folderIconSelectedColor, tv.folderIconSelectedShadowColor, params.themeName, { .suffix = "_selected" }); + const QString normalPath = recoloredSvgToThemeFile(":/images/sidebar/folder.svg", tv.folderIconColor, tv.folderIconShadowColor, params.meta.id); + const QString selectedPath = recoloredSvgToThemeFile(":/images/sidebar/folder.svg", tv.folderIconSelectedColor, tv.folderIconSelectedShadowColor, params.meta.id, { .suffix = "_selected" }); theme.treeView.folderIcon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); theme.treeView.folderIcon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); } // Folder finished icon — same but with tick (#ff0) recolored independently for each state { - const QString normalPath = recoloredSvgToThemeFile(":/images/sidebar/folder_finished.svg", tv.folderIconColor, tv.folderIconShadowColor, tv.folderReadOverlayColor, params.themeName); - const QString selectedPath = recoloredSvgToThemeFile(":/images/sidebar/folder_finished.svg", tv.folderIconSelectedColor, tv.folderIconSelectedShadowColor, tv.folderReadOverlaySelectedColor, params.themeName, { .suffix = "_selected" }); + const QString normalPath = recoloredSvgToThemeFile(":/images/sidebar/folder_finished.svg", tv.folderIconColor, tv.folderIconShadowColor, tv.folderReadOverlayColor, params.meta.id); + const QString selectedPath = recoloredSvgToThemeFile(":/images/sidebar/folder_finished.svg", tv.folderIconSelectedColor, tv.folderIconSelectedShadowColor, tv.folderReadOverlaySelectedColor, params.meta.id, { .suffix = "_selected" }); theme.treeView.folderFinishedIcon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); theme.treeView.folderFinishedIcon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); } @@ -695,7 +695,7 @@ Theme makeTheme(const ThemeParams ¶ms) // Helper to create single-color icons for comics view toolbar auto makeComicsViewIcon = [&](const QString &basePath) { - const QString path = recoloredSvgToThemeFile(basePath, cvt.iconColor, params.themeName); + const QString path = recoloredSvgToThemeFile(basePath, cvt.iconColor, params.meta.id); QIcon icon; icon.addFile(path, QSize(), QIcon::Normal, QIcon::Off); icon.addFile(path, QSize(), QIcon::Selected, QIcon::Off); @@ -734,8 +734,8 @@ Theme makeTheme(const ThemeParams ¶ms) theme.searchLineEdit.clearButtonQSS = sle.t.clearButtonQSS; const qreal dpr = qApp->devicePixelRatio(); - theme.searchLineEdit.searchIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/iconSearchNew.svg", sle.iconColor, params.themeName), 15, dpr); - theme.searchLineEdit.clearIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/clearSearchNew.svg", sle.iconColor, params.themeName), 12, dpr); + theme.searchLineEdit.searchIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/iconSearchNew.svg", sle.iconColor, params.meta.id), 15, dpr); + theme.searchLineEdit.clearIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/clearSearchNew.svg", sle.iconColor, params.meta.id), 12, dpr); // end SearchLineEdit // ReadingListIcons @@ -743,8 +743,8 @@ Theme makeTheme(const ThemeParams ¶ms) // Helper to create label icons from template (uses color name to generate label_.svg files) auto makeLabelIcon = [&](const QString &colorName, const QColor &mainColor) { - const QString normalPath = recoloredSvgToThemeFile(":/images/lists/label_template.svg", mainColor, rli.labelShadowColor, params.themeName, { .fileName = "label_" + colorName }); - const QString selectedPath = recoloredSvgToThemeFile(":/images/lists/label_template.svg", mainColor, rli.labelShadowSelectedColor, params.themeName, { .suffix = "_selected", .fileName = "label_" + colorName }); + const QString normalPath = recoloredSvgToThemeFile(":/images/lists/label_template.svg", mainColor, rli.labelShadowColor, params.meta.id, { .fileName = "label_" + colorName }); + const QString selectedPath = recoloredSvgToThemeFile(":/images/lists/label_template.svg", mainColor, rli.labelShadowSelectedColor, params.meta.id, { .suffix = "_selected", .fileName = "label_" + colorName }); QIcon icon; icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); icon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); @@ -757,8 +757,8 @@ Theme makeTheme(const ThemeParams ¶ms) // Special list icons auto makeSpecialIcon = [&](const QString &basePath, const QColor &mainColor, const QColor &mainSelectedColor) { - const QString normalPath = recoloredSvgToThemeFile(basePath, mainColor, rli.specialListShadowColor, params.themeName); - const QString selectedPath = recoloredSvgToThemeFile(basePath, mainSelectedColor, rli.specialListShadowSelectedColor, params.themeName, { .suffix = "_selected" }); + const QString normalPath = recoloredSvgToThemeFile(basePath, mainColor, rli.specialListShadowColor, params.meta.id); + const QString selectedPath = recoloredSvgToThemeFile(basePath, mainSelectedColor, rli.specialListShadowSelectedColor, params.meta.id, { .suffix = "_selected" }); QIcon icon; icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); icon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); @@ -770,8 +770,8 @@ Theme makeTheme(const ThemeParams ¶ms) // Currently reading has 3 colors { - const QString normalPath = recoloredSvgToThemeFile(":/images/lists/default_2.svg", rli.currentlyReadingMainColor, rli.specialListShadowColor, rli.currentlyReadingOuterColor, params.themeName); - const QString selectedPath = recoloredSvgToThemeFile(":/images/lists/default_2.svg", rli.currentlyReadingMainSelectedColor, rli.specialListShadowSelectedColor, rli.currentlyReadingOuterSelectedColor, params.themeName, { .suffix = "_selected" }); + const QString normalPath = recoloredSvgToThemeFile(":/images/lists/default_2.svg", rli.currentlyReadingMainColor, rli.specialListShadowColor, rli.currentlyReadingOuterColor, params.meta.id); + const QString selectedPath = recoloredSvgToThemeFile(":/images/lists/default_2.svg", rli.currentlyReadingMainSelectedColor, rli.specialListShadowSelectedColor, rli.currentlyReadingOuterSelectedColor, params.meta.id, { .suffix = "_selected" }); QIcon icon; icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); icon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); @@ -780,8 +780,8 @@ Theme makeTheme(const ThemeParams ¶ms) // List icon (3 colors) { - const QString normalPath = recoloredSvgToThemeFile(":/images/lists/list.svg", rli.listMainColor, rli.listShadowColor, rli.listDetailColor, params.themeName); - const QString selectedPath = recoloredSvgToThemeFile(":/images/lists/list.svg", rli.listMainSelectedColor, rli.listShadowSelectedColor, rli.listDetailSelectedColor, params.themeName, { .suffix = "_selected" }); + const QString normalPath = recoloredSvgToThemeFile(":/images/lists/list.svg", rli.listMainColor, rli.listShadowColor, rli.listDetailColor, params.meta.id); + const QString selectedPath = recoloredSvgToThemeFile(":/images/lists/list.svg", rli.listMainSelectedColor, rli.listShadowSelectedColor, rli.listDetailSelectedColor, params.meta.id, { .suffix = "_selected" }); QIcon icon; icon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); icon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); @@ -792,7 +792,7 @@ Theme makeTheme(const ThemeParams ¶ms) // MenuIcons const auto &mi = params.menuIconsParams; auto makeMenuIcon = [&](const QString &basePath) { - const QString path = recoloredSvgToThemeFile(basePath, mi.iconColor, params.themeName); + const QString path = recoloredSvgToThemeFile(basePath, mi.iconColor, params.meta.id); return QIcon(path); }; @@ -811,7 +811,7 @@ Theme makeTheme(const ThemeParams ¶ms) // DialogIcons const auto &di = params.dialogIconsParams; auto makeDialogIcon = [&](const QString &basePath) { - const QString path = recoloredSvgToThemeFile(basePath, di.iconColor, params.themeName); + const QString path = recoloredSvgToThemeFile(basePath, di.iconColor, params.meta.id); return QPixmap(path); }; theme.dialogIcons.newLibraryIcon = makeDialogIcon(":/images/library_dialogs/new.svg"); @@ -822,7 +822,7 @@ Theme makeTheme(const ThemeParams ¶ms) theme.dialogIcons.exportLibraryIcon = makeDialogIcon(":/images/library_dialogs/exportLibrary.svg"); theme.dialogIcons.importLibraryIcon = makeDialogIcon(":/images/library_dialogs/importLibrary.svg"); { - const QString path = recoloredSvgToThemeFile(":/images/find_folder.svg", di.iconColor, params.themeName); + const QString path = recoloredSvgToThemeFile(":/images/find_folder.svg", di.iconColor, params.meta.id); const qreal dpr = qApp->devicePixelRatio(); theme.dialogIcons.findFolderIcon = QIcon(renderSvgToPixmap(path, 13, 13, dpr)); } @@ -831,7 +831,7 @@ Theme makeTheme(const ThemeParams ¶ms) // ShortcutsIcons const auto &sci = params.shortcutsIconsParams; auto makeShortcutsIcon = [&](const QString &basePath) { - const QString path = recoloredSvgToThemeFile(basePath, sci.iconColor, params.themeName); + const QString path = recoloredSvgToThemeFile(basePath, sci.iconColor, params.meta.id); return QIcon(path); }; @@ -852,842 +852,332 @@ Theme makeTheme(const ThemeParams ¶ms) theme.serverConfigDialog.checkBoxQSS = scd.t.checkBoxQSS.arg(scd.checkBoxTextColor.name()); theme.serverConfigDialog.qrBackgroundColor = scd.qrBackgroundColor; theme.serverConfigDialog.qrForegroundColor = scd.qrForegroundColor; - theme.serverConfigDialog.backgroundDecoration = QPixmap(recoloredSvgToThemeFile(":/images/serverConfigBackground.svg", scd.decorationColor, params.themeName)); + theme.serverConfigDialog.backgroundDecoration = QPixmap(recoloredSvgToThemeFile(":/images/serverConfigBackground.svg", scd.decorationColor, params.meta.id)); + + theme.meta = params.meta; return theme; } -ThemeParams classicThemeParams(); -ThemeParams lightThemeParams(); -ThemeParams darkThemeParams(); +// JSON helpers --------------------------------------------------------------- + +static QColor colorFromJson(const QJsonObject &obj, const QString &key, const QColor &fallback) +{ + if (!obj.contains(key)) + return fallback; + QColor c(obj[key].toString()); + return c.isValid() ? c : fallback; +} -Theme makeTheme(ThemeId themeId) +Theme makeTheme(const QJsonObject &json) { + ThemeParams p; - switch (themeId) { - case ThemeId::Classic: - return makeTheme(classicThemeParams()); - case ThemeId::Light: - return makeTheme(lightThemeParams()); - case ThemeId::Dark: - return makeTheme(darkThemeParams()); + if (json.contains("defaultContentBackgroundColor")) { + QColor c(json["defaultContentBackgroundColor"].toString()); + if (c.isValid()) + p.defaultContentBackgroundColor = c; } - return makeTheme(classicThemeParams()); -} + if (json.contains("comicFlow")) { + const auto o = json["comicFlow"].toObject(); + p.comicFlowColors.backgroundColor = colorFromJson(o, "backgroundColor", p.comicFlowColors.backgroundColor); + p.comicFlowColors.textColor = colorFromJson(o, "textColor", p.comicFlowColors.textColor); + } -ThemeParams classicThemeParams() -{ - ThemeParams params; - params.themeName = "classic"; - params.defaultContentBackgroundColor = QColor(0x2A2A2A); - - ComicFlowColors cf; - cf.backgroundColor = Qt::black; - cf.textColor = QColor(0x4C4C4C); - - ComicVineParams cv; - cv.contentTextColor = Qt::white; - cv.contentBackgroundColor = QColor(0x2B2B2B); - cv.contentAltBackgroundColor = QColor(0x2B2B2B); - cv.dialogBackgroundColor = QColor(0x404040); - - cv.tableBackgroundColor = QColor(0x2B2B2B); - cv.tableAltBackgroundColor = QColor(0x2E2E2E); - cv.tableBorderColor = QColor(0x242424); - cv.tableSelectedColor = QColor(0x555555); - cv.tableHeaderBackgroundColor = QColor(0x292929); - cv.tableHeaderGradientColor = QColor(0x292929); - cv.tableHeaderBorderColor = QColor(0x1F1F1F); - cv.tableHeaderTextColor = QColor(0xEBEBEB); - cv.tableScrollHandleColor = QColor(0xDDDDDD); - cv.tableScrollBackgroundColor = QColor(0x404040); - cv.tableSectionBorderLight = QColor(0xFEFEFE); - cv.tableSectionBorderDark = QColor(0xDFDFDF); - - cv.labelTextColor = Qt::white; - cv.labelBackgroundColor = QColor(0x2B2B2B); - cv.hyperlinkColor = QColor(0xFFCC00); - - cv.buttonBackgroundColor = QColor(0x2E2E2E); - cv.buttonTextColor = Qt::white; - cv.buttonBorderColor = QColor(0x242424); - - cv.radioUncheckedColor = QColor(0xE5E5E5); - - cv.radioCheckedBackgroundColor = QColor(0xE5E5E5); - cv.radioCheckedIndicatorColor = QColor(0x5F5F5F); - - cv.checkBoxTickColor = Qt::white; - - cv.toolButtonAccentColor = QColor(0x282828); - - cv.downArrowColor = QColor(0x9F9F9F); - cv.upArrowColor = QColor(0x9F9F9F); - - cv.busyIndicatorColor = Qt::white; - cv.navIconColor = Qt::white; - cv.rowIconColor = QColor(0xE5E5E5); - - cv.t = ComicVineThemeTemplates(); - - params.comicFlowColors = cf; - params.comicVineParams = cv; - - params.helpAboutDialogParams.headingColor = QColor(0x302f2d); - params.helpAboutDialogParams.linkColor = QColor(0xC19441); - - WhatsNewDialogParams wnp; - wnp.backgroundColor = QColor(0x2A2A2A); - wnp.headerTextColor = QColor(0xE0E0E0); - wnp.versionTextColor = QColor(0x858585); - wnp.contentTextColor = QColor(0xE0E0E0); - wnp.linkColor = QColor(0xE8B800); - wnp.closeButtonColor = QColor(0xDDDDDD); - wnp.headerDecorationColor = QColor(0xE8B800); - params.whatsNewDialogParams = wnp; - - EmptyContainerParams ec; - ec.backgroundColor = QColor(0x2A2A2A); - ec.titleTextColor = QColor(0xCCCCCC); - ec.textColor = QColor(0xCCCCCC); - ec.descriptionTextColor = QColor(0xAAAAAA); - ec.searchIconColor = QColor(0x4C4C4C); - ec.t = EmptyContainerThemeTemplates(); - params.emptyContainerParams = ec; - - SidebarParams sb; - sb.backgroundColor = QColor(0x454545); - sb.separatorColor = QColor(0xBDBFBF); - sb.sectionSeparatorColor = QColor(0x575757); - sb.uppercaseLabels = true; - sb.titleTextColor = QColor(0xBDBFBF); - sb.titleDropShadowColor = Qt::black; - sb.busyIndicatorColor = Qt::white; - params.sidebarParams = sb; - - ImportWidgetParams iw; - iw.backgroundColor = QColor(0x2A2A2A); - iw.titleTextColor = QColor(0xCCCCCC); - iw.descriptionTextColor = QColor(0xAAAAAA); - iw.currentComicTextColor = QColor(0xAAAAAA); - iw.coversViewBackgroundColor = QColor(0x3A3A3A); - iw.coversLabelColor = QColor(0xAAAAAA); - iw.coversDecorationBgColor = QColor(0x3A3A3A); - iw.coversDecorationShadowColor = QColor(0x1A1A1A); - iw.modeIconColor = QColor(0x4A4A4A); - iw.iconColor = QColor(0xCCCCCC); - iw.iconCheckedColor = QColor(0xAAAAAA); - params.importWidgetParams = iw; - - TreeViewParams tv; - tv.textColor = QColor(0xDDDFDF); - tv.selectionBackgroundColor = QColor(0x2E2E2E); - tv.scrollBackgroundColor = QColor(0x404040); - tv.scrollHandleColor = QColor(0xDDDDDD); - tv.selectedTextColor = Qt::white; - tv.folderIndicatorColor = QColor(237, 197, 24); - tv.branchIndicatorColor = QColor(0xE0E0E0); - tv.branchIndicatorSelectedColor = QColor(0xFFFFFF); - tv.folderIconColor = QColor(0xE0E0E0); - tv.folderIconShadowColor = QColor(0xFF000000); - tv.folderIconSelectedColor = QColor(0xE0E0E0); - tv.folderIconSelectedShadowColor = QColor(0xFF000000); - tv.folderReadOverlayColor = QColor(0x464646); - tv.folderReadOverlaySelectedColor = QColor(0x464646); - params.treeViewParams = tv; - - TableViewParams tav; - tav.alternateBackgroundColor = QColor(0xF2F2F2); - tav.backgroundColor = QColor(0xFAFAFA); - tav.headerBackgroundColor = QColor(0xF5F5F5); - tav.headerBorderColor = QColor(0xB8BDC4); - tav.headerGradientColor = QColor(0xD1D1D1); - tav.itemBorderBottomColor = QColor(0xDFDFDF); - tav.itemBorderTopColor = QColor(0xFEFEFE); - tav.itemBorderBottomWidth = 1; - tav.itemBorderTopWidth = 1; - tav.itemTextColor = QColor(0x252626); - tav.selectedColor = QColor(0xD4D4D4); - tav.selectedTextColor = QColor(0x252626); - tav.headerTextColor = QColor(0x313232); - tav.starRatingColor = QColor(0xE9BE0F); - tav.starRatingSelectedColor = QColor(0xFFFFFF); - tav.t = TableViewThemeTemplates(); - params.tableViewParams = tav; - - QmlViewParams qv; - qv.backgroundColor = QColor(0x2A2A2A); - qv.cellColor = QColor(0x212121); - qv.cellColorWithBackground = QColor(0x21, 0x21, 0x21, 0x99); - qv.selectedColor = QColor(0x121212); - qv.selectedBorderColor = QColor(0xFFCC00); - qv.borderColor = QColor(0x121212); - qv.titleColor = QColor(0xFFFFFF); - qv.textColor = QColor(0xA8A8A8); - qv.showDropShadow = true; - qv.infoBackgroundColor = QColor(0x2E2E2E); - qv.infoBorderColor = QColor(0x404040); - qv.infoShadowColor = Qt::black; - qv.infoTextColor = QColor(0xB0B0B0); - qv.infoTitleColor = QColor(0xFFFFFF); - qv.ratingUnselectedColor = QColor(0x1C1C1C); - qv.ratingSelectedColor = QColor(0xFFFFFF); - qv.favUncheckedColor = QColor(0x1C1C1C); - qv.favCheckedColor = QColor(0xE84852); - qv.readTickUncheckedColor = QColor(0x1C1C1C); - qv.readTickCheckedColor = QColor(0xE84852); - qv.currentComicBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); - qv.continueReadingBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); - qv.continueReadingColor = QColor(0xFFFFFF); - qv.backgroundBlurOverlayColor = QColor(0x2A2A2A); - params.qmlViewParams = qv; - - MainToolbarParams mt; - mt.backgroundColor = QColor(0xF0F0F0); - mt.folderNameColor = QColor(0x404040); - mt.dividerColor = QColor(0xB8BDC4); - mt.iconColor = QColor(0x404040); - mt.iconDisabledColor = QColor(0xB0B0B0); - params.mainToolbarParams = mt; - - ContentSplitterParams cs; - cs.handleColor = QColor(0xB8B8B8); - cs.horizontalHandleHeight = 4; - cs.verticalHandleWidth = 4; - params.contentSplitterParams = cs; - - SidebarIconsParams si; - si.iconColor = QColor(0xE0E0E0); - si.shadowColor = QColor(0xFF000000); - si.useSystemFolderIcons = false; - params.sidebarIconsParams = si; - - LibraryItemParams li; - li.textColor = QColor(0xDDDFDF); - li.libraryIconColor = QColor(0xDDDFDF); - li.libraryIconShadowColor = QColor(0xFF000000); - li.selectedTextColor = Qt::white; - li.selectedBackgroundColor = QColor(0x2E2E2E); - li.libraryIconSelectedColor = Qt::white; - li.libraryOptionsIconColor = Qt::white; - params.libraryItemParams = li; - - ComicsViewToolbarParams cvt; - cvt.backgroundColor = QColor(0xF0F0F0); - cvt.separatorColor = QColor(0xCCCCCC); - cvt.checkedBackgroundColor = QColor(0xCCCCCC); - cvt.iconColor = QColor(0x404040); - params.comicsViewToolbarParams = cvt; - - SearchLineEditParams sle; - sle.textColor = QColor(0xABABAB); - sle.backgroundColor = QColor(0x404040); - sle.iconColor = QColor(0xF7F7F7); - params.searchLineEditParams = sle; - - ReadingListIconsParams rli; - rli.labelColors = { - { "red", QColor(0xf67a7b) }, - { "orange", QColor(0xf5c240) }, - { "yellow", QColor(0xf2e446) }, - { "green", QColor(0xade738) }, - { "cyan", QColor(0xa0fddb) }, - { "blue", QColor(0x82c7ff) }, - { "violet", QColor(0x8f95ff) }, - { "purple", QColor(0xd692fc) }, - { "pink", QColor(0xfd9cda) }, - { "white", QColor(0xfcfcfc) }, - { "light", QColor(0xcbcbcb) }, - { "dark", QColor(0xb7b7b7) } - }; - rli.labelShadowColor = Qt::black; - rli.labelShadowSelectedColor = Qt::black; - rli.readingListMainColor = QColor(0xe7e7e7); - rli.readingListMainSelectedColor = QColor(0xe7e7e7); - rli.favoritesMainColor = QColor(0xe15055); - rli.favoritesMainSelectedColor = QColor(0xe15055); - rli.currentlyReadingMainColor = QColor(0xffcc00); - rli.currentlyReadingMainSelectedColor = QColor(0xffcc00); - rli.currentlyReadingOuterColor = Qt::black; - rli.currentlyReadingOuterSelectedColor = Qt::black; - rli.specialListShadowColor = Qt::black; - rli.specialListShadowSelectedColor = Qt::black; - rli.listMainColor = QColor(0xe7e7e7); - rli.listMainSelectedColor = QColor(0xe7e7e7); - rli.listShadowColor = Qt::black; - rli.listShadowSelectedColor = Qt::black; - rli.listDetailColor = QColor(0x464646); - rli.listDetailSelectedColor = QColor(0x464646); - params.readingListIconsParams = rli; - - MenuIconsParams mi; - mi.iconColor = QColor(0xF7F7F7); - params.menuIconsParams = mi; - - DialogIconsParams dip; - dip.iconColor = mi.iconColor; - params.dialogIconsParams = dip; - - ShortcutsIconsParams sci; - sci.iconColor = QColor(0xF7F7F7); - params.shortcutsIconsParams = sci; - - ServerConfigDialogParams scd; - scd.backgroundColor = QColor(0x2A2A2A); - scd.titleTextColor = QColor(0x474747); - scd.qrMessageTextColor = QColor(0xA3A3A3); - scd.propagandaTextColor = QColor(0x4D4D4D); - scd.labelTextColor = QColor(0x575757); - scd.checkBoxTextColor = QColor(0x262626); - scd.qrBackgroundColor = QColor(0x2A2A2A); - scd.qrForegroundColor = Qt::white; - scd.decorationColor = QColor(0xF7F7F7); - params.serverConfigDialogParams = scd; - - return params; -} + if (json.contains("comicVine")) { + const auto o = json["comicVine"].toObject(); + auto &cv = p.comicVineParams; + cv.contentTextColor = colorFromJson(o, "contentTextColor", cv.contentTextColor); + cv.contentBackgroundColor = colorFromJson(o, "contentBackgroundColor", cv.contentBackgroundColor); + cv.contentAltBackgroundColor = colorFromJson(o, "contentAltBackgroundColor", cv.contentAltBackgroundColor); + cv.dialogBackgroundColor = colorFromJson(o, "dialogBackgroundColor", cv.dialogBackgroundColor); + cv.tableBackgroundColor = colorFromJson(o, "tableBackgroundColor", cv.tableBackgroundColor); + cv.tableAltBackgroundColor = colorFromJson(o, "tableAltBackgroundColor", cv.tableAltBackgroundColor); + cv.tableBorderColor = colorFromJson(o, "tableBorderColor", cv.tableBorderColor); + cv.tableSelectedColor = colorFromJson(o, "tableSelectedColor", cv.tableSelectedColor); + cv.tableHeaderBackgroundColor = colorFromJson(o, "tableHeaderBackgroundColor", cv.tableHeaderBackgroundColor); + cv.tableHeaderGradientColor = colorFromJson(o, "tableHeaderGradientColor", cv.tableHeaderGradientColor); + cv.tableHeaderBorderColor = colorFromJson(o, "tableHeaderBorderColor", cv.tableHeaderBorderColor); + cv.tableHeaderTextColor = colorFromJson(o, "tableHeaderTextColor", cv.tableHeaderTextColor); + cv.tableScrollHandleColor = colorFromJson(o, "tableScrollHandleColor", cv.tableScrollHandleColor); + cv.tableScrollBackgroundColor = colorFromJson(o, "tableScrollBackgroundColor", cv.tableScrollBackgroundColor); + cv.tableSectionBorderLight = colorFromJson(o, "tableSectionBorderLight", cv.tableSectionBorderLight); + cv.tableSectionBorderDark = colorFromJson(o, "tableSectionBorderDark", cv.tableSectionBorderDark); + cv.labelTextColor = colorFromJson(o, "labelTextColor", cv.labelTextColor); + cv.labelBackgroundColor = colorFromJson(o, "labelBackgroundColor", cv.labelBackgroundColor); + cv.hyperlinkColor = colorFromJson(o, "hyperlinkColor", cv.hyperlinkColor); + cv.buttonBackgroundColor = colorFromJson(o, "buttonBackgroundColor", cv.buttonBackgroundColor); + cv.buttonTextColor = colorFromJson(o, "buttonTextColor", cv.buttonTextColor); + cv.buttonBorderColor = colorFromJson(o, "buttonBorderColor", cv.buttonBorderColor); + cv.radioUncheckedColor = colorFromJson(o, "radioUncheckedColor", cv.radioUncheckedColor); + cv.radioCheckedBackgroundColor = colorFromJson(o, "radioCheckedBackgroundColor", cv.radioCheckedBackgroundColor); + cv.radioCheckedIndicatorColor = colorFromJson(o, "radioCheckedIndicatorColor", cv.radioCheckedIndicatorColor); + cv.checkBoxTickColor = colorFromJson(o, "checkBoxTickColor", cv.checkBoxTickColor); + cv.toolButtonAccentColor = colorFromJson(o, "toolButtonAccentColor", cv.toolButtonAccentColor); + cv.downArrowColor = colorFromJson(o, "downArrowColor", cv.downArrowColor); + cv.upArrowColor = colorFromJson(o, "upArrowColor", cv.upArrowColor); + cv.busyIndicatorColor = colorFromJson(o, "busyIndicatorColor", cv.busyIndicatorColor); + cv.navIconColor = colorFromJson(o, "navIconColor", cv.navIconColor); + cv.rowIconColor = colorFromJson(o, "rowIconColor", cv.rowIconColor); + } -ThemeParams lightThemeParams() -{ - ThemeParams params; - params.themeName = "light"; - params.defaultContentBackgroundColor = QColor(0xFFFFFF); - - ComicFlowColors cf; - cf.backgroundColor = QColor(0xDCDCDC); - cf.textColor = QColor(0x303030); - - ComicVineParams cv; - cv.contentTextColor = Qt::black; - cv.contentBackgroundColor = QColor(0xECECEC); - cv.contentAltBackgroundColor = QColor(0xE0E0E0); - cv.dialogBackgroundColor = QColor(0xFBFBFB); - - cv.tableBackgroundColor = QColor(0xF4F4F4); - cv.tableAltBackgroundColor = QColor(0xFAFAFA); - cv.tableBorderColor = QColor(0xCCCCCC); - cv.tableSelectedColor = QColor(0xDDDDDD); - cv.tableHeaderBackgroundColor = QColor(0xE0E0E0); - cv.tableHeaderGradientColor = QColor(0xE0E0E0); - cv.tableHeaderBorderColor = QColor(0xC0C0C0); - cv.tableHeaderTextColor = QColor(0x333333); - cv.tableScrollHandleColor = QColor(0x888888); - cv.tableScrollBackgroundColor = QColor(0xD0D0D0); - cv.tableSectionBorderLight = QColor(0xFFFFFF); - cv.tableSectionBorderDark = QColor(0xCCCCCC); - - cv.labelTextColor = Qt::black; - cv.labelBackgroundColor = QColor(0xECECEC); - cv.hyperlinkColor = QColor(0xFFCC00); - - cv.buttonBackgroundColor = QColor(0xE0E0E0); - cv.buttonTextColor = Qt::black; - cv.buttonBorderColor = QColor(0xCCCCCC); - - cv.radioUncheckedColor = QColor(0xE0E0E0); - - cv.radioCheckedBackgroundColor = QColor(0xE0E0E0); - cv.radioCheckedIndicatorColor = QColor(0x222222); - - cv.checkBoxTickColor = Qt::black; - - cv.toolButtonAccentColor = QColor(0xA0A0A0); - - cv.downArrowColor = QColor(0x222222); - cv.upArrowColor = QColor(0x222222); - - cv.busyIndicatorColor = Qt::black; - cv.navIconColor = QColor(0x222222); - cv.rowIconColor = QColor(0x222222); - - cv.t = ComicVineThemeTemplates(); - - params.comicFlowColors = cf; - params.comicVineParams = cv; - - params.helpAboutDialogParams.headingColor = QColor(0x302f2d); - params.helpAboutDialogParams.linkColor = QColor(0xC19441); - - WhatsNewDialogParams wnp; - wnp.backgroundColor = QColor(0xFFFFFF); - wnp.headerTextColor = QColor(0x0A0A0A); - wnp.versionTextColor = QColor(0x858585); - wnp.contentTextColor = QColor(0x0A0A0A); - wnp.linkColor = QColor(0xE8B800); - wnp.closeButtonColor = QColor(0x444444); - wnp.headerDecorationColor = QColor(0xE8B800); - params.whatsNewDialogParams = wnp; - - EmptyContainerParams ec; - ec.backgroundColor = QColor(0xFFFFFF); - ec.titleTextColor = QColor(0x888888); - ec.textColor = QColor(0x495252); - ec.descriptionTextColor = QColor(0x565959); - ec.searchIconColor = QColor(0xCCCCCC); - ec.t = EmptyContainerThemeTemplates(); - params.emptyContainerParams = ec; - - SidebarParams sb; - sb.backgroundColor = QColor(0xFBFBFB); - sb.separatorColor = QColor(0x808080); - sb.sectionSeparatorColor = QColor(0xE0E0E0); - sb.uppercaseLabels = true; - sb.titleTextColor = QColor(0x4A494A); - sb.titleDropShadowColor = QColor(0xFFFFFF); - sb.busyIndicatorColor = QColor(0x808080); - params.sidebarParams = sb; - - ImportWidgetParams iw; - iw.backgroundColor = QColor(0xFAFAFA); - iw.titleTextColor = QColor(0x495252); - iw.descriptionTextColor = QColor(0x565959); - iw.currentComicTextColor = QColor(0x565959); - iw.coversViewBackgroundColor = QColor(0xE6E6E6); - iw.coversLabelColor = QColor(0x565959); - iw.coversDecorationBgColor = QColor(0xE6E6E6); - iw.coversDecorationShadowColor = QColor(0xA1A1A1); - iw.modeIconColor = QColor(0xE6E6E6); - iw.iconColor = QColor(0x495252); - iw.iconCheckedColor = QColor(0x565959); - params.importWidgetParams = iw; - - TreeViewParams tv; - tv.textColor = Qt::black; - tv.selectionBackgroundColor = QColor(0x333133); - tv.scrollBackgroundColor = QColor(0xE0E0E0); - tv.scrollHandleColor = QColor(0x888888); - tv.selectedTextColor = QColor(0xFFFFFF); - tv.folderIndicatorColor = QColor(85, 95, 127); - tv.branchIndicatorColor = QColor(0x606060); - tv.branchIndicatorSelectedColor = QColor(0xFFFFFF); - tv.folderIconColor = QColor(0x606060); - tv.folderIconShadowColor = QColor(0xFFFFFF); - tv.folderIconSelectedColor = QColor(0xFFFFFF); - tv.folderIconSelectedShadowColor = QColor(0x161616); - tv.folderReadOverlayColor = QColor(0xFFFFFF); - tv.folderReadOverlaySelectedColor = QColor(0x161616); - params.treeViewParams = tv; - - TableViewParams tav; - tav.alternateBackgroundColor = QColor(0xF2F2F2); - tav.backgroundColor = QColor(0xFAFAFA); - tav.headerBackgroundColor = QColor(0xF5F5F5); - tav.headerBorderColor = QColor(0xB8BDC4); - tav.headerGradientColor = QColor(0xF5F5F5); - tav.itemBorderBottomColor = QColor(0xDFDFDF); - tav.itemBorderTopColor = QColor(0xFEFEFE); - tav.itemBorderBottomWidth = 0; - tav.itemBorderTopWidth = 0; - tav.itemTextColor = QColor(0x252626); - tav.selectedColor = QColor(0x595959); - tav.selectedTextColor = QColor(0xFFFFFF); - tav.headerTextColor = QColor(0x313232); - tav.starRatingColor = QColor(0xE9BE0F); - tav.starRatingSelectedColor = QColor(0xFFFFFF); - tav.t = TableViewThemeTemplates(); - params.tableViewParams = tav; - - QmlViewParams qv; - qv.backgroundColor = QColor(0xF6F6F6); - qv.cellColor = QColor(0xFFFFFF); - qv.cellColorWithBackground = QColor(0xFF, 0xFF, 0xFF, 0x99); - qv.selectedColor = QColor(0xFFFFFF); - qv.selectedBorderColor = QColor(0xFFCC00); - qv.borderColor = QColor(0xDBDBDB); - qv.titleColor = QColor(0x121212); - qv.textColor = QColor(0x636363); - qv.showDropShadow = true; - qv.infoBackgroundColor = QColor(0xFFFFFF); - qv.infoBorderColor = QColor(0x808080); - qv.infoShadowColor = QColor(0x444444); - qv.infoTextColor = QColor(0x404040); - qv.infoTitleColor = QColor(0x2E2E2E); - qv.ratingUnselectedColor = QColor(0xDEDEDE); - qv.ratingSelectedColor = QColor(0x2B2B2B); - qv.favUncheckedColor = QColor(0xDEDEDE); - qv.favCheckedColor = QColor(0xE84852); - qv.readTickUncheckedColor = QColor(0xDEDEDE); - qv.readTickCheckedColor = QColor(0xE84852); - qv.currentComicBackgroundColor = QColor(0xFF, 0xFF, 0xFF, 0x88); - qv.continueReadingBackgroundColor = QColor(0xE8E8E8); - qv.continueReadingColor = QColor::fromRgb(0x000000); - qv.backgroundBlurOverlayColor = QColor(0x9E9E9E); - params.qmlViewParams = qv; - - MainToolbarParams mt; - mt.backgroundColor = QColor(0xF0F0F0); - mt.folderNameColor = QColor(0x333133); - mt.dividerColor = QColor(0xB8BDC4); - mt.iconColor = QColor(0x333133); - mt.iconDisabledColor = QColor(0xB0B0B0); - params.mainToolbarParams = mt; - - ContentSplitterParams cs; - cs.handleColor = QColor(0xF0F0F0); - cs.horizontalHandleHeight = 4; - cs.verticalHandleWidth = 4; - params.contentSplitterParams = cs; - - SidebarIconsParams si; - si.iconColor = QColor(0x4F4E4F); - si.shadowColor = QColor(0xFBFBFB); - si.useSystemFolderIcons = false; - params.sidebarIconsParams = si; - - LibraryItemParams li; - li.textColor = Qt::black; - li.libraryIconColor = QColor(0x606060); - li.libraryIconShadowColor = QColor(0xFFFFFF); - li.selectedTextColor = QColor(0xFFFFFF); - li.selectedBackgroundColor = QColor(0x333133); - li.libraryIconSelectedColor = QColor(0xFFFFFF); - li.libraryOptionsIconColor = QColor(0xFFFFFF); - params.libraryItemParams = li; - - ComicsViewToolbarParams cvt; - cvt.backgroundColor = QColor(0xF0F0F0); - cvt.separatorColor = QColor(0xCCCCCC); - cvt.checkedBackgroundColor = QColor(0xCCCCCC); - cvt.iconColor = QColor(0x404040); - params.comicsViewToolbarParams = cvt; - - SearchLineEditParams sle; - sle.textColor = QColor(0xFFFFFF); - sle.backgroundColor = QColor(0x333133); - sle.iconColor = QColor(0xEFEFEF); - params.searchLineEditParams = sle; - - ReadingListIconsParams rli; - rli.labelColors = { - { "red", QColor(0xf67a7b) }, - { "orange", QColor(0xf5c240) }, - { "yellow", QColor(0xf2e446) }, - { "green", QColor(0xade738) }, - { "cyan", QColor(0xa0fddb) }, - { "blue", QColor(0x82c7ff) }, - { "violet", QColor(0x8f95ff) }, - { "purple", QColor(0xd692fc) }, - { "pink", QColor(0xfd9cda) }, - { "white", QColor(0xfcfcfc) }, - { "light", QColor(0xcbcbcb) }, - { "dark", QColor(0xb7b7b7) } - }; - rli.labelShadowColor = QColor(0x8F8F8F); - rli.labelShadowSelectedColor = QColor(0x161616); - rli.readingListMainColor = QColor(0x808080); - rli.readingListMainSelectedColor = QColor(0x808080); - rli.favoritesMainColor = QColor(0xe15055); - rli.favoritesMainSelectedColor = QColor(0xe15055); - rli.currentlyReadingMainColor = QColor(0xffcc00); - rli.currentlyReadingMainSelectedColor = QColor(0xffcc00); - rli.currentlyReadingOuterColor = Qt::black; - rli.currentlyReadingOuterSelectedColor = Qt::black; - rli.specialListShadowColor = QColor(0x8F8F8F); - rli.specialListShadowSelectedColor = QColor(0x161616); - rli.listMainColor = QColor(0x808080); - rli.listMainSelectedColor = QColor(0xFFFFFF); - rli.listShadowColor = QColor(0x8F8F8F); - rli.listShadowSelectedColor = QColor(0x161616); - rli.listDetailColor = QColor(0xFFFFFF); - rli.listDetailSelectedColor = QColor(0x161616); - params.readingListIconsParams = rli; - - MenuIconsParams mi; - mi.iconColor = QColor(0x606060); - params.menuIconsParams = mi; - - DialogIconsParams dip; - dip.iconColor = mi.iconColor; - params.dialogIconsParams = dip; - - ShortcutsIconsParams sci; - sci.iconColor = QColor(0x606060); - params.shortcutsIconsParams = sci; - - ServerConfigDialogParams scd; - scd.backgroundColor = QColor(0xFFFFFF); - scd.titleTextColor = QColor(0x474747); - scd.qrMessageTextColor = QColor(0xA3A3A3); - scd.propagandaTextColor = QColor(0x4D4D4D); - scd.labelTextColor = QColor(0x575757); - scd.checkBoxTextColor = QColor(0x262626); - scd.qrBackgroundColor = Qt::white; - scd.qrForegroundColor = QColor(0x606060); - scd.decorationColor = QColor(0x606060); - params.serverConfigDialogParams = scd; - - return params; -} + if (json.contains("helpAboutDialog")) { + const auto o = json["helpAboutDialog"].toObject(); + p.helpAboutDialogParams.headingColor = colorFromJson(o, "headingColor", p.helpAboutDialogParams.headingColor); + p.helpAboutDialogParams.linkColor = colorFromJson(o, "linkColor", p.helpAboutDialogParams.linkColor); + } -ThemeParams darkThemeParams() -{ - ThemeParams params; - params.themeName = "dark"; - params.defaultContentBackgroundColor = QColor(0x2A2A2A); - - ComicFlowColors cf; - cf.backgroundColor = QColor(0x111111); - cf.textColor = QColor(0x888888); - - ComicVineParams cv; - cv.contentTextColor = Qt::white; - cv.contentBackgroundColor = QColor(0x2B2B2B); - cv.contentAltBackgroundColor = QColor(0x2E2E2E); - cv.dialogBackgroundColor = QColor(0x404040); - - cv.tableBackgroundColor = QColor(0x2B2B2B); - cv.tableAltBackgroundColor = QColor(0x2E2E2E); - cv.tableBorderColor = QColor(0x242424); - cv.tableSelectedColor = QColor(0x555555); - cv.tableHeaderBackgroundColor = QColor(0x292929); - cv.tableHeaderGradientColor = QColor(0x292929); - cv.tableHeaderBorderColor = QColor(0x1F1F1F); - cv.tableHeaderTextColor = QColor(0xEBEBEB); - cv.tableScrollHandleColor = QColor(0xDDDDDD); - cv.tableScrollBackgroundColor = QColor(0x404040); - cv.tableSectionBorderLight = QColor(0xFEFEFE); - cv.tableSectionBorderDark = QColor(0xDFDFDF); - - cv.labelTextColor = Qt::white; - cv.labelBackgroundColor = QColor(0x2B2B2B); - cv.hyperlinkColor = QColor(0xFFCC00); - - cv.buttonBackgroundColor = QColor(0x2E2E2E); - cv.buttonTextColor = Qt::white; - cv.buttonBorderColor = QColor(0x242424); - - cv.radioUncheckedColor = QColor(0xE5E5E5); - - cv.radioCheckedBackgroundColor = QColor(0xE5E5E5); - cv.radioCheckedIndicatorColor = QColor(0x5F5F5F); - - cv.checkBoxTickColor = Qt::white; - - cv.toolButtonAccentColor = QColor(0x282828); - - cv.downArrowColor = QColor(0x9F9F9F); - cv.upArrowColor = QColor(0x9F9F9F); - - cv.busyIndicatorColor = Qt::white; - cv.navIconColor = Qt::white; - cv.rowIconColor = QColor(0xE5E5E5); - - cv.t = ComicVineThemeTemplates(); - - params.comicFlowColors = cf; - params.comicVineParams = cv; - - params.helpAboutDialogParams.headingColor = QColor(0xE0E0E0); - params.helpAboutDialogParams.linkColor = QColor(0xD4A84B); - - WhatsNewDialogParams wnp; - wnp.backgroundColor = QColor(0x2A2A2A); - wnp.headerTextColor = QColor(0xE0E0E0); - wnp.versionTextColor = QColor(0x858585); - wnp.contentTextColor = QColor(0xE0E0E0); - wnp.linkColor = QColor(0xE8B800); - wnp.closeButtonColor = QColor(0xDDDDDD); - wnp.headerDecorationColor = QColor(0xE8B800); - params.whatsNewDialogParams = wnp; - - EmptyContainerParams ec; - ec.backgroundColor = QColor(0x2A2A2A); - ec.titleTextColor = QColor(0xCCCCCC); - ec.textColor = QColor(0xCCCCCC); - ec.descriptionTextColor = QColor(0xAAAAAA); - ec.searchIconColor = QColor(0x4C4C4C); - ec.t = EmptyContainerThemeTemplates(); - params.emptyContainerParams = ec; - - SidebarParams sb; - sb.backgroundColor = QColor(0x454545); - sb.separatorColor = QColor(0xBDBFBF); - sb.sectionSeparatorColor = QColor(0x575757); - sb.uppercaseLabels = true; - sb.titleTextColor = QColor(0xBDBFBF); - sb.titleDropShadowColor = Qt::black; - sb.busyIndicatorColor = Qt::white; - params.sidebarParams = sb; - - ImportWidgetParams iw; - iw.backgroundColor = QColor(0x2A2A2A); - iw.titleTextColor = QColor(0xCCCCCC); - iw.descriptionTextColor = QColor(0xAAAAAA); - iw.currentComicTextColor = QColor(0xAAAAAA); - iw.coversViewBackgroundColor = QColor(0x3A3A3A); - iw.coversLabelColor = QColor(0xAAAAAA); - iw.coversDecorationBgColor = QColor(0x3A3A3A); - iw.coversDecorationShadowColor = QColor(0x1A1A1A); - iw.modeIconColor = QColor(0x4A4A4A); - iw.iconColor = QColor(0xCCCCCC); - iw.iconCheckedColor = QColor(0xAAAAAA); - params.importWidgetParams = iw; - - TreeViewParams tv; - tv.textColor = QColor(0xDDDFDF); - tv.selectionBackgroundColor = QColor(0x2E2E2E); - tv.scrollBackgroundColor = QColor(0x404040); - tv.scrollHandleColor = QColor(0xDDDDDD); - tv.selectedTextColor = Qt::white; - tv.folderIndicatorColor = QColor(237, 197, 24); - tv.branchIndicatorColor = QColor(0xE0E0E0); - tv.branchIndicatorSelectedColor = QColor(0xFFFFFF); - tv.folderIconColor = QColor(0xE0E0E0); - tv.folderIconShadowColor = QColor(0xFF000000); - tv.folderIconSelectedColor = QColor(0xE0E0E0); - tv.folderIconSelectedShadowColor = QColor(0xFF000000); - tv.folderReadOverlayColor = QColor(0x222222); - tv.folderReadOverlaySelectedColor = QColor(0x222222); - params.treeViewParams = tv; - - TableViewParams tav; - tav.alternateBackgroundColor = QColor(0x2E2E2E); - tav.backgroundColor = QColor(0x2A2A2A); - tav.headerBackgroundColor = QColor(0x2A2A2A); - tav.headerBorderColor = QColor(0x1F1F1F); - tav.headerGradientColor = QColor(0x252525); - tav.itemBorderBottomColor = QColor(0x1F1F1F); - tav.itemBorderTopColor = QColor(0x353535); - tav.itemBorderBottomWidth = 1; - tav.itemBorderTopWidth = 1; - tav.itemTextColor = QColor(0xDDDDDD); - tav.selectedColor = QColor(0x555555); - tav.selectedTextColor = QColor(0xFFFFFF); - tav.headerTextColor = QColor(0xDDDDDD); - tav.starRatingColor = QColor(0xE9BE0F); - tav.starRatingSelectedColor = QColor(0xFFFFFF); - tav.t = TableViewThemeTemplates(); - params.tableViewParams = tav; - - QmlViewParams qv; - qv.backgroundColor = QColor(0x2A2A2A); - qv.cellColor = QColor(0x212121); - qv.cellColorWithBackground = QColor(0x21, 0x21, 0x21, 0x99); - qv.selectedColor = QColor(0x121212); - qv.selectedBorderColor = QColor(0xFFCC00); - qv.borderColor = QColor(0x121212); - qv.titleColor = QColor(0xFFFFFF); - qv.textColor = QColor(0xA8A8A8); - qv.showDropShadow = true; - qv.infoBackgroundColor = QColor(0x2E2E2E); - qv.infoBorderColor = QColor(0x404040); - qv.infoShadowColor = Qt::black; - qv.infoTextColor = QColor(0xB0B0B0); - qv.infoTitleColor = QColor(0xFFFFFF); - qv.ratingUnselectedColor = QColor(0x1C1C1C); - qv.ratingSelectedColor = QColor(0xFFFFFF); - qv.favUncheckedColor = QColor(0x1C1C1C); - qv.favCheckedColor = QColor(0xE84852); - qv.readTickUncheckedColor = QColor(0x1C1C1C); - qv.readTickCheckedColor = QColor(0xE84852); - qv.currentComicBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); - qv.continueReadingBackgroundColor = QColor(0x00, 0x00, 0x00, 0x88); - qv.continueReadingColor = QColor(0xFFFFFF); - qv.backgroundBlurOverlayColor = QColor(0x2A2A2A); - params.qmlViewParams = qv; - - MainToolbarParams mt; - mt.backgroundColor = QColor(0x2A2A2A); - mt.folderNameColor = QColor(0xDDDDDD); - mt.dividerColor = QColor(0x555555); - mt.iconColor = QColor(0xDDDDDD); - mt.iconDisabledColor = QColor(0x666666); - params.mainToolbarParams = mt; - - ContentSplitterParams cs; - cs.handleColor = QColor(0x1F1F1F); - cs.horizontalHandleHeight = 4; - cs.verticalHandleWidth = 4; - params.contentSplitterParams = cs; - - SidebarIconsParams si; - si.iconColor = QColor(0xE0E0E0); - si.shadowColor = QColor(0xFF000000); - si.useSystemFolderIcons = false; - params.sidebarIconsParams = si; - - LibraryItemParams li; - li.textColor = QColor(0xDDDFDF); - li.libraryIconColor = QColor(0xDDDFDF); - li.libraryIconShadowColor = QColor(0xFF000000); - li.selectedTextColor = Qt::white; - li.selectedBackgroundColor = QColor(0x2E2E2E); - li.libraryIconSelectedColor = Qt::white; - li.libraryOptionsIconColor = Qt::white; - params.libraryItemParams = li; - - ComicsViewToolbarParams cvt; - cvt.backgroundColor = QColor(0x2A2A2A); - cvt.separatorColor = QColor(0x444444); - cvt.checkedBackgroundColor = QColor(0x555555); - cvt.iconColor = QColor(0xDDDDDD); - params.comicsViewToolbarParams = cvt; - - SearchLineEditParams sle; - sle.textColor = QColor(0xABABAB); - sle.backgroundColor = QColor(0x404040); - sle.iconColor = QColor(0xF7F7F7); - params.searchLineEditParams = sle; - - ReadingListIconsParams rli; - rli.labelColors = { - { "red", QColor(0xf67a7b) }, - { "orange", QColor(0xf5c240) }, - { "yellow", QColor(0xf2e446) }, - { "green", QColor(0xade738) }, - { "cyan", QColor(0xa0fddb) }, - { "blue", QColor(0x82c7ff) }, - { "violet", QColor(0x8f95ff) }, - { "purple", QColor(0xd692fc) }, - { "pink", QColor(0xfd9cda) }, - { "white", QColor(0xfcfcfc) }, - { "light", QColor(0xcbcbcb) }, - { "dark", QColor(0xb7b7b7) } - }; - rli.labelShadowColor = Qt::black; - rli.labelShadowSelectedColor = Qt::black; - rli.readingListMainColor = QColor(0xe7e7e7); - rli.readingListMainSelectedColor = QColor(0xe7e7e7); - rli.favoritesMainColor = QColor(0xe15055); - rli.favoritesMainSelectedColor = QColor(0xe15055); - rli.currentlyReadingMainColor = QColor(0xffcc00); - rli.currentlyReadingMainSelectedColor = QColor(0xffcc00); - rli.currentlyReadingOuterColor = Qt::black; - rli.currentlyReadingOuterSelectedColor = Qt::black; - rli.specialListShadowColor = Qt::black; - rli.specialListShadowSelectedColor = Qt::black; - rli.listMainColor = QColor(0xe7e7e7); - rli.listMainSelectedColor = QColor(0xe7e7e7); - rli.listShadowColor = Qt::black; - rli.listShadowSelectedColor = Qt::black; - rli.listDetailColor = QColor(0x464646); - rli.listDetailSelectedColor = QColor(0x464646); - params.readingListIconsParams = rli; - - MenuIconsParams mi; - mi.iconColor = QColor(0xF7F7F7); - params.menuIconsParams = mi; - - DialogIconsParams dip; - dip.iconColor = mi.iconColor; - params.dialogIconsParams = dip; - - ShortcutsIconsParams sci; - sci.iconColor = QColor(0xF7F7F7); - params.shortcutsIconsParams = sci; - - ServerConfigDialogParams scd; - scd.backgroundColor = QColor(0x2A2A2A); - scd.titleTextColor = QColor(0xD0D0D0); - scd.qrMessageTextColor = QColor(0xA3A3A3); - scd.propagandaTextColor = QColor(0xB0B0B0); - scd.labelTextColor = QColor(0xC0C0C0); - scd.checkBoxTextColor = QColor(0xDDDDDD); - scd.qrBackgroundColor = QColor(0x2A2A2A); - scd.qrForegroundColor = Qt::white; - scd.decorationColor = QColor(0xF7F7F7); - params.serverConfigDialogParams = scd; - - return params; + if (json.contains("whatsNewDialog")) { + const auto o = json["whatsNewDialog"].toObject(); + auto &wn = p.whatsNewDialogParams; + wn.backgroundColor = colorFromJson(o, "backgroundColor", wn.backgroundColor); + wn.headerTextColor = colorFromJson(o, "headerTextColor", wn.headerTextColor); + wn.versionTextColor = colorFromJson(o, "versionTextColor", wn.versionTextColor); + wn.contentTextColor = colorFromJson(o, "contentTextColor", wn.contentTextColor); + wn.linkColor = colorFromJson(o, "linkColor", wn.linkColor); + wn.closeButtonColor = colorFromJson(o, "closeButtonColor", wn.closeButtonColor); + wn.headerDecorationColor = colorFromJson(o, "headerDecorationColor", wn.headerDecorationColor); + } + + if (json.contains("emptyContainer")) { + const auto o = json["emptyContainer"].toObject(); + auto &ec = p.emptyContainerParams; + ec.backgroundColor = colorFromJson(o, "backgroundColor", ec.backgroundColor); + ec.titleTextColor = colorFromJson(o, "titleTextColor", ec.titleTextColor); + ec.textColor = colorFromJson(o, "textColor", ec.textColor); + ec.descriptionTextColor = colorFromJson(o, "descriptionTextColor", ec.descriptionTextColor); + ec.searchIconColor = colorFromJson(o, "searchIconColor", ec.searchIconColor); + } + + if (json.contains("sidebar")) { + const auto o = json["sidebar"].toObject(); + auto &sb = p.sidebarParams; + sb.backgroundColor = colorFromJson(o, "backgroundColor", sb.backgroundColor); + sb.separatorColor = colorFromJson(o, "separatorColor", sb.separatorColor); + sb.sectionSeparatorColor = colorFromJson(o, "sectionSeparatorColor", sb.sectionSeparatorColor); + if (o.contains("uppercaseLabels")) + sb.uppercaseLabels = o["uppercaseLabels"].toBool(sb.uppercaseLabels); + sb.titleTextColor = colorFromJson(o, "titleTextColor", sb.titleTextColor); + sb.titleDropShadowColor = colorFromJson(o, "titleDropShadowColor", sb.titleDropShadowColor); + sb.busyIndicatorColor = colorFromJson(o, "busyIndicatorColor", sb.busyIndicatorColor); + } + + if (json.contains("sidebarIcons")) { + const auto o = json["sidebarIcons"].toObject(); + auto &si = p.sidebarIconsParams; + si.iconColor = colorFromJson(o, "iconColor", si.iconColor); + si.shadowColor = colorFromJson(o, "shadowColor", si.shadowColor); + if (o.contains("useSystemFolderIcons")) + si.useSystemFolderIcons = o["useSystemFolderIcons"].toBool(si.useSystemFolderIcons); + } + + if (json.contains("libraryItem")) { + const auto o = json["libraryItem"].toObject(); + auto &li = p.libraryItemParams; + li.textColor = colorFromJson(o, "textColor", li.textColor); + li.libraryIconColor = colorFromJson(o, "libraryIconColor", li.libraryIconColor); + li.libraryIconShadowColor = colorFromJson(o, "libraryIconShadowColor", li.libraryIconShadowColor); + li.selectedTextColor = colorFromJson(o, "selectedTextColor", li.selectedTextColor); + li.selectedBackgroundColor = colorFromJson(o, "selectedBackgroundColor", li.selectedBackgroundColor); + li.libraryIconSelectedColor = colorFromJson(o, "libraryIconSelectedColor", li.libraryIconSelectedColor); + li.libraryOptionsIconColor = colorFromJson(o, "libraryOptionsIconColor", li.libraryOptionsIconColor); + } + + if (json.contains("importWidget")) { + const auto o = json["importWidget"].toObject(); + auto &iw = p.importWidgetParams; + iw.backgroundColor = colorFromJson(o, "backgroundColor", iw.backgroundColor); + iw.titleTextColor = colorFromJson(o, "titleTextColor", iw.titleTextColor); + iw.descriptionTextColor = colorFromJson(o, "descriptionTextColor", iw.descriptionTextColor); + iw.currentComicTextColor = colorFromJson(o, "currentComicTextColor", iw.currentComicTextColor); + iw.coversViewBackgroundColor = colorFromJson(o, "coversViewBackgroundColor", iw.coversViewBackgroundColor); + iw.coversLabelColor = colorFromJson(o, "coversLabelColor", iw.coversLabelColor); + iw.coversDecorationBgColor = colorFromJson(o, "coversDecorationBgColor", iw.coversDecorationBgColor); + iw.coversDecorationShadowColor = colorFromJson(o, "coversDecorationShadowColor", iw.coversDecorationShadowColor); + iw.modeIconColor = colorFromJson(o, "modeIconColor", iw.modeIconColor); + iw.iconColor = colorFromJson(o, "iconColor", iw.iconColor); + iw.iconCheckedColor = colorFromJson(o, "iconCheckedColor", iw.iconCheckedColor); + } + + if (json.contains("serverConfigDialog")) { + const auto o = json["serverConfigDialog"].toObject(); + auto &scd2 = p.serverConfigDialogParams; + scd2.backgroundColor = colorFromJson(o, "backgroundColor", scd2.backgroundColor); + scd2.titleTextColor = colorFromJson(o, "titleTextColor", scd2.titleTextColor); + scd2.qrMessageTextColor = colorFromJson(o, "qrMessageTextColor", scd2.qrMessageTextColor); + scd2.propagandaTextColor = colorFromJson(o, "propagandaTextColor", scd2.propagandaTextColor); + scd2.labelTextColor = colorFromJson(o, "labelTextColor", scd2.labelTextColor); + scd2.checkBoxTextColor = colorFromJson(o, "checkBoxTextColor", scd2.checkBoxTextColor); + scd2.qrBackgroundColor = colorFromJson(o, "qrBackgroundColor", scd2.qrBackgroundColor); + scd2.qrForegroundColor = colorFromJson(o, "qrForegroundColor", scd2.qrForegroundColor); + scd2.decorationColor = colorFromJson(o, "decorationColor", scd2.decorationColor); + } + + if (json.contains("mainToolbar")) { + const auto o = json["mainToolbar"].toObject(); + auto &mt = p.mainToolbarParams; + mt.backgroundColor = colorFromJson(o, "backgroundColor", mt.backgroundColor); + mt.folderNameColor = colorFromJson(o, "folderNameColor", mt.folderNameColor); + mt.dividerColor = colorFromJson(o, "dividerColor", mt.dividerColor); + mt.iconColor = colorFromJson(o, "iconColor", mt.iconColor); + mt.iconDisabledColor = colorFromJson(o, "iconDisabledColor", mt.iconDisabledColor); + } + + if (json.contains("contentSplitter")) { + const auto o = json["contentSplitter"].toObject(); + auto &cs = p.contentSplitterParams; + cs.handleColor = colorFromJson(o, "handleColor", cs.handleColor); + if (o.contains("horizontalHandleHeight")) + cs.horizontalHandleHeight = o["horizontalHandleHeight"].toInt(cs.horizontalHandleHeight); + if (o.contains("verticalHandleWidth")) + cs.verticalHandleWidth = o["verticalHandleWidth"].toInt(cs.verticalHandleWidth); + } + + if (json.contains("treeView")) { + const auto o = json["treeView"].toObject(); + auto &tv = p.treeViewParams; + tv.textColor = colorFromJson(o, "textColor", tv.textColor); + tv.selectionBackgroundColor = colorFromJson(o, "selectionBackgroundColor", tv.selectionBackgroundColor); + tv.scrollBackgroundColor = colorFromJson(o, "scrollBackgroundColor", tv.scrollBackgroundColor); + tv.scrollHandleColor = colorFromJson(o, "scrollHandleColor", tv.scrollHandleColor); + tv.selectedTextColor = colorFromJson(o, "selectedTextColor", tv.selectedTextColor); + tv.folderIndicatorColor = colorFromJson(o, "folderIndicatorColor", tv.folderIndicatorColor); + tv.branchIndicatorColor = colorFromJson(o, "branchIndicatorColor", tv.branchIndicatorColor); + tv.branchIndicatorSelectedColor = colorFromJson(o, "branchIndicatorSelectedColor", tv.branchIndicatorSelectedColor); + tv.folderIconColor = colorFromJson(o, "folderIconColor", tv.folderIconColor); + tv.folderIconShadowColor = colorFromJson(o, "folderIconShadowColor", tv.folderIconShadowColor); + tv.folderIconSelectedColor = colorFromJson(o, "folderIconSelectedColor", tv.folderIconSelectedColor); + tv.folderIconSelectedShadowColor = colorFromJson(o, "folderIconSelectedShadowColor", tv.folderIconSelectedShadowColor); + tv.folderReadOverlayColor = colorFromJson(o, "folderReadOverlayColor", tv.folderReadOverlayColor); + tv.folderReadOverlaySelectedColor = colorFromJson(o, "folderReadOverlaySelectedColor", tv.folderReadOverlaySelectedColor); + } + + if (json.contains("tableView")) { + const auto o = json["tableView"].toObject(); + auto &tbv = p.tableViewParams; + tbv.alternateBackgroundColor = colorFromJson(o, "alternateBackgroundColor", tbv.alternateBackgroundColor); + tbv.backgroundColor = colorFromJson(o, "backgroundColor", tbv.backgroundColor); + tbv.headerBackgroundColor = colorFromJson(o, "headerBackgroundColor", tbv.headerBackgroundColor); + tbv.headerBorderColor = colorFromJson(o, "headerBorderColor", tbv.headerBorderColor); + tbv.headerGradientColor = colorFromJson(o, "headerGradientColor", tbv.headerGradientColor); + tbv.itemBorderBottomColor = colorFromJson(o, "itemBorderBottomColor", tbv.itemBorderBottomColor); + tbv.itemBorderTopColor = colorFromJson(o, "itemBorderTopColor", tbv.itemBorderTopColor); + tbv.itemBorderBottomWidth = o["itemBorderBottomWidth"].toInt(tbv.itemBorderBottomWidth); + tbv.itemBorderTopWidth = o["itemBorderTopWidth"].toInt(tbv.itemBorderTopWidth); + tbv.itemTextColor = colorFromJson(o, "itemTextColor", tbv.itemTextColor); + tbv.selectedColor = colorFromJson(o, "selectedColor", tbv.selectedColor); + tbv.selectedTextColor = colorFromJson(o, "selectedTextColor", tbv.selectedTextColor); + tbv.headerTextColor = colorFromJson(o, "headerTextColor", tbv.headerTextColor); + tbv.starRatingColor = colorFromJson(o, "starRatingColor", tbv.starRatingColor); + tbv.starRatingSelectedColor = colorFromJson(o, "starRatingSelectedColor", tbv.starRatingSelectedColor); + } + + if (json.contains("qmlView")) { + const auto o = json["qmlView"].toObject(); + auto &qv = p.qmlViewParams; + qv.backgroundColor = colorFromJson(o, "backgroundColor", qv.backgroundColor); + qv.cellColor = colorFromJson(o, "cellColor", qv.cellColor); + qv.cellColorWithBackground = colorFromJson(o, "cellColorWithBackground", qv.cellColorWithBackground); + qv.selectedColor = colorFromJson(o, "selectedColor", qv.selectedColor); + qv.selectedBorderColor = colorFromJson(o, "selectedBorderColor", qv.selectedBorderColor); + qv.borderColor = colorFromJson(o, "borderColor", qv.borderColor); + qv.titleColor = colorFromJson(o, "titleColor", qv.titleColor); + qv.textColor = colorFromJson(o, "textColor", qv.textColor); + if (o.contains("showDropShadow")) + qv.showDropShadow = o["showDropShadow"].toBool(qv.showDropShadow); + qv.infoBackgroundColor = colorFromJson(o, "infoBackgroundColor", qv.infoBackgroundColor); + qv.infoBorderColor = colorFromJson(o, "infoBorderColor", qv.infoBorderColor); + qv.infoShadowColor = colorFromJson(o, "infoShadowColor", qv.infoShadowColor); + qv.infoTextColor = colorFromJson(o, "infoTextColor", qv.infoTextColor); + qv.infoTitleColor = colorFromJson(o, "infoTitleColor", qv.infoTitleColor); + qv.ratingUnselectedColor = colorFromJson(o, "ratingUnselectedColor", qv.ratingUnselectedColor); + qv.ratingSelectedColor = colorFromJson(o, "ratingSelectedColor", qv.ratingSelectedColor); + qv.favUncheckedColor = colorFromJson(o, "favUncheckedColor", qv.favUncheckedColor); + qv.favCheckedColor = colorFromJson(o, "favCheckedColor", qv.favCheckedColor); + qv.readTickUncheckedColor = colorFromJson(o, "readTickUncheckedColor", qv.readTickUncheckedColor); + qv.readTickCheckedColor = colorFromJson(o, "readTickCheckedColor", qv.readTickCheckedColor); + qv.currentComicBackgroundColor = colorFromJson(o, "currentComicBackgroundColor", qv.currentComicBackgroundColor); + qv.continueReadingBackgroundColor = colorFromJson(o, "continueReadingBackgroundColor", qv.continueReadingBackgroundColor); + qv.continueReadingColor = colorFromJson(o, "continueReadingColor", qv.continueReadingColor); + qv.backgroundBlurOverlayColor = colorFromJson(o, "backgroundBlurOverlayColor", qv.backgroundBlurOverlayColor); + } + + if (json.contains("comicsViewToolbar")) { + const auto o = json["comicsViewToolbar"].toObject(); + auto &cvt = p.comicsViewToolbarParams; + cvt.backgroundColor = colorFromJson(o, "backgroundColor", cvt.backgroundColor); + cvt.separatorColor = colorFromJson(o, "separatorColor", cvt.separatorColor); + cvt.checkedBackgroundColor = colorFromJson(o, "checkedBackgroundColor", cvt.checkedBackgroundColor); + cvt.iconColor = colorFromJson(o, "iconColor", cvt.iconColor); + } + + if (json.contains("searchLineEdit")) { + const auto o = json["searchLineEdit"].toObject(); + auto &sle = p.searchLineEditParams; + sle.textColor = colorFromJson(o, "textColor", sle.textColor); + sle.backgroundColor = colorFromJson(o, "backgroundColor", sle.backgroundColor); + sle.iconColor = colorFromJson(o, "iconColor", sle.iconColor); + } + + if (json.contains("readingListIcons")) { + const auto o = json["readingListIcons"].toObject(); + auto &rli = p.readingListIconsParams; + if (o.contains("labelColors")) { + const auto lc = o["labelColors"].toObject(); + for (auto it = lc.constBegin(); it != lc.constEnd(); ++it) { + QColor c(it.value().toString()); + if (c.isValid()) + rli.labelColors[it.key()] = c; + } + } + rli.labelShadowColor = colorFromJson(o, "labelShadowColor", rli.labelShadowColor); + rli.labelShadowSelectedColor = colorFromJson(o, "labelShadowSelectedColor", rli.labelShadowSelectedColor); + rli.readingListMainColor = colorFromJson(o, "readingListMainColor", rli.readingListMainColor); + rli.readingListMainSelectedColor = colorFromJson(o, "readingListMainSelectedColor", rli.readingListMainSelectedColor); + rli.favoritesMainColor = colorFromJson(o, "favoritesMainColor", rli.favoritesMainColor); + rli.favoritesMainSelectedColor = colorFromJson(o, "favoritesMainSelectedColor", rli.favoritesMainSelectedColor); + rli.currentlyReadingMainColor = colorFromJson(o, "currentlyReadingMainColor", rli.currentlyReadingMainColor); + rli.currentlyReadingMainSelectedColor = colorFromJson(o, "currentlyReadingMainSelectedColor", rli.currentlyReadingMainSelectedColor); + rli.currentlyReadingOuterColor = colorFromJson(o, "currentlyReadingOuterColor", rli.currentlyReadingOuterColor); + rli.currentlyReadingOuterSelectedColor = colorFromJson(o, "currentlyReadingOuterSelectedColor", rli.currentlyReadingOuterSelectedColor); + rli.specialListShadowColor = colorFromJson(o, "specialListShadowColor", rli.specialListShadowColor); + rli.specialListShadowSelectedColor = colorFromJson(o, "specialListShadowSelectedColor", rli.specialListShadowSelectedColor); + rli.listMainColor = colorFromJson(o, "listMainColor", rli.listMainColor); + rli.listMainSelectedColor = colorFromJson(o, "listMainSelectedColor", rli.listMainSelectedColor); + rli.listShadowColor = colorFromJson(o, "listShadowColor", rli.listShadowColor); + rli.listShadowSelectedColor = colorFromJson(o, "listShadowSelectedColor", rli.listShadowSelectedColor); + rli.listDetailColor = colorFromJson(o, "listDetailColor", rli.listDetailColor); + rli.listDetailSelectedColor = colorFromJson(o, "listDetailSelectedColor", rli.listDetailSelectedColor); + } + + if (json.contains("dialogIcons")) { + const auto o = json["dialogIcons"].toObject(); + p.dialogIconsParams.iconColor = colorFromJson(o, "iconColor", p.dialogIconsParams.iconColor); + } + + if (json.contains("menuIcons")) { + const auto o = json["menuIcons"].toObject(); + p.menuIconsParams.iconColor = colorFromJson(o, "iconColor", p.menuIconsParams.iconColor); + } + + if (json.contains("shortcutsIcons")) { + const auto o = json["shortcutsIcons"].toObject(); + p.shortcutsIconsParams.iconColor = colorFromJson(o, "iconColor", p.shortcutsIconsParams.iconColor); + } + + if (json.contains("meta")) { + const auto o = json["meta"].toObject(); + p.meta.id = o["id"].toString(p.meta.id); + p.meta.displayName = o["displayName"].toString(p.meta.displayName); + const QString variantStr = o["variant"].toString(); + if (variantStr == "light") + p.meta.variant = ThemeVariant::Light; + else if (variantStr == "dark") + p.meta.variant = ThemeVariant::Dark; + } + + Theme theme = makeTheme(p); + theme.sourceJson = json; + return theme; } diff --git a/YACReaderLibrary/themes/theme_factory.h b/YACReaderLibrary/themes/theme_factory.h index 72cb4ca28..ebed9bbb1 100644 --- a/YACReaderLibrary/themes/theme_factory.h +++ b/YACReaderLibrary/themes/theme_factory.h @@ -2,8 +2,9 @@ #define THEME_FACTORY_H #include "theme.h" -#include "theme_id.h" -Theme makeTheme(ThemeId themeId); +#include + +Theme makeTheme(const QJsonObject &json); #endif // THEME_FACTORY_H diff --git a/YACReaderLibrary/themes/themes.qrc b/YACReaderLibrary/themes/themes.qrc new file mode 100644 index 000000000..62ec21fee --- /dev/null +++ b/YACReaderLibrary/themes/themes.qrc @@ -0,0 +1,7 @@ + + + builtin_classic.json + builtin_light.json + builtin_dark.json + + diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index c754f5523..ae0c16392 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -111,17 +111,27 @@ add_library(common_gui STATIC # themes infrastructure (does NOT depend on app-specific theme.h) themes/icon_utils.h themes/icon_utils.cpp - themes/theme_id.h + themes/appearance_configuration.h + themes/appearance_configuration.cpp + themes/theme_variant.h themes/themable.h themes/yacreader_icon.h themes/shared/help_about_dialog_theme.h themes/shared/whats_new_dialog_theme.h + themes/theme_editor_dialog.h + themes/theme_editor_dialog.cpp + themes/theme_meta.h + themes/theme_repository.h + themes/theme_repository.cpp + themes/appearance_tab_widget.h + themes/appearance_tab_widget.cpp ) target_include_directories(common_gui PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/themes ${CMAKE_CURRENT_SOURCE_DIR}/themes/shared ) + target_link_libraries(common_gui PUBLIC Qt::Core Qt::Core5Compat diff --git a/common/themes/appearance_config_images.qrc b/common/themes/appearance_config_images.qrc new file mode 100644 index 000000000..c274e5636 --- /dev/null +++ b/common/themes/appearance_config_images.qrc @@ -0,0 +1,7 @@ + + + ../../images/appearance_config/theme-mode-system.svg + ../../images/appearance_config/theme-mode-light.svg + ../../images/appearance_config/theme-mode-dark.svg + + diff --git a/common/themes/appearance_configuration.cpp b/common/themes/appearance_configuration.cpp new file mode 100644 index 000000000..dade4c262 --- /dev/null +++ b/common/themes/appearance_configuration.cpp @@ -0,0 +1,96 @@ +#include "appearance_configuration.h" + +#include + +static constexpr auto kGroup = "Appearance"; +static constexpr auto kMode = "ThemeMode"; +static constexpr auto kLightId = "LightThemeId"; +static constexpr auto kDarkId = "DarkThemeId"; +static constexpr auto kFixedId = "FixedThemeId"; + +static QString themeModeToString(ThemeMode mode) +{ + switch (mode) { + case ThemeMode::FollowSystem: + return "FollowSystem"; + case ThemeMode::Light: + return "Light"; + case ThemeMode::Dark: + return "Dark"; + case ThemeMode::ForcedTheme: + return "ForcedTheme"; + } + return "FollowSystem"; +} + +static ThemeMode themeModeFromString(const QString &s) +{ + if (s == "Light") + return ThemeMode::Light; + if (s == "Dark") + return ThemeMode::Dark; + if (s == "ForcedTheme") + return ThemeMode::ForcedTheme; + return ThemeMode::FollowSystem; +} + +AppearanceConfiguration::AppearanceConfiguration(const QString &settingsFilePath, QObject *parent) + : QObject(parent), path(settingsFilePath) +{ + load(); +} + +void AppearanceConfiguration::load() +{ + QSettings s(path, QSettings::IniFormat); + s.beginGroup(kGroup); + sel.mode = themeModeFromString(s.value(kMode, "FollowSystem").toString()); + sel.lightThemeId = s.value(kLightId, sel.lightThemeId).toString(); + sel.darkThemeId = s.value(kDarkId, sel.darkThemeId).toString(); + sel.fixedThemeId = s.value(kFixedId, sel.fixedThemeId).toString(); + s.endGroup(); +} + +void AppearanceConfiguration::write(const QString &key, const QString &value) +{ + QSettings s(path, QSettings::IniFormat); + s.beginGroup(kGroup); + s.setValue(key, value); + s.endGroup(); +} + +void AppearanceConfiguration::setMode(ThemeMode mode) +{ + if (sel.mode == mode) + return; + sel.mode = mode; + write(kMode, themeModeToString(mode)); + emit selectionChanged(); +} + +void AppearanceConfiguration::setLightThemeId(const QString &id) +{ + if (sel.lightThemeId == id) + return; + sel.lightThemeId = id; + write(kLightId, id); + emit selectionChanged(); +} + +void AppearanceConfiguration::setDarkThemeId(const QString &id) +{ + if (sel.darkThemeId == id) + return; + sel.darkThemeId = id; + write(kDarkId, id); + emit selectionChanged(); +} + +void AppearanceConfiguration::setFixedThemeId(const QString &id) +{ + if (sel.fixedThemeId == id) + return; + sel.fixedThemeId = id; + write(kFixedId, id); + emit selectionChanged(); +} diff --git a/common/themes/appearance_configuration.h b/common/themes/appearance_configuration.h new file mode 100644 index 000000000..bcc4d501f --- /dev/null +++ b/common/themes/appearance_configuration.h @@ -0,0 +1,48 @@ +#ifndef APPEARANCE_CONFIGURATION_H +#define APPEARANCE_CONFIGURATION_H + +#include +#include + +enum class ThemeMode { + FollowSystem, + Light, + Dark, + ForcedTheme, +}; + +struct ThemeSelection { + ThemeMode mode = ThemeMode::FollowSystem; + QString lightThemeId = "builtin/light"; + QString darkThemeId = "builtin/dark"; + QString fixedThemeId = "builtin/classic"; +}; + +// Persists theme selection settings to a QSettings INI file under the +// [Appearance] group. All access is on-demand (no persistent QSettings handle) +// so the caller does not need to manage a QSettings lifetime. +class AppearanceConfiguration : public QObject +{ + Q_OBJECT +public: + explicit AppearanceConfiguration(const QString &settingsFilePath, QObject *parent = nullptr); + + ThemeSelection selection() const { return sel; } + + void setMode(ThemeMode mode); + void setLightThemeId(const QString &id); + void setDarkThemeId(const QString &id); + void setFixedThemeId(const QString &id); + +signals: + void selectionChanged(); + +private: + QString path; + ThemeSelection sel; + + void load(); + void write(const QString &key, const QString &value); +}; + +#endif // APPEARANCE_CONFIGURATION_H diff --git a/common/themes/appearance_tab_widget.cpp b/common/themes/appearance_tab_widget.cpp new file mode 100644 index 000000000..8563fb055 --- /dev/null +++ b/common/themes/appearance_tab_widget.cpp @@ -0,0 +1,98 @@ +#include "appearance_tab_widget.h" + +#include "appearance_configuration.h" +#include "theme_editor_dialog.h" + +#include +#include +#include +#include +#include +#include +#include + +AppearanceTabWidget::AppearanceTabWidget( + AppearanceConfiguration *config, + std::function currentThemeJson, + std::function applyTheme, + QWidget *parent) + : QWidget(parent), config(config), currentThemeJson(std::move(currentThemeJson)), applyTheme(std::move(applyTheme)) +{ + // Color scheme selector + auto *modeBox = new QGroupBox(tr("Color scheme"), this); + auto *modeLayout = new QHBoxLayout(); + + auto *sysBtn = new QToolButton(); + auto *lightBtn = new QToolButton(); + auto *darkBtn = new QToolButton(); + + sysBtn->setText(tr("System")); + lightBtn->setText(tr("Light")); + darkBtn->setText(tr("Dark")); + + sysBtn->setIcon(QIcon(":/images/appearance_config/theme-mode-system.svg")); + lightBtn->setIcon(QIcon(":/images/appearance_config/theme-mode-light.svg")); + darkBtn->setIcon(QIcon(":/images/appearance_config/theme-mode-dark.svg")); + + for (auto *btn : { sysBtn, lightBtn, darkBtn }) { + btn->setCheckable(true); + btn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + btn->setIconSize(QSize(93, 58)); + btn->setMinimumSize(115, 90); + } + + auto *modeGroup = new QButtonGroup(this); + modeGroup->addButton(sysBtn, static_cast(ThemeMode::FollowSystem)); + modeGroup->addButton(lightBtn, static_cast(ThemeMode::Light)); + modeGroup->addButton(darkBtn, static_cast(ThemeMode::Dark)); + modeGroup->setExclusive(true); + + if (this->config) { + const auto mode = this->config->selection().mode; + if (auto *btn = modeGroup->button(static_cast(mode))) + btn->setChecked(true); + } + + connect(modeGroup, &QButtonGroup::idClicked, this, [this](int id) { + if (this->config) + this->config->setMode(static_cast(id)); + }); + + modeLayout->addStretch(); + modeLayout->addWidget(sysBtn); + modeLayout->addWidget(lightBtn); + modeLayout->addWidget(darkBtn); + modeLayout->addStretch(); + modeBox->setLayout(modeLayout); + + // Theme editor + auto *themeEditorBox = new QGroupBox(tr("Theme editor"), this); + auto *themeEditorLayout = new QVBoxLayout(); + auto *openBtn = new QPushButton(tr("Open Theme Editor...")); + themeEditorLayout->addWidget(openBtn); + themeEditorBox->setLayout(themeEditorLayout); + + connect(openBtn, &QPushButton::clicked, this, [this]() { + if (!themeEditor) { + QJsonObject json = this->currentThemeJson(); + if (json.isEmpty()) { + QMessageBox::critical(this, + tr("Theme editor error"), + tr("The current theme JSON could not be loaded.")); + return; + } + themeEditor = new ThemeEditorDialog(json, this); + themeEditor->setAttribute(Qt::WA_DeleteOnClose); + connect(themeEditor, &ThemeEditorDialog::themeJsonChanged, this, + [this](const QJsonObject &json) { this->applyTheme(json); }); + } + themeEditor->show(); + themeEditor->raise(); + themeEditor->activateWindow(); + }); + + auto *layout = new QVBoxLayout(this); + layout->addWidget(modeBox); + layout->addWidget(themeEditorBox); + layout->addStretch(); +} diff --git a/common/themes/appearance_tab_widget.h b/common/themes/appearance_tab_widget.h new file mode 100644 index 000000000..cbccb88bc --- /dev/null +++ b/common/themes/appearance_tab_widget.h @@ -0,0 +1,29 @@ +#ifndef APPEARANCE_TAB_WIDGET_H +#define APPEARANCE_TAB_WIDGET_H + +#include +#include +#include +#include + +class AppearanceConfiguration; +class ThemeEditorDialog; + +class AppearanceTabWidget : public QWidget +{ + Q_OBJECT +public: + explicit AppearanceTabWidget( + AppearanceConfiguration *config, + std::function currentThemeJson, + std::function applyTheme, + QWidget *parent = nullptr); + +private: + AppearanceConfiguration *config; + std::function currentThemeJson; + std::function applyTheme; + QPointer themeEditor; +}; + +#endif // APPEARANCE_TAB_WIDGET_H diff --git a/common/themes/theme_editor_dialog.cpp b/common/themes/theme_editor_dialog.cpp new file mode 100644 index 000000000..eaeed5153 --- /dev/null +++ b/common/themes/theme_editor_dialog.cpp @@ -0,0 +1,477 @@ +#include "theme_editor_dialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Role used to store the JSON path (QStringList) on each leaf item. +static const int PathRole = Qt::UserRole; +// Role used to distinguish color items from others. +static const int IsColorRole = Qt::UserRole + 1; +// Role used to distinguish boolean items. +static const int IsBoolRole = Qt::UserRole + 2; +// Role used to distinguish numeric items. +static const int IsNumberRole = Qt::UserRole + 3; + +static bool isColorString(const QString &s) +{ + // Accepts #RGB, #RRGGBB, #AARRGGBB + if (!s.startsWith('#')) + return false; + const int len = s.length(); + return len == 4 || len == 7 || len == 9; +} + +ThemeEditorDialog::ThemeEditorDialog(const QJsonObject ¶ms, QWidget *parent) + : QDialog(parent), params(params) +{ + setWindowTitle(tr("Theme Editor")); + resize(520, 700); + + // --- top toolbar --- + auto *expandBtn = new QPushButton(tr("+"), this); + auto *collapseBtn = new QPushButton(tr("-"), this); + auto *identifyBtn = new QPushButton(tr("i"), this); + expandBtn->setFixedWidth(28); + collapseBtn->setFixedWidth(28); + identifyBtn->setFixedWidth(28); + expandBtn->setToolTip(tr("Expand all")); + collapseBtn->setToolTip(tr("Collapse all")); + identifyBtn->setToolTip(tr("Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original.")); + // NoFocus so clicking the button doesn't steal the tree's current item + identifyBtn->setFocusPolicy(Qt::NoFocus); + + searchEdit = new QLineEdit(this); + searchEdit->setPlaceholderText(tr("Search…")); + searchEdit->setClearButtonEnabled(true); + + auto *toolbar = new QHBoxLayout(); + toolbar->addWidget(expandBtn); + toolbar->addWidget(collapseBtn); + toolbar->addWidget(identifyBtn); + toolbar->addStretch(); + toolbar->addWidget(searchEdit); + + connect(identifyBtn, &QPushButton::pressed, this, &ThemeEditorDialog::identifyPressed); + connect(identifyBtn, &QPushButton::released, this, &ThemeEditorDialog::identifyReleased); + + // --- meta section --- + idLabel = new QLabel(this); + idLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); + nameEdit = new QLineEdit(this); + variantCombo = new QComboBox(this); + variantCombo->addItem(tr("Light"), "light"); + variantCombo->addItem(tr("Dark"), "dark"); + + auto *metaForm = new QFormLayout(); + metaForm->addRow(tr("ID:"), idLabel); + metaForm->addRow(tr("Display name:"), nameEdit); + metaForm->addRow(tr("Variant:"), variantCombo); + + auto *metaBox = new QGroupBox(tr("Theme info"), this); + metaBox->setLayout(metaForm); + + syncMetaFromParams(); + + connect(nameEdit, &QLineEdit::textEdited, this, [this](const QString &text) { + auto meta = this->params["meta"].toObject(); + meta["displayName"] = text; + this->params["meta"] = meta; + emit themeJsonChanged(this->params); + }); + connect(variantCombo, &QComboBox::currentIndexChanged, this, [this](int index) { + auto meta = this->params["meta"].toObject(); + meta["variant"] = variantCombo->itemData(index).toString(); + this->params["meta"] = meta; + emit themeJsonChanged(this->params); + }); + + // --- tree --- + tree = new QTreeWidget(this); + tree->setColumnCount(2); + tree->setHeaderLabels({ tr("Parameter"), tr("Value") }); + tree->header()->setSectionResizeMode(0, QHeaderView::Stretch); + tree->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + tree->setRootIsDecorated(true); + tree->setUniformRowHeights(true); + tree->setAlternatingRowColors(true); + + populate(nullptr, params, {}); + tree->expandAll(); + + connect(expandBtn, &QPushButton::clicked, tree, &QTreeWidget::expandAll); + connect(collapseBtn, &QPushButton::clicked, tree, &QTreeWidget::collapseAll); + connect(searchEdit, &QLineEdit::textChanged, this, &ThemeEditorDialog::filterTree); + + connect(tree, &QTreeWidget::itemDoubleClicked, this, [this](QTreeWidgetItem *item, int) { + if (item->data(0, IsColorRole).toBool()) + editColorItem(item); + else if (item->data(0, IsBoolRole).toBool()) + toggleBoolItem(item); + else if (item->data(0, IsNumberRole).toBool()) + editNumberItem(item); + }); + + // --- bottom buttons --- + auto *saveBtn = new QPushButton(tr("Save to file..."), this); + auto *loadBtn = new QPushButton(tr("Load from file..."), this); + auto *closeBtn = new QPushButton(tr("Close"), this); + connect(saveBtn, &QPushButton::clicked, this, &ThemeEditorDialog::saveToFile); + connect(loadBtn, &QPushButton::clicked, this, &ThemeEditorDialog::loadFromFile); + connect(closeBtn, &QPushButton::clicked, this, &QDialog::close); + auto *buttons = new QHBoxLayout(); + buttons->addWidget(saveBtn); + buttons->addWidget(loadBtn); + buttons->addStretch(); + buttons->addWidget(closeBtn); + + auto *layout = new QVBoxLayout(this); + layout->addLayout(toolbar); + layout->addWidget(metaBox); + layout->addWidget(tree); + layout->addLayout(buttons); + + setLayout(layout); +} + +void ThemeEditorDialog::populate(QTreeWidgetItem *parent, const QJsonObject &obj, const QStringList &path) +{ + for (auto it = obj.constBegin(); it != obj.constEnd(); ++it) { + const QString key = it.key(); + + // "meta" is handled by the dedicated UI above the tree + if (path.isEmpty() && key == "meta") + continue; + const QJsonValue val = it.value(); + const QStringList childPath = path + QStringList(key); + + if (val.isObject()) { + // Group row + QTreeWidgetItem *group = parent ? new QTreeWidgetItem(parent) + : new QTreeWidgetItem(tree); + QFont bold = group->font(0); + bold.setBold(true); + group->setFont(0, bold); + group->setText(0, key); + group->setFlags(group->flags() & ~Qt::ItemIsSelectable); + populate(group, val.toObject(), childPath); + } else { + // Leaf row + QTreeWidgetItem *item = parent ? new QTreeWidgetItem(parent) + : new QTreeWidgetItem(tree); + item->setText(0, key); + item->setData(0, PathRole, childPath); + + const QString strVal = val.toString(); + if (val.isString() && isColorString(strVal)) { + const QColor color(strVal); + item->setIcon(1, colorIcon(color)); + item->setText(1, strVal); + item->setData(0, IsColorRole, true); + item->setToolTip(1, tr("Double-click to edit color")); + } else if (val.isBool()) { + item->setText(1, val.toBool() ? tr("true") : tr("false")); + item->setData(0, IsColorRole, false); + item->setData(0, IsBoolRole, true); + item->setToolTip(1, tr("Double-click to toggle")); + } else if (val.isDouble()) { + item->setText(1, QString::number(val.toDouble())); + item->setData(0, IsNumberRole, true); + item->setToolTip(1, tr("Double-click to edit value")); + } else { + item->setText(1, strVal); + item->setData(0, IsColorRole, false); + } + } + } +} + +void ThemeEditorDialog::editColorItem(QTreeWidgetItem *item) +{ + const QColor current(item->text(1)); + QColorDialog dialog(current, this); + dialog.setOption(QColorDialog::ShowAlphaChannel, true); + dialog.setWindowTitle(tr("Edit: %1").arg(item->text(0))); + + // Live update as user drags the picker + connect(&dialog, &QColorDialog::currentColorChanged, this, [this, item](const QColor &color) { + applyColorToItem(item, color); + emit themeJsonChanged(params); + }); + + if (dialog.exec() == QDialog::Accepted) { + applyColorToItem(item, dialog.selectedColor()); + } else { + // Revert to original if cancelled + applyColorToItem(item, current); + } + emit themeJsonChanged(params); +} + +void ThemeEditorDialog::applyColorToItem(QTreeWidgetItem *item, const QColor &color) +{ + const QString hexStr = color.alpha() < 255 + ? color.name(QColor::HexArgb) + : color.name(QColor::HexRgb); + item->setText(1, hexStr); + item->setIcon(1, colorIcon(color)); + + const QStringList path = item->data(0, PathRole).toStringList(); + setJsonPath(params, path, hexStr); +} + +void ThemeEditorDialog::toggleBoolItem(QTreeWidgetItem *item) +{ + const bool newValue = item->text(1) != tr("true"); + item->setText(1, newValue ? tr("true") : tr("false")); + const QStringList path = item->data(0, PathRole).toStringList(); + setJsonPath(params, path, newValue); + emit themeJsonChanged(params); +} + +void ThemeEditorDialog::editNumberItem(QTreeWidgetItem *item) +{ + const double current = item->text(1).toDouble(); + // Use integer dialog when the stored value has no fractional part + const bool isInt = (current == std::floor(current)); + bool ok = false; + double newValue; + if (isInt) { + const int result = QInputDialog::getInt( + this, tr("Edit: %1").arg(item->text(0)), item->text(0), + static_cast(current), INT_MIN, INT_MAX, 1, &ok); + newValue = result; + } else { + newValue = QInputDialog::getDouble( + this, tr("Edit: %1").arg(item->text(0)), item->text(0), + current, -1e9, 1e9, 4, &ok); + } + if (!ok) + return; + item->setText(1, isInt ? QString::number(static_cast(newValue)) : QString::number(newValue)); + const QStringList path = item->data(0, PathRole).toStringList(); + setJsonPath(params, path, newValue); + emit themeJsonChanged(params); +} + +// Returns true if the item or any of its descendants should be visible. +static bool applyFilter(QTreeWidgetItem *item, const QString &query) +{ + if (query.isEmpty()) { + item->setHidden(false); + for (int i = 0; i < item->childCount(); ++i) + applyFilter(item->child(i), query); + return true; + } + + const bool selfMatch = item->text(0).contains(query, Qt::CaseInsensitive); + + if (item->childCount() == 0) { + // Leaf: match on key name or value text + const bool match = selfMatch || item->text(1).contains(query, Qt::CaseInsensitive); + item->setHidden(!match); + return match; + } + + // Group: if the group name itself matches, show all children + bool anyChildVisible = false; + for (int i = 0; i < item->childCount(); ++i) { + if (selfMatch) { + item->child(i)->setHidden(false); + anyChildVisible = true; + } else { + if (applyFilter(item->child(i), query)) + anyChildVisible = true; + } + } + item->setHidden(!anyChildVisible); + return anyChildVisible; +} + +void ThemeEditorDialog::filterTree(const QString &query) +{ + for (int i = 0; i < tree->topLevelItemCount(); ++i) + applyFilter(tree->topLevelItem(i), query); + + // Keep visible results expanded so they're reachable + if (!query.isEmpty()) + tree->expandAll(); +} + +QIcon ThemeEditorDialog::colorIcon(const QColor &color) +{ + const int size = qApp->style()->pixelMetric(QStyle::PM_SmallIconSize); + QPixmap pix(size, size); + pix.fill(color); + return QIcon(pix); +} + +void ThemeEditorDialog::setJsonPath(QJsonObject &root, const QStringList &path, const QJsonValue &value) +{ + if (path.isEmpty()) + return; + if (path.size() == 1) { + root[path[0]] = value; + return; + } + QJsonObject sub = root[path[0]].toObject(); + setJsonPath(sub, path.mid(1), value); + root[path[0]] = sub; +} + +void ThemeEditorDialog::syncMetaToParams() +{ + auto meta = params["meta"].toObject(); + meta["displayName"] = nameEdit->text(); + meta["variant"] = variantCombo->currentData().toString(); + params["meta"] = meta; +} + +void ThemeEditorDialog::syncMetaFromParams() +{ + const auto meta = params["meta"].toObject(); + idLabel->setText(meta["id"].toString()); + nameEdit->setText(meta["displayName"].toString()); + const QString variant = meta["variant"].toString("dark"); + variantCombo->setCurrentIndex(variant == "light" ? 0 : 1); +} + +void ThemeEditorDialog::saveToFile() +{ + // Assign a user-scoped UUID if the current id is builtin or empty + auto meta = params["meta"].toObject(); + const QString currentId = meta["id"].toString(); + if (currentId.isEmpty() || currentId.startsWith("builtin/")) { + const QString newId = "user/" + QUuid::createUuid().toString(QUuid::WithoutBraces); + meta["id"] = newId; + params["meta"] = meta; + idLabel->setText(newId); + } + + const QString path = QFileDialog::getSaveFileName( + this, tr("Save theme"), QString(), tr("JSON files (*.json);;All files (*)")); + if (path.isEmpty()) + return; + + QFile file(path); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QMessageBox::warning(this, tr("Save failed"), tr("Could not open file for writing:\n%1").arg(path)); + return; + } + file.write(QJsonDocument(params).toJson(QJsonDocument::Indented)); +} + +void ThemeEditorDialog::loadFromFile() +{ + const QString path = QFileDialog::getOpenFileName( + this, tr("Load theme"), QString(), tr("JSON files (*.json);;All files (*)")); + if (path.isEmpty()) + return; + + QFile file(path); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QMessageBox::warning(this, tr("Load failed"), tr("Could not open file:\n%1").arg(path)); + return; + } + + QJsonParseError err; + const QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &err); + if (doc.isNull()) { + QMessageBox::warning(this, tr("Load failed"), tr("Invalid JSON:\n%1").arg(err.errorString())); + return; + } + if (!doc.isObject()) { + QMessageBox::warning(this, tr("Load failed"), tr("Expected a JSON object.")); + return; + } + + params = doc.object(); + syncMetaFromParams(); + tree->clear(); + populate(nullptr, params, {}); + tree->expandAll(); + emit themeJsonChanged(params); +} + +void ThemeEditorDialog::identifyPressed() +{ + QTreeWidgetItem *item = tree->currentItem(); + if (!item) + return; + + const QStringList path = item->data(0, PathRole).toStringList(); + if (path.isEmpty()) + return; // group row, not a leaf + + if (item->data(0, IsColorRole).toBool()) { + identifySnapshot = QJsonValue(item->text(1)); + identifyItem = item; + identifyPath = path; + applyColorToItem(item, QColor(0xFA00FA)); + } else if (item->data(0, IsBoolRole).toBool()) { + const bool current = (item->text(1) == tr("true")); + identifySnapshot = QJsonValue(current); + identifyItem = item; + identifyPath = path; + const bool flipped = !current; + item->setText(1, flipped ? tr("true") : tr("false")); + setJsonPath(params, path, flipped); + } else if (item->data(0, IsNumberRole).toBool()) { + const double current = item->text(1).toDouble(); + identifySnapshot = QJsonValue(current); + identifyItem = item; + identifyPath = path; + const bool isInt = (current == std::floor(current)); + const double highlight = (current > 0.0) ? 0.0 : 10.0; + item->setText(1, isInt ? QString::number(static_cast(highlight)) : QString::number(highlight)); + setJsonPath(params, path, highlight); + } else { + return; // non-editable leaf (plain string), nothing to flash + } + emit themeJsonChanged(params); +} + +void ThemeEditorDialog::identifyReleased() +{ + if (!identifyItem) + return; + + QTreeWidgetItem *item = identifyItem; + const QStringList path = identifyPath; + identifyItem = nullptr; + identifyPath.clear(); + + if (item->data(0, IsColorRole).toBool()) { + applyColorToItem(item, QColor(identifySnapshot.toString())); + } else if (item->data(0, IsBoolRole).toBool()) { + const bool restored = identifySnapshot.toBool(); + item->setText(1, restored ? tr("true") : tr("false")); + setJsonPath(params, path, restored); + } else if (item->data(0, IsNumberRole).toBool()) { + const double restored = identifySnapshot.toDouble(); + const bool isInt = (restored == std::floor(restored)); + item->setText(1, isInt ? QString::number(static_cast(restored)) : QString::number(restored)); + setJsonPath(params, path, restored); + } + identifySnapshot = QJsonValue(); + emit themeJsonChanged(params); +} diff --git a/common/themes/theme_editor_dialog.h b/common/themes/theme_editor_dialog.h new file mode 100644 index 000000000..a2f5a5e25 --- /dev/null +++ b/common/themes/theme_editor_dialog.h @@ -0,0 +1,63 @@ +#ifndef THEME_EDITOR_DIALOG_H +#define THEME_EDITOR_DIALOG_H + +#include +#include + +class QComboBox; +class QLabel; +class QLineEdit; +class QTreeWidget; +class QTreeWidgetItem; + +// Generic theme parameter editor. +// Works entirely on QJsonObject — has no knowledge of app-specific ThemeParams. +// Connect to themeJsonChanged to receive live updates as the user edits colors. +class ThemeEditorDialog : public QDialog +{ + Q_OBJECT +public: + explicit ThemeEditorDialog(const QJsonObject ¶ms, QWidget *parent = nullptr); + + QJsonObject currentParams() const { return params; } + +signals: + void themeJsonChanged(const QJsonObject ¶ms); + +private: + void populate(QTreeWidgetItem *parent, const QJsonObject &obj, const QStringList &path); + void editColorItem(QTreeWidgetItem *item); + void applyColorToItem(QTreeWidgetItem *item, const QColor &color); + void toggleBoolItem(QTreeWidgetItem *item); + void editNumberItem(QTreeWidgetItem *item); + void filterTree(const QString &query); + void saveToFile(); + void loadFromFile(); + + // Identify feature: hold the (i) button to temporarily flash the UI element + // that uses the current item's value. The original value is restored on release. + void identifyPressed(); + void identifyReleased(); + + static QIcon colorIcon(const QColor &color); + static void setJsonPath(QJsonObject &root, const QStringList &path, const QJsonValue &value); + + QTreeWidget *tree; + QLineEdit *searchEdit; + QJsonObject params; + + // Meta UI + QLabel *idLabel; + QLineEdit *nameEdit; + QComboBox *variantCombo; + + void syncMetaToParams(); + void syncMetaFromParams(); + + // Identify state (null item = inactive) + QTreeWidgetItem *identifyItem = nullptr; + QStringList identifyPath; + QJsonValue identifySnapshot; // original value saved on press, restored on release +}; + +#endif // THEME_EDITOR_DIALOG_H diff --git a/common/themes/theme_id.h b/common/themes/theme_id.h deleted file mode 100644 index f42c30696..000000000 --- a/common/themes/theme_id.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef THEME_ID_H -#define THEME_ID_H - -enum class ThemeId { - Classic, - Light, - Dark, -}; - -#endif // THEME_ID_H diff --git a/common/themes/theme_manager.cpp b/common/themes/theme_manager.cpp index 094000c2e..589b201ef 100644 --- a/common/themes/theme_manager.cpp +++ b/common/themes/theme_manager.cpp @@ -1,14 +1,13 @@ #include "theme_manager.h" +#include "appearance_configuration.h" #include "theme.h" #include "theme_factory.h" +#include "theme_repository.h" #include -#include #include -// TODO: add API to force color scheme //styleHints->setColorScheme(Qt::ColorScheme::Dark); - ThemeManager::ThemeManager() { } @@ -19,36 +18,106 @@ ThemeManager &ThemeManager::instance() return instance; } -void ThemeManager::initialize() +void ThemeManager::initialize(AppearanceConfiguration *config, ThemeRepository *repository) { + this->config = config; + this->repository = repository; + auto *styleHints = qGuiApp->styleHints(); - auto colorScheme = styleHints->colorScheme(); + // Re-resolve when OS color scheme changes (relevant for FollowSystem mode) + connect(styleHints, &QStyleHints::colorSchemeChanged, this, &ThemeManager::resolveTheme, Qt::QueuedConnection); - // TODO: settings are needed to decide what theme to use - auto applyColorScheme = [this](Qt::ColorScheme scheme) { - setTheme(scheme == Qt::ColorScheme::Dark ? ThemeId::Dark : ThemeId::Light); - }; + // Re-resolve when the user changes any theme setting + connect(config, &AppearanceConfiguration::selectionChanged, this, &ThemeManager::resolveTheme); - applyColorScheme(colorScheme); + resolveTheme(); +} - connect(styleHints, &QStyleHints::colorSchemeChanged, this, applyColorScheme, Qt::QueuedConnection); +void ThemeManager::setTheme(const Theme &theme) +{ + currentTheme = theme; + emit themeChanged(); } -void ThemeManager::setTheme(ThemeId themeId) +Theme ThemeManager::themeFromId(const QString &id, ThemeVariant fallbackVariant) { - if (this->themeId == themeId) { - return; + // Try the repository first (handles both builtin and user themes via JSON) + if (repository && repository->contains(id)) { + QJsonObject json = repository->loadThemeJson(id); + if (!json.isEmpty()) + return makeTheme(json); } - this->themeId = themeId; - - updateCurrentTheme(); + // Fallback to the builtin that matches the current dark/light intent. + const QString fallbackId = (fallbackVariant == ThemeVariant::Dark) + ? QStringLiteral("builtin/dark") + : QStringLiteral("builtin/light"); + if (repository && repository->contains(fallbackId)) { + QJsonObject json = repository->loadThemeJson(fallbackId); + if (!json.isEmpty()) + return makeTheme(json); + } - emit themeChanged(); + return {}; } -void ThemeManager::updateCurrentTheme() +void ThemeManager::resolveTheme() { - currentTheme = makeTheme(themeId); + if (!config) + return; + + const auto &sel = config->selection(); + + QString id; + ThemeVariant fallbackVariant; + switch (sel.mode) { + case ThemeMode::FollowSystem: { + const bool isDark = (qGuiApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark); + id = isDark ? sel.darkThemeId : sel.lightThemeId; + fallbackVariant = isDark ? ThemeVariant::Dark : ThemeVariant::Light; + break; + } + case ThemeMode::Light: + id = sel.lightThemeId; + fallbackVariant = ThemeVariant::Light; + break; + case ThemeMode::Dark: + id = sel.darkThemeId; + fallbackVariant = ThemeVariant::Dark; + break; + case ThemeMode::ForcedTheme: + id = sel.fixedThemeId; + fallbackVariant = (qGuiApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark) + ? ThemeVariant::Dark + : ThemeVariant::Light; + break; + } + + const Theme theme = themeFromId(id, fallbackVariant); + + // Sync Qt's application-level color scheme so native widgets (menus, scrollbars, + // standard dialogs) use the correct palette before themeChanged() is emitted. +#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) + Qt::ColorScheme scheme; + switch (sel.mode) { + case ThemeMode::FollowSystem: + scheme = Qt::ColorScheme::Unknown; // delegate to OS + break; + case ThemeMode::Light: + scheme = Qt::ColorScheme::Light; + break; + case ThemeMode::Dark: + scheme = Qt::ColorScheme::Dark; + break; + case ThemeMode::ForcedTheme: + scheme = (theme.meta.variant == ThemeVariant::Dark) + ? Qt::ColorScheme::Dark + : Qt::ColorScheme::Light; + break; + } + qGuiApp->styleHints()->setColorScheme(scheme); +#endif + + setTheme(theme); } diff --git a/common/themes/theme_manager.h b/common/themes/theme_manager.h index 8bac2dad5..42b8d0d0c 100644 --- a/common/themes/theme_manager.h +++ b/common/themes/theme_manager.h @@ -1,11 +1,13 @@ #ifndef THEME_MANAGER_H #define THEME_MANAGER_H +#include "appearance_configuration.h" #include "theme.h" -#include "theme_id.h" #include +class ThemeRepository; + class ThemeManager : public QObject { Q_OBJECT @@ -17,21 +19,27 @@ class ThemeManager : public QObject ThemeManager(ThemeManager &&) = delete; ThemeManager &operator=(ThemeManager &&) = delete; - void initialize(); - - void setTheme(ThemeId themeId); + void initialize(AppearanceConfiguration *config, ThemeRepository *repository); + void setTheme(const Theme &theme); const Theme &getCurrentTheme() const { return currentTheme; } + AppearanceConfiguration *getAppearanceConfiguration() const { return config; } + signals: void themeChanged(); private: explicit ThemeManager(); - ThemeId themeId = ThemeId::Classic; + + AppearanceConfiguration *config = nullptr; + ThemeRepository *repository = nullptr; Theme currentTheme; - void updateCurrentTheme(); + Theme themeFromId(const QString &id, ThemeVariant fallbackVariant); + +private slots: + void resolveTheme(); }; #endif // THEME_MANAGER_H diff --git a/common/themes/theme_meta.h b/common/themes/theme_meta.h new file mode 100644 index 000000000..e3b9c6d8f --- /dev/null +++ b/common/themes/theme_meta.h @@ -0,0 +1,14 @@ +#ifndef THEME_META_H +#define THEME_META_H + +#include "theme_variant.h" + +#include + +struct ThemeMeta { + QString id; + QString displayName; + ThemeVariant variant; +}; + +#endif // THEME_META_H diff --git a/common/themes/theme_repository.cpp b/common/themes/theme_repository.cpp new file mode 100644 index 000000000..3290cd631 --- /dev/null +++ b/common/themes/theme_repository.cpp @@ -0,0 +1,206 @@ +#include "theme_repository.h" + +#include +#include +#include +#include +#include + +ThemeRepository::ThemeRepository(const QString &qrcPrefix, const QString &userThemesDir) + : qrcPrefix(qrcPrefix), userThemesDir(userThemesDir) +{ + scanBuiltins(); + scanUserThemes(); +} + +QList ThemeRepository::availableThemes() const +{ + QList result; + result.reserve(builtins.size() + userThemes.size()); + + for (const auto &b : builtins) + result.append({ b.meta.id, b.meta.displayName, b.meta.variant, true }); + + for (const auto &u : userThemes) + result.append({ u.meta.id, u.meta.displayName, u.meta.variant, false }); + + return result; +} + +bool ThemeRepository::contains(const QString &themeId) const +{ + for (const auto &b : builtins) + if (b.id == themeId) + return true; + + for (const auto &u : userThemes) + if (u.id == themeId) + return true; + + return false; +} + +QJsonObject ThemeRepository::loadThemeJson(const QString &themeId) const +{ + for (const auto &b : builtins) + if (b.id == themeId) + return readJsonFile(b.resourcePath); + + for (const auto &u : userThemes) + if (u.id == themeId) + return readJsonFile(u.filePath); + + return {}; +} + +QString ThemeRepository::saveUserTheme(QJsonObject themeJson) +{ + QDir().mkpath(userThemesDir); + + auto metaObj = themeJson["meta"].toObject(); + QString id = metaObj["id"].toString(); + + if (id.isEmpty() || id.startsWith("builtin/")) { + const QString uuid = QUuid::createUuid().toString(QUuid::WithoutBraces); + id = "user/" + uuid; + metaObj["id"] = id; + themeJson["meta"] = metaObj; + } + + // Extract uuid from "user/" + const QString uuid = id.mid(5); // skip "user/" + const QString filePath = filePathForUserTheme(uuid); + + QFile file(filePath); + if (file.open(QIODevice::WriteOnly)) { + file.write(QJsonDocument(themeJson).toJson(QJsonDocument::Indented)); + file.close(); + } + + // Update cache + refresh(); + + return id; +} + +bool ThemeRepository::deleteUserTheme(const QString &themeId) +{ + if (themeId.startsWith("builtin/")) + return false; + + for (const auto &u : userThemes) { + if (u.id == themeId) { + const bool removed = QFile::remove(u.filePath); + if (removed) + refresh(); + return removed; + } + } + + return false; +} + +QString ThemeRepository::importThemeFromFile(const QString &filePath) +{ + QJsonObject json = readJsonFile(filePath); + if (json.isEmpty()) + return {}; + + // Force a new user id regardless of what the file contains + auto metaObj = json["meta"].toObject(); + const QString uuid = QUuid::createUuid().toString(QUuid::WithoutBraces); + const QString id = "user/" + uuid; + metaObj["id"] = id; + json["meta"] = metaObj; + + return saveUserTheme(json); +} + +void ThemeRepository::refresh() +{ + scanUserThemes(); +} + +// --- Private helpers --- + +void ThemeRepository::scanBuiltins() +{ + builtins.clear(); + + static const QStringList builtinNames = { "classic", "light", "dark" }; + + for (const auto &name : builtinNames) { + const QString resourcePath = qrcPrefix + "/builtin_" + name + ".json"; + const QJsonObject json = readJsonFile(resourcePath); + if (json.isEmpty()) + continue; + + BuiltinEntry entry; + entry.id = "builtin/" + name; + entry.resourcePath = resourcePath; + entry.meta = extractMeta(json); + // Ensure the id matches the canonical form + entry.meta.id = entry.id; + builtins.append(entry); + } +} + +void ThemeRepository::scanUserThemes() +{ + userThemes.clear(); + + QDir dir(userThemesDir); + if (!dir.exists()) + return; + + const auto entries = dir.entryList({ "*.json" }, QDir::Files); + for (const auto &fileName : entries) { + const QString filePath = dir.absoluteFilePath(fileName); + const QJsonObject json = readJsonFile(filePath); + if (json.isEmpty()) + continue; + + ThemeMeta meta = extractMeta(json); + if (meta.id.isEmpty()) { + // Derive id from filename (strip .json extension) + const QString baseName = fileName.chopped(5); // remove ".json" + meta.id = "user/" + baseName; + } + + UserEntry entry; + entry.id = meta.id; + entry.filePath = filePath; + entry.meta = meta; + userThemes.append(entry); + } +} + +ThemeMeta ThemeRepository::extractMeta(const QJsonObject &json) +{ + const auto meta = json["meta"].toObject(); + return ThemeMeta { + meta["id"].toString(), + meta["displayName"].toString(), + (meta["variant"].toString() == "light") ? ThemeVariant::Light : ThemeVariant::Dark + }; +} + +QJsonObject ThemeRepository::readJsonFile(const QString &path) +{ + QFile file(path); + if (!file.open(QIODevice::ReadOnly)) + return {}; + + const QByteArray data = file.readAll(); + QJsonParseError error; + const QJsonDocument doc = QJsonDocument::fromJson(data, &error); + if (error.error != QJsonParseError::NoError) + return {}; + + return doc.object(); +} + +QString ThemeRepository::filePathForUserTheme(const QString &uuid) const +{ + return userThemesDir + "/" + uuid + ".json"; +} diff --git a/common/themes/theme_repository.h b/common/themes/theme_repository.h new file mode 100644 index 000000000..e9ec4a855 --- /dev/null +++ b/common/themes/theme_repository.h @@ -0,0 +1,57 @@ +#ifndef THEME_REPOSITORY_H +#define THEME_REPOSITORY_H + +#include "theme_meta.h" + +#include +#include +#include + +struct ThemeListEntry { + QString id; + QString displayName; + ThemeVariant variant; + bool isBuiltin; +}; + +class ThemeRepository +{ +public: + explicit ThemeRepository(const QString &qrcPrefix, const QString &userThemesDir); + + QList availableThemes() const; + bool contains(const QString &themeId) const; + QJsonObject loadThemeJson(const QString &themeId) const; + + QString saveUserTheme(QJsonObject themeJson); + bool deleteUserTheme(const QString &themeId); + QString importThemeFromFile(const QString &filePath); + + void refresh(); + +private: + QString qrcPrefix; + QString userThemesDir; + + struct BuiltinEntry { + QString id; + QString resourcePath; + ThemeMeta meta; + }; + QList builtins; + + struct UserEntry { + QString id; + QString filePath; + ThemeMeta meta; + }; + QList userThemes; + + void scanBuiltins(); + void scanUserThemes(); + static ThemeMeta extractMeta(const QJsonObject &json); + static QJsonObject readJsonFile(const QString &path); + QString filePathForUserTheme(const QString &uuid) const; +}; + +#endif // THEME_REPOSITORY_H diff --git a/common/themes/theme_variant.h b/common/themes/theme_variant.h new file mode 100644 index 000000000..adff03274 --- /dev/null +++ b/common/themes/theme_variant.h @@ -0,0 +1,9 @@ +#ifndef THEME_VARIANT_H +#define THEME_VARIANT_H + +enum class ThemeVariant { + Light, + Dark, +}; + +#endif // THEME_VARIANT_H diff --git a/images/appearance_config/theme-mode-dark.svg b/images/appearance_config/theme-mode-dark.svg new file mode 100644 index 000000000..a30277b96 --- /dev/null +++ b/images/appearance_config/theme-mode-dark.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/appearance_config/theme-mode-light.svg b/images/appearance_config/theme-mode-light.svg new file mode 100644 index 000000000..401b54c82 --- /dev/null +++ b/images/appearance_config/theme-mode-light.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/appearance_config/theme-mode-system.svg b/images/appearance_config/theme-mode-system.svg new file mode 100644 index 000000000..62fc45696 --- /dev/null +++ b/images/appearance_config/theme-mode-system.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From e0930d7a68c0c77ec397efc334a0e62b8cb3410e Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 2 Mar 2026 22:31:56 +0100 Subject: [PATCH 109/187] Rename YACReaderLibrary json theme sections to be more user friendly --- .../comic_vine/comic_vine_dialog.cpp | 18 +- .../comic_vine/scraper_checkbox.cpp | 4 +- .../comic_vine/scraper_lineedit.cpp | 6 +- .../comic_vine/scraper_results_paginator.cpp | 18 +- .../comic_vine/scraper_scroll_label.cpp | 6 +- .../comic_vine/scraper_tableview.cpp | 4 +- .../comic_vine/search_single_comic.cpp | 4 +- YACReaderLibrary/comic_vine/search_volume.cpp | 4 +- YACReaderLibrary/comic_vine/select_comic.cpp | 6 +- YACReaderLibrary/comic_vine/select_volume.cpp | 6 +- .../comic_vine/series_question.cpp | 8 +- .../comic_vine/sort_volume_comics.cpp | 24 +- YACReaderLibrary/comic_vine/title_header.cpp | 6 +- YACReaderLibrary/comics_view_transition.cpp | 4 +- YACReaderLibrary/db/folder_model.cpp | 4 +- YACReaderLibrary/db/reading_list_item.cpp | 2 +- YACReaderLibrary/folder_content_view.cpp | 40 +- YACReaderLibrary/grid_comics_view.cpp | 48 +- YACReaderLibrary/info_comics_view.cpp | 32 +- YACReaderLibrary/themes/builtin_classic.json | 9 +- YACReaderLibrary/themes/builtin_dark.json | 9 +- YACReaderLibrary/themes/builtin_light.json | 9 +- YACReaderLibrary/themes/theme.h | 32 +- YACReaderLibrary/themes/theme_factory.cpp | 468 +++++++++--------- custom_widgets/yacreader_table_view.cpp | 2 +- custom_widgets/yacreader_table_view.h | 4 +- custom_widgets/yacreader_treeview.cpp | 2 +- custom_widgets/yacreader_treeview.h | 2 +- 28 files changed, 383 insertions(+), 398 deletions(-) diff --git a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp index 23d74cd3c..5efab5272 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp +++ b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp @@ -649,16 +649,16 @@ void ComicVineDialog::launchSearchComic() void ComicVineDialog::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; - setStyleSheet(comicVineTheme.dialogQSS); + setStyleSheet(metadataScraperDialogTheme.dialogQSS); - skipButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); - backButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); - nextButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); - searchButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); - closeButton->setStyleSheet(comicVineTheme.dialogButtonsQSS); + skipButton->setStyleSheet(metadataScraperDialogTheme.dialogButtonsQSS); + backButton->setStyleSheet(metadataScraperDialogTheme.dialogButtonsQSS); + nextButton->setStyleSheet(metadataScraperDialogTheme.dialogButtonsQSS); + searchButton->setStyleSheet(metadataScraperDialogTheme.dialogButtonsQSS); + closeButton->setStyleSheet(metadataScraperDialogTheme.dialogButtonsQSS); - loadingMessage->setStyleSheet(comicVineTheme.defaultLabelQSS); - busyWidget->setColor(comicVineTheme.busyIndicatorColor); + loadingMessage->setStyleSheet(metadataScraperDialogTheme.defaultLabelQSS); + busyWidget->setColor(metadataScraperDialogTheme.busyIndicatorColor); } diff --git a/YACReaderLibrary/comic_vine/scraper_checkbox.cpp b/YACReaderLibrary/comic_vine/scraper_checkbox.cpp index 2aa78b9b2..e15b3ac98 100644 --- a/YACReaderLibrary/comic_vine/scraper_checkbox.cpp +++ b/YACReaderLibrary/comic_vine/scraper_checkbox.cpp @@ -8,7 +8,7 @@ ScraperCheckBox::ScraperCheckBox(const QString &text, QWidget *parent) void ScraperCheckBox::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; - setStyleSheet(comicVineTheme.checkBoxQSS); + setStyleSheet(metadataScraperDialogTheme.checkBoxQSS); } diff --git a/YACReaderLibrary/comic_vine/scraper_lineedit.cpp b/YACReaderLibrary/comic_vine/scraper_lineedit.cpp index fb305c05f..a67c80047 100644 --- a/YACReaderLibrary/comic_vine/scraper_lineedit.cpp +++ b/YACReaderLibrary/comic_vine/scraper_lineedit.cpp @@ -20,8 +20,8 @@ void ScraperLineEdit::resizeEvent(QResizeEvent *) void ScraperLineEdit::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; - titleLabel->setStyleSheet(comicVineTheme.scraperLineEditTitleLabelQSS); - setStyleSheet(comicVineTheme.scraperLineEditQSS.arg(titleLabel->sizeHint().width() + 6)); + titleLabel->setStyleSheet(metadataScraperDialogTheme.scraperLineEditTitleLabelQSS); + setStyleSheet(metadataScraperDialogTheme.scraperLineEditQSS.arg(titleLabel->sizeHint().width() + 6)); } diff --git a/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp b/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp index 637b7fb90..8594656fc 100644 --- a/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp +++ b/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp @@ -63,16 +63,16 @@ void ScraperResultsPaginator::setCustomLabel(const QString &label) void ScraperResultsPaginator::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; - numElements->setStyleSheet(comicVineTheme.defaultLabelQSS); - numPages->setStyleSheet(comicVineTheme.defaultLabelQSS); + numElements->setStyleSheet(metadataScraperDialogTheme.defaultLabelQSS); + numPages->setStyleSheet(metadataScraperDialogTheme.defaultLabelQSS); - nextPage->setStyleSheet(comicVineTheme.noBorderToolButtonQSS); - nextPage->setIconSize(comicVineTheme.nextPageIcon.size); - nextPage->setIcon(comicVineTheme.nextPageIcon.icon); + nextPage->setStyleSheet(metadataScraperDialogTheme.noBorderToolButtonQSS); + nextPage->setIconSize(metadataScraperDialogTheme.nextPageIcon.size); + nextPage->setIcon(metadataScraperDialogTheme.nextPageIcon.icon); - previousPage->setStyleSheet(comicVineTheme.noBorderToolButtonQSS); - previousPage->setIconSize(comicVineTheme.previousPageIcon.size); - previousPage->setIcon(comicVineTheme.previousPageIcon.icon); + previousPage->setStyleSheet(metadataScraperDialogTheme.noBorderToolButtonQSS); + previousPage->setIconSize(metadataScraperDialogTheme.previousPageIcon.size); + previousPage->setIcon(metadataScraperDialogTheme.previousPageIcon.icon); } diff --git a/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp b/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp index 314a7ac3c..f9422890f 100644 --- a/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp +++ b/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp @@ -41,8 +41,8 @@ void ScraperScrollLabel::openLink(const QString &link) void ScraperScrollLabel::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; - textLabel->setStyleSheet(comicVineTheme.scraperScrollLabelTextQSS); - setStyleSheet(comicVineTheme.scraperScrollLabelScrollAreaQSS); + textLabel->setStyleSheet(metadataScraperDialogTheme.scraperScrollLabelTextQSS); + setStyleSheet(metadataScraperDialogTheme.scraperScrollLabelScrollAreaQSS); } diff --git a/YACReaderLibrary/comic_vine/scraper_tableview.cpp b/YACReaderLibrary/comic_vine/scraper_tableview.cpp index 0b5288022..47efab2c8 100644 --- a/YACReaderLibrary/comic_vine/scraper_tableview.cpp +++ b/YACReaderLibrary/comic_vine/scraper_tableview.cpp @@ -32,7 +32,7 @@ ScraperTableView::ScraperTableView(QWidget *parent) void ScraperTableView::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; - setStyleSheet(comicVineTheme.scraperTableViewQSS); + setStyleSheet(metadataScraperDialogTheme.scraperTableViewQSS); } diff --git a/YACReaderLibrary/comic_vine/search_single_comic.cpp b/YACReaderLibrary/comic_vine/search_single_comic.cpp index edf187828..9dd7c7db2 100644 --- a/YACReaderLibrary/comic_vine/search_single_comic.cpp +++ b/YACReaderLibrary/comic_vine/search_single_comic.cpp @@ -74,7 +74,7 @@ void SearchSingleComic::clean() void SearchSingleComic::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; - label->setStyleSheet(comicVineTheme.defaultLabelQSS); + label->setStyleSheet(metadataScraperDialogTheme.defaultLabelQSS); } diff --git a/YACReaderLibrary/comic_vine/search_volume.cpp b/YACReaderLibrary/comic_vine/search_volume.cpp index e520f02c1..7a0a4cfab 100644 --- a/YACReaderLibrary/comic_vine/search_volume.cpp +++ b/YACReaderLibrary/comic_vine/search_volume.cpp @@ -49,7 +49,7 @@ QString SearchVolume::getVolumeInfo() const void SearchVolume::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; - label->setStyleSheet(comicVineTheme.defaultLabelQSS); + label->setStyleSheet(metadataScraperDialogTheme.defaultLabelQSS); } diff --git a/YACReaderLibrary/comic_vine/select_comic.cpp b/YACReaderLibrary/comic_vine/select_comic.cpp index aa5eb668d..67dd1ac2e 100644 --- a/YACReaderLibrary/comic_vine/select_comic.cpp +++ b/YACReaderLibrary/comic_vine/select_comic.cpp @@ -165,8 +165,8 @@ QString SelectComic::getSelectedComicId() void SelectComic::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; - label->setStyleSheet(comicVineTheme.defaultLabelQSS); - cover->setStyleSheet(comicVineTheme.coverLabelQSS); + label->setStyleSheet(metadataScraperDialogTheme.defaultLabelQSS); + cover->setStyleSheet(metadataScraperDialogTheme.coverLabelQSS); } diff --git a/YACReaderLibrary/comic_vine/select_volume.cpp b/YACReaderLibrary/comic_vine/select_volume.cpp index 2ed1656df..66e6c5ee4 100644 --- a/YACReaderLibrary/comic_vine/select_volume.cpp +++ b/YACReaderLibrary/comic_vine/select_volume.cpp @@ -219,8 +219,8 @@ SelectedVolumeInfo SelectVolume::getSelectedVolumeInfo() void SelectVolume::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; - label->setStyleSheet(comicVineTheme.defaultLabelQSS); - cover->setStyleSheet(comicVineTheme.coverLabelQSS); + label->setStyleSheet(metadataScraperDialogTheme.defaultLabelQSS); + cover->setStyleSheet(metadataScraperDialogTheme.coverLabelQSS); } diff --git a/YACReaderLibrary/comic_vine/series_question.cpp b/YACReaderLibrary/comic_vine/series_question.cpp index caab57fe1..34c53c7ec 100644 --- a/YACReaderLibrary/comic_vine/series_question.cpp +++ b/YACReaderLibrary/comic_vine/series_question.cpp @@ -40,9 +40,9 @@ void SeriesQuestion::setYes(bool y) void SeriesQuestion::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; - questionLabel->setStyleSheet(comicVineTheme.defaultLabelQSS); - yes->setStyleSheet(comicVineTheme.radioButtonQSS); - no->setStyleSheet(comicVineTheme.radioButtonQSS); + questionLabel->setStyleSheet(metadataScraperDialogTheme.defaultLabelQSS); + yes->setStyleSheet(metadataScraperDialogTheme.radioButtonQSS); + no->setStyleSheet(metadataScraperDialogTheme.radioButtonQSS); } diff --git a/YACReaderLibrary/comic_vine/sort_volume_comics.cpp b/YACReaderLibrary/comic_vine/sort_volume_comics.cpp index d44774d4f..5bb2d6c5e 100644 --- a/YACReaderLibrary/comic_vine/sort_volume_comics.cpp +++ b/YACReaderLibrary/comic_vine/sort_volume_comics.cpp @@ -22,8 +22,8 @@ QWidget *ScrapperToolButton::getSeparator() { QWidget *w = new QWidget; w->setFixedWidth(1); - auto comicVineTheme = ThemeManager::instance().getCurrentTheme().comicVine; - w->setStyleSheet(comicVineTheme.scraperToolButtonSeparatorQSS); + auto metadataScraperDialogTheme = ThemeManager::instance().getCurrentTheme().metadataScraperDialog; + w->setStyleSheet(metadataScraperDialogTheme.scraperToolButtonSeparatorQSS); return w; } @@ -47,9 +47,9 @@ void ScrapperToolButton::paintEvent(QPaintEvent *e) void ScrapperToolButton::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; - setStyleSheet(comicVineTheme.scraperToolButtonQSS); - fillColor = comicVineTheme.scraperToolButtonFillColor; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; + setStyleSheet(metadataScraperDialogTheme.scraperToolButtonQSS); + fillColor = metadataScraperDialogTheme.scraperToolButtonFillColor; update(); } @@ -267,13 +267,13 @@ QList> SortVolumeComics::getMatchingInfo() void SortVolumeComics::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; - label->setStyleSheet(comicVineTheme.defaultLabelQSS); - sortLabel->setStyleSheet(comicVineTheme.defaultLabelQSS); + label->setStyleSheet(metadataScraperDialogTheme.defaultLabelQSS); + sortLabel->setStyleSheet(metadataScraperDialogTheme.defaultLabelQSS); - moveUpButtonCL->setIconSize(comicVineTheme.rowUpIcon.size); - moveUpButtonCL->setIcon(comicVineTheme.rowUpIcon.icon); - moveDownButtonCL->setIconSize(comicVineTheme.rowDownIcon.size); - moveDownButtonCL->setIcon(comicVineTheme.rowDownIcon.icon); + moveUpButtonCL->setIconSize(metadataScraperDialogTheme.rowUpIcon.size); + moveUpButtonCL->setIcon(metadataScraperDialogTheme.rowUpIcon.icon); + moveDownButtonCL->setIconSize(metadataScraperDialogTheme.rowDownIcon.size); + moveDownButtonCL->setIcon(metadataScraperDialogTheme.rowDownIcon.icon); } diff --git a/YACReaderLibrary/comic_vine/title_header.cpp b/YACReaderLibrary/comic_vine/title_header.cpp index 06585908f..8f54c5b3a 100644 --- a/YACReaderLibrary/comic_vine/title_header.cpp +++ b/YACReaderLibrary/comic_vine/title_header.cpp @@ -49,8 +49,8 @@ void TitleHeader::showButtons(bool show) void TitleHeader::applyTheme(const Theme &theme) { - auto comicVineTheme = theme.comicVine; + auto metadataScraperDialogTheme = theme.metadataScraperDialog; - mainTitleLabel->setStyleSheet(comicVineTheme.titleLabelQSS); - subTitleLabel->setStyleSheet(comicVineTheme.defaultLabelQSS); + mainTitleLabel->setStyleSheet(metadataScraperDialogTheme.titleLabelQSS); + subTitleLabel->setStyleSheet(metadataScraperDialogTheme.defaultLabelQSS); } diff --git a/YACReaderLibrary/comics_view_transition.cpp b/YACReaderLibrary/comics_view_transition.cpp index 0c083d93a..886292ac7 100644 --- a/YACReaderLibrary/comics_view_transition.cpp +++ b/YACReaderLibrary/comics_view_transition.cpp @@ -10,12 +10,12 @@ ComicsViewTransition::ComicsViewTransition(QWidget *parent) void ComicsViewTransition::applyTheme(const Theme &theme) { - setStyleSheet(QString("QWidget {background:%1}").arg(theme.defaultContentBackgroundColor.name())); + setStyleSheet(QString("QWidget {background:%1}").arg(theme.gridAndInfoView.backgroundColor.name())); update(); } void ComicsViewTransition::paintEvent(QPaintEvent *) { QPainter painter(this); - painter.fillRect(0, 0, width(), height(), theme.defaultContentBackgroundColor); + painter.fillRect(0, 0, width(), height(), theme.gridAndInfoView.backgroundColor); } diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 8a71c9c2a..a160ecd69 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -144,8 +144,8 @@ void FolderModel::applyTheme(const Theme &theme) folderIcon = QFileIconProvider().icon(QFileIconProvider::Folder); folderFinishedIcon = drawFinishedFolderIcon(sidebarIcons.folderReadOverlay); } else { - folderIcon = theme.treeView.folderIcon; - folderFinishedIcon = theme.treeView.folderFinishedIcon; + folderIcon = theme.navigationTree.folderIcon; + folderFinishedIcon = theme.navigationTree.folderFinishedIcon; } } diff --git a/YACReaderLibrary/db/reading_list_item.cpp b/YACReaderLibrary/db/reading_list_item.cpp index e403f2edb..0fd02f3d0 100644 --- a/YACReaderLibrary/db/reading_list_item.cpp +++ b/YACReaderLibrary/db/reading_list_item.cpp @@ -153,7 +153,7 @@ QIcon ReadingListItem::getIcon() const else if (theme.sidebarIcons.useSystemFolderIcons) return QFileIconProvider().icon(QFileIconProvider::Folder); else - return theme.treeView.folderIcon; // sublist + return theme.navigationTree.folderIcon; // sublist } int ReadingListItem::childCount() const diff --git a/YACReaderLibrary/folder_content_view.cpp b/YACReaderLibrary/folder_content_view.cpp index 485032bf7..28535922e 100644 --- a/YACReaderLibrary/folder_content_view.cpp +++ b/YACReaderLibrary/folder_content_view.cpp @@ -263,36 +263,36 @@ void FolderContentView::droppedFiles(const QList &urls, Qt::DropAction act void FolderContentView::applyTheme(const Theme &theme) { QQmlContext *ctxt = view->rootContext(); - const auto &qv = theme.qmlView; + const auto &giv = theme.gridAndInfoView; toolbar->setStyleSheet(theme.comicsViewToolbar.toolbarQSS); // Continue reading section colors - ctxt->setContextProperty("continueReadingBackgroundColor", qv.continueReadingBackgroundColor); - ctxt->setContextProperty("continueReadingColor", qv.continueReadingColor); + ctxt->setContextProperty("continueReadingBackgroundColor", giv.continueReadingBackgroundColor); + ctxt->setContextProperty("continueReadingColor", giv.continueReadingColor); // Grid colors - ctxt->setContextProperty("backgroundColor", qv.backgroundColor); - ctxt->setContextProperty("cellColor", qv.cellColor); - ctxt->setContextProperty("selectedColor", qv.selectedColor); - ctxt->setContextProperty("selectedBorderColor", qv.selectedBorderColor); - ctxt->setContextProperty("borderColor", qv.borderColor); - ctxt->setContextProperty("titleColor", qv.titleColor); - ctxt->setContextProperty("textColor", qv.textColor); - ctxt->setContextProperty("dropShadow", QVariant(qv.showDropShadow)); + ctxt->setContextProperty("backgroundColor", giv.backgroundColor); + ctxt->setContextProperty("cellColor", giv.cellColor); + ctxt->setContextProperty("selectedColor", giv.selectedColor); + ctxt->setContextProperty("selectedBorderColor", giv.selectedBorderColor); + ctxt->setContextProperty("borderColor", giv.borderColor); + ctxt->setContextProperty("titleColor", giv.titleColor); + ctxt->setContextProperty("textColor", giv.textColor); + ctxt->setContextProperty("dropShadow", QVariant(giv.showDropShadow)); // Info panel colors - ctxt->setContextProperty("infoBackgroundColor", qv.infoBackgroundColor); - ctxt->setContextProperty("infoTextColor", qv.infoTextColor); - ctxt->setContextProperty("infoTitleColor", qv.infoTitleColor); + ctxt->setContextProperty("infoBackgroundColor", giv.infoBackgroundColor); + ctxt->setContextProperty("infoTextColor", giv.infoTextColor); + ctxt->setContextProperty("infoTitleColor", giv.infoTitleColor); // Rating and favorite colors - ctxt->setContextProperty("ratingUnselectedColor", qv.ratingUnselectedColor); - ctxt->setContextProperty("ratingSelectedColor", qv.ratingSelectedColor); - ctxt->setContextProperty("favUncheckedColor", qv.favUncheckedColor); - ctxt->setContextProperty("favCheckedColor", qv.favCheckedColor); - ctxt->setContextProperty("readTickUncheckedColor", qv.readTickUncheckedColor); - ctxt->setContextProperty("readTickCheckedColor", qv.readTickCheckedColor); + ctxt->setContextProperty("ratingUnselectedColor", giv.ratingUnselectedColor); + ctxt->setContextProperty("ratingSelectedColor", giv.ratingSelectedColor); + ctxt->setContextProperty("favUncheckedColor", giv.favUncheckedColor); + ctxt->setContextProperty("favCheckedColor", giv.favCheckedColor); + ctxt->setContextProperty("readTickUncheckedColor", giv.readTickUncheckedColor); + ctxt->setContextProperty("readTickCheckedColor", giv.readTickCheckedColor); // Update zoom slider icons if (smallZoomLabel) { diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index 39b67f017..2542f85cb 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -219,10 +219,10 @@ void GridComicsView::updateBackgroundConfig() } // Use theme colors for cell and selected colors - const auto &qv = theme.qmlView; - ctxt->setContextProperty("backgroundColor", useBackgroundImage ? qv.backgroundBlurOverlayColor : qv.backgroundColor); - ctxt->setContextProperty("cellColor", useBackgroundImage ? qv.cellColorWithBackground : qv.cellColor); - ctxt->setContextProperty("selectedColor", qv.selectedColor); + const auto &giv = theme.gridAndInfoView; + ctxt->setContextProperty("backgroundColor", useBackgroundImage ? giv.backgroundBlurOverlayColor : giv.backgroundColor); + ctxt->setContextProperty("cellColor", useBackgroundImage ? giv.cellColorWithBackground : giv.cellColor); + ctxt->setContextProperty("selectedColor", giv.selectedColor); } void GridComicsView::showInfo() @@ -488,34 +488,34 @@ void GridComicsView::selectedItem(int index) void GridComicsView::applyTheme(const Theme &theme) { QQmlContext *ctxt = view->rootContext(); - const auto &qv = theme.qmlView; + const auto &giv = theme.gridAndInfoView; // Grid colors - ctxt->setContextProperty("backgroundColor", qv.backgroundColor); - ctxt->setContextProperty("backgroundBlurOverlayColor", qv.backgroundBlurOverlayColor); - ctxt->setContextProperty("cellColor", qv.cellColor); - ctxt->setContextProperty("selectedColor", qv.selectedColor); - ctxt->setContextProperty("selectedBorderColor", qv.selectedBorderColor); - ctxt->setContextProperty("borderColor", qv.borderColor); - ctxt->setContextProperty("titleColor", qv.titleColor); - ctxt->setContextProperty("textColor", qv.textColor); - ctxt->setContextProperty("showDropShadow", QVariant(qv.showDropShadow)); + ctxt->setContextProperty("backgroundColor", giv.backgroundColor); + ctxt->setContextProperty("backgroundBlurOverlayColor", giv.backgroundBlurOverlayColor); + ctxt->setContextProperty("cellColor", giv.cellColor); + ctxt->setContextProperty("selectedColor", giv.selectedColor); + ctxt->setContextProperty("selectedBorderColor", giv.selectedBorderColor); + ctxt->setContextProperty("borderColor", giv.borderColor); + ctxt->setContextProperty("titleColor", giv.titleColor); + ctxt->setContextProperty("textColor", giv.textColor); + ctxt->setContextProperty("showDropShadow", QVariant(giv.showDropShadow)); // Info panel colors - ctxt->setContextProperty("infoBackgroundColor", qv.infoBackgroundColor); - ctxt->setContextProperty("infoTextColor", qv.infoTextColor); - ctxt->setContextProperty("infoTitleColor", qv.infoTitleColor); + ctxt->setContextProperty("infoBackgroundColor", giv.infoBackgroundColor); + ctxt->setContextProperty("infoTextColor", giv.infoTextColor); + ctxt->setContextProperty("infoTitleColor", giv.infoTitleColor); // Rating and favorite colors - ctxt->setContextProperty("ratingUnselectedColor", qv.ratingUnselectedColor); - ctxt->setContextProperty("ratingSelectedColor", qv.ratingSelectedColor); - ctxt->setContextProperty("favUncheckedColor", qv.favUncheckedColor); - ctxt->setContextProperty("favCheckedColor", qv.favCheckedColor); - ctxt->setContextProperty("readTickUncheckedColor", qv.readTickUncheckedColor); - ctxt->setContextProperty("readTickCheckedColor", qv.readTickCheckedColor); + ctxt->setContextProperty("ratingUnselectedColor", giv.ratingUnselectedColor); + ctxt->setContextProperty("ratingSelectedColor", giv.ratingSelectedColor); + ctxt->setContextProperty("favUncheckedColor", giv.favUncheckedColor); + ctxt->setContextProperty("favCheckedColor", giv.favCheckedColor); + ctxt->setContextProperty("readTickUncheckedColor", giv.readTickUncheckedColor); + ctxt->setContextProperty("readTickCheckedColor", giv.readTickCheckedColor); // Current comic banner - ctxt->setContextProperty("currentComicBackgroundColor", qv.currentComicBackgroundColor); + ctxt->setContextProperty("currentComicBackgroundColor", giv.currentComicBackgroundColor); // Update background config to apply theme cell colors updateBackgroundConfig(); diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp index bb58b5bfa..9aba46c9b 100644 --- a/YACReaderLibrary/info_comics_view.cpp +++ b/YACReaderLibrary/info_comics_view.cpp @@ -224,7 +224,7 @@ void InfoComicsView::selectedItem(int index) void InfoComicsView::applyTheme(const Theme &theme) { QQmlContext *ctxt = view->rootContext(); - const auto &qv = theme.qmlView; + const auto &giv = theme.gridAndInfoView; // Info panel colors // Cache-bust the SVG file URLs so QML's image cache doesn't serve stale @@ -235,21 +235,21 @@ void InfoComicsView::applyTheme(const Theme &theme) url.setQuery(bust); return url; }; - ctxt->setContextProperty("infoBackgroundColor", qv.infoBackgroundColor); - ctxt->setContextProperty("topShadow", svgUrl(qv.topShadow)); - ctxt->setContextProperty("infoShadow", svgUrl(qv.infoShadow)); - ctxt->setContextProperty("infoIndicator", svgUrl(qv.infoIndicator)); - ctxt->setContextProperty("infoTextColor", qv.infoTextColor); - ctxt->setContextProperty("infoTitleColor", qv.infoTitleColor); + ctxt->setContextProperty("infoBackgroundColor", giv.infoBackgroundColor); + ctxt->setContextProperty("topShadow", svgUrl(giv.topShadow)); + ctxt->setContextProperty("infoShadow", svgUrl(giv.infoShadow)); + ctxt->setContextProperty("infoIndicator", svgUrl(giv.infoIndicator)); + ctxt->setContextProperty("infoTextColor", giv.infoTextColor); + ctxt->setContextProperty("infoTitleColor", giv.infoTitleColor); // Rating and favorite colors - ctxt->setContextProperty("ratingUnselectedColor", qv.ratingUnselectedColor); - ctxt->setContextProperty("ratingSelectedColor", qv.ratingSelectedColor); - ctxt->setContextProperty("favUncheckedColor", qv.favUncheckedColor); - ctxt->setContextProperty("favCheckedColor", qv.favCheckedColor); - ctxt->setContextProperty("readTickUncheckedColor", qv.readTickUncheckedColor); - ctxt->setContextProperty("readTickCheckedColor", qv.readTickCheckedColor); - - ctxt->setContextProperty("showDropShadow", QVariant(qv.showDropShadow)); - ctxt->setContextProperty("backgroundBlurOverlayColor", qv.backgroundBlurOverlayColor); + ctxt->setContextProperty("ratingUnselectedColor", giv.ratingUnselectedColor); + ctxt->setContextProperty("ratingSelectedColor", giv.ratingSelectedColor); + ctxt->setContextProperty("favUncheckedColor", giv.favUncheckedColor); + ctxt->setContextProperty("favCheckedColor", giv.favCheckedColor); + ctxt->setContextProperty("readTickUncheckedColor", giv.readTickUncheckedColor); + ctxt->setContextProperty("readTickCheckedColor", giv.readTickCheckedColor); + + ctxt->setContextProperty("showDropShadow", QVariant(giv.showDropShadow)); + ctxt->setContextProperty("backgroundBlurOverlayColor", giv.backgroundBlurOverlayColor); } diff --git a/YACReaderLibrary/themes/builtin_classic.json b/YACReaderLibrary/themes/builtin_classic.json index a365fbb87..b410662d9 100644 --- a/YACReaderLibrary/themes/builtin_classic.json +++ b/YACReaderLibrary/themes/builtin_classic.json @@ -4,12 +4,11 @@ "displayName": "Default Classic", "variant": "dark" }, - "defaultContentBackgroundColor": "#2a2a2a", "comicFlow": { "backgroundColor": "#000000", "textColor": "#4c4c4c" }, - "comicVine": { + "metadataScraperDialog": { "contentTextColor": "#ffffff", "contentBackgroundColor": "#2b2b2b", "contentAltBackgroundColor": "#2b2b2b", @@ -122,7 +121,7 @@ "horizontalHandleHeight": 4, "verticalHandleWidth": 4 }, - "treeView": { + "navigationTree": { "textColor": "#dddfdf", "selectionBackgroundColor": "#2e2e2e", "scrollBackgroundColor": "#404040", @@ -138,7 +137,7 @@ "folderReadOverlayColor": "#464646", "folderReadOverlaySelectedColor": "#464646" }, - "tableView": { + "comicsViewTable": { "alternateBackgroundColor": "#f2f2f2", "backgroundColor": "#fafafa", "headerBackgroundColor": "#f5f5f5", @@ -155,7 +154,7 @@ "starRatingColor": "#e9be0f", "starRatingSelectedColor": "#ffffff" }, - "qmlView": { + "gridAndInfoView": { "backgroundColor": "#2a2a2a", "cellColor": "#212121", "cellColorWithBackground": "#99212121", diff --git a/YACReaderLibrary/themes/builtin_dark.json b/YACReaderLibrary/themes/builtin_dark.json index 21855acaf..1634400a9 100644 --- a/YACReaderLibrary/themes/builtin_dark.json +++ b/YACReaderLibrary/themes/builtin_dark.json @@ -4,12 +4,11 @@ "displayName": "Default Dark", "variant": "dark" }, - "defaultContentBackgroundColor": "#2a2a2a", "comicFlow": { "backgroundColor": "#111111", "textColor": "#888888" }, - "comicVine": { + "metadataScraperDialog": { "contentTextColor": "#ffffff", "contentBackgroundColor": "#2b2b2b", "contentAltBackgroundColor": "#2e2e2e", @@ -122,7 +121,7 @@ "horizontalHandleHeight": 4, "verticalHandleWidth": 4 }, - "treeView": { + "navigationTree": { "textColor": "#dddfdf", "selectionBackgroundColor": "#2e2e2e", "scrollBackgroundColor": "#404040", @@ -138,7 +137,7 @@ "folderReadOverlayColor": "#222222", "folderReadOverlaySelectedColor": "#222222" }, - "tableView": { + "comicsViewTable": { "alternateBackgroundColor": "#2e2e2e", "backgroundColor": "#2a2a2a", "headerBackgroundColor": "#2a2a2a", @@ -155,7 +154,7 @@ "starRatingColor": "#e9be0f", "starRatingSelectedColor": "#ffffff" }, - "qmlView": { + "gridAndInfoView": { "backgroundColor": "#2a2a2a", "cellColor": "#212121", "cellColorWithBackground": "#99212121", diff --git a/YACReaderLibrary/themes/builtin_light.json b/YACReaderLibrary/themes/builtin_light.json index 4d9c8744a..f1cf40e40 100644 --- a/YACReaderLibrary/themes/builtin_light.json +++ b/YACReaderLibrary/themes/builtin_light.json @@ -4,12 +4,11 @@ "displayName": "Default Light", "variant": "light" }, - "defaultContentBackgroundColor": "#ffffff", "comicFlow": { "backgroundColor": "#dcdcdc", "textColor": "#303030" }, - "comicVine": { + "metadataScraperDialog": { "contentTextColor": "#000000", "contentBackgroundColor": "#ececec", "contentAltBackgroundColor": "#e0e0e0", @@ -122,7 +121,7 @@ "horizontalHandleHeight": 4, "verticalHandleWidth": 4 }, - "treeView": { + "navigationTree": { "textColor": "#000000", "selectionBackgroundColor": "#333133", "scrollBackgroundColor": "#e0e0e0", @@ -138,7 +137,7 @@ "folderReadOverlayColor": "#ffffff", "folderReadOverlaySelectedColor": "#161616" }, - "tableView": { + "comicsViewTable": { "alternateBackgroundColor": "#f2f2f2", "backgroundColor": "#fafafa", "headerBackgroundColor": "#f5f5f5", @@ -155,7 +154,7 @@ "starRatingColor": "#e9be0f", "starRatingSelectedColor": "#ffffff" }, - "qmlView": { + "gridAndInfoView": { "backgroundColor": "#f6f6f6", "cellColor": "#ffffff", "cellColorWithBackground": "#99ffffff", diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index b0254429b..767645088 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -9,7 +9,7 @@ #include "whats_new_dialog_theme.h" #include "theme_meta.h" -struct ComicVineThemeTemplates { +struct MetadataScraperDialogThemeTemplates { QString defaultLabelQSS = "QLabel {color:%1; font-size:12px;font-family:Arial;}"; QString titleLabelQSS = "QLabel {color:%1; font-size:18px;font-family:Arial;}"; QString coverLabelQSS = "QLabel {background-color: %1; color:%2; font-size:12px; font-family:Arial; }"; @@ -98,7 +98,7 @@ struct ComicFlowColors { QColor textColor; }; -struct TableViewThemeTemplates { +struct ComicsViewTableThemeTemplates { QString tableViewQSS = "QTableView {alternate-background-color: %1; background-color: %2; outline: 0px; border: none;}" "QTableCornerButton::section {background-color:%3; border:none; border-bottom:1px solid %4; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %5, stop: 1 %4);}" "QTableView::item {outline: 0px; border-bottom: %12px solid %6; border-top: %13px solid %7; padding-bottom:1px; color:%8;}" @@ -107,7 +107,7 @@ struct TableViewThemeTemplates { "QHeaderView::section:vertical {border-bottom: 1px solid %6; border-top: 1px solid %7;}"; }; -struct TableViewTheme { +struct ComicsViewTableTheme { QString tableViewQSS; QColor starRatingColor; QColor starRatingSelectedColor; @@ -173,10 +173,10 @@ struct ImportWidgetTheme { QIcon coversToggleIcon; }; -struct TreeViewThemeTemplates { +struct NavigationTreeThemeTemplates { // Styled tree view template with custom scroll bars // %1 = text color, %2 = selection/hover background, %3 = scroll background, %4 = scroll handle, %5 = selected text color - QString styledTreeViewQSS = "QTreeView {background-color:transparent; border: none; color:%1; outline:0; show-decoration-selected: 0;}" + QString navigationTreeQSS = "QTreeView {background-color:transparent; border: none; color:%1; outline:0; show-decoration-selected: 0;}" "QTreeView::item:selected {background-color: %2; color:%5; font:bold;}" "QTreeView::item:hover {background-color:%2; color:%5; font:bold;}" "QTreeView::branch:selected {background-color:%2;}" @@ -193,8 +193,8 @@ struct TreeViewThemeTemplates { "QTreeView::branch:open:has-children:selected:!has-siblings,QTreeView::branch:open:has-children:selected:has-siblings {border-image: none;image: url('%9');}"; }; -struct TreeViewTheme { - QString treeViewQSS; +struct NavigationTreeTheme { + QString navigationTreeQSS; QColor folderIndicatorColor; // For incomplete folders and recently updated folders // Branch indicator icon paths (used by QSS url()) @@ -208,8 +208,8 @@ struct TreeViewTheme { QIcon folderFinishedIcon; }; -// QML view theme colors (used by GridComicsView, FolderContentView, InfoComicsView) -struct QmlViewTheme { +// Grid and info view theme colors (used by GridComicsView, FolderContentView, InfoComicsView) +struct GridAndInfoViewTheme { // Grid colors QColor backgroundColor; QColor cellColor; @@ -281,7 +281,7 @@ struct ContentSplitterTheme { struct SidebarIconsTheme { // When true, use QFileIconProvider for folder icons and overlay folderReadOverlay for finished folders - // When false, use the themed folderIcon and folderFinishedIcon from TreeViewTheme + // When false, use the themed folderIcon and folderFinishedIcon from NavigationTreeTheme bool useSystemFolderIcons; QPixmap folderReadOverlay; // Tick overlay drawn on system folder icons when useSystemFolderIcons is true @@ -420,7 +420,7 @@ struct MainToolbarTheme { QString folderNameLabelQSS; }; -struct ComicVineTheme { +struct MetadataScraperDialogTheme { QString defaultLabelQSS; QString titleLabelQSS; QString coverLabelQSS; @@ -457,10 +457,8 @@ struct Theme { ThemeMeta meta; QJsonObject sourceJson; - QColor defaultContentBackgroundColor; - ComicFlowColors comicFlow; - ComicVineTheme comicVine; + MetadataScraperDialogTheme metadataScraperDialog; HelpAboutDialogTheme helpAboutDialog; WhatsNewDialogTheme whatsNewDialog; EmptyContainerTheme emptyContainer; @@ -469,9 +467,9 @@ struct Theme { LibraryItemTheme libraryItem; ImportWidgetTheme importWidget; ServerConfigDialogTheme serverConfigDialog; - TreeViewTheme treeView; - TableViewTheme tableView; - QmlViewTheme qmlView; + NavigationTreeTheme navigationTree; + ComicsViewTableTheme comicsViewTable; + GridAndInfoViewTheme gridAndInfoView; MainToolbarTheme mainToolbar; ContentSplitterTheme contentSplitter; ComicsViewToolbarTheme comicsViewToolbar; diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 1e0818cd5..dbe90109e 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -5,8 +5,8 @@ #include "icon_utils.h" #include "yacreader_global.h" -struct ComicVineParams { - ComicVineThemeTemplates t; +struct MetadataScraperDialogParams { + MetadataScraperDialogThemeTemplates t; QColor contentTextColor; QColor contentBackgroundColor; @@ -93,8 +93,8 @@ struct ImportWidgetParams { QColor iconCheckedColor; }; -struct TreeViewParams { - TreeViewThemeTemplates t; +struct NavigationTreeParams { + NavigationTreeThemeTemplates t; QColor textColor; QColor selectionBackgroundColor; @@ -116,8 +116,8 @@ struct TreeViewParams { QColor folderReadOverlaySelectedColor; // Tick/checkmark color for selected folder }; -struct TableViewParams { - TableViewThemeTemplates t; +struct ComicsViewTableParams { + ComicsViewTableThemeTemplates t; QColor alternateBackgroundColor; QColor backgroundColor; @@ -137,7 +137,7 @@ struct TableViewParams { QColor starRatingSelectedColor; }; -struct QmlViewParams { +struct GridAndInfoViewParams { // Grid colors QColor backgroundColor; QColor cellColor; @@ -301,10 +301,9 @@ struct WhatsNewDialogParams { struct ThemeParams { ThemeMeta meta; - QColor defaultContentBackgroundColor; ComicFlowColors comicFlowColors; - ComicVineParams comicVineParams; + MetadataScraperDialogParams metadataScraperDialogParams; HelpAboutDialogTheme helpAboutDialogParams; EmptyContainerParams emptyContainerParams; SidebarParams sidebarParams; @@ -314,9 +313,9 @@ struct ThemeParams { ServerConfigDialogParams serverConfigDialogParams; MainToolbarParams mainToolbarParams; ContentSplitterParams contentSplitterParams; - TreeViewParams treeViewParams; - TableViewParams tableViewParams; - QmlViewParams qmlViewParams; + NavigationTreeParams navigationTreeParams; + ComicsViewTableParams comicsViewTableParams; + GridAndInfoViewParams gridAndInfoViewParams; ComicsViewToolbarParams comicsViewToolbarParams; SearchLineEditParams searchLineEditParams; ReadingListIconsParams readingListIconsParams; @@ -330,63 +329,61 @@ Theme makeTheme(const ThemeParams ¶ms) { Theme theme; - theme.defaultContentBackgroundColor = params.defaultContentBackgroundColor; - // Comic Flow const auto &cf = params.comicFlowColors; theme.comicFlow.backgroundColor = cf.backgroundColor; theme.comicFlow.textColor = cf.textColor; - // Comic Vine - const auto &cv = params.comicVineParams; - const auto &t = cv.t; + // MetadataScraperDialog + const auto &msd = params.metadataScraperDialogParams; + const auto &t = msd.t; auto recolor = [&](const QString &path, const QColor &color) { return recoloredSvgToThemeFile(path, color, params.meta.id); }; - theme.comicVine.defaultLabelQSS = t.defaultLabelQSS.arg(cv.labelTextColor.name()); - theme.comicVine.titleLabelQSS = t.titleLabelQSS.arg(cv.labelTextColor.name()); - theme.comicVine.coverLabelQSS = t.coverLabelQSS.arg(cv.labelBackgroundColor.name(), cv.labelTextColor.name()); - theme.comicVine.radioButtonQSS = t.radioButtonQSS.arg(cv.buttonTextColor.name(), recolor(":/images/comic_vine/radioUnchecked.svg", cv.radioUncheckedColor), recoloredSvgToThemeFile(":/images/comic_vine/radioChecked.svg", cv.radioCheckedBackgroundColor, cv.radioCheckedIndicatorColor, params.meta.id)); - theme.comicVine.checkBoxQSS = t.checkBoxQSS.arg(cv.buttonTextColor.name(), cv.buttonBorderColor.name(), cv.buttonBackgroundColor.name(), recolor(":/images/comic_vine/checkBoxTick.svg", cv.checkBoxTickColor)); - - theme.comicVine.scraperLineEditTitleLabelQSS = t.scraperLineEditTitleLabelQSS.arg(cv.contentTextColor.name()); - theme.comicVine.scraperLineEditQSS = t.scraperLineEditQSS.arg(cv.contentAltBackgroundColor.name(), cv.contentTextColor.name(), "%1"); - - theme.comicVine.scraperToolButtonQSS = t.scraperToolButtonQSS.arg(cv.buttonBackgroundColor.name(), cv.buttonTextColor.name(), cv.toolButtonAccentColor.name()); - theme.comicVine.scraperToolButtonSeparatorQSS = t.scraperToolButtonSeparatorQSS.arg(cv.toolButtonAccentColor.name()); - theme.comicVine.scraperToolButtonFillColor = cv.buttonBackgroundColor; - - theme.comicVine.scraperScrollLabelTextQSS = t.scraperScrollLabelTextQSS.arg(cv.contentBackgroundColor.name(), cv.contentTextColor.name(), cv.hyperlinkColor.name()); - theme.comicVine.scraperScrollLabelScrollAreaQSS = t.scraperScrollLabelScrollAreaQSS.arg(cv.contentBackgroundColor.name(), cv.tableScrollHandleColor.name(), cv.tableScrollBackgroundColor.name()); - - theme.comicVine.scraperTableViewQSS = t.scraperTableViewQSS - .arg(cv.tableHeaderTextColor.name(), - cv.tableAltBackgroundColor.name(), - cv.tableBackgroundColor.name(), - cv.tableSelectedColor.name(), - cv.tableHeaderBackgroundColor.name(), - cv.tableHeaderBorderColor.name(), - cv.tableHeaderTextColor.name(), - cv.tableSectionBorderDark.name(), - cv.tableSectionBorderLight.name(), - cv.tableScrollHandleColor.name(), - cv.tableScrollBackgroundColor.name(), - recolor(":/images/comic_vine/downArrow.svg", cv.downArrowColor), - recolor(":/images/comic_vine/upArrow.svg", cv.upArrowColor), - cv.tableHeaderGradientColor.name()); - - theme.comicVine.dialogQSS = t.dialogQSS.arg(cv.dialogBackgroundColor.name()); - theme.comicVine.dialogButtonsQSS = t.dialogButtonsQSS.arg(cv.buttonBorderColor.name(), cv.buttonBackgroundColor.name(), cv.buttonTextColor.name()); - - theme.comicVine.busyIndicatorColor = cv.busyIndicatorColor; - - theme.comicVine.nextPageIcon = { QIcon(recolor(t.nextPageIcon, cv.navIconColor)), t.pageIconSize }; - theme.comicVine.previousPageIcon = { QIcon(recolor(t.previousPageIcon, cv.navIconColor)), t.pageIconSize }; - - theme.comicVine.rowUpIcon = { QIcon(recolor(t.rowUpIcon, cv.rowIconColor)), t.rowIconSize }; - theme.comicVine.rowDownIcon = { QIcon(recolor(t.rowDownIcon, cv.rowIconColor)), t.rowIconSize }; + theme.metadataScraperDialog.defaultLabelQSS = t.defaultLabelQSS.arg(msd.labelTextColor.name()); + theme.metadataScraperDialog.titleLabelQSS = t.titleLabelQSS.arg(msd.labelTextColor.name()); + theme.metadataScraperDialog.coverLabelQSS = t.coverLabelQSS.arg(msd.labelBackgroundColor.name(), msd.labelTextColor.name()); + theme.metadataScraperDialog.radioButtonQSS = t.radioButtonQSS.arg(msd.buttonTextColor.name(), recolor(":/images/comic_vine/radioUnchecked.svg", msd.radioUncheckedColor), recoloredSvgToThemeFile(":/images/comic_vine/radioChecked.svg", msd.radioCheckedBackgroundColor, msd.radioCheckedIndicatorColor, params.meta.id)); + theme.metadataScraperDialog.checkBoxQSS = t.checkBoxQSS.arg(msd.buttonTextColor.name(), msd.buttonBorderColor.name(), msd.buttonBackgroundColor.name(), recolor(":/images/comic_vine/checkBoxTick.svg", msd.checkBoxTickColor)); + + theme.metadataScraperDialog.scraperLineEditTitleLabelQSS = t.scraperLineEditTitleLabelQSS.arg(msd.contentTextColor.name()); + theme.metadataScraperDialog.scraperLineEditQSS = t.scraperLineEditQSS.arg(msd.contentAltBackgroundColor.name(), msd.contentTextColor.name(), "%1"); + + theme.metadataScraperDialog.scraperToolButtonQSS = t.scraperToolButtonQSS.arg(msd.buttonBackgroundColor.name(), msd.buttonTextColor.name(), msd.toolButtonAccentColor.name()); + theme.metadataScraperDialog.scraperToolButtonSeparatorQSS = t.scraperToolButtonSeparatorQSS.arg(msd.toolButtonAccentColor.name()); + theme.metadataScraperDialog.scraperToolButtonFillColor = msd.buttonBackgroundColor; + + theme.metadataScraperDialog.scraperScrollLabelTextQSS = t.scraperScrollLabelTextQSS.arg(msd.contentBackgroundColor.name(), msd.contentTextColor.name(), msd.hyperlinkColor.name()); + theme.metadataScraperDialog.scraperScrollLabelScrollAreaQSS = t.scraperScrollLabelScrollAreaQSS.arg(msd.contentBackgroundColor.name(), msd.tableScrollHandleColor.name(), msd.tableScrollBackgroundColor.name()); + + theme.metadataScraperDialog.scraperTableViewQSS = t.scraperTableViewQSS + .arg(msd.tableHeaderTextColor.name(), + msd.tableAltBackgroundColor.name(), + msd.tableBackgroundColor.name(), + msd.tableSelectedColor.name(), + msd.tableHeaderBackgroundColor.name(), + msd.tableHeaderBorderColor.name(), + msd.tableHeaderTextColor.name(), + msd.tableSectionBorderDark.name(), + msd.tableSectionBorderLight.name(), + msd.tableScrollHandleColor.name(), + msd.tableScrollBackgroundColor.name(), + recolor(":/images/comic_vine/downArrow.svg", msd.downArrowColor), + recolor(":/images/comic_vine/upArrow.svg", msd.upArrowColor), + msd.tableHeaderGradientColor.name()); + + theme.metadataScraperDialog.dialogQSS = t.dialogQSS.arg(msd.dialogBackgroundColor.name()); + theme.metadataScraperDialog.dialogButtonsQSS = t.dialogButtonsQSS.arg(msd.buttonBorderColor.name(), msd.buttonBackgroundColor.name(), msd.buttonTextColor.name()); + + theme.metadataScraperDialog.busyIndicatorColor = msd.busyIndicatorColor; + + theme.metadataScraperDialog.nextPageIcon = { QIcon(recolor(t.nextPageIcon, msd.navIconColor)), t.pageIconSize }; + theme.metadataScraperDialog.previousPageIcon = { QIcon(recolor(t.previousPageIcon, msd.navIconColor)), t.pageIconSize }; + + theme.metadataScraperDialog.rowUpIcon = { QIcon(recolor(t.rowUpIcon, msd.rowIconColor)), t.rowIconSize }; + theme.metadataScraperDialog.rowDownIcon = { QIcon(recolor(t.rowDownIcon, msd.rowIconColor)), t.rowIconSize }; // HelpAboutDialog theme.helpAboutDialog = params.helpAboutDialogParams; @@ -470,55 +467,54 @@ Theme makeTheme(const ThemeParams ¶ms) } // end ImportWidget - // TableView - const auto &tav = params.tableViewParams; - const auto &tavt = tav.t; - theme.tableView.tableViewQSS = tavt.tableViewQSS - .arg(tav.alternateBackgroundColor.name(), - tav.backgroundColor.name(), - tav.headerBackgroundColor.name(), - tav.headerBorderColor.name(), - tav.headerGradientColor.name(), - tav.itemBorderBottomColor.name(), - tav.itemBorderTopColor.name(), - tav.itemTextColor.name(), - tav.selectedColor.name(), - tav.selectedTextColor.name(), - tav.headerTextColor.name(), - QString::number(tav.itemBorderBottomWidth), - QString::number(tav.itemBorderTopWidth)); - theme.tableView.starRatingColor = tav.starRatingColor; - theme.tableView.starRatingSelectedColor = tav.starRatingSelectedColor; - // end TableView - - // QmlView - const auto &qv = params.qmlViewParams; - theme.qmlView.backgroundColor = qv.backgroundColor; - theme.qmlView.cellColor = qv.cellColor; - theme.qmlView.cellColorWithBackground = qv.cellColorWithBackground; - theme.qmlView.selectedColor = qv.selectedColor; - theme.qmlView.selectedBorderColor = qv.selectedBorderColor; - theme.qmlView.borderColor = qv.borderColor; - theme.qmlView.titleColor = qv.titleColor; - theme.qmlView.textColor = qv.textColor; - theme.qmlView.showDropShadow = qv.showDropShadow; - theme.qmlView.infoBackgroundColor = qv.infoBackgroundColor; - theme.qmlView.topShadow = recoloredSvgToThemeFile(":/qml/info-top-shadow.svg", qv.infoBackgroundColor, qv.infoBorderColor, qv.infoShadowColor, params.meta.id); - theme.qmlView.infoShadow = recoloredSvgToThemeFile(":/qml/info-shadow.svg", qv.infoBackgroundColor, qv.infoBorderColor, qv.infoShadowColor, params.meta.id); - theme.qmlView.infoIndicator = recoloredSvgToThemeFile(":/qml/info-indicator.svg", qv.infoBackgroundColor, qv.infoBorderColor, qv.infoShadowColor, params.meta.id); - theme.qmlView.infoTextColor = qv.infoTextColor; - theme.qmlView.infoTitleColor = qv.infoTitleColor; - theme.qmlView.ratingUnselectedColor = qv.ratingUnselectedColor; - theme.qmlView.ratingSelectedColor = qv.ratingSelectedColor; - theme.qmlView.favUncheckedColor = qv.favUncheckedColor; - theme.qmlView.favCheckedColor = qv.favCheckedColor; - theme.qmlView.readTickUncheckedColor = qv.readTickUncheckedColor; - theme.qmlView.readTickCheckedColor = qv.readTickCheckedColor; - theme.qmlView.currentComicBackgroundColor = qv.currentComicBackgroundColor; - theme.qmlView.continueReadingBackgroundColor = qv.continueReadingBackgroundColor; - theme.qmlView.continueReadingColor = qv.continueReadingColor; - theme.qmlView.backgroundBlurOverlayColor = qv.backgroundBlurOverlayColor; - // end QmlView + // ComicsViewTable + const auto &cvta = params.comicsViewTableParams; + theme.comicsViewTable.tableViewQSS = cvta.t.tableViewQSS + .arg(cvta.alternateBackgroundColor.name(), + cvta.backgroundColor.name(), + cvta.headerBackgroundColor.name(), + cvta.headerBorderColor.name(), + cvta.headerGradientColor.name(), + cvta.itemBorderBottomColor.name(), + cvta.itemBorderTopColor.name(), + cvta.itemTextColor.name(), + cvta.selectedColor.name(), + cvta.selectedTextColor.name(), + cvta.headerTextColor.name(), + QString::number(cvta.itemBorderBottomWidth), + QString::number(cvta.itemBorderTopWidth)); + theme.comicsViewTable.starRatingColor = cvta.starRatingColor; + theme.comicsViewTable.starRatingSelectedColor = cvta.starRatingSelectedColor; + // end ComicsViewTable + + // GridAndInfoView + const auto &giv = params.gridAndInfoViewParams; + theme.gridAndInfoView.backgroundColor = giv.backgroundColor; + theme.gridAndInfoView.cellColor = giv.cellColor; + theme.gridAndInfoView.cellColorWithBackground = giv.cellColorWithBackground; + theme.gridAndInfoView.selectedColor = giv.selectedColor; + theme.gridAndInfoView.selectedBorderColor = giv.selectedBorderColor; + theme.gridAndInfoView.borderColor = giv.borderColor; + theme.gridAndInfoView.titleColor = giv.titleColor; + theme.gridAndInfoView.textColor = giv.textColor; + theme.gridAndInfoView.showDropShadow = giv.showDropShadow; + theme.gridAndInfoView.infoBackgroundColor = giv.infoBackgroundColor; + theme.gridAndInfoView.topShadow = recoloredSvgToThemeFile(":/qml/info-top-shadow.svg", giv.infoBackgroundColor, giv.infoBorderColor, giv.infoShadowColor, params.meta.id); + theme.gridAndInfoView.infoShadow = recoloredSvgToThemeFile(":/qml/info-shadow.svg", giv.infoBackgroundColor, giv.infoBorderColor, giv.infoShadowColor, params.meta.id); + theme.gridAndInfoView.infoIndicator = recoloredSvgToThemeFile(":/qml/info-indicator.svg", giv.infoBackgroundColor, giv.infoBorderColor, giv.infoShadowColor, params.meta.id); + theme.gridAndInfoView.infoTextColor = giv.infoTextColor; + theme.gridAndInfoView.infoTitleColor = giv.infoTitleColor; + theme.gridAndInfoView.ratingUnselectedColor = giv.ratingUnselectedColor; + theme.gridAndInfoView.ratingSelectedColor = giv.ratingSelectedColor; + theme.gridAndInfoView.favUncheckedColor = giv.favUncheckedColor; + theme.gridAndInfoView.favCheckedColor = giv.favCheckedColor; + theme.gridAndInfoView.readTickUncheckedColor = giv.readTickUncheckedColor; + theme.gridAndInfoView.readTickCheckedColor = giv.readTickCheckedColor; + theme.gridAndInfoView.currentComicBackgroundColor = giv.currentComicBackgroundColor; + theme.gridAndInfoView.continueReadingBackgroundColor = giv.continueReadingBackgroundColor; + theme.gridAndInfoView.continueReadingColor = giv.continueReadingColor; + theme.gridAndInfoView.backgroundBlurOverlayColor = giv.backgroundBlurOverlayColor; + // end GridAndInfoView // MainToolbar const auto &mt = params.mainToolbarParams; @@ -600,7 +596,7 @@ Theme makeTheme(const ThemeParams ¶ms) // System folder icons flag and overlay theme.sidebarIcons.useSystemFolderIcons = si.useSystemFolderIcons; if (si.useSystemFolderIcons) { - const QString overlayPath = recoloredSvgToThemeFile(":/images/sidebar/folder_read_overlay.svg", params.treeViewParams.folderReadOverlayColor, params.meta.id); + const QString overlayPath = recoloredSvgToThemeFile(":/images/sidebar/folder_read_overlay.svg", params.navigationTreeParams.folderReadOverlayColor, params.meta.id); theme.sidebarIcons.folderReadOverlay = QPixmap(overlayPath); } @@ -642,43 +638,43 @@ Theme makeTheme(const ThemeParams ¶ms) theme.libraryItem.libraryOptionsIcon = QIcon(libraryOptionsPath); // end LibraryItem - // TreeView - const auto &tv = params.treeViewParams; + // NavigationTree + const auto &nt = params.navigationTreeParams; // Branch indicator icons — own colors, independent of the sidebar icon color - theme.treeView.branchClosedIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-closed.svg", tv.branchIndicatorColor, params.meta.id); - theme.treeView.branchOpenIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", tv.branchIndicatorColor, params.meta.id); - theme.treeView.branchClosedIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/branch-closed.svg", tv.branchIndicatorSelectedColor, params.meta.id, { .suffix = "_selected" }); - theme.treeView.branchOpenIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", tv.branchIndicatorSelectedColor, params.meta.id, { .suffix = "_selected" }); - - theme.treeView.treeViewQSS = tv.t.styledTreeViewQSS - .arg(tv.textColor.name(), - tv.selectionBackgroundColor.name(), - tv.scrollBackgroundColor.name(), - tv.scrollHandleColor.name(), - tv.selectedTextColor.name(), - theme.treeView.branchClosedIconPath, - theme.treeView.branchOpenIconPath, - theme.treeView.branchClosedIconSelectedPath, - theme.treeView.branchOpenIconSelectedPath); - theme.treeView.folderIndicatorColor = tv.folderIndicatorColor; + theme.navigationTree.branchClosedIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-closed.svg", nt.branchIndicatorColor, params.meta.id); + theme.navigationTree.branchOpenIconPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", nt.branchIndicatorColor, params.meta.id); + theme.navigationTree.branchClosedIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/branch-closed.svg", nt.branchIndicatorSelectedColor, params.meta.id, { .suffix = "_selected" }); + theme.navigationTree.branchOpenIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", nt.branchIndicatorSelectedColor, params.meta.id, { .suffix = "_selected" }); + + theme.navigationTree.navigationTreeQSS = nt.t.navigationTreeQSS + .arg(nt.textColor.name(), + nt.selectionBackgroundColor.name(), + nt.scrollBackgroundColor.name(), + nt.scrollHandleColor.name(), + nt.selectedTextColor.name(), + theme.navigationTree.branchClosedIconPath, + theme.navigationTree.branchOpenIconPath, + theme.navigationTree.branchClosedIconSelectedPath, + theme.navigationTree.branchOpenIconSelectedPath); + theme.navigationTree.folderIndicatorColor = nt.folderIndicatorColor; // Folder icon — normal and selected states with independent colors { - const QString normalPath = recoloredSvgToThemeFile(":/images/sidebar/folder.svg", tv.folderIconColor, tv.folderIconShadowColor, params.meta.id); - const QString selectedPath = recoloredSvgToThemeFile(":/images/sidebar/folder.svg", tv.folderIconSelectedColor, tv.folderIconSelectedShadowColor, params.meta.id, { .suffix = "_selected" }); - theme.treeView.folderIcon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); - theme.treeView.folderIcon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); + const QString normalPath = recoloredSvgToThemeFile(":/images/sidebar/folder.svg", nt.folderIconColor, nt.folderIconShadowColor, params.meta.id); + const QString selectedPath = recoloredSvgToThemeFile(":/images/sidebar/folder.svg", nt.folderIconSelectedColor, nt.folderIconSelectedShadowColor, params.meta.id, { .suffix = "_selected" }); + theme.navigationTree.folderIcon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); + theme.navigationTree.folderIcon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); } // Folder finished icon — same but with tick (#ff0) recolored independently for each state { - const QString normalPath = recoloredSvgToThemeFile(":/images/sidebar/folder_finished.svg", tv.folderIconColor, tv.folderIconShadowColor, tv.folderReadOverlayColor, params.meta.id); - const QString selectedPath = recoloredSvgToThemeFile(":/images/sidebar/folder_finished.svg", tv.folderIconSelectedColor, tv.folderIconSelectedShadowColor, tv.folderReadOverlaySelectedColor, params.meta.id, { .suffix = "_selected" }); - theme.treeView.folderFinishedIcon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); - theme.treeView.folderFinishedIcon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); + const QString normalPath = recoloredSvgToThemeFile(":/images/sidebar/folder_finished.svg", nt.folderIconColor, nt.folderIconShadowColor, nt.folderReadOverlayColor, params.meta.id); + const QString selectedPath = recoloredSvgToThemeFile(":/images/sidebar/folder_finished.svg", nt.folderIconSelectedColor, nt.folderIconSelectedShadowColor, nt.folderReadOverlaySelectedColor, params.meta.id, { .suffix = "_selected" }); + theme.navigationTree.folderFinishedIcon.addFile(normalPath, QSize(), QIcon::Normal, QIcon::Off); + theme.navigationTree.folderFinishedIcon.addFile(selectedPath, QSize(), QIcon::Selected, QIcon::Off); } - // end TreeView + // end NavigationTree // ContentSplitter const auto &cs = params.contentSplitterParams; @@ -873,53 +869,47 @@ Theme makeTheme(const QJsonObject &json) { ThemeParams p; - if (json.contains("defaultContentBackgroundColor")) { - QColor c(json["defaultContentBackgroundColor"].toString()); - if (c.isValid()) - p.defaultContentBackgroundColor = c; - } - if (json.contains("comicFlow")) { const auto o = json["comicFlow"].toObject(); p.comicFlowColors.backgroundColor = colorFromJson(o, "backgroundColor", p.comicFlowColors.backgroundColor); p.comicFlowColors.textColor = colorFromJson(o, "textColor", p.comicFlowColors.textColor); } - if (json.contains("comicVine")) { - const auto o = json["comicVine"].toObject(); - auto &cv = p.comicVineParams; - cv.contentTextColor = colorFromJson(o, "contentTextColor", cv.contentTextColor); - cv.contentBackgroundColor = colorFromJson(o, "contentBackgroundColor", cv.contentBackgroundColor); - cv.contentAltBackgroundColor = colorFromJson(o, "contentAltBackgroundColor", cv.contentAltBackgroundColor); - cv.dialogBackgroundColor = colorFromJson(o, "dialogBackgroundColor", cv.dialogBackgroundColor); - cv.tableBackgroundColor = colorFromJson(o, "tableBackgroundColor", cv.tableBackgroundColor); - cv.tableAltBackgroundColor = colorFromJson(o, "tableAltBackgroundColor", cv.tableAltBackgroundColor); - cv.tableBorderColor = colorFromJson(o, "tableBorderColor", cv.tableBorderColor); - cv.tableSelectedColor = colorFromJson(o, "tableSelectedColor", cv.tableSelectedColor); - cv.tableHeaderBackgroundColor = colorFromJson(o, "tableHeaderBackgroundColor", cv.tableHeaderBackgroundColor); - cv.tableHeaderGradientColor = colorFromJson(o, "tableHeaderGradientColor", cv.tableHeaderGradientColor); - cv.tableHeaderBorderColor = colorFromJson(o, "tableHeaderBorderColor", cv.tableHeaderBorderColor); - cv.tableHeaderTextColor = colorFromJson(o, "tableHeaderTextColor", cv.tableHeaderTextColor); - cv.tableScrollHandleColor = colorFromJson(o, "tableScrollHandleColor", cv.tableScrollHandleColor); - cv.tableScrollBackgroundColor = colorFromJson(o, "tableScrollBackgroundColor", cv.tableScrollBackgroundColor); - cv.tableSectionBorderLight = colorFromJson(o, "tableSectionBorderLight", cv.tableSectionBorderLight); - cv.tableSectionBorderDark = colorFromJson(o, "tableSectionBorderDark", cv.tableSectionBorderDark); - cv.labelTextColor = colorFromJson(o, "labelTextColor", cv.labelTextColor); - cv.labelBackgroundColor = colorFromJson(o, "labelBackgroundColor", cv.labelBackgroundColor); - cv.hyperlinkColor = colorFromJson(o, "hyperlinkColor", cv.hyperlinkColor); - cv.buttonBackgroundColor = colorFromJson(o, "buttonBackgroundColor", cv.buttonBackgroundColor); - cv.buttonTextColor = colorFromJson(o, "buttonTextColor", cv.buttonTextColor); - cv.buttonBorderColor = colorFromJson(o, "buttonBorderColor", cv.buttonBorderColor); - cv.radioUncheckedColor = colorFromJson(o, "radioUncheckedColor", cv.radioUncheckedColor); - cv.radioCheckedBackgroundColor = colorFromJson(o, "radioCheckedBackgroundColor", cv.radioCheckedBackgroundColor); - cv.radioCheckedIndicatorColor = colorFromJson(o, "radioCheckedIndicatorColor", cv.radioCheckedIndicatorColor); - cv.checkBoxTickColor = colorFromJson(o, "checkBoxTickColor", cv.checkBoxTickColor); - cv.toolButtonAccentColor = colorFromJson(o, "toolButtonAccentColor", cv.toolButtonAccentColor); - cv.downArrowColor = colorFromJson(o, "downArrowColor", cv.downArrowColor); - cv.upArrowColor = colorFromJson(o, "upArrowColor", cv.upArrowColor); - cv.busyIndicatorColor = colorFromJson(o, "busyIndicatorColor", cv.busyIndicatorColor); - cv.navIconColor = colorFromJson(o, "navIconColor", cv.navIconColor); - cv.rowIconColor = colorFromJson(o, "rowIconColor", cv.rowIconColor); + if (json.contains("metadataScraperDialog")) { + const auto o = json["metadataScraperDialog"].toObject(); + auto &msd = p.metadataScraperDialogParams; + msd.contentTextColor = colorFromJson(o, "contentTextColor", msd.contentTextColor); + msd.contentBackgroundColor = colorFromJson(o, "contentBackgroundColor", msd.contentBackgroundColor); + msd.contentAltBackgroundColor = colorFromJson(o, "contentAltBackgroundColor", msd.contentAltBackgroundColor); + msd.dialogBackgroundColor = colorFromJson(o, "dialogBackgroundColor", msd.dialogBackgroundColor); + msd.tableBackgroundColor = colorFromJson(o, "tableBackgroundColor", msd.tableBackgroundColor); + msd.tableAltBackgroundColor = colorFromJson(o, "tableAltBackgroundColor", msd.tableAltBackgroundColor); + msd.tableBorderColor = colorFromJson(o, "tableBorderColor", msd.tableBorderColor); + msd.tableSelectedColor = colorFromJson(o, "tableSelectedColor", msd.tableSelectedColor); + msd.tableHeaderBackgroundColor = colorFromJson(o, "tableHeaderBackgroundColor", msd.tableHeaderBackgroundColor); + msd.tableHeaderGradientColor = colorFromJson(o, "tableHeaderGradientColor", msd.tableHeaderGradientColor); + msd.tableHeaderBorderColor = colorFromJson(o, "tableHeaderBorderColor", msd.tableHeaderBorderColor); + msd.tableHeaderTextColor = colorFromJson(o, "tableHeaderTextColor", msd.tableHeaderTextColor); + msd.tableScrollHandleColor = colorFromJson(o, "tableScrollHandleColor", msd.tableScrollHandleColor); + msd.tableScrollBackgroundColor = colorFromJson(o, "tableScrollBackgroundColor", msd.tableScrollBackgroundColor); + msd.tableSectionBorderLight = colorFromJson(o, "tableSectionBorderLight", msd.tableSectionBorderLight); + msd.tableSectionBorderDark = colorFromJson(o, "tableSectionBorderDark", msd.tableSectionBorderDark); + msd.labelTextColor = colorFromJson(o, "labelTextColor", msd.labelTextColor); + msd.labelBackgroundColor = colorFromJson(o, "labelBackgroundColor", msd.labelBackgroundColor); + msd.hyperlinkColor = colorFromJson(o, "hyperlinkColor", msd.hyperlinkColor); + msd.buttonBackgroundColor = colorFromJson(o, "buttonBackgroundColor", msd.buttonBackgroundColor); + msd.buttonTextColor = colorFromJson(o, "buttonTextColor", msd.buttonTextColor); + msd.buttonBorderColor = colorFromJson(o, "buttonBorderColor", msd.buttonBorderColor); + msd.radioUncheckedColor = colorFromJson(o, "radioUncheckedColor", msd.radioUncheckedColor); + msd.radioCheckedBackgroundColor = colorFromJson(o, "radioCheckedBackgroundColor", msd.radioCheckedBackgroundColor); + msd.radioCheckedIndicatorColor = colorFromJson(o, "radioCheckedIndicatorColor", msd.radioCheckedIndicatorColor); + msd.checkBoxTickColor = colorFromJson(o, "checkBoxTickColor", msd.checkBoxTickColor); + msd.toolButtonAccentColor = colorFromJson(o, "toolButtonAccentColor", msd.toolButtonAccentColor); + msd.downArrowColor = colorFromJson(o, "downArrowColor", msd.downArrowColor); + msd.upArrowColor = colorFromJson(o, "upArrowColor", msd.upArrowColor); + msd.busyIndicatorColor = colorFromJson(o, "busyIndicatorColor", msd.busyIndicatorColor); + msd.navIconColor = colorFromJson(o, "navIconColor", msd.navIconColor); + msd.rowIconColor = colorFromJson(o, "rowIconColor", msd.rowIconColor); } if (json.contains("helpAboutDialog")) { @@ -1034,73 +1024,73 @@ Theme makeTheme(const QJsonObject &json) cs.verticalHandleWidth = o["verticalHandleWidth"].toInt(cs.verticalHandleWidth); } - if (json.contains("treeView")) { - const auto o = json["treeView"].toObject(); - auto &tv = p.treeViewParams; - tv.textColor = colorFromJson(o, "textColor", tv.textColor); - tv.selectionBackgroundColor = colorFromJson(o, "selectionBackgroundColor", tv.selectionBackgroundColor); - tv.scrollBackgroundColor = colorFromJson(o, "scrollBackgroundColor", tv.scrollBackgroundColor); - tv.scrollHandleColor = colorFromJson(o, "scrollHandleColor", tv.scrollHandleColor); - tv.selectedTextColor = colorFromJson(o, "selectedTextColor", tv.selectedTextColor); - tv.folderIndicatorColor = colorFromJson(o, "folderIndicatorColor", tv.folderIndicatorColor); - tv.branchIndicatorColor = colorFromJson(o, "branchIndicatorColor", tv.branchIndicatorColor); - tv.branchIndicatorSelectedColor = colorFromJson(o, "branchIndicatorSelectedColor", tv.branchIndicatorSelectedColor); - tv.folderIconColor = colorFromJson(o, "folderIconColor", tv.folderIconColor); - tv.folderIconShadowColor = colorFromJson(o, "folderIconShadowColor", tv.folderIconShadowColor); - tv.folderIconSelectedColor = colorFromJson(o, "folderIconSelectedColor", tv.folderIconSelectedColor); - tv.folderIconSelectedShadowColor = colorFromJson(o, "folderIconSelectedShadowColor", tv.folderIconSelectedShadowColor); - tv.folderReadOverlayColor = colorFromJson(o, "folderReadOverlayColor", tv.folderReadOverlayColor); - tv.folderReadOverlaySelectedColor = colorFromJson(o, "folderReadOverlaySelectedColor", tv.folderReadOverlaySelectedColor); + if (json.contains("navigationTree")) { + const auto o = json["navigationTree"].toObject(); + auto &nt = p.navigationTreeParams; + nt.textColor = colorFromJson(o, "textColor", nt.textColor); + nt.selectionBackgroundColor = colorFromJson(o, "selectionBackgroundColor", nt.selectionBackgroundColor); + nt.scrollBackgroundColor = colorFromJson(o, "scrollBackgroundColor", nt.scrollBackgroundColor); + nt.scrollHandleColor = colorFromJson(o, "scrollHandleColor", nt.scrollHandleColor); + nt.selectedTextColor = colorFromJson(o, "selectedTextColor", nt.selectedTextColor); + nt.folderIndicatorColor = colorFromJson(o, "folderIndicatorColor", nt.folderIndicatorColor); + nt.branchIndicatorColor = colorFromJson(o, "branchIndicatorColor", nt.branchIndicatorColor); + nt.branchIndicatorSelectedColor = colorFromJson(o, "branchIndicatorSelectedColor", nt.branchIndicatorSelectedColor); + nt.folderIconColor = colorFromJson(o, "folderIconColor", nt.folderIconColor); + nt.folderIconShadowColor = colorFromJson(o, "folderIconShadowColor", nt.folderIconShadowColor); + nt.folderIconSelectedColor = colorFromJson(o, "folderIconSelectedColor", nt.folderIconSelectedColor); + nt.folderIconSelectedShadowColor = colorFromJson(o, "folderIconSelectedShadowColor", nt.folderIconSelectedShadowColor); + nt.folderReadOverlayColor = colorFromJson(o, "folderReadOverlayColor", nt.folderReadOverlayColor); + nt.folderReadOverlaySelectedColor = colorFromJson(o, "folderReadOverlaySelectedColor", nt.folderReadOverlaySelectedColor); } - if (json.contains("tableView")) { - const auto o = json["tableView"].toObject(); - auto &tbv = p.tableViewParams; - tbv.alternateBackgroundColor = colorFromJson(o, "alternateBackgroundColor", tbv.alternateBackgroundColor); - tbv.backgroundColor = colorFromJson(o, "backgroundColor", tbv.backgroundColor); - tbv.headerBackgroundColor = colorFromJson(o, "headerBackgroundColor", tbv.headerBackgroundColor); - tbv.headerBorderColor = colorFromJson(o, "headerBorderColor", tbv.headerBorderColor); - tbv.headerGradientColor = colorFromJson(o, "headerGradientColor", tbv.headerGradientColor); - tbv.itemBorderBottomColor = colorFromJson(o, "itemBorderBottomColor", tbv.itemBorderBottomColor); - tbv.itemBorderTopColor = colorFromJson(o, "itemBorderTopColor", tbv.itemBorderTopColor); - tbv.itemBorderBottomWidth = o["itemBorderBottomWidth"].toInt(tbv.itemBorderBottomWidth); - tbv.itemBorderTopWidth = o["itemBorderTopWidth"].toInt(tbv.itemBorderTopWidth); - tbv.itemTextColor = colorFromJson(o, "itemTextColor", tbv.itemTextColor); - tbv.selectedColor = colorFromJson(o, "selectedColor", tbv.selectedColor); - tbv.selectedTextColor = colorFromJson(o, "selectedTextColor", tbv.selectedTextColor); - tbv.headerTextColor = colorFromJson(o, "headerTextColor", tbv.headerTextColor); - tbv.starRatingColor = colorFromJson(o, "starRatingColor", tbv.starRatingColor); - tbv.starRatingSelectedColor = colorFromJson(o, "starRatingSelectedColor", tbv.starRatingSelectedColor); + if (json.contains("comicsViewTable")) { + const auto o = json["comicsViewTable"].toObject(); + auto &cvta = p.comicsViewTableParams; + cvta.alternateBackgroundColor = colorFromJson(o, "alternateBackgroundColor", cvta.alternateBackgroundColor); + cvta.backgroundColor = colorFromJson(o, "backgroundColor", cvta.backgroundColor); + cvta.headerBackgroundColor = colorFromJson(o, "headerBackgroundColor", cvta.headerBackgroundColor); + cvta.headerBorderColor = colorFromJson(o, "headerBorderColor", cvta.headerBorderColor); + cvta.headerGradientColor = colorFromJson(o, "headerGradientColor", cvta.headerGradientColor); + cvta.itemBorderBottomColor = colorFromJson(o, "itemBorderBottomColor", cvta.itemBorderBottomColor); + cvta.itemBorderTopColor = colorFromJson(o, "itemBorderTopColor", cvta.itemBorderTopColor); + cvta.itemBorderBottomWidth = o["itemBorderBottomWidth"].toInt(cvta.itemBorderBottomWidth); + cvta.itemBorderTopWidth = o["itemBorderTopWidth"].toInt(cvta.itemBorderTopWidth); + cvta.itemTextColor = colorFromJson(o, "itemTextColor", cvta.itemTextColor); + cvta.selectedColor = colorFromJson(o, "selectedColor", cvta.selectedColor); + cvta.selectedTextColor = colorFromJson(o, "selectedTextColor", cvta.selectedTextColor); + cvta.headerTextColor = colorFromJson(o, "headerTextColor", cvta.headerTextColor); + cvta.starRatingColor = colorFromJson(o, "starRatingColor", cvta.starRatingColor); + cvta.starRatingSelectedColor = colorFromJson(o, "starRatingSelectedColor", cvta.starRatingSelectedColor); } - if (json.contains("qmlView")) { - const auto o = json["qmlView"].toObject(); - auto &qv = p.qmlViewParams; - qv.backgroundColor = colorFromJson(o, "backgroundColor", qv.backgroundColor); - qv.cellColor = colorFromJson(o, "cellColor", qv.cellColor); - qv.cellColorWithBackground = colorFromJson(o, "cellColorWithBackground", qv.cellColorWithBackground); - qv.selectedColor = colorFromJson(o, "selectedColor", qv.selectedColor); - qv.selectedBorderColor = colorFromJson(o, "selectedBorderColor", qv.selectedBorderColor); - qv.borderColor = colorFromJson(o, "borderColor", qv.borderColor); - qv.titleColor = colorFromJson(o, "titleColor", qv.titleColor); - qv.textColor = colorFromJson(o, "textColor", qv.textColor); + if (json.contains("gridAndInfoView")) { + const auto o = json["gridAndInfoView"].toObject(); + auto &giv = p.gridAndInfoViewParams; + giv.backgroundColor = colorFromJson(o, "backgroundColor", giv.backgroundColor); + giv.cellColor = colorFromJson(o, "cellColor", giv.cellColor); + giv.cellColorWithBackground = colorFromJson(o, "cellColorWithBackground", giv.cellColorWithBackground); + giv.selectedColor = colorFromJson(o, "selectedColor", giv.selectedColor); + giv.selectedBorderColor = colorFromJson(o, "selectedBorderColor", giv.selectedBorderColor); + giv.borderColor = colorFromJson(o, "borderColor", giv.borderColor); + giv.titleColor = colorFromJson(o, "titleColor", giv.titleColor); + giv.textColor = colorFromJson(o, "textColor", giv.textColor); if (o.contains("showDropShadow")) - qv.showDropShadow = o["showDropShadow"].toBool(qv.showDropShadow); - qv.infoBackgroundColor = colorFromJson(o, "infoBackgroundColor", qv.infoBackgroundColor); - qv.infoBorderColor = colorFromJson(o, "infoBorderColor", qv.infoBorderColor); - qv.infoShadowColor = colorFromJson(o, "infoShadowColor", qv.infoShadowColor); - qv.infoTextColor = colorFromJson(o, "infoTextColor", qv.infoTextColor); - qv.infoTitleColor = colorFromJson(o, "infoTitleColor", qv.infoTitleColor); - qv.ratingUnselectedColor = colorFromJson(o, "ratingUnselectedColor", qv.ratingUnselectedColor); - qv.ratingSelectedColor = colorFromJson(o, "ratingSelectedColor", qv.ratingSelectedColor); - qv.favUncheckedColor = colorFromJson(o, "favUncheckedColor", qv.favUncheckedColor); - qv.favCheckedColor = colorFromJson(o, "favCheckedColor", qv.favCheckedColor); - qv.readTickUncheckedColor = colorFromJson(o, "readTickUncheckedColor", qv.readTickUncheckedColor); - qv.readTickCheckedColor = colorFromJson(o, "readTickCheckedColor", qv.readTickCheckedColor); - qv.currentComicBackgroundColor = colorFromJson(o, "currentComicBackgroundColor", qv.currentComicBackgroundColor); - qv.continueReadingBackgroundColor = colorFromJson(o, "continueReadingBackgroundColor", qv.continueReadingBackgroundColor); - qv.continueReadingColor = colorFromJson(o, "continueReadingColor", qv.continueReadingColor); - qv.backgroundBlurOverlayColor = colorFromJson(o, "backgroundBlurOverlayColor", qv.backgroundBlurOverlayColor); + giv.showDropShadow = o["showDropShadow"].toBool(giv.showDropShadow); + giv.infoBackgroundColor = colorFromJson(o, "infoBackgroundColor", giv.infoBackgroundColor); + giv.infoBorderColor = colorFromJson(o, "infoBorderColor", giv.infoBorderColor); + giv.infoShadowColor = colorFromJson(o, "infoShadowColor", giv.infoShadowColor); + giv.infoTextColor = colorFromJson(o, "infoTextColor", giv.infoTextColor); + giv.infoTitleColor = colorFromJson(o, "infoTitleColor", giv.infoTitleColor); + giv.ratingUnselectedColor = colorFromJson(o, "ratingUnselectedColor", giv.ratingUnselectedColor); + giv.ratingSelectedColor = colorFromJson(o, "ratingSelectedColor", giv.ratingSelectedColor); + giv.favUncheckedColor = colorFromJson(o, "favUncheckedColor", giv.favUncheckedColor); + giv.favCheckedColor = colorFromJson(o, "favCheckedColor", giv.favCheckedColor); + giv.readTickUncheckedColor = colorFromJson(o, "readTickUncheckedColor", giv.readTickUncheckedColor); + giv.readTickCheckedColor = colorFromJson(o, "readTickCheckedColor", giv.readTickCheckedColor); + giv.currentComicBackgroundColor = colorFromJson(o, "currentComicBackgroundColor", giv.currentComicBackgroundColor); + giv.continueReadingBackgroundColor = colorFromJson(o, "continueReadingBackgroundColor", giv.continueReadingBackgroundColor); + giv.continueReadingColor = colorFromJson(o, "continueReadingColor", giv.continueReadingColor); + giv.backgroundBlurOverlayColor = colorFromJson(o, "backgroundBlurOverlayColor", giv.backgroundBlurOverlayColor); } if (json.contains("comicsViewToolbar")) { diff --git a/custom_widgets/yacreader_table_view.cpp b/custom_widgets/yacreader_table_view.cpp index 85c6ccba5..1075f9dd4 100644 --- a/custom_widgets/yacreader_table_view.cpp +++ b/custom_widgets/yacreader_table_view.cpp @@ -56,7 +56,7 @@ YACReaderTableView::YACReaderTableView(QWidget *parent) void YACReaderTableView::applyTheme(const Theme &theme) { - setStyleSheet(theme.tableView.tableViewQSS); + setStyleSheet(theme.comicsViewTable.tableViewQSS); } void YACReaderTableView::mouseMoveEvent(QMouseEvent *event) diff --git a/custom_widgets/yacreader_table_view.h b/custom_widgets/yacreader_table_view.h index 7c17e34fa..f455854a4 100644 --- a/custom_widgets/yacreader_table_view.h +++ b/custom_widgets/yacreader_table_view.h @@ -13,8 +13,8 @@ class YACReaderTableView : public QTableView, protected Themable Q_OBJECT public: explicit YACReaderTableView(QWidget *parent = 0); - QColor starRatingColor() const { return theme.tableView.starRatingColor; } - QColor starRatingSelectedColor() const { return theme.tableView.starRatingSelectedColor; } + QColor starRatingColor() const { return theme.comicsViewTable.starRatingColor; } + QColor starRatingSelectedColor() const { return theme.comicsViewTable.starRatingSelectedColor; } protected: void applyTheme(const Theme &theme) override; diff --git a/custom_widgets/yacreader_treeview.cpp b/custom_widgets/yacreader_treeview.cpp index 4a07424ea..c2699bd43 100644 --- a/custom_widgets/yacreader_treeview.cpp +++ b/custom_widgets/yacreader_treeview.cpp @@ -21,7 +21,7 @@ YACReaderTreeView::YACReaderTreeView(QWidget *parent) void YACReaderTreeView::applyTheme(const Theme &theme) { - setStyleSheet(theme.treeView.treeViewQSS); + setStyleSheet(theme.navigationTree.navigationTreeQSS); } void YACReaderTreeView::mousePressEvent(QMouseEvent *event) diff --git a/custom_widgets/yacreader_treeview.h b/custom_widgets/yacreader_treeview.h index 78b0154f4..bf8e43f10 100644 --- a/custom_widgets/yacreader_treeview.h +++ b/custom_widgets/yacreader_treeview.h @@ -10,7 +10,7 @@ class YACReaderTreeView : public QTreeView, protected Themable Q_OBJECT public: explicit YACReaderTreeView(QWidget *parent = 0); - QColor folderIndicatorColor() const { return theme.treeView.folderIndicatorColor; } + QColor folderIndicatorColor() const { return theme.navigationTree.folderIndicatorColor; } private: void mousePressEvent(QMouseEvent *event) override; From 2d669870453884ae3e675d502d3f25b56b13adbd Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 2 Mar 2026 22:44:08 +0100 Subject: [PATCH 110/187] Make json keys display as human readable strings in the theme editor --- common/themes/theme_editor_dialog.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/common/themes/theme_editor_dialog.cpp b/common/themes/theme_editor_dialog.cpp index eaeed5153..4f4ef7d44 100644 --- a/common/themes/theme_editor_dialog.cpp +++ b/common/themes/theme_editor_dialog.cpp @@ -32,6 +32,24 @@ static const int IsBoolRole = Qt::UserRole + 2; // Role used to distinguish numeric items. static const int IsNumberRole = Qt::UserRole + 3; +// Converts a camelCase JSON key to a human-readable display string. +// "metadataScraperDialog" → "Metadata scraper dialog" +// "navigationTreeQSS" → "Navigation tree qss" +// Consecutive uppercase letters (acronyms) are kept together as one word. +static QString displayKey(const QString &key) +{ + QString result; + for (int i = 0; i < key.size(); ++i) { + const bool isUpper = key[i].isUpper(); + const bool prevIsLower = (i > 0) && key[i - 1].isLower(); + const bool nextIsLower = (i + 1 < key.size()) && key[i + 1].isLower(); + if (i > 0 && isUpper && (prevIsLower || nextIsLower)) + result += ' '; + result += result.isEmpty() ? key[i].toUpper() : key[i].toLower(); + } + return result; +} + static bool isColorString(const QString &s) { // Accepts #RGB, #RRGGBB, #AARRGGBB @@ -171,14 +189,14 @@ void ThemeEditorDialog::populate(QTreeWidgetItem *parent, const QJsonObject &obj QFont bold = group->font(0); bold.setBold(true); group->setFont(0, bold); - group->setText(0, key); + group->setText(0, displayKey(key)); group->setFlags(group->flags() & ~Qt::ItemIsSelectable); populate(group, val.toObject(), childPath); } else { // Leaf row QTreeWidgetItem *item = parent ? new QTreeWidgetItem(parent) : new QTreeWidgetItem(tree); - item->setText(0, key); + item->setText(0, displayKey(key)); item->setData(0, PathRole, childPath); const QString strVal = val.toString(); From ad28216f5024a292b4eab23bdd4a8dc6fe6a2e05 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Tue, 3 Mar 2026 22:13:39 +0100 Subject: [PATCH 111/187] Fix qrc prefix --- common/themes/appearance_config_images.qrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/themes/appearance_config_images.qrc b/common/themes/appearance_config_images.qrc index c274e5636..3284bda98 100644 --- a/common/themes/appearance_config_images.qrc +++ b/common/themes/appearance_config_images.qrc @@ -1,5 +1,5 @@ - + ../../images/appearance_config/theme-mode-system.svg ../../images/appearance_config/theme-mode-light.svg ../../images/appearance_config/theme-mode-dark.svg From 3799c0633d1fda249c81828b12b58067bd3255a5 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Tue, 3 Mar 2026 22:43:23 +0100 Subject: [PATCH 112/187] Reformat json theme files so the content is sorted alphabetically allowing easy tracking of changes through git --- YACReader/themes/builtin_classic.json | 60 +-- YACReader/themes/builtin_dark.json | 60 +-- YACReader/themes/builtin_light.json | 60 +-- YACReaderLibrary/themes/builtin_classic.json | 364 +++++++++---------- YACReaderLibrary/themes/builtin_dark.json | 362 +++++++++--------- YACReaderLibrary/themes/builtin_light.json | 362 +++++++++--------- 6 files changed, 634 insertions(+), 634 deletions(-) diff --git a/YACReader/themes/builtin_classic.json b/YACReader/themes/builtin_classic.json index 74dff6b4a..f3edf0886 100644 --- a/YACReader/themes/builtin_classic.json +++ b/YACReader/themes/builtin_classic.json @@ -1,17 +1,37 @@ { + "goToFlowWidget": { + "editBackgroundColor": "#55000000", + "editBorderColor": "#77000000", + "editTextColor": "#ffffff", + "flowBackgroundColor": "#282828", + "flowTextColor": "#ffffff", + "iconColor": "#ffffff", + "labelTextColor": "#ffffff", + "sliderBorderColor": "#22ffffff", + "sliderGrooveColor": "#77000000", + "sliderHandleColor": "#55ffffff", + "toolbarBackgroundColor": "#99000000" + }, + "helpAboutDialog": { + "headingColor": "#302f2d", + "linkColor": "#c19441" + }, "meta": { - "id": "builtin/classic", "displayName": "Default Classic", + "id": "builtin/classic", "variant": "dark" }, + "shortcutsIcons": { + "iconColor": "#404040" + }, "toolbar": { - "iconColor": "#404040", - "iconDisabledColor": "#858585", - "iconCheckedColor": "#5a5a5a", "backgroundColor": "#f3f3f3", - "separatorColor": "#cccccc", "checkedButtonColor": "#cccccc", - "menuIndicatorColor": "#404040" + "iconCheckedColor": "#5a5a5a", + "iconColor": "#404040", + "iconDisabledColor": "#858585", + "menuIndicatorColor": "#404040", + "separatorColor": "#cccccc" }, "viewer": { "defaultBackgroundColor": "#282828", @@ -19,33 +39,13 @@ "infoBackgroundColor": "#bb000000", "infoTextColor": "#ffffff" }, - "goToFlowWidget": { - "flowBackgroundColor": "#282828", - "flowTextColor": "#ffffff", - "toolbarBackgroundColor": "#99000000", - "sliderBorderColor": "#22ffffff", - "sliderGrooveColor": "#77000000", - "sliderHandleColor": "#55ffffff", - "editBorderColor": "#77000000", - "editBackgroundColor": "#55000000", - "editTextColor": "#ffffff", - "labelTextColor": "#ffffff", - "iconColor": "#ffffff" - }, - "helpAboutDialog": { - "headingColor": "#302f2d", - "linkColor": "#c19441" - }, "whatsNewDialog": { "backgroundColor": "#ffffff", - "headerTextColor": "#0a0a0a", - "versionTextColor": "#858585", + "closeButtonColor": "#444444", "contentTextColor": "#0a0a0a", + "headerDecorationColor": "#e8b800", + "headerTextColor": "#0a0a0a", "linkColor": "#e8b800", - "closeButtonColor": "#444444", - "headerDecorationColor": "#e8b800" - }, - "shortcutsIcons": { - "iconColor": "#404040" + "versionTextColor": "#858585" } } diff --git a/YACReader/themes/builtin_dark.json b/YACReader/themes/builtin_dark.json index 01085ca9c..61038dfa8 100644 --- a/YACReader/themes/builtin_dark.json +++ b/YACReader/themes/builtin_dark.json @@ -1,17 +1,37 @@ { + "goToFlowWidget": { + "editBackgroundColor": "#55000000", + "editBorderColor": "#77000000", + "editTextColor": "#ffffff", + "flowBackgroundColor": "#282828", + "flowTextColor": "#ffffff", + "iconColor": "#cccccc", + "labelTextColor": "#ffffff", + "sliderBorderColor": "#22ffffff", + "sliderGrooveColor": "#77000000", + "sliderHandleColor": "#55ffffff", + "toolbarBackgroundColor": "#99000000" + }, + "helpAboutDialog": { + "headingColor": "#e0e0e0", + "linkColor": "#d4a84b" + }, "meta": { - "id": "builtin/dark", "displayName": "Default Dark", + "id": "builtin/dark", "variant": "dark" }, + "shortcutsIcons": { + "iconColor": "#d0d0d0" + }, "toolbar": { - "iconColor": "#cccccc", - "iconDisabledColor": "#444444", - "iconCheckedColor": "#dadada", "backgroundColor": "#202020", - "separatorColor": "#444444", "checkedButtonColor": "#3a3a3a", - "menuIndicatorColor": "#cccccc" + "iconCheckedColor": "#dadada", + "iconColor": "#cccccc", + "iconDisabledColor": "#444444", + "menuIndicatorColor": "#cccccc", + "separatorColor": "#444444" }, "viewer": { "defaultBackgroundColor": "#282828", @@ -19,33 +39,13 @@ "infoBackgroundColor": "#bb000000", "infoTextColor": "#b0b0b0" }, - "goToFlowWidget": { - "flowBackgroundColor": "#282828", - "flowTextColor": "#ffffff", - "toolbarBackgroundColor": "#99000000", - "sliderBorderColor": "#22ffffff", - "sliderGrooveColor": "#77000000", - "sliderHandleColor": "#55ffffff", - "editBorderColor": "#77000000", - "editBackgroundColor": "#55000000", - "editTextColor": "#ffffff", - "labelTextColor": "#ffffff", - "iconColor": "#cccccc" - }, - "helpAboutDialog": { - "headingColor": "#e0e0e0", - "linkColor": "#d4a84b" - }, "whatsNewDialog": { "backgroundColor": "#2a2a2a", - "headerTextColor": "#e0e0e0", - "versionTextColor": "#858585", + "closeButtonColor": "#dddddd", "contentTextColor": "#e0e0e0", + "headerDecorationColor": "#e8b800", + "headerTextColor": "#e0e0e0", "linkColor": "#e8b800", - "closeButtonColor": "#dddddd", - "headerDecorationColor": "#e8b800" - }, - "shortcutsIcons": { - "iconColor": "#d0d0d0" + "versionTextColor": "#858585" } } diff --git a/YACReader/themes/builtin_light.json b/YACReader/themes/builtin_light.json index 979057911..dbd77f07e 100644 --- a/YACReader/themes/builtin_light.json +++ b/YACReader/themes/builtin_light.json @@ -1,17 +1,37 @@ { + "goToFlowWidget": { + "editBackgroundColor": "#22000000", + "editBorderColor": "#33000000", + "editTextColor": "#202020", + "flowBackgroundColor": "#f6f6f6", + "flowTextColor": "#202020", + "iconColor": "#404040", + "labelTextColor": "#202020", + "sliderBorderColor": "#22000000", + "sliderGrooveColor": "#33000000", + "sliderHandleColor": "#55000000", + "toolbarBackgroundColor": "#bbffffff" + }, + "helpAboutDialog": { + "headingColor": "#302f2d", + "linkColor": "#c19441" + }, "meta": { - "id": "builtin/light", "displayName": "Default Light", + "id": "builtin/light", "variant": "light" }, + "shortcutsIcons": { + "iconColor": "#606060" + }, "toolbar": { - "iconColor": "#404040", - "iconDisabledColor": "#b0b0b0", - "iconCheckedColor": "#5a5a5a", "backgroundColor": "#f3f3f3", - "separatorColor": "#cccccc", "checkedButtonColor": "#cccccc", - "menuIndicatorColor": "#404040" + "iconCheckedColor": "#5a5a5a", + "iconColor": "#404040", + "iconDisabledColor": "#b0b0b0", + "menuIndicatorColor": "#404040", + "separatorColor": "#cccccc" }, "viewer": { "defaultBackgroundColor": "#f6f6f6", @@ -19,33 +39,13 @@ "infoBackgroundColor": "#bbffffff", "infoTextColor": "#404040" }, - "goToFlowWidget": { - "flowBackgroundColor": "#f6f6f6", - "flowTextColor": "#202020", - "toolbarBackgroundColor": "#bbffffff", - "sliderBorderColor": "#22000000", - "sliderGrooveColor": "#33000000", - "sliderHandleColor": "#55000000", - "editBorderColor": "#33000000", - "editBackgroundColor": "#22000000", - "editTextColor": "#202020", - "labelTextColor": "#202020", - "iconColor": "#404040" - }, - "helpAboutDialog": { - "headingColor": "#302f2d", - "linkColor": "#c19441" - }, "whatsNewDialog": { "backgroundColor": "#ffffff", - "headerTextColor": "#0a0a0a", - "versionTextColor": "#858585", + "closeButtonColor": "#444444", "contentTextColor": "#0a0a0a", + "headerDecorationColor": "#e8b800", + "headerTextColor": "#0a0a0a", "linkColor": "#e8b800", - "closeButtonColor": "#444444", - "headerDecorationColor": "#e8b800" - }, - "shortcutsIcons": { - "iconColor": "#606060" + "versionTextColor": "#858585" } } diff --git a/YACReaderLibrary/themes/builtin_classic.json b/YACReaderLibrary/themes/builtin_classic.json index b410662d9..ea571a116 100644 --- a/YACReaderLibrary/themes/builtin_classic.json +++ b/YACReaderLibrary/themes/builtin_classic.json @@ -1,237 +1,237 @@ { - "meta": { - "id": "builtin/classic", - "displayName": "Default Classic", - "variant": "dark" - }, "comicFlow": { "backgroundColor": "#000000", "textColor": "#4c4c4c" }, - "metadataScraperDialog": { - "contentTextColor": "#ffffff", - "contentBackgroundColor": "#2b2b2b", - "contentAltBackgroundColor": "#2b2b2b", - "dialogBackgroundColor": "#404040", - "tableBackgroundColor": "#2b2b2b", - "tableAltBackgroundColor": "#2e2e2e", - "tableBorderColor": "#242424", - "tableSelectedColor": "#555555", - "tableHeaderBackgroundColor": "#292929", - "tableHeaderGradientColor": "#292929", - "tableHeaderBorderColor": "#1f1f1f", - "tableHeaderTextColor": "#ebebeb", - "tableScrollHandleColor": "#dddddd", - "tableScrollBackgroundColor": "#404040", - "tableSectionBorderLight": "#fefefe", - "tableSectionBorderDark": "#dfdfdf", - "labelTextColor": "#ffffff", - "labelBackgroundColor": "#2b2b2b", - "hyperlinkColor": "#ffcc00", - "buttonBackgroundColor": "#2e2e2e", - "buttonTextColor": "#ffffff", - "buttonBorderColor": "#242424", - "radioUncheckedColor": "#e5e5e5", - "radioCheckedBackgroundColor": "#e5e5e5", - "radioCheckedIndicatorColor": "#5f5f5f", - "checkBoxTickColor": "#ffffff", - "toolButtonAccentColor": "#282828", - "downArrowColor": "#9f9f9f", - "upArrowColor": "#9f9f9f", - "busyIndicatorColor": "#ffffff", - "navIconColor": "#ffffff", - "rowIconColor": "#e5e5e5" - }, - "helpAboutDialog": { - "headingColor": "#302f2d", - "linkColor": "#c19441" - }, - "whatsNewDialog": { - "backgroundColor": "#2a2a2a", - "headerTextColor": "#e0e0e0", - "versionTextColor": "#858585", - "contentTextColor": "#e0e0e0", - "linkColor": "#e8b800", - "closeButtonColor": "#dddddd", - "headerDecorationColor": "#e8b800" - }, - "emptyContainer": { - "backgroundColor": "#2a2a2a", - "titleTextColor": "#cccccc", - "textColor": "#cccccc", - "descriptionTextColor": "#aaaaaa", - "searchIconColor": "#4c4c4c" - }, - "sidebar": { - "backgroundColor": "#454545", - "separatorColor": "#bdbfbf", - "sectionSeparatorColor": "#575757", - "uppercaseLabels": true, - "titleTextColor": "#bdbfbf", - "titleDropShadowColor": "#000000", - "busyIndicatorColor": "#ffffff" - }, - "sidebarIcons": { - "iconColor": "#e0e0e0", - "shadowColor": "#000000", - "useSystemFolderIcons": false - }, - "libraryItem": { - "textColor": "#dddfdf", - "libraryIconColor": "#dddfdf", - "libraryIconShadowColor": "#000000", - "selectedTextColor": "#ffffff", - "selectedBackgroundColor": "#2e2e2e", - "libraryIconSelectedColor": "#ffffff", - "libraryOptionsIconColor": "#ffffff" - }, - "importWidget": { - "backgroundColor": "#2a2a2a", - "titleTextColor": "#cccccc", - "descriptionTextColor": "#aaaaaa", - "currentComicTextColor": "#aaaaaa", - "coversViewBackgroundColor": "#3a3a3a", - "coversLabelColor": "#aaaaaa", - "coversDecorationBgColor": "#3a3a3a", - "coversDecorationShadowColor": "#1a1a1a", - "modeIconColor": "#4a4a4a", - "iconColor": "#cccccc", - "iconCheckedColor": "#aaaaaa" - }, - "serverConfigDialog": { - "backgroundColor": "#2a2a2a", - "titleTextColor": "#474747", - "qrMessageTextColor": "#a3a3a3", - "propagandaTextColor": "#4d4d4d", - "labelTextColor": "#575757", - "checkBoxTextColor": "#262626", - "qrBackgroundColor": "#2a2a2a", - "qrForegroundColor": "#ffffff", - "decorationColor": "#f7f7f7" - }, - "mainToolbar": { - "backgroundColor": "#f0f0f0", - "folderNameColor": "#404040", - "dividerColor": "#b8bdc4", - "iconColor": "#404040", - "iconDisabledColor": "#b0b0b0" - }, - "contentSplitter": { - "handleColor": "#b8b8b8", - "horizontalHandleHeight": 4, - "verticalHandleWidth": 4 - }, - "navigationTree": { - "textColor": "#dddfdf", - "selectionBackgroundColor": "#2e2e2e", - "scrollBackgroundColor": "#404040", - "scrollHandleColor": "#dddddd", - "selectedTextColor": "#ffffff", - "folderIndicatorColor": "#edc518", - "branchIndicatorColor": "#e0e0e0", - "branchIndicatorSelectedColor": "#ffffff", - "folderIconColor": "#e0e0e0", - "folderIconShadowColor": "#000000", - "folderIconSelectedColor": "#e0e0e0", - "folderIconSelectedShadowColor": "#000000", - "folderReadOverlayColor": "#464646", - "folderReadOverlaySelectedColor": "#464646" - }, "comicsViewTable": { "alternateBackgroundColor": "#f2f2f2", "backgroundColor": "#fafafa", "headerBackgroundColor": "#f5f5f5", "headerBorderColor": "#b8bdc4", "headerGradientColor": "#d1d1d1", + "headerTextColor": "#313232", "itemBorderBottomColor": "#dfdfdf", - "itemBorderTopColor": "#fefefe", "itemBorderBottomWidth": 1, + "itemBorderTopColor": "#fefefe", "itemBorderTopWidth": 1, "itemTextColor": "#252626", "selectedColor": "#d4d4d4", "selectedTextColor": "#252626", - "headerTextColor": "#313232", "starRatingColor": "#e9be0f", "starRatingSelectedColor": "#ffffff" }, + "comicsViewToolbar": { + "backgroundColor": "#f0f0f0", + "checkedBackgroundColor": "#cccccc", + "iconColor": "#404040", + "separatorColor": "#cccccc" + }, + "contentSplitter": { + "handleColor": "#b8b8b8", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "dialogIcons": { + "iconColor": "#f7f7f7" + }, + "emptyContainer": { + "backgroundColor": "#2a2a2a", + "descriptionTextColor": "#aaaaaa", + "searchIconColor": "#4c4c4c", + "textColor": "#cccccc", + "titleTextColor": "#cccccc" + }, "gridAndInfoView": { + "backgroundBlurOverlayColor": "#2a2a2a", "backgroundColor": "#2a2a2a", + "borderColor": "#121212", "cellColor": "#212121", "cellColorWithBackground": "#99212121", - "selectedColor": "#121212", - "selectedBorderColor": "#ffcc00", - "borderColor": "#121212", - "titleColor": "#ffffff", - "textColor": "#a8a8a8", - "showDropShadow": true, + "continueReadingBackgroundColor": "#88000000", + "continueReadingColor": "#ffffff", + "currentComicBackgroundColor": "#88000000", + "favCheckedColor": "#e84852", + "favUncheckedColor": "#1c1c1c", "infoBackgroundColor": "#2e2e2e", "infoBorderColor": "#404040", "infoShadowColor": "#000000", "infoTextColor": "#b0b0b0", "infoTitleColor": "#ffffff", - "ratingUnselectedColor": "#1c1c1c", "ratingSelectedColor": "#ffffff", - "favUncheckedColor": "#1c1c1c", - "favCheckedColor": "#e84852", - "readTickUncheckedColor": "#1c1c1c", + "ratingUnselectedColor": "#1c1c1c", "readTickCheckedColor": "#e84852", - "currentComicBackgroundColor": "#88000000", - "continueReadingBackgroundColor": "#88000000", - "continueReadingColor": "#ffffff", - "backgroundBlurOverlayColor": "#2a2a2a" + "readTickUncheckedColor": "#1c1c1c", + "selectedBorderColor": "#ffcc00", + "selectedColor": "#121212", + "showDropShadow": true, + "textColor": "#a8a8a8", + "titleColor": "#ffffff" }, - "comicsViewToolbar": { + "helpAboutDialog": { + "headingColor": "#302f2d", + "linkColor": "#c19441" + }, + "importWidget": { + "backgroundColor": "#2a2a2a", + "coversDecorationBgColor": "#3a3a3a", + "coversDecorationShadowColor": "#1a1a1a", + "coversLabelColor": "#aaaaaa", + "coversViewBackgroundColor": "#3a3a3a", + "currentComicTextColor": "#aaaaaa", + "descriptionTextColor": "#aaaaaa", + "iconCheckedColor": "#aaaaaa", + "iconColor": "#cccccc", + "modeIconColor": "#4a4a4a", + "titleTextColor": "#cccccc" + }, + "libraryItem": { + "libraryIconColor": "#dddfdf", + "libraryIconSelectedColor": "#ffffff", + "libraryIconShadowColor": "#000000", + "libraryOptionsIconColor": "#ffffff", + "selectedBackgroundColor": "#2e2e2e", + "selectedTextColor": "#ffffff", + "textColor": "#dddfdf" + }, + "mainToolbar": { "backgroundColor": "#f0f0f0", - "separatorColor": "#cccccc", - "checkedBackgroundColor": "#cccccc", - "iconColor": "#404040" + "dividerColor": "#b8bdc4", + "folderNameColor": "#404040", + "iconColor": "#404040", + "iconDisabledColor": "#b0b0b0" }, - "searchLineEdit": { - "textColor": "#ababab", - "backgroundColor": "#404040", + "menuIcons": { "iconColor": "#f7f7f7" }, + "meta": { + "displayName": "Default Classic", + "id": "builtin/classic", + "variant": "dark" + }, + "metadataScraperDialog": { + "busyIndicatorColor": "#ffffff", + "buttonBackgroundColor": "#2e2e2e", + "buttonBorderColor": "#242424", + "buttonTextColor": "#ffffff", + "checkBoxTickColor": "#ffffff", + "contentAltBackgroundColor": "#2b2b2b", + "contentBackgroundColor": "#2b2b2b", + "contentTextColor": "#ffffff", + "dialogBackgroundColor": "#404040", + "downArrowColor": "#9f9f9f", + "hyperlinkColor": "#ffcc00", + "labelBackgroundColor": "#2b2b2b", + "labelTextColor": "#ffffff", + "navIconColor": "#ffffff", + "radioCheckedBackgroundColor": "#e5e5e5", + "radioCheckedIndicatorColor": "#5f5f5f", + "radioUncheckedColor": "#e5e5e5", + "rowIconColor": "#e5e5e5", + "tableAltBackgroundColor": "#2e2e2e", + "tableBackgroundColor": "#2b2b2b", + "tableBorderColor": "#242424", + "tableHeaderBackgroundColor": "#292929", + "tableHeaderBorderColor": "#1f1f1f", + "tableHeaderGradientColor": "#292929", + "tableHeaderTextColor": "#ebebeb", + "tableScrollBackgroundColor": "#404040", + "tableScrollHandleColor": "#dddddd", + "tableSectionBorderDark": "#dfdfdf", + "tableSectionBorderLight": "#fefefe", + "tableSelectedColor": "#555555", + "toolButtonAccentColor": "#282828", + "upArrowColor": "#9f9f9f" + }, + "navigationTree": { + "branchIndicatorColor": "#e0e0e0", + "branchIndicatorSelectedColor": "#ffffff", + "folderIconColor": "#e0e0e0", + "folderIconSelectedColor": "#e0e0e0", + "folderIconSelectedShadowColor": "#000000", + "folderIconShadowColor": "#000000", + "folderIndicatorColor": "#edc518", + "folderReadOverlayColor": "#464646", + "folderReadOverlaySelectedColor": "#464646", + "scrollBackgroundColor": "#404040", + "scrollHandleColor": "#dddddd", + "selectedTextColor": "#ffffff", + "selectionBackgroundColor": "#2e2e2e", + "textColor": "#dddfdf" + }, "readingListIcons": { + "currentlyReadingMainColor": "#ffcc00", + "currentlyReadingMainSelectedColor": "#ffcc00", + "currentlyReadingOuterColor": "#000000", + "currentlyReadingOuterSelectedColor": "#000000", + "favoritesMainColor": "#e15055", + "favoritesMainSelectedColor": "#e15055", "labelColors": { - "red": "#f67a7b", - "orange": "#f5c240", - "yellow": "#f2e446", - "green": "#ade738", - "cyan": "#a0fddb", "blue": "#82c7ff", - "violet": "#8f95ff", - "purple": "#d692fc", + "cyan": "#a0fddb", + "dark": "#b7b7b7", + "green": "#ade738", + "light": "#cbcbcb", + "orange": "#f5c240", "pink": "#fd9cda", + "purple": "#d692fc", + "red": "#f67a7b", + "violet": "#8f95ff", "white": "#fcfcfc", - "light": "#cbcbcb", - "dark": "#b7b7b7" + "yellow": "#f2e446" }, "labelShadowColor": "#000000", "labelShadowSelectedColor": "#000000", - "readingListMainColor": "#e7e7e7", - "readingListMainSelectedColor": "#e7e7e7", - "favoritesMainColor": "#e15055", - "favoritesMainSelectedColor": "#e15055", - "currentlyReadingMainColor": "#ffcc00", - "currentlyReadingMainSelectedColor": "#ffcc00", - "currentlyReadingOuterColor": "#000000", - "currentlyReadingOuterSelectedColor": "#000000", - "specialListShadowColor": "#000000", - "specialListShadowSelectedColor": "#000000", + "listDetailColor": "#464646", + "listDetailSelectedColor": "#464646", "listMainColor": "#e7e7e7", "listMainSelectedColor": "#e7e7e7", "listShadowColor": "#000000", "listShadowSelectedColor": "#000000", - "listDetailColor": "#464646", - "listDetailSelectedColor": "#464646" + "readingListMainColor": "#e7e7e7", + "readingListMainSelectedColor": "#e7e7e7", + "specialListShadowColor": "#000000", + "specialListShadowSelectedColor": "#000000" }, - "dialogIcons": { - "iconColor": "#f7f7f7" + "searchLineEdit": { + "backgroundColor": "#404040", + "iconColor": "#f7f7f7", + "textColor": "#ababab" }, - "menuIcons": { - "iconColor": "#f7f7f7" + "serverConfigDialog": { + "backgroundColor": "#2a2a2a", + "checkBoxTextColor": "#262626", + "decorationColor": "#f7f7f7", + "labelTextColor": "#575757", + "propagandaTextColor": "#4d4d4d", + "qrBackgroundColor": "#2a2a2a", + "qrForegroundColor": "#ffffff", + "qrMessageTextColor": "#a3a3a3", + "titleTextColor": "#474747" }, "shortcutsIcons": { "iconColor": "#f7f7f7" + }, + "sidebar": { + "backgroundColor": "#454545", + "busyIndicatorColor": "#ffffff", + "sectionSeparatorColor": "#575757", + "separatorColor": "#bdbfbf", + "titleDropShadowColor": "#000000", + "titleTextColor": "#bdbfbf", + "uppercaseLabels": true + }, + "sidebarIcons": { + "iconColor": "#e0e0e0", + "shadowColor": "#000000", + "useSystemFolderIcons": false + }, + "whatsNewDialog": { + "backgroundColor": "#2a2a2a", + "closeButtonColor": "#dddddd", + "contentTextColor": "#e0e0e0", + "headerDecorationColor": "#e8b800", + "headerTextColor": "#e0e0e0", + "linkColor": "#e8b800", + "versionTextColor": "#858585" } } diff --git a/YACReaderLibrary/themes/builtin_dark.json b/YACReaderLibrary/themes/builtin_dark.json index 1634400a9..45fbcc64b 100644 --- a/YACReaderLibrary/themes/builtin_dark.json +++ b/YACReaderLibrary/themes/builtin_dark.json @@ -1,237 +1,237 @@ { - "meta": { - "id": "builtin/dark", - "displayName": "Default Dark", - "variant": "dark" - }, "comicFlow": { "backgroundColor": "#111111", "textColor": "#888888" }, - "metadataScraperDialog": { - "contentTextColor": "#ffffff", - "contentBackgroundColor": "#2b2b2b", - "contentAltBackgroundColor": "#2e2e2e", - "dialogBackgroundColor": "#404040", - "tableBackgroundColor": "#2b2b2b", - "tableAltBackgroundColor": "#2e2e2e", - "tableBorderColor": "#242424", - "tableSelectedColor": "#555555", - "tableHeaderBackgroundColor": "#292929", - "tableHeaderGradientColor": "#292929", - "tableHeaderBorderColor": "#1f1f1f", - "tableHeaderTextColor": "#ebebeb", - "tableScrollHandleColor": "#dddddd", - "tableScrollBackgroundColor": "#404040", - "tableSectionBorderLight": "#fefefe", - "tableSectionBorderDark": "#dfdfdf", - "labelTextColor": "#ffffff", - "labelBackgroundColor": "#2b2b2b", - "hyperlinkColor": "#ffcc00", - "buttonBackgroundColor": "#2e2e2e", - "buttonTextColor": "#ffffff", - "buttonBorderColor": "#242424", - "radioUncheckedColor": "#e5e5e5", - "radioCheckedBackgroundColor": "#e5e5e5", - "radioCheckedIndicatorColor": "#5f5f5f", - "checkBoxTickColor": "#ffffff", - "toolButtonAccentColor": "#282828", - "downArrowColor": "#9f9f9f", - "upArrowColor": "#9f9f9f", - "busyIndicatorColor": "#ffffff", - "navIconColor": "#ffffff", - "rowIconColor": "#e5e5e5" - }, - "helpAboutDialog": { - "headingColor": "#e0e0e0", - "linkColor": "#d4a84b" + "comicsViewTable": { + "alternateBackgroundColor": "#2e2e2e", + "backgroundColor": "#2a2a2a", + "headerBackgroundColor": "#2a2a2a", + "headerBorderColor": "#1f1f1f", + "headerGradientColor": "#252525", + "headerTextColor": "#dddddd", + "itemBorderBottomColor": "#1f1f1f", + "itemBorderBottomWidth": 1, + "itemBorderTopColor": "#353535", + "itemBorderTopWidth": 1, + "itemTextColor": "#dddddd", + "selectedColor": "#555555", + "selectedTextColor": "#ffffff", + "starRatingColor": "#e9be0f", + "starRatingSelectedColor": "#ffffff" }, - "whatsNewDialog": { + "comicsViewToolbar": { "backgroundColor": "#2a2a2a", - "headerTextColor": "#e0e0e0", - "versionTextColor": "#858585", - "contentTextColor": "#e0e0e0", - "linkColor": "#e8b800", - "closeButtonColor": "#dddddd", - "headerDecorationColor": "#e8b800" + "checkedBackgroundColor": "#555555", + "iconColor": "#dddddd", + "separatorColor": "#444444" + }, + "contentSplitter": { + "handleColor": "#1f1f1f", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "dialogIcons": { + "iconColor": "#f7f7f7" }, "emptyContainer": { "backgroundColor": "#2a2a2a", - "titleTextColor": "#cccccc", - "textColor": "#cccccc", "descriptionTextColor": "#aaaaaa", - "searchIconColor": "#4c4c4c" - }, - "sidebar": { - "backgroundColor": "#454545", - "separatorColor": "#bdbfbf", - "sectionSeparatorColor": "#575757", - "uppercaseLabels": true, - "titleTextColor": "#bdbfbf", - "titleDropShadowColor": "#000000", - "busyIndicatorColor": "#ffffff" + "searchIconColor": "#4c4c4c", + "textColor": "#cccccc", + "titleTextColor": "#cccccc" }, - "sidebarIcons": { - "iconColor": "#e0e0e0", - "shadowColor": "#000000", - "useSystemFolderIcons": false + "gridAndInfoView": { + "backgroundBlurOverlayColor": "#2a2a2a", + "backgroundColor": "#2a2a2a", + "borderColor": "#121212", + "cellColor": "#212121", + "cellColorWithBackground": "#99212121", + "continueReadingBackgroundColor": "#88000000", + "continueReadingColor": "#ffffff", + "currentComicBackgroundColor": "#88000000", + "favCheckedColor": "#e84852", + "favUncheckedColor": "#1c1c1c", + "infoBackgroundColor": "#2e2e2e", + "infoBorderColor": "#404040", + "infoShadowColor": "#000000", + "infoTextColor": "#b0b0b0", + "infoTitleColor": "#ffffff", + "ratingSelectedColor": "#ffffff", + "ratingUnselectedColor": "#1c1c1c", + "readTickCheckedColor": "#e84852", + "readTickUncheckedColor": "#1c1c1c", + "selectedBorderColor": "#ffcc00", + "selectedColor": "#121212", + "showDropShadow": true, + "textColor": "#a8a8a8", + "titleColor": "#ffffff" }, - "libraryItem": { - "textColor": "#dddfdf", - "libraryIconColor": "#dddfdf", - "libraryIconShadowColor": "#000000", - "selectedTextColor": "#ffffff", - "selectedBackgroundColor": "#2e2e2e", - "libraryIconSelectedColor": "#ffffff", - "libraryOptionsIconColor": "#ffffff" + "helpAboutDialog": { + "headingColor": "#e0e0e0", + "linkColor": "#d4a84b" }, "importWidget": { "backgroundColor": "#2a2a2a", - "titleTextColor": "#cccccc", - "descriptionTextColor": "#aaaaaa", - "currentComicTextColor": "#aaaaaa", - "coversViewBackgroundColor": "#3a3a3a", - "coversLabelColor": "#aaaaaa", "coversDecorationBgColor": "#3a3a3a", "coversDecorationShadowColor": "#1a1a1a", - "modeIconColor": "#4a4a4a", + "coversLabelColor": "#aaaaaa", + "coversViewBackgroundColor": "#3a3a3a", + "currentComicTextColor": "#aaaaaa", + "descriptionTextColor": "#aaaaaa", + "iconCheckedColor": "#aaaaaa", "iconColor": "#cccccc", - "iconCheckedColor": "#aaaaaa" + "modeIconColor": "#4a4a4a", + "titleTextColor": "#cccccc" }, - "serverConfigDialog": { - "backgroundColor": "#2a2a2a", - "titleTextColor": "#d0d0d0", - "qrMessageTextColor": "#a3a3a3", - "propagandaTextColor": "#b0b0b0", - "labelTextColor": "#c0c0c0", - "checkBoxTextColor": "#dddddd", - "qrBackgroundColor": "#2a2a2a", - "qrForegroundColor": "#ffffff", - "decorationColor": "#f7f7f7" + "libraryItem": { + "libraryIconColor": "#dddfdf", + "libraryIconSelectedColor": "#ffffff", + "libraryIconShadowColor": "#000000", + "libraryOptionsIconColor": "#ffffff", + "selectedBackgroundColor": "#2e2e2e", + "selectedTextColor": "#ffffff", + "textColor": "#dddfdf" }, "mainToolbar": { "backgroundColor": "#2a2a2a", - "folderNameColor": "#dddddd", "dividerColor": "#555555", + "folderNameColor": "#dddddd", "iconColor": "#dddddd", "iconDisabledColor": "#666666" }, - "contentSplitter": { - "handleColor": "#1f1f1f", - "horizontalHandleHeight": 4, - "verticalHandleWidth": 4 + "menuIcons": { + "iconColor": "#f7f7f7" + }, + "meta": { + "displayName": "Default Dark", + "id": "builtin/dark", + "variant": "dark" + }, + "metadataScraperDialog": { + "busyIndicatorColor": "#ffffff", + "buttonBackgroundColor": "#2e2e2e", + "buttonBorderColor": "#242424", + "buttonTextColor": "#ffffff", + "checkBoxTickColor": "#ffffff", + "contentAltBackgroundColor": "#2e2e2e", + "contentBackgroundColor": "#2b2b2b", + "contentTextColor": "#ffffff", + "dialogBackgroundColor": "#404040", + "downArrowColor": "#9f9f9f", + "hyperlinkColor": "#ffcc00", + "labelBackgroundColor": "#2b2b2b", + "labelTextColor": "#ffffff", + "navIconColor": "#ffffff", + "radioCheckedBackgroundColor": "#e5e5e5", + "radioCheckedIndicatorColor": "#5f5f5f", + "radioUncheckedColor": "#e5e5e5", + "rowIconColor": "#e5e5e5", + "tableAltBackgroundColor": "#2e2e2e", + "tableBackgroundColor": "#2b2b2b", + "tableBorderColor": "#242424", + "tableHeaderBackgroundColor": "#292929", + "tableHeaderBorderColor": "#1f1f1f", + "tableHeaderGradientColor": "#292929", + "tableHeaderTextColor": "#ebebeb", + "tableScrollBackgroundColor": "#404040", + "tableScrollHandleColor": "#dddddd", + "tableSectionBorderDark": "#dfdfdf", + "tableSectionBorderLight": "#fefefe", + "tableSelectedColor": "#555555", + "toolButtonAccentColor": "#282828", + "upArrowColor": "#9f9f9f" }, "navigationTree": { - "textColor": "#dddfdf", - "selectionBackgroundColor": "#2e2e2e", - "scrollBackgroundColor": "#404040", - "scrollHandleColor": "#dddddd", - "selectedTextColor": "#ffffff", - "folderIndicatorColor": "#edc518", "branchIndicatorColor": "#e0e0e0", "branchIndicatorSelectedColor": "#ffffff", "folderIconColor": "#e0e0e0", - "folderIconShadowColor": "#000000", "folderIconSelectedColor": "#e0e0e0", "folderIconSelectedShadowColor": "#000000", + "folderIconShadowColor": "#000000", + "folderIndicatorColor": "#edc518", "folderReadOverlayColor": "#222222", - "folderReadOverlaySelectedColor": "#222222" - }, - "comicsViewTable": { - "alternateBackgroundColor": "#2e2e2e", - "backgroundColor": "#2a2a2a", - "headerBackgroundColor": "#2a2a2a", - "headerBorderColor": "#1f1f1f", - "headerGradientColor": "#252525", - "itemBorderBottomColor": "#1f1f1f", - "itemBorderTopColor": "#353535", - "itemBorderBottomWidth": 1, - "itemBorderTopWidth": 1, - "itemTextColor": "#dddddd", - "selectedColor": "#555555", + "folderReadOverlaySelectedColor": "#222222", + "scrollBackgroundColor": "#404040", + "scrollHandleColor": "#dddddd", "selectedTextColor": "#ffffff", - "headerTextColor": "#dddddd", - "starRatingColor": "#e9be0f", - "starRatingSelectedColor": "#ffffff" - }, - "gridAndInfoView": { - "backgroundColor": "#2a2a2a", - "cellColor": "#212121", - "cellColorWithBackground": "#99212121", - "selectedColor": "#121212", - "selectedBorderColor": "#ffcc00", - "borderColor": "#121212", - "titleColor": "#ffffff", - "textColor": "#a8a8a8", - "showDropShadow": true, - "infoBackgroundColor": "#2e2e2e", - "infoBorderColor": "#404040", - "infoShadowColor": "#000000", - "infoTextColor": "#b0b0b0", - "infoTitleColor": "#ffffff", - "ratingUnselectedColor": "#1c1c1c", - "ratingSelectedColor": "#ffffff", - "favUncheckedColor": "#1c1c1c", - "favCheckedColor": "#e84852", - "readTickUncheckedColor": "#1c1c1c", - "readTickCheckedColor": "#e84852", - "currentComicBackgroundColor": "#88000000", - "continueReadingBackgroundColor": "#88000000", - "continueReadingColor": "#ffffff", - "backgroundBlurOverlayColor": "#2a2a2a" - }, - "comicsViewToolbar": { - "backgroundColor": "#2a2a2a", - "separatorColor": "#444444", - "checkedBackgroundColor": "#555555", - "iconColor": "#dddddd" - }, - "searchLineEdit": { - "textColor": "#ababab", - "backgroundColor": "#404040", - "iconColor": "#f7f7f7" + "selectionBackgroundColor": "#2e2e2e", + "textColor": "#dddfdf" }, "readingListIcons": { + "currentlyReadingMainColor": "#ffcc00", + "currentlyReadingMainSelectedColor": "#ffcc00", + "currentlyReadingOuterColor": "#000000", + "currentlyReadingOuterSelectedColor": "#000000", + "favoritesMainColor": "#e15055", + "favoritesMainSelectedColor": "#e15055", "labelColors": { - "red": "#f67a7b", - "orange": "#f5c240", - "yellow": "#f2e446", - "green": "#ade738", - "cyan": "#a0fddb", "blue": "#82c7ff", - "violet": "#8f95ff", - "purple": "#d692fc", + "cyan": "#a0fddb", + "dark": "#b7b7b7", + "green": "#ade738", + "light": "#cbcbcb", + "orange": "#f5c240", "pink": "#fd9cda", + "purple": "#d692fc", + "red": "#f67a7b", + "violet": "#8f95ff", "white": "#fcfcfc", - "light": "#cbcbcb", - "dark": "#b7b7b7" + "yellow": "#f2e446" }, "labelShadowColor": "#000000", "labelShadowSelectedColor": "#000000", - "readingListMainColor": "#e7e7e7", - "readingListMainSelectedColor": "#e7e7e7", - "favoritesMainColor": "#e15055", - "favoritesMainSelectedColor": "#e15055", - "currentlyReadingMainColor": "#ffcc00", - "currentlyReadingMainSelectedColor": "#ffcc00", - "currentlyReadingOuterColor": "#000000", - "currentlyReadingOuterSelectedColor": "#000000", - "specialListShadowColor": "#000000", - "specialListShadowSelectedColor": "#000000", + "listDetailColor": "#464646", + "listDetailSelectedColor": "#464646", "listMainColor": "#e7e7e7", "listMainSelectedColor": "#e7e7e7", "listShadowColor": "#000000", "listShadowSelectedColor": "#000000", - "listDetailColor": "#464646", - "listDetailSelectedColor": "#464646" + "readingListMainColor": "#e7e7e7", + "readingListMainSelectedColor": "#e7e7e7", + "specialListShadowColor": "#000000", + "specialListShadowSelectedColor": "#000000" }, - "dialogIcons": { - "iconColor": "#f7f7f7" + "searchLineEdit": { + "backgroundColor": "#404040", + "iconColor": "#f7f7f7", + "textColor": "#ababab" }, - "menuIcons": { - "iconColor": "#f7f7f7" + "serverConfigDialog": { + "backgroundColor": "#2a2a2a", + "checkBoxTextColor": "#dddddd", + "decorationColor": "#f7f7f7", + "labelTextColor": "#c0c0c0", + "propagandaTextColor": "#b0b0b0", + "qrBackgroundColor": "#2a2a2a", + "qrForegroundColor": "#ffffff", + "qrMessageTextColor": "#a3a3a3", + "titleTextColor": "#d0d0d0" }, "shortcutsIcons": { "iconColor": "#f7f7f7" + }, + "sidebar": { + "backgroundColor": "#454545", + "busyIndicatorColor": "#ffffff", + "sectionSeparatorColor": "#575757", + "separatorColor": "#bdbfbf", + "titleDropShadowColor": "#000000", + "titleTextColor": "#bdbfbf", + "uppercaseLabels": true + }, + "sidebarIcons": { + "iconColor": "#e0e0e0", + "shadowColor": "#000000", + "useSystemFolderIcons": false + }, + "whatsNewDialog": { + "backgroundColor": "#2a2a2a", + "closeButtonColor": "#dddddd", + "contentTextColor": "#e0e0e0", + "headerDecorationColor": "#e8b800", + "headerTextColor": "#e0e0e0", + "linkColor": "#e8b800", + "versionTextColor": "#858585" } } diff --git a/YACReaderLibrary/themes/builtin_light.json b/YACReaderLibrary/themes/builtin_light.json index f1cf40e40..9d514d4be 100644 --- a/YACReaderLibrary/themes/builtin_light.json +++ b/YACReaderLibrary/themes/builtin_light.json @@ -1,237 +1,237 @@ { - "meta": { - "id": "builtin/light", - "displayName": "Default Light", - "variant": "light" - }, "comicFlow": { "backgroundColor": "#dcdcdc", "textColor": "#303030" }, - "metadataScraperDialog": { - "contentTextColor": "#000000", - "contentBackgroundColor": "#ececec", - "contentAltBackgroundColor": "#e0e0e0", - "dialogBackgroundColor": "#fbfbfb", - "tableBackgroundColor": "#f4f4f4", - "tableAltBackgroundColor": "#fafafa", - "tableBorderColor": "#cccccc", - "tableSelectedColor": "#dddddd", - "tableHeaderBackgroundColor": "#e0e0e0", - "tableHeaderGradientColor": "#e0e0e0", - "tableHeaderBorderColor": "#c0c0c0", - "tableHeaderTextColor": "#333333", - "tableScrollHandleColor": "#888888", - "tableScrollBackgroundColor": "#d0d0d0", - "tableSectionBorderLight": "#ffffff", - "tableSectionBorderDark": "#cccccc", - "labelTextColor": "#000000", - "labelBackgroundColor": "#ececec", - "hyperlinkColor": "#ffcc00", - "buttonBackgroundColor": "#e0e0e0", - "buttonTextColor": "#000000", - "buttonBorderColor": "#cccccc", - "radioUncheckedColor": "#e0e0e0", - "radioCheckedBackgroundColor": "#e0e0e0", - "radioCheckedIndicatorColor": "#222222", - "checkBoxTickColor": "#000000", - "toolButtonAccentColor": "#a0a0a0", - "downArrowColor": "#222222", - "upArrowColor": "#222222", - "busyIndicatorColor": "#000000", - "navIconColor": "#222222", - "rowIconColor": "#222222" + "comicsViewTable": { + "alternateBackgroundColor": "#f2f2f2", + "backgroundColor": "#fafafa", + "headerBackgroundColor": "#f5f5f5", + "headerBorderColor": "#b8bdc4", + "headerGradientColor": "#f5f5f5", + "headerTextColor": "#313232", + "itemBorderBottomColor": "#dfdfdf", + "itemBorderBottomWidth": 0, + "itemBorderTopColor": "#fefefe", + "itemBorderTopWidth": 0, + "itemTextColor": "#252626", + "selectedColor": "#595959", + "selectedTextColor": "#ffffff", + "starRatingColor": "#e9be0f", + "starRatingSelectedColor": "#ffffff" }, - "helpAboutDialog": { - "headingColor": "#302f2d", - "linkColor": "#c19441" + "comicsViewToolbar": { + "backgroundColor": "#f0f0f0", + "checkedBackgroundColor": "#cccccc", + "iconColor": "#404040", + "separatorColor": "#cccccc" }, - "whatsNewDialog": { - "backgroundColor": "#ffffff", - "headerTextColor": "#0a0a0a", - "versionTextColor": "#858585", - "contentTextColor": "#0a0a0a", - "linkColor": "#e8b800", - "closeButtonColor": "#444444", - "headerDecorationColor": "#e8b800" + "contentSplitter": { + "handleColor": "#f0f0f0", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "dialogIcons": { + "iconColor": "#606060" }, "emptyContainer": { "backgroundColor": "#ffffff", - "titleTextColor": "#888888", - "textColor": "#495252", "descriptionTextColor": "#565959", - "searchIconColor": "#cccccc" - }, - "sidebar": { - "backgroundColor": "#fbfbfb", - "separatorColor": "#808080", - "sectionSeparatorColor": "#e0e0e0", - "uppercaseLabels": true, - "titleTextColor": "#4a494a", - "titleDropShadowColor": "#ffffff", - "busyIndicatorColor": "#808080" + "searchIconColor": "#cccccc", + "textColor": "#495252", + "titleTextColor": "#888888" }, - "sidebarIcons": { - "iconColor": "#4f4e4f", - "shadowColor": "#fbfbfb", - "useSystemFolderIcons": false + "gridAndInfoView": { + "backgroundBlurOverlayColor": "#9e9e9e", + "backgroundColor": "#f6f6f6", + "borderColor": "#dbdbdb", + "cellColor": "#ffffff", + "cellColorWithBackground": "#99ffffff", + "continueReadingBackgroundColor": "#e8e8e8", + "continueReadingColor": "#000000", + "currentComicBackgroundColor": "#88ffffff", + "favCheckedColor": "#e84852", + "favUncheckedColor": "#dedede", + "infoBackgroundColor": "#ffffff", + "infoBorderColor": "#808080", + "infoShadowColor": "#444444", + "infoTextColor": "#404040", + "infoTitleColor": "#2e2e2e", + "ratingSelectedColor": "#2b2b2b", + "ratingUnselectedColor": "#dedede", + "readTickCheckedColor": "#e84852", + "readTickUncheckedColor": "#dedede", + "selectedBorderColor": "#ffcc00", + "selectedColor": "#ffffff", + "showDropShadow": true, + "textColor": "#636363", + "titleColor": "#121212" }, - "libraryItem": { - "textColor": "#000000", - "libraryIconColor": "#606060", - "libraryIconShadowColor": "#ffffff", - "selectedTextColor": "#ffffff", - "selectedBackgroundColor": "#333133", - "libraryIconSelectedColor": "#ffffff", - "libraryOptionsIconColor": "#ffffff" + "helpAboutDialog": { + "headingColor": "#302f2d", + "linkColor": "#c19441" }, "importWidget": { "backgroundColor": "#fafafa", - "titleTextColor": "#495252", - "descriptionTextColor": "#565959", - "currentComicTextColor": "#565959", - "coversViewBackgroundColor": "#e6e6e6", - "coversLabelColor": "#565959", "coversDecorationBgColor": "#e6e6e6", "coversDecorationShadowColor": "#a1a1a1", - "modeIconColor": "#e6e6e6", + "coversLabelColor": "#565959", + "coversViewBackgroundColor": "#e6e6e6", + "currentComicTextColor": "#565959", + "descriptionTextColor": "#565959", + "iconCheckedColor": "#565959", "iconColor": "#495252", - "iconCheckedColor": "#565959" + "modeIconColor": "#e6e6e6", + "titleTextColor": "#495252" }, - "serverConfigDialog": { - "backgroundColor": "#ffffff", - "titleTextColor": "#474747", - "qrMessageTextColor": "#a3a3a3", - "propagandaTextColor": "#4d4d4d", - "labelTextColor": "#575757", - "checkBoxTextColor": "#262626", - "qrBackgroundColor": "#ffffff", - "qrForegroundColor": "#606060", - "decorationColor": "#606060" + "libraryItem": { + "libraryIconColor": "#606060", + "libraryIconSelectedColor": "#ffffff", + "libraryIconShadowColor": "#ffffff", + "libraryOptionsIconColor": "#ffffff", + "selectedBackgroundColor": "#333133", + "selectedTextColor": "#ffffff", + "textColor": "#000000" }, "mainToolbar": { "backgroundColor": "#f0f0f0", - "folderNameColor": "#333133", "dividerColor": "#b8bdc4", + "folderNameColor": "#333133", "iconColor": "#333133", "iconDisabledColor": "#b0b0b0" }, - "contentSplitter": { - "handleColor": "#f0f0f0", - "horizontalHandleHeight": 4, - "verticalHandleWidth": 4 + "menuIcons": { + "iconColor": "#606060" + }, + "meta": { + "displayName": "Default Light", + "id": "builtin/light", + "variant": "light" + }, + "metadataScraperDialog": { + "busyIndicatorColor": "#000000", + "buttonBackgroundColor": "#e0e0e0", + "buttonBorderColor": "#cccccc", + "buttonTextColor": "#000000", + "checkBoxTickColor": "#000000", + "contentAltBackgroundColor": "#e0e0e0", + "contentBackgroundColor": "#ececec", + "contentTextColor": "#000000", + "dialogBackgroundColor": "#fbfbfb", + "downArrowColor": "#222222", + "hyperlinkColor": "#ffcc00", + "labelBackgroundColor": "#ececec", + "labelTextColor": "#000000", + "navIconColor": "#222222", + "radioCheckedBackgroundColor": "#e0e0e0", + "radioCheckedIndicatorColor": "#222222", + "radioUncheckedColor": "#e0e0e0", + "rowIconColor": "#222222", + "tableAltBackgroundColor": "#fafafa", + "tableBackgroundColor": "#f4f4f4", + "tableBorderColor": "#cccccc", + "tableHeaderBackgroundColor": "#e0e0e0", + "tableHeaderBorderColor": "#c0c0c0", + "tableHeaderGradientColor": "#e0e0e0", + "tableHeaderTextColor": "#333333", + "tableScrollBackgroundColor": "#d0d0d0", + "tableScrollHandleColor": "#888888", + "tableSectionBorderDark": "#cccccc", + "tableSectionBorderLight": "#ffffff", + "tableSelectedColor": "#dddddd", + "toolButtonAccentColor": "#a0a0a0", + "upArrowColor": "#222222" }, "navigationTree": { - "textColor": "#000000", - "selectionBackgroundColor": "#333133", - "scrollBackgroundColor": "#e0e0e0", - "scrollHandleColor": "#888888", - "selectedTextColor": "#ffffff", - "folderIndicatorColor": "#555f7f", "branchIndicatorColor": "#606060", "branchIndicatorSelectedColor": "#ffffff", "folderIconColor": "#606060", - "folderIconShadowColor": "#ffffff", "folderIconSelectedColor": "#ffffff", "folderIconSelectedShadowColor": "#161616", + "folderIconShadowColor": "#ffffff", + "folderIndicatorColor": "#555f7f", "folderReadOverlayColor": "#ffffff", - "folderReadOverlaySelectedColor": "#161616" - }, - "comicsViewTable": { - "alternateBackgroundColor": "#f2f2f2", - "backgroundColor": "#fafafa", - "headerBackgroundColor": "#f5f5f5", - "headerBorderColor": "#b8bdc4", - "headerGradientColor": "#f5f5f5", - "itemBorderBottomColor": "#dfdfdf", - "itemBorderTopColor": "#fefefe", - "itemBorderBottomWidth": 0, - "itemBorderTopWidth": 0, - "itemTextColor": "#252626", - "selectedColor": "#595959", + "folderReadOverlaySelectedColor": "#161616", + "scrollBackgroundColor": "#e0e0e0", + "scrollHandleColor": "#888888", "selectedTextColor": "#ffffff", - "headerTextColor": "#313232", - "starRatingColor": "#e9be0f", - "starRatingSelectedColor": "#ffffff" - }, - "gridAndInfoView": { - "backgroundColor": "#f6f6f6", - "cellColor": "#ffffff", - "cellColorWithBackground": "#99ffffff", - "selectedColor": "#ffffff", - "selectedBorderColor": "#ffcc00", - "borderColor": "#dbdbdb", - "titleColor": "#121212", - "textColor": "#636363", - "showDropShadow": true, - "infoBackgroundColor": "#ffffff", - "infoBorderColor": "#808080", - "infoShadowColor": "#444444", - "infoTextColor": "#404040", - "infoTitleColor": "#2e2e2e", - "ratingUnselectedColor": "#dedede", - "ratingSelectedColor": "#2b2b2b", - "favUncheckedColor": "#dedede", - "favCheckedColor": "#e84852", - "readTickUncheckedColor": "#dedede", - "readTickCheckedColor": "#e84852", - "currentComicBackgroundColor": "#88ffffff", - "continueReadingBackgroundColor": "#e8e8e8", - "continueReadingColor": "#000000", - "backgroundBlurOverlayColor": "#9e9e9e" - }, - "comicsViewToolbar": { - "backgroundColor": "#f0f0f0", - "separatorColor": "#cccccc", - "checkedBackgroundColor": "#cccccc", - "iconColor": "#404040" - }, - "searchLineEdit": { - "textColor": "#ffffff", - "backgroundColor": "#333133", - "iconColor": "#efefef" + "selectionBackgroundColor": "#333133", + "textColor": "#000000" }, "readingListIcons": { + "currentlyReadingMainColor": "#ffcc00", + "currentlyReadingMainSelectedColor": "#ffcc00", + "currentlyReadingOuterColor": "#000000", + "currentlyReadingOuterSelectedColor": "#000000", + "favoritesMainColor": "#e15055", + "favoritesMainSelectedColor": "#e15055", "labelColors": { - "red": "#f67a7b", - "orange": "#f5c240", - "yellow": "#f2e446", - "green": "#ade738", - "cyan": "#a0fddb", "blue": "#82c7ff", - "violet": "#8f95ff", - "purple": "#d692fc", + "cyan": "#a0fddb", + "dark": "#b7b7b7", + "green": "#ade738", + "light": "#cbcbcb", + "orange": "#f5c240", "pink": "#fd9cda", + "purple": "#d692fc", + "red": "#f67a7b", + "violet": "#8f95ff", "white": "#fcfcfc", - "light": "#cbcbcb", - "dark": "#b7b7b7" + "yellow": "#f2e446" }, "labelShadowColor": "#8f8f8f", "labelShadowSelectedColor": "#161616", - "readingListMainColor": "#808080", - "readingListMainSelectedColor": "#808080", - "favoritesMainColor": "#e15055", - "favoritesMainSelectedColor": "#e15055", - "currentlyReadingMainColor": "#ffcc00", - "currentlyReadingMainSelectedColor": "#ffcc00", - "currentlyReadingOuterColor": "#000000", - "currentlyReadingOuterSelectedColor": "#000000", - "specialListShadowColor": "#8f8f8f", - "specialListShadowSelectedColor": "#161616", + "listDetailColor": "#ffffff", + "listDetailSelectedColor": "#161616", "listMainColor": "#808080", "listMainSelectedColor": "#ffffff", "listShadowColor": "#8f8f8f", "listShadowSelectedColor": "#161616", - "listDetailColor": "#ffffff", - "listDetailSelectedColor": "#161616" + "readingListMainColor": "#808080", + "readingListMainSelectedColor": "#808080", + "specialListShadowColor": "#8f8f8f", + "specialListShadowSelectedColor": "#161616" }, - "dialogIcons": { - "iconColor": "#606060" + "searchLineEdit": { + "backgroundColor": "#333133", + "iconColor": "#efefef", + "textColor": "#ffffff" }, - "menuIcons": { - "iconColor": "#606060" + "serverConfigDialog": { + "backgroundColor": "#ffffff", + "checkBoxTextColor": "#262626", + "decorationColor": "#606060", + "labelTextColor": "#575757", + "propagandaTextColor": "#4d4d4d", + "qrBackgroundColor": "#ffffff", + "qrForegroundColor": "#606060", + "qrMessageTextColor": "#a3a3a3", + "titleTextColor": "#474747" }, "shortcutsIcons": { "iconColor": "#606060" + }, + "sidebar": { + "backgroundColor": "#fbfbfb", + "busyIndicatorColor": "#808080", + "sectionSeparatorColor": "#e0e0e0", + "separatorColor": "#808080", + "titleDropShadowColor": "#ffffff", + "titleTextColor": "#4a494a", + "uppercaseLabels": true + }, + "sidebarIcons": { + "iconColor": "#4f4e4f", + "shadowColor": "#fbfbfb", + "useSystemFolderIcons": false + }, + "whatsNewDialog": { + "backgroundColor": "#ffffff", + "closeButtonColor": "#444444", + "contentTextColor": "#0a0a0a", + "headerDecorationColor": "#e8b800", + "headerTextColor": "#0a0a0a", + "linkColor": "#e8b800", + "versionTextColor": "#858585" } } From 5058f47a20c65a774e545500fcbf338e4a10d274 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Wed, 4 Mar 2026 17:51:35 +0100 Subject: [PATCH 113/187] Tweak default dark YACReaderLibrary theme --- YACReaderLibrary/themes/builtin_dark.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/YACReaderLibrary/themes/builtin_dark.json b/YACReaderLibrary/themes/builtin_dark.json index 45fbcc64b..6a9a7a281 100644 --- a/YACReaderLibrary/themes/builtin_dark.json +++ b/YACReaderLibrary/themes/builtin_dark.json @@ -4,16 +4,16 @@ "textColor": "#888888" }, "comicsViewTable": { - "alternateBackgroundColor": "#2e2e2e", - "backgroundColor": "#2a2a2a", + "alternateBackgroundColor": "#2c2c2c", + "backgroundColor": "#232323", "headerBackgroundColor": "#2a2a2a", "headerBorderColor": "#1f1f1f", "headerGradientColor": "#252525", "headerTextColor": "#dddddd", "itemBorderBottomColor": "#1f1f1f", - "itemBorderBottomWidth": 1, + "itemBorderBottomWidth": 0, "itemBorderTopColor": "#353535", - "itemBorderTopWidth": 1, + "itemBorderTopWidth": 0, "itemTextColor": "#dddddd", "selectedColor": "#555555", "selectedTextColor": "#ffffff", @@ -21,7 +21,7 @@ "starRatingSelectedColor": "#ffffff" }, "comicsViewToolbar": { - "backgroundColor": "#2a2a2a", + "backgroundColor": "#1f1f1f", "checkedBackgroundColor": "#555555", "iconColor": "#dddddd", "separatorColor": "#444444" @@ -49,7 +49,7 @@ "cellColorWithBackground": "#99212121", "continueReadingBackgroundColor": "#88000000", "continueReadingColor": "#ffffff", - "currentComicBackgroundColor": "#88000000", + "currentComicBackgroundColor": "#55000000", "favCheckedColor": "#e84852", "favUncheckedColor": "#1c1c1c", "infoBackgroundColor": "#2e2e2e", @@ -94,7 +94,7 @@ "textColor": "#dddfdf" }, "mainToolbar": { - "backgroundColor": "#2a2a2a", + "backgroundColor": "#1f1f1f", "dividerColor": "#555555", "folderNameColor": "#dddddd", "iconColor": "#dddddd", From 46661becaf0af3af7cd8c8b12d5cba2a665ce4b9 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 5 Mar 2026 08:22:04 +0100 Subject: [PATCH 114/187] Implement theme pickers + importing --- YACReader/options_dialog.cpp | 1 + YACReaderLibrary/options_dialog.cpp | 1 + common/themes/appearance_config_images.qrc | 1 + common/themes/appearance_tab_widget.cpp | 225 +++++++++++++++++- common/themes/appearance_tab_widget.h | 29 +++ common/themes/theme_manager.h | 1 + .../appearance_config/theme-mode-custom.svg | 36 +++ 7 files changed, 289 insertions(+), 5 deletions(-) create mode 100644 images/appearance_config/theme-mode-custom.svg diff --git a/YACReader/options_dialog.cpp b/YACReader/options_dialog.cpp index c39e71155..43f50e675 100644 --- a/YACReader/options_dialog.cpp +++ b/YACReader/options_dialog.cpp @@ -210,6 +210,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) auto *pageAppearance = new AppearanceTabWidget( ThemeManager::instance().getAppearanceConfiguration(), + ThemeManager::instance().getRepository(), []() { return ThemeManager::instance().getCurrentTheme().sourceJson; }, [](const QJsonObject &json) { ThemeManager::instance().setTheme(makeTheme(json)); }, this); diff --git a/YACReaderLibrary/options_dialog.cpp b/YACReaderLibrary/options_dialog.cpp index 1087d8ada..f2cdb4bf8 100644 --- a/YACReaderLibrary/options_dialog.cpp +++ b/YACReaderLibrary/options_dialog.cpp @@ -419,6 +419,7 @@ QWidget *OptionsDialog::createAppearanceTab() { return new AppearanceTabWidget( ThemeManager::instance().getAppearanceConfiguration(), + ThemeManager::instance().getRepository(), []() { return ThemeManager::instance().getCurrentTheme().sourceJson; }, [](const QJsonObject &json) { ThemeManager::instance().setTheme(makeTheme(json)); }, this); diff --git a/common/themes/appearance_config_images.qrc b/common/themes/appearance_config_images.qrc index 3284bda98..b67edae76 100644 --- a/common/themes/appearance_config_images.qrc +++ b/common/themes/appearance_config_images.qrc @@ -3,5 +3,6 @@ ../../images/appearance_config/theme-mode-system.svg ../../images/appearance_config/theme-mode-light.svg ../../images/appearance_config/theme-mode-dark.svg + ../../images/appearance_config/theme-mode-custom.svg diff --git a/common/themes/appearance_tab_widget.cpp b/common/themes/appearance_tab_widget.cpp index 8563fb055..9dcb49c26 100644 --- a/common/themes/appearance_tab_widget.cpp +++ b/common/themes/appearance_tab_widget.cpp @@ -2,39 +2,58 @@ #include "appearance_configuration.h" #include "theme_editor_dialog.h" +#include "theme_repository.h" #include +#include +#include #include #include +#include #include #include #include #include +// Select the item in combo whose UserRole data matches id (no-op if not found). +static void selectInCombo(QComboBox *combo, const QString &id) +{ + for (int i = 0; i < combo->count(); ++i) { + if (combo->itemData(i).toString() == id) { + combo->setCurrentIndex(i); + return; + } + } +} + AppearanceTabWidget::AppearanceTabWidget( AppearanceConfiguration *config, + ThemeRepository *repository, std::function currentThemeJson, std::function applyTheme, QWidget *parent) - : QWidget(parent), config(config), currentThemeJson(std::move(currentThemeJson)), applyTheme(std::move(applyTheme)) + : QWidget(parent), config(config), repository(repository), currentThemeJson(std::move(currentThemeJson)), applyTheme(std::move(applyTheme)) { - // Color scheme selector + // --- Color scheme selector --- auto *modeBox = new QGroupBox(tr("Color scheme"), this); auto *modeLayout = new QHBoxLayout(); auto *sysBtn = new QToolButton(); auto *lightBtn = new QToolButton(); auto *darkBtn = new QToolButton(); + auto *customBtn = new QToolButton(); sysBtn->setText(tr("System")); lightBtn->setText(tr("Light")); darkBtn->setText(tr("Dark")); + customBtn->setText(tr("Custom")); sysBtn->setIcon(QIcon(":/images/appearance_config/theme-mode-system.svg")); lightBtn->setIcon(QIcon(":/images/appearance_config/theme-mode-light.svg")); darkBtn->setIcon(QIcon(":/images/appearance_config/theme-mode-dark.svg")); + customBtn->setIcon(QIcon(":/images/appearance_config/theme-mode-custom.svg")); - for (auto *btn : { sysBtn, lightBtn, darkBtn }) { + for (auto *btn : { sysBtn, lightBtn, darkBtn, customBtn }) { btn->setCheckable(true); btn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); btn->setIconSize(QSize(93, 58)); @@ -45,6 +64,7 @@ AppearanceTabWidget::AppearanceTabWidget( modeGroup->addButton(sysBtn, static_cast(ThemeMode::FollowSystem)); modeGroup->addButton(lightBtn, static_cast(ThemeMode::Light)); modeGroup->addButton(darkBtn, static_cast(ThemeMode::Dark)); + modeGroup->addButton(customBtn, static_cast(ThemeMode::ForcedTheme)); modeGroup->setExclusive(true); if (this->config) { @@ -54,18 +74,102 @@ AppearanceTabWidget::AppearanceTabWidget( } connect(modeGroup, &QButtonGroup::idClicked, this, [this](int id) { - if (this->config) + if (this->config) { this->config->setMode(static_cast(id)); + updateModeRows(); + } }); modeLayout->addStretch(); modeLayout->addWidget(sysBtn); modeLayout->addWidget(lightBtn); modeLayout->addWidget(darkBtn); + modeLayout->addWidget(customBtn); modeLayout->addStretch(); modeBox->setLayout(modeLayout); - // Theme editor + // --- Theme selection --- + // Each row: [label fixed] [combo expanding] [Remove btn] + // Rows are shown/hidden based on mode — only relevant ones are visible. + auto makeRow = [](const QString &label, QComboBox *&combo, QPushButton *&deleteBtn) { + auto *row = new QWidget(); + auto *hl = new QHBoxLayout(row); + hl->setContentsMargins(0, 0, 0, 0); + + auto *lbl = new QLabel(label); + lbl->setFixedWidth(52); + + combo = new QComboBox(); + combo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + deleteBtn = new QPushButton(tr("Remove")); + deleteBtn->setEnabled(false); + deleteBtn->setToolTip(tr("Remove this user-imported theme")); + + hl->addWidget(lbl); + hl->addWidget(combo); + hl->addWidget(deleteBtn); + return row; + }; + + lightRow = makeRow(tr("Light:"), lightCombo, lightDeleteBtn); + darkRow = makeRow(tr("Dark:"), darkCombo, darkDeleteBtn); + customRow = makeRow(tr("Custom:"), customCombo, customDeleteBtn); + + auto *importBtn = new QPushButton(tr("Import theme...")); + + auto *themeSelBox = new QGroupBox(tr("Theme"), this); + auto *themeSelLayout = new QVBoxLayout(); + themeSelLayout->addWidget(lightRow); + themeSelLayout->addWidget(darkRow); + themeSelLayout->addWidget(customRow); + themeSelLayout->addWidget(importBtn, 0, Qt::AlignRight); + themeSelBox->setLayout(themeSelLayout); + + // Populate combos and set initial row visibility + if (this->config && this->repository) { + const auto &sel = this->config->selection(); + populateCombo(lightCombo, ThemeVariant::Light, sel.lightThemeId); + populateCombo(darkCombo, ThemeVariant::Dark, sel.darkThemeId); + populateCombo(customCombo, std::nullopt, sel.fixedThemeId); + updateDeleteButton(lightCombo, lightDeleteBtn); + updateDeleteButton(darkCombo, darkDeleteBtn); + updateDeleteButton(customCombo, customDeleteBtn); + updateModeRows(); + } + + // Combo selection → update config (live theme preview via selectionChanged chain) + connect(lightCombo, &QComboBox::currentIndexChanged, this, [this](int) { + if (!this->config) + return; + this->config->setLightThemeId(lightCombo->currentData().toString()); + updateDeleteButton(lightCombo, lightDeleteBtn); + }); + connect(darkCombo, &QComboBox::currentIndexChanged, this, [this](int) { + if (!this->config) + return; + this->config->setDarkThemeId(darkCombo->currentData().toString()); + updateDeleteButton(darkCombo, darkDeleteBtn); + }); + connect(customCombo, &QComboBox::currentIndexChanged, this, [this](int) { + if (!this->config) + return; + this->config->setFixedThemeId(customCombo->currentData().toString()); + updateDeleteButton(customCombo, customDeleteBtn); + }); + + // Delete buttons + connect(lightDeleteBtn, &QPushButton::clicked, this, + [this]() { deleteTheme(lightCombo, lightDeleteBtn); }); + connect(darkDeleteBtn, &QPushButton::clicked, this, + [this]() { deleteTheme(darkCombo, darkDeleteBtn); }); + connect(customDeleteBtn, &QPushButton::clicked, this, + [this]() { deleteTheme(customCombo, customDeleteBtn); }); + + // Import + connect(importBtn, &QPushButton::clicked, this, &AppearanceTabWidget::importTheme); + + // --- Theme editor --- auto *themeEditorBox = new QGroupBox(tr("Theme editor"), this); auto *themeEditorLayout = new QVBoxLayout(); auto *openBtn = new QPushButton(tr("Open Theme Editor...")); @@ -93,6 +197,117 @@ AppearanceTabWidget::AppearanceTabWidget( auto *layout = new QVBoxLayout(this); layout->addWidget(modeBox); + layout->addWidget(themeSelBox); layout->addWidget(themeEditorBox); layout->addStretch(); } + +void AppearanceTabWidget::populateCombo(QComboBox *combo, + std::optional variantFilter, + const QString &selectedId) +{ + QSignalBlocker blocker(combo); + combo->clear(); + if (!repository) + return; + + for (const auto &entry : repository->availableThemes()) { + if (variantFilter && entry.variant != *variantFilter) + continue; + combo->addItem(entry.displayName, entry.id); + } + + // Restore selection; fall back to first item if the saved ID is no longer present + for (int i = 0; i < combo->count(); ++i) { + if (combo->itemData(i).toString() == selectedId) { + combo->setCurrentIndex(i); + return; + } + } + if (combo->count() > 0) + combo->setCurrentIndex(0); +} + +void AppearanceTabWidget::repopulateCombos() +{ + if (!config) + return; + const auto &sel = config->selection(); + populateCombo(lightCombo, ThemeVariant::Light, sel.lightThemeId); + populateCombo(darkCombo, ThemeVariant::Dark, sel.darkThemeId); + populateCombo(customCombo, std::nullopt, sel.fixedThemeId); + updateDeleteButton(lightCombo, lightDeleteBtn); + updateDeleteButton(darkCombo, darkDeleteBtn); + updateDeleteButton(customCombo, customDeleteBtn); +} + +void AppearanceTabWidget::updateDeleteButton(QComboBox *combo, QPushButton *btn) +{ + const QString id = combo->currentData().toString(); + btn->setEnabled(!id.isEmpty() && id.startsWith(QLatin1String("user/"))); +} + +void AppearanceTabWidget::updateModeRows() +{ + if (!config) + return; + const auto mode = config->selection().mode; + lightRow->setVisible(mode == ThemeMode::FollowSystem || mode == ThemeMode::Light); + darkRow->setVisible(mode == ThemeMode::FollowSystem || mode == ThemeMode::Dark); + customRow->setVisible(mode == ThemeMode::ForcedTheme); +} + +void AppearanceTabWidget::importTheme() +{ + const QString path = QFileDialog::getOpenFileName( + this, tr("Import theme"), QString(), tr("JSON files (*.json);;All files (*)")); + if (path.isEmpty() || !repository) + return; + + const QString id = repository->importThemeFromFile(path); + if (id.isEmpty()) { + QMessageBox::warning(this, tr("Import failed"), + tr("Could not import theme from:\n%1").arg(path)); + return; + } + + // Detect variant of the imported theme to auto-select it in the right combo + const QJsonObject json = repository->loadThemeJson(id); + const bool isLight = (json["meta"].toObject()["variant"].toString() == "light"); + + repopulateCombos(); + + // Select in the appropriate combo → triggers currentIndexChanged → config update + if (isLight) + selectInCombo(lightCombo, id); + else + selectInCombo(darkCombo, id); + + // If in Custom mode, also select in customCombo + if (config && config->selection().mode == ThemeMode::ForcedTheme) + selectInCombo(customCombo, id); +} + +void AppearanceTabWidget::deleteTheme(QComboBox *combo, QPushButton *deleteBtn) +{ + if (!repository) + return; + const QString id = combo->currentData().toString(); + if (!id.startsWith(QLatin1String("user/"))) + return; + + repository->deleteUserTheme(id); + repopulateCombos(); + + // repopulateCombos() blocked signals; manually push the new selection into config + // so the theme resolves correctly (important when the deleted theme was active). + const QString newId = combo->currentData().toString(); + if (combo == lightCombo && config) + config->setLightThemeId(newId); + else if (combo == darkCombo && config) + config->setDarkThemeId(newId); + else if (combo == customCombo && config) + config->setFixedThemeId(newId); + + updateDeleteButton(combo, deleteBtn); +} diff --git a/common/themes/appearance_tab_widget.h b/common/themes/appearance_tab_widget.h index cbccb88bc..981950581 100644 --- a/common/themes/appearance_tab_widget.h +++ b/common/themes/appearance_tab_widget.h @@ -1,13 +1,19 @@ #ifndef APPEARANCE_TAB_WIDGET_H #define APPEARANCE_TAB_WIDGET_H +#include "theme_variant.h" + #include #include #include #include +#include class AppearanceConfiguration; +class QComboBox; +class QPushButton; class ThemeEditorDialog; +class ThemeRepository; class AppearanceTabWidget : public QWidget { @@ -15,15 +21,38 @@ class AppearanceTabWidget : public QWidget public: explicit AppearanceTabWidget( AppearanceConfiguration *config, + ThemeRepository *repository, std::function currentThemeJson, std::function applyTheme, QWidget *parent = nullptr); private: AppearanceConfiguration *config; + ThemeRepository *repository; std::function currentThemeJson; std::function applyTheme; QPointer themeEditor; + + // One row per picker; shown/hidden based on active mode + QWidget *lightRow = nullptr; + QWidget *darkRow = nullptr; + QWidget *customRow = nullptr; + + QComboBox *lightCombo = nullptr; + QComboBox *darkCombo = nullptr; + QComboBox *customCombo = nullptr; + + QPushButton *lightDeleteBtn = nullptr; + QPushButton *darkDeleteBtn = nullptr; + QPushButton *customDeleteBtn = nullptr; + + // Populate a combo with themes, filtered strictly by variant (or all if nullopt). + void populateCombo(QComboBox *combo, std::optional variantFilter, const QString &selectedId); + void repopulateCombos(); + void updateDeleteButton(QComboBox *combo, QPushButton *btn); + void updateModeRows(); + void importTheme(); + void deleteTheme(QComboBox *combo, QPushButton *deleteBtn); }; #endif // APPEARANCE_TAB_WIDGET_H diff --git a/common/themes/theme_manager.h b/common/themes/theme_manager.h index 42b8d0d0c..7ffbeea76 100644 --- a/common/themes/theme_manager.h +++ b/common/themes/theme_manager.h @@ -25,6 +25,7 @@ class ThemeManager : public QObject const Theme &getCurrentTheme() const { return currentTheme; } AppearanceConfiguration *getAppearanceConfiguration() const { return config; } + ThemeRepository *getRepository() const { return repository; } signals: void themeChanged(); diff --git a/images/appearance_config/theme-mode-custom.svg b/images/appearance_config/theme-mode-custom.svg new file mode 100644 index 000000000..227cd5da3 --- /dev/null +++ b/images/appearance_config/theme-mode-custom.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From df03b1c6b0000608ce67dd9cd7bdc81b0d835187 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 5 Mar 2026 09:48:21 +0100 Subject: [PATCH 115/187] Print clang-format version in CI --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d866bd151..d3ba5313d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,6 +45,9 @@ jobs: - name: Install dependencies run: brew install clang-format + - name: Print clang-format version + run: clang-format --version + - name: Run clang-format run: | find . \( -name '*.h' -or -name '*.cpp' -or -name '*.c' -or -name '*.mm' -or -name '*.m' \) -print0 | xargs -0 clang-format -style=file -i From d8678bcf95b71191cdde9a5b3ac307c163525d86 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 5 Mar 2026 10:54:03 +0100 Subject: [PATCH 116/187] Update .clang-format --- .clang-format | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.clang-format b/.clang-format index 61441ef66..d68fa440c 100644 --- a/.clang-format +++ b/.clang-format @@ -5,7 +5,8 @@ Standard: Cpp11 ColumnLimit: 0 # We want a space between the type and the star for pointer types. -PointerBindsToType: false +DerivePointerAlignment: false +PointerAlignment: Right # We use template< without space. SpaceAfterTemplateKeyword: false @@ -43,7 +44,7 @@ NamespaceIndentation: None # The coding style does not specify the following, but this is what gives # results closest to the existing code. AlignAfterOpenBracket: true -AlwaysBreakTemplateDeclarations: true +BreakTemplateDeclarations: Yes # Ideally we should also allow less short function in a single line, but # clang-format does not handle that. @@ -60,3 +61,6 @@ ForEachMacros: [ foreach, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENC # Break constructor initializers before the colon and after the commas. BreakConstructorInitializers: BeforeColon + +# Empty blocks should be {} +SpaceInEmptyBraces: Always From a876f339027e8b0387082b3e17b24b9f1e44e895 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 5 Mar 2026 10:54:41 +0100 Subject: [PATCH 117/187] Format --- YACReader/themes/theme_factory.cpp | 52 +++++++------- YACReaderLibrary/db/comic_model.cpp | 2 +- YACReaderLibrary/db/folder_model.cpp | 2 +- YACReaderLibrary/db/query_lexer.h | 4 +- YACReaderLibrary/db/query_parser.cpp | 10 +-- YACReaderLibrary/db/reading_list_model.cpp | 4 +- YACReaderLibrary/themes/theme_factory.cpp | 72 +++++++++---------- common/themes/icon_utils.cpp | 4 +- common/themes/icon_utils.h | 8 +-- common/themes/theme_editor_dialog.cpp | 4 +- common/themes/theme_manager.cpp | 2 +- common/themes/theme_repository.cpp | 8 +-- .../actions_shortcuts_model.cpp | 2 +- .../concurrent_queue_test.cpp | 10 +-- 14 files changed, 92 insertions(+), 92 deletions(-) diff --git a/YACReader/themes/theme_factory.cpp b/YACReader/themes/theme_factory.cpp index 7a19d4f85..a0cb207f3 100644 --- a/YACReader/themes/theme_factory.cpp +++ b/YACReader/themes/theme_factory.cpp @@ -231,11 +231,11 @@ Theme makeTheme(const QJsonObject &json) if (json.contains("toolbar")) { const auto t = json["toolbar"].toObject(); auto &tp = p.toolbarParams; - tp.iconColor = colorFromJson(t, "iconColor", tp.iconColor); - tp.iconDisabledColor = colorFromJson(t, "iconDisabledColor", tp.iconDisabledColor); - tp.iconCheckedColor = colorFromJson(t, "iconCheckedColor", tp.iconCheckedColor); - tp.backgroundColor = colorFromJson(t, "backgroundColor", tp.backgroundColor); - tp.separatorColor = colorFromJson(t, "separatorColor", tp.separatorColor); + tp.iconColor = colorFromJson(t, "iconColor", tp.iconColor); + tp.iconDisabledColor = colorFromJson(t, "iconDisabledColor", tp.iconDisabledColor); + tp.iconCheckedColor = colorFromJson(t, "iconCheckedColor", tp.iconCheckedColor); + tp.backgroundColor = colorFromJson(t, "backgroundColor", tp.backgroundColor); + tp.separatorColor = colorFromJson(t, "separatorColor", tp.separatorColor); tp.checkedButtonColor = colorFromJson(t, "checkedButtonColor", tp.checkedButtonColor); tp.menuIndicatorColor = colorFromJson(t, "menuIndicatorColor", tp.menuIndicatorColor); } @@ -244,43 +244,43 @@ Theme makeTheme(const QJsonObject &json) const auto v = json["viewer"].toObject(); auto &vp = p.viewerParams; vp.defaultBackgroundColor = colorFromJson(v, "defaultBackgroundColor", vp.defaultBackgroundColor); - vp.defaultTextColor = colorFromJson(v, "defaultTextColor", vp.defaultTextColor); - vp.infoBackgroundColor = colorFromJson(v, "infoBackgroundColor", vp.infoBackgroundColor); - vp.infoTextColor = colorFromJson(v, "infoTextColor", vp.infoTextColor); + vp.defaultTextColor = colorFromJson(v, "defaultTextColor", vp.defaultTextColor); + vp.infoBackgroundColor = colorFromJson(v, "infoBackgroundColor", vp.infoBackgroundColor); + vp.infoTextColor = colorFromJson(v, "infoTextColor", vp.infoTextColor); } if (json.contains("goToFlowWidget")) { const auto g = json["goToFlowWidget"].toObject(); auto &gp = p.goToFlowWidgetParams; - gp.flowBackgroundColor = colorFromJson(g, "flowBackgroundColor", gp.flowBackgroundColor); - gp.flowTextColor = colorFromJson(g, "flowTextColor", gp.flowTextColor); + gp.flowBackgroundColor = colorFromJson(g, "flowBackgroundColor", gp.flowBackgroundColor); + gp.flowTextColor = colorFromJson(g, "flowTextColor", gp.flowTextColor); gp.toolbarBackgroundColor = colorFromJson(g, "toolbarBackgroundColor", gp.toolbarBackgroundColor); - gp.sliderBorderColor = colorFromJson(g, "sliderBorderColor", gp.sliderBorderColor); - gp.sliderGrooveColor = colorFromJson(g, "sliderGrooveColor", gp.sliderGrooveColor); - gp.sliderHandleColor = colorFromJson(g, "sliderHandleColor", gp.sliderHandleColor); - gp.editBorderColor = colorFromJson(g, "editBorderColor", gp.editBorderColor); - gp.editBackgroundColor = colorFromJson(g, "editBackgroundColor", gp.editBackgroundColor); - gp.editTextColor = colorFromJson(g, "editTextColor", gp.editTextColor); - gp.labelTextColor = colorFromJson(g, "labelTextColor", gp.labelTextColor); - gp.iconColor = colorFromJson(g, "iconColor", gp.iconColor); + gp.sliderBorderColor = colorFromJson(g, "sliderBorderColor", gp.sliderBorderColor); + gp.sliderGrooveColor = colorFromJson(g, "sliderGrooveColor", gp.sliderGrooveColor); + gp.sliderHandleColor = colorFromJson(g, "sliderHandleColor", gp.sliderHandleColor); + gp.editBorderColor = colorFromJson(g, "editBorderColor", gp.editBorderColor); + gp.editBackgroundColor = colorFromJson(g, "editBackgroundColor", gp.editBackgroundColor); + gp.editTextColor = colorFromJson(g, "editTextColor", gp.editTextColor); + gp.labelTextColor = colorFromJson(g, "labelTextColor", gp.labelTextColor); + gp.iconColor = colorFromJson(g, "iconColor", gp.iconColor); } if (json.contains("helpAboutDialog")) { const auto h = json["helpAboutDialog"].toObject(); p.helpAboutDialogParams.headingColor = colorFromJson(h, "headingColor", p.helpAboutDialogParams.headingColor); - p.helpAboutDialogParams.linkColor = colorFromJson(h, "linkColor", p.helpAboutDialogParams.linkColor); + p.helpAboutDialogParams.linkColor = colorFromJson(h, "linkColor", p.helpAboutDialogParams.linkColor); } if (json.contains("whatsNewDialog")) { const auto w = json["whatsNewDialog"].toObject(); auto &wn = p.whatsNewDialogParams; - wn.backgroundColor = colorFromJson(w, "backgroundColor", wn.backgroundColor); - wn.headerTextColor = colorFromJson(w, "headerTextColor", wn.headerTextColor); - wn.versionTextColor = colorFromJson(w, "versionTextColor", wn.versionTextColor); - wn.contentTextColor = colorFromJson(w, "contentTextColor", wn.contentTextColor); - wn.linkColor = colorFromJson(w, "linkColor", wn.linkColor); - wn.closeButtonColor = colorFromJson(w, "closeButtonColor", wn.closeButtonColor); - wn.headerDecorationColor = colorFromJson(w, "headerDecorationColor",wn.headerDecorationColor); + wn.backgroundColor = colorFromJson(w, "backgroundColor", wn.backgroundColor); + wn.headerTextColor = colorFromJson(w, "headerTextColor", wn.headerTextColor); + wn.versionTextColor = colorFromJson(w, "versionTextColor", wn.versionTextColor); + wn.contentTextColor = colorFromJson(w, "contentTextColor", wn.contentTextColor); + wn.linkColor = colorFromJson(w, "linkColor", wn.linkColor); + wn.closeButtonColor = colorFromJson(w, "closeButtonColor", wn.closeButtonColor); + wn.headerDecorationColor = colorFromJson(w, "headerDecorationColor", wn.headerDecorationColor); } if (json.contains("shortcutsIcons")) { diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index b0a401298..d85339b04 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -378,7 +378,7 @@ QVariant ComicModel::data(const QModelIndex &index, int role) const Qt::ItemFlags ComicModel::flags(const QModelIndex &index) const { if (!index.isValid()) - return {}; + return { }; if (index.column() == ComicModel::Rating) return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index a160ecd69..17b70cf6e 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -434,7 +434,7 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const Qt::ItemFlags FolderModel::flags(const QModelIndex &index) const { if (!index.isValid()) - return {}; + return { }; return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled; } diff --git a/YACReaderLibrary/db/query_lexer.h b/YACReaderLibrary/db/query_lexer.h index d3136d0b1..ece898e95 100644 --- a/YACReaderLibrary/db/query_lexer.h +++ b/YACReaderLibrary/db/query_lexer.h @@ -36,8 +36,8 @@ class Token } private: - Type _type {}; - std::string _lexeme {}; + Type _type { }; + std::string _lexeme { }; }; class QueryLexer diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index 35fd77e33..d66919301 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -316,9 +316,9 @@ QueryParser::TreeNode QueryParser::expression() } auto right = token(true); - return TreeNode("expression", { TreeNode(toLower(left), {}), TreeNode(right, {}) }, expOperator); + return TreeNode("expression", { TreeNode(toLower(left), { }), TreeNode(right, { }) }, expOperator); } else { - return TreeNode("expression", { TreeNode("all", {}), TreeNode(left, {}) }); + return TreeNode("expression", { TreeNode("all", { }), TreeNode(left, { }) }); } } @@ -328,12 +328,12 @@ QueryParser::TreeNode QueryParser::expression() QueryParser::TreeNode QueryParser::baseToken() { if (tokenType() == Token::Type::quotedWord) { - return TreeNode("expression", { TreeNode("all", {}), TreeNode(token(true), {}) }); + return TreeNode("expression", { TreeNode("all", { }), TreeNode(token(true), { }) }); } if (tokenType() == Token::Type::word) { - return TreeNode("expression", { TreeNode("all", {}), TreeNode(token(true), {}) }); + return TreeNode("expression", { TreeNode("all", { }), TreeNode(token(true), { }) }); } - return TreeNode("expression", { TreeNode("all", {}), TreeNode(token(true), {}) }); + return TreeNode("expression", { TreeNode("all", { }), TreeNode(token(true), { }) }); } diff --git a/YACReaderLibrary/db/reading_list_model.cpp b/YACReaderLibrary/db/reading_list_model.cpp index 856fa87b3..55aa626ec 100644 --- a/YACReaderLibrary/db/reading_list_model.cpp +++ b/YACReaderLibrary/db/reading_list_model.cpp @@ -101,11 +101,11 @@ QVariant ReadingListModel::data(const QModelIndex &index, int role) const Qt::ItemFlags ReadingListModel::flags(const QModelIndex &index) const { if (!index.isValid()) - return {}; + return { }; auto item = static_cast(index.internalPointer()); if (typeid(*item) == typeid(ReadingListSeparatorItem)) - return {}; + return { }; if (typeid(*item) == typeid(ReadingListItem) && static_cast(item)->parent->getId() != 0) return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled; // only sublists are dragable diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index dbe90109e..eaba930da 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -359,20 +359,20 @@ Theme makeTheme(const ThemeParams ¶ms) theme.metadataScraperDialog.scraperScrollLabelScrollAreaQSS = t.scraperScrollLabelScrollAreaQSS.arg(msd.contentBackgroundColor.name(), msd.tableScrollHandleColor.name(), msd.tableScrollBackgroundColor.name()); theme.metadataScraperDialog.scraperTableViewQSS = t.scraperTableViewQSS - .arg(msd.tableHeaderTextColor.name(), - msd.tableAltBackgroundColor.name(), - msd.tableBackgroundColor.name(), - msd.tableSelectedColor.name(), - msd.tableHeaderBackgroundColor.name(), - msd.tableHeaderBorderColor.name(), - msd.tableHeaderTextColor.name(), - msd.tableSectionBorderDark.name(), - msd.tableSectionBorderLight.name(), - msd.tableScrollHandleColor.name(), - msd.tableScrollBackgroundColor.name(), - recolor(":/images/comic_vine/downArrow.svg", msd.downArrowColor), - recolor(":/images/comic_vine/upArrow.svg", msd.upArrowColor), - msd.tableHeaderGradientColor.name()); + .arg(msd.tableHeaderTextColor.name(), + msd.tableAltBackgroundColor.name(), + msd.tableBackgroundColor.name(), + msd.tableSelectedColor.name(), + msd.tableHeaderBackgroundColor.name(), + msd.tableHeaderBorderColor.name(), + msd.tableHeaderTextColor.name(), + msd.tableSectionBorderDark.name(), + msd.tableSectionBorderLight.name(), + msd.tableScrollHandleColor.name(), + msd.tableScrollBackgroundColor.name(), + recolor(":/images/comic_vine/downArrow.svg", msd.downArrowColor), + recolor(":/images/comic_vine/upArrow.svg", msd.upArrowColor), + msd.tableHeaderGradientColor.name()); theme.metadataScraperDialog.dialogQSS = t.dialogQSS.arg(msd.dialogBackgroundColor.name()); theme.metadataScraperDialog.dialogButtonsQSS = t.dialogButtonsQSS.arg(msd.buttonBorderColor.name(), msd.buttonBackgroundColor.name(), msd.buttonTextColor.name()); @@ -470,19 +470,19 @@ Theme makeTheme(const ThemeParams ¶ms) // ComicsViewTable const auto &cvta = params.comicsViewTableParams; theme.comicsViewTable.tableViewQSS = cvta.t.tableViewQSS - .arg(cvta.alternateBackgroundColor.name(), - cvta.backgroundColor.name(), - cvta.headerBackgroundColor.name(), - cvta.headerBorderColor.name(), - cvta.headerGradientColor.name(), - cvta.itemBorderBottomColor.name(), - cvta.itemBorderTopColor.name(), - cvta.itemTextColor.name(), - cvta.selectedColor.name(), - cvta.selectedTextColor.name(), - cvta.headerTextColor.name(), - QString::number(cvta.itemBorderBottomWidth), - QString::number(cvta.itemBorderTopWidth)); + .arg(cvta.alternateBackgroundColor.name(), + cvta.backgroundColor.name(), + cvta.headerBackgroundColor.name(), + cvta.headerBorderColor.name(), + cvta.headerGradientColor.name(), + cvta.itemBorderBottomColor.name(), + cvta.itemBorderTopColor.name(), + cvta.itemTextColor.name(), + cvta.selectedColor.name(), + cvta.selectedTextColor.name(), + cvta.headerTextColor.name(), + QString::number(cvta.itemBorderBottomWidth), + QString::number(cvta.itemBorderTopWidth)); theme.comicsViewTable.starRatingColor = cvta.starRatingColor; theme.comicsViewTable.starRatingSelectedColor = cvta.starRatingSelectedColor; // end ComicsViewTable @@ -648,15 +648,15 @@ Theme makeTheme(const ThemeParams ¶ms) theme.navigationTree.branchOpenIconSelectedPath = recoloredSvgToThemeFile(":/images/sidebar/branch-open.svg", nt.branchIndicatorSelectedColor, params.meta.id, { .suffix = "_selected" }); theme.navigationTree.navigationTreeQSS = nt.t.navigationTreeQSS - .arg(nt.textColor.name(), - nt.selectionBackgroundColor.name(), - nt.scrollBackgroundColor.name(), - nt.scrollHandleColor.name(), - nt.selectedTextColor.name(), - theme.navigationTree.branchClosedIconPath, - theme.navigationTree.branchOpenIconPath, - theme.navigationTree.branchClosedIconSelectedPath, - theme.navigationTree.branchOpenIconSelectedPath); + .arg(nt.textColor.name(), + nt.selectionBackgroundColor.name(), + nt.scrollBackgroundColor.name(), + nt.scrollHandleColor.name(), + nt.selectedTextColor.name(), + theme.navigationTree.branchClosedIconPath, + theme.navigationTree.branchOpenIconPath, + theme.navigationTree.branchClosedIconSelectedPath, + theme.navigationTree.branchOpenIconSelectedPath); theme.navigationTree.folderIndicatorColor = nt.folderIndicatorColor; // Folder icon — normal and selected states with independent colors diff --git a/common/themes/icon_utils.cpp b/common/themes/icon_utils.cpp index 680a78a86..395347ddc 100644 --- a/common/themes/icon_utils.cpp +++ b/common/themes/icon_utils.cpp @@ -28,7 +28,7 @@ QString readSvg(const QString &resourcePath) QFile in(resourcePath); if (!in.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "Failed to open SVG resource:" << resourcePath; - return {}; + return { }; } QString svg = QString::fromUtf8(in.readAll()); @@ -53,7 +53,7 @@ QString writeSvg(const QString &svg, const QString &resourcePath, const QString QFile out(outPath); if (!out.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { qWarning() << "Failed to write SVG:" << outPath; - return {}; + return { }; } out.write(svg.toUtf8()); diff --git a/common/themes/icon_utils.h b/common/themes/icon_utils.h index 48b4462cc..aef05bd70 100644 --- a/common/themes/icon_utils.h +++ b/common/themes/icon_utils.h @@ -14,23 +14,23 @@ struct RecolorOptions { }; QString readSvg(const QString &resourcePath); -QString writeSvg(const QString &svg, const QString &resourcePath, const QString &themeName, const RecolorOptions &options = {}); +QString writeSvg(const QString &svg, const QString &resourcePath, const QString &themeName, const RecolorOptions &options = { }); QString recolorSvgXML(QString &svg, const QString &placeHolder, const QColor &color); QString recoloredSvgToThemeFile(const QString &resourcePath, const QColor &color, // #f0f (magenta) const QString &themeName, - const RecolorOptions &options = {}); + const RecolorOptions &options = { }); QString recoloredSvgToThemeFile(const QString &resourcePath, const QColor &color1, // #f0f (magenta) const QColor &color2, // #0ff (cyan) const QString &themeName, - const RecolorOptions &options = {}); + const RecolorOptions &options = { }); QString recoloredSvgToThemeFile(const QString &resourcePath, const QColor &color1, // #f0f (magenta) const QColor &color2, // #0ff (cyan) const QColor &color3, // #ff0 (yellow) const QString &themeName, - const RecolorOptions &options = {}); + const RecolorOptions &options = { }); #endif // ICON_UTILS_H diff --git a/common/themes/theme_editor_dialog.cpp b/common/themes/theme_editor_dialog.cpp index 4f4ef7d44..72d033276 100644 --- a/common/themes/theme_editor_dialog.cpp +++ b/common/themes/theme_editor_dialog.cpp @@ -133,7 +133,7 @@ ThemeEditorDialog::ThemeEditorDialog(const QJsonObject ¶ms, QWidget *parent) tree->setUniformRowHeights(true); tree->setAlternatingRowColors(true); - populate(nullptr, params, {}); + populate(nullptr, params, { }); tree->expandAll(); connect(expandBtn, &QPushButton::clicked, tree, &QTreeWidget::expandAll); @@ -425,7 +425,7 @@ void ThemeEditorDialog::loadFromFile() params = doc.object(); syncMetaFromParams(); tree->clear(); - populate(nullptr, params, {}); + populate(nullptr, params, { }); tree->expandAll(); emit themeJsonChanged(params); } diff --git a/common/themes/theme_manager.cpp b/common/themes/theme_manager.cpp index 589b201ef..bf0031644 100644 --- a/common/themes/theme_manager.cpp +++ b/common/themes/theme_manager.cpp @@ -59,7 +59,7 @@ Theme ThemeManager::themeFromId(const QString &id, ThemeVariant fallbackVariant) return makeTheme(json); } - return {}; + return { }; } void ThemeManager::resolveTheme() diff --git a/common/themes/theme_repository.cpp b/common/themes/theme_repository.cpp index 3290cd631..d76695c88 100644 --- a/common/themes/theme_repository.cpp +++ b/common/themes/theme_repository.cpp @@ -50,7 +50,7 @@ QJsonObject ThemeRepository::loadThemeJson(const QString &themeId) const if (u.id == themeId) return readJsonFile(u.filePath); - return {}; + return { }; } QString ThemeRepository::saveUserTheme(QJsonObject themeJson) @@ -104,7 +104,7 @@ QString ThemeRepository::importThemeFromFile(const QString &filePath) { QJsonObject json = readJsonFile(filePath); if (json.isEmpty()) - return {}; + return { }; // Force a new user id regardless of what the file contains auto metaObj = json["meta"].toObject(); @@ -189,13 +189,13 @@ QJsonObject ThemeRepository::readJsonFile(const QString &path) { QFile file(path); if (!file.open(QIODevice::ReadOnly)) - return {}; + return { }; const QByteArray data = file.readAll(); QJsonParseError error; const QJsonDocument doc = QJsonDocument::fromJson(data, &error); if (error.error != QJsonParseError::NoError) - return {}; + return { }; return doc.object(); } diff --git a/shortcuts_management/actions_shortcuts_model.cpp b/shortcuts_management/actions_shortcuts_model.cpp index 7238b2c74..baf50c16c 100644 --- a/shortcuts_management/actions_shortcuts_model.cpp +++ b/shortcuts_management/actions_shortcuts_model.cpp @@ -34,7 +34,7 @@ QModelIndex ActionsShortcutsModel::index(int row, int column, const QModelIndex Qt::ItemFlags ActionsShortcutsModel::flags(const QModelIndex &index) const { if (!index.isValid()) - return {}; + return { }; if (index.column() == KEYS) return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; return Qt::ItemIsEnabled | Qt::ItemIsSelectable; diff --git a/tests/concurrent_queue_test/concurrent_queue_test.cpp b/tests/concurrent_queue_test/concurrent_queue_test.cpp index d9c4eb4bb..ee187df93 100644 --- a/tests/concurrent_queue_test/concurrent_queue_test.cpp +++ b/tests/concurrent_queue_test/concurrent_queue_test.cpp @@ -461,8 +461,8 @@ void ConcurrentQueueTest::singleUserThread_data() using ms = chrono::milliseconds; - QTest::newRow("-") << 0 << JobDataSet {}; - QTest::newRow("0") << 7 << JobDataSet {}; + QTest::newRow("-") << 0 << JobDataSet { }; + QTest::newRow("0") << 7 << JobDataSet { }; QTest::newRow("A") << 1 << JobDataSet { { 5, ms(0) } }; QTest::newRow("B") << 5 << JobDataSet { { 12, ms(1) } }; QTest::newRow("C") << 1 << JobDataSet { { 1, ms(0) }, { 5, ms(2) }, { 3, ms(1) } }; @@ -559,9 +559,9 @@ void ConcurrentQueueTest::cancelPending1UserThread_data() const auto ms = [](int count) -> Clock::duration { return chrono::milliseconds(count); }; const auto us = [](int count) -> Clock::duration { return chrono::microseconds(count); }; - QTest::newRow("-") << 0 << JobDataSet {} << ms(0); - QTest::newRow("01") << 2 << JobDataSet {} << ms(0); - QTest::newRow("02") << 3 << JobDataSet {} << ms(1); + QTest::newRow("-") << 0 << JobDataSet { } << ms(0); + QTest::newRow("01") << 2 << JobDataSet { } << ms(0); + QTest::newRow("02") << 3 << JobDataSet { } << ms(1); QTest::newRow("A") << 1 << JobDataSet { { 5, ms(3) } } << ms(1); QTest::newRow("B") << 5 << JobDataSet { { 12, ms(1) } } << ms(1); From e699237c44dddf58839c71afa1f3de537fcd31bc Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 5 Mar 2026 14:12:29 +0100 Subject: [PATCH 118/187] Use curl instead of wget --- .github/workflows/build.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d3ba5313d..96ff368b3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -191,9 +191,8 @@ jobs: mkdir C:\Qt python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_64 -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools dir C:\Qt\6.9.3\msvc2022_64\bin - choco install -y wget - choco install innosetup - wget "https://aka.ms/vs/17/release/vc_redist.x64.exe" -O %GITHUB_WORKSPACE%\vc_redist.x64.exe + curl.exe -L --retry 5 --retry-delay 5 --retry-all-errors "https://aka.ms/vs/17/release/vc_redist.x64.exe" -o "%GITHUB_WORKSPACE%\vc_redist.x64.exe" + where iscc - name: Build shell: cmd @@ -337,9 +336,8 @@ jobs: python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_64 -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_arm64_cross_compiled -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools dir C:\Qt\6.9.3\msvc2022_arm64\bin - choco install -y wget - choco install innosetup - wget "https://aka.ms/vs/17/release/vc_redist.arm64.exe" -O %GITHUB_WORKSPACE%\vc_redist.arm64.exe + curl.exe -L --retry 5 --retry-delay 5 --retry-all-errors "https://aka.ms/vs/17/release/vc_redist.arm64.exe" -o "%GITHUB_WORKSPACE%\vc_redist.arm64.exe" + where iscc - name: Build shell: cmd From b3048f0bffaef088c52c27737364621c3b3d0f31 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 5 Mar 2026 15:16:26 +0100 Subject: [PATCH 119/187] Fix translator using new backends --- .github/workflows/build.yml | 18 +++--- CMakeLists.txt | 1 + YACReader/CMakeLists.txt | 1 + YACReader/translator.cpp | 100 +++++++-------------------------- YACReader/translator.h | 25 ++------- ci/win/build_installer_qt6.iss | 2 + 6 files changed, 39 insertions(+), 108 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 96ff368b3..f93ce14ec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,13 +66,14 @@ jobs: run: | sudo apt-get update sudo apt-get install -y libunarr-dev libgl-dev libgles2-mesa-dev \ - libfontconfig1-dev libfreetype-dev libxkbcommon-dev libpoppler-qt6-dev + libfontconfig1-dev libfreetype-dev libxkbcommon-dev libpoppler-qt6-dev \ + libspeechd-dev - name: Install Qt uses: jurplel/install-qt-action@v4 with: version: '6.9.3' - modules: 'qt5compat qtmultimedia qtimageformats qtshadertools' + modules: 'qt5compat qtmultimedia qtimageformats qtshadertools qtspeech' cache: true - name: Build @@ -98,13 +99,14 @@ jobs: run: | sudo apt-get update sudo apt-get install -y libgl-dev libgles2-mesa-dev \ - libfontconfig1-dev libfreetype-dev libxkbcommon-dev libpoppler-qt6-dev + libfontconfig1-dev libfreetype-dev libxkbcommon-dev libpoppler-qt6-dev \ + libspeechd-dev - name: Install Qt uses: jurplel/install-qt-action@v4 with: version: '6.9.3' - modules: 'qt5compat qtmultimedia qtimageformats qtshadertools' + modules: 'qt5compat qtmultimedia qtimageformats qtshadertools qtspeech' cache: true - name: Build @@ -134,7 +136,7 @@ jobs: - name: Install dependencies run: | pip3 install --break-system-packages aqtinstall - python3 -m aqt install-qt mac desktop 6.9.3 -m qt5compat qtmultimedia qtimageformats qtshadertools + python3 -m aqt install-qt mac desktop 6.9.3 -m qt5compat qtmultimedia qtimageformats qtshadertools qtspeech echo "${{ github.workspace }}/6.9.3/macos/bin" >> $GITHUB_PATH npm install -g appdmg @@ -189,7 +191,7 @@ jobs: pip install -U pip pip install aqtinstall mkdir C:\Qt - python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_64 -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools + python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_64 -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools qtspeech dir C:\Qt\6.9.3\msvc2022_64\bin curl.exe -L --retry 5 --retry-delay 5 --retry-all-errors "https://aka.ms/vs/17/release/vc_redist.x64.exe" -o "%GITHUB_WORKSPACE%\vc_redist.x64.exe" where iscc @@ -333,8 +335,8 @@ jobs: run: | pip install aqtinstall mkdir C:\Qt - python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_64 -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools - python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_arm64_cross_compiled -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools + python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_64 -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools qtspeech + python -m aqt install-qt windows desktop 6.9.3 win64_msvc2022_arm64_cross_compiled -O c:\Qt -m qt5compat qtmultimedia qtimageformats qtshadertools qtspeech dir C:\Qt\6.9.3\msvc2022_arm64\bin curl.exe -L --retry 5 --retry-delay 5 --retry-all-errors "https://aka.ms/vs/17/release/vc_redist.arm64.exe" -o "%GITHUB_WORKSPACE%\vc_redist.arm64.exe" where iscc diff --git a/CMakeLists.txt b/CMakeLists.txt index badd9f259..7e3012b62 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,6 +106,7 @@ else() Sql Svg Test + TextToSpeech Widgets ) endif() diff --git a/YACReader/CMakeLists.txt b/YACReader/CMakeLists.txt index 62cf58643..f5e9eeec9 100644 --- a/YACReader/CMakeLists.txt +++ b/YACReader/CMakeLists.txt @@ -89,6 +89,7 @@ target_link_libraries(YACReader PRIVATE Qt::Network Qt::Widgets Qt::Multimedia + Qt::TextToSpeech Qt::Svg Qt::Core5Compat comic_backend diff --git a/YACReader/translator.cpp b/YACReader/translator.cpp index a2524706f..4822b55c9 100644 --- a/YACReader/translator.cpp +++ b/YACReader/translator.cpp @@ -1,6 +1,6 @@ -#include - -#include +#include +#include +#include #include #include @@ -26,8 +26,6 @@ #include -#define APPID "417CEAD93449502CC3C9B69FED26C54118E62BCC" - YACReaderTranslator::YACReaderTranslator(Viewer *parent) : QWidget(parent), drag(false) { @@ -155,7 +153,7 @@ YACReaderTranslator::YACReaderTranslator(Viewer *parent) connect(speakButton, &QAbstractButton::pressed, this, &YACReaderTranslator::play); connect(clearButton, &QAbstractButton::pressed, this, &YACReaderTranslator::clear); - player = new QMediaPlayer; + tts = new QTextToSpeech(this); } void YACReaderTranslator::hideResults() @@ -179,20 +177,16 @@ void YACReaderTranslator::translate() QString from = this->from->itemData(this->from->currentIndex()).toString(); QString to = this->to->itemData(this->to->currentIndex()).toString(); + speakText = text; + speakLocale = from; + TranslationLoader *translationLoader = new TranslationLoader(text, from, to); connect(translationLoader, &TranslationLoader::requestFinished, this, &YACReaderTranslator::setTranslation); connect(translationLoader, &TranslationLoader::error, this, &YACReaderTranslator::error); connect(translationLoader, &TranslationLoader::timeOut, this, &YACReaderTranslator::error); connect(translationLoader, &QThread::finished, translationLoader, &QObject::deleteLater); - TextToSpeachLoader *tts = new TextToSpeachLoader(text, from); - connect(tts, &TextToSpeachLoader::requestFinished, this, &YACReaderTranslator::setSpeak); - connect(tts, &TextToSpeachLoader::error, this, &YACReaderTranslator::error); - connect(tts, &TextToSpeachLoader::timeOut, this, &YACReaderTranslator::error); - connect(tts, &QThread::finished, tts, &QObject::deleteLater); - translationLoader->start(); - tts->start(); resultsTitle->setText(tr("Translation")); @@ -208,19 +202,12 @@ void YACReaderTranslator::error() busyIndicator->hide(); } -void YACReaderTranslator::setSpeak(const QUrl &url) -{ - resultsTitle->setHidden(false); - speakButton->setHidden(false); - - ttsSource = url; -} - void YACReaderTranslator::setTranslation(const QString &string) { resultText->setText(string); resultsTitle->setHidden(false); + speakButton->setHidden(false); resultText->setHidden(false); busyIndicator->hide(); } @@ -236,8 +223,8 @@ void YACReaderTranslator::populateCombos() combo->addItem("Arabic", "ar"); combo->addItem("Bulgarian", "bg"); combo->addItem("Catalan", "ca"); - combo->addItem("Chinese Simplified", "zh-CHS"); - combo->addItem("Chinese Traditional", "zh-CHT"); + combo->addItem("Chinese Simplified", "zh-CN"); + combo->addItem("Chinese Traditional", "zh-TW"); combo->addItem("Czech", "cs"); combo->addItem("Danish", "da"); combo->addItem("Dutch", "nl"); @@ -277,10 +264,8 @@ void YACReaderTranslator::populateCombos() void YACReaderTranslator::play() { - - player->setSource(ttsSource); - - player->play(); + tts->setLocale(QLocale(speakLocale)); + tts->say(speakText); } void YACReaderTranslator::mousePressEvent(QMouseEvent *event) @@ -324,53 +309,10 @@ void TranslationLoader::run() connect(&tT, &QTimer::timeout, &q, &QEventLoop::quit); connect(&manager, &QNetworkAccessManager::finished, &q, &QEventLoop::quit); - QString url = "http://api.microsofttranslator.com/V2/Ajax.svc/Translate?appid=%1&from=%2&to=%3&text=%4&contentType=text/plain"; - url = url.arg(APPID, from, to, text); - - QNetworkReply *reply = manager.get(QNetworkRequest(QUrl(url))); - - tT.start(5000); // 5s timeout - q.exec(); - - if (tT.isActive()) { - // download complete - if (reply->error() == QNetworkReply::NoError) { - QString utf8 = QString::fromUtf8(reply->readAll()); - utf8 = utf8.remove(0, 1); - utf8 = utf8.remove(utf8.count() - 1, 1); - - QString translated(utf8); - emit requestFinished(translated); - } else - emit error(); - } else { - emit timeOut(); - } -} - -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- -//--------------------------------------------------------------------------- - -TextToSpeachLoader::TextToSpeachLoader(QString text, QString language) - : QThread(), text(text), language(language) -{ -} - -void TextToSpeachLoader::run() -{ - QNetworkAccessManager manager; - QEventLoop q; - QTimer tT; - - tT.setSingleShot(true); - connect(&tT, &QTimer::timeout, &q, &QEventLoop::quit); - connect(&manager, &QNetworkAccessManager::finished, &q, &QEventLoop::quit); - - QString url = "http://api.microsofttranslator.com/V2/Ajax.svc/Speak?appid=%1&language=%2&text=%3&contentType=text/plain"; - url = url.arg(APPID, language, text); + QString urlStr = QString("https://api.mymemory.translated.net/get?q=%1&langpair=%2|%3") + .arg(QString::fromUtf8(QUrl::toPercentEncoding(text)), from, to); - QNetworkReply *reply = manager.get(QNetworkRequest(QUrl(url))); + QNetworkReply *reply = manager.get(QNetworkRequest(QUrl(urlStr))); tT.start(5000); // 5s timeout q.exec(); @@ -378,12 +320,12 @@ void TextToSpeachLoader::run() if (tT.isActive()) { // download complete if (reply->error() == QNetworkReply::NoError) { - QString utf8 = QString::fromUtf8(reply->readAll()); - utf8 = utf8.remove(0, 1); - utf8 = utf8.remove(utf8.count() - 1, 1); - utf8 = utf8.replace("\\", ""); - - emit requestFinished(QUrl(utf8)); + QJsonDocument doc = QJsonDocument::fromJson(reply->readAll()); + QString translated = doc["responseData"]["translatedText"].toString(); + if (!translated.isEmpty()) + emit requestFinished(translated); + else + emit error(); } else emit error(); } else { diff --git a/YACReader/translator.h b/YACReader/translator.h index be50f8b61..b26b2480d 100644 --- a/YACReader/translator.h +++ b/YACReader/translator.h @@ -1,7 +1,6 @@ #ifndef __TRANSLATOR_H #define __TRANSLATOR_H -class QUrl; class QMouseEvent; class QPoint; class QTextEdit; @@ -9,14 +8,13 @@ class QComboBox; class QLabel; class QPushButton; class YACReaderBusyWidget; +class QTextToSpeech; #include #include #include #include "viewer.h" -class QMediaPlayer; - class YACReaderTranslator : public QWidget { Q_OBJECT @@ -28,7 +26,6 @@ public slots: protected slots: void translate(); - void setSpeak(const QUrl &url); void setTranslation(const QString &string); void error(); void clear(); @@ -44,7 +41,9 @@ protected slots: QPoint click; private: - QMediaPlayer *player; + QTextToSpeech *tts; + QString speakText; + QString speakLocale; QTextEdit *text; QComboBox *from; @@ -53,7 +52,6 @@ protected slots: QPushButton *speakButton; QLabel *resultText; YACReaderBusyWidget *busyIndicator; - QUrl ttsSource; QPushButton *clearButton; }; @@ -74,19 +72,4 @@ class TranslationLoader : public QThread void run() override; }; -class TextToSpeachLoader : public QThread -{ - Q_OBJECT -public: - TextToSpeachLoader(QString text, QString language); -signals: - void requestFinished(QUrl); - void timeOut(); - void error(); - -private: - QString text; - QString language; - void run() override; -}; #endif diff --git a/ci/win/build_installer_qt6.iss b/ci/win/build_installer_qt6.iss index 87e03c4d7..06930e903 100644 --- a/ci/win/build_installer_qt6.iss +++ b/ci/win/build_installer_qt6.iss @@ -60,6 +60,7 @@ Source: Qt6QuickTemplates2.dll; DestDir: {app} Source: Qt6QuickWidgets.dll; DestDir: {app} Source: Qt6Sql.dll; DestDir: {app} Source: Qt6Svg.dll; DestDir: {app} +Source: Qt6TextToSpeech.dll; DestDir: {app} Source: opengl32sw.dll; DestDir: {app}; Flags: skipifsourcedoesntexist Source: D3Dcompiler_47.dll; DestDir: {app}; Flags: skipifsourcedoesntexist @@ -74,6 +75,7 @@ Source:qml\*; DestDir: {app}\qml\; Flags: recursesubdirs Source:qmltooling\*; DestDir: {app}\qmltooling\ Source:sqldrivers\qsqlite.dll; DestDir: {app}\sqldrivers\ Source:styles\*; DestDir: {app}\styles\ +Source:texttospeech\*; DestDir: {app}\texttospeech\ Source:tls\*; DestDir: {app}\tls\ Source:translations\*; DestDir: {app}\translations\ From 6ea857fa59f5e4beb4264412d6595088701b8048 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 5 Mar 2026 15:23:13 +0100 Subject: [PATCH 120/187] Remove unused images --- YACReader/yacreader_images.qrc | 2 -- images/down.png | Bin 689 -> 0 bytes images/up.png | Bin 702 -> 0 bytes 3 files changed, 2 deletions(-) delete mode 100644 images/down.png delete mode 100644 images/up.png diff --git a/YACReader/yacreader_images.qrc b/YACReader/yacreader_images.qrc index df996b67c..a5ba0eb8f 100644 --- a/YACReader/yacreader_images.qrc +++ b/YACReader/yacreader_images.qrc @@ -10,8 +10,6 @@ ../images/flow5.png ../images/notCover.png ../images/close.svg - ../images/up.png - ../images/down.png ../images/centerFlow.svg ../images/gotoFlow.svg ../images/defaultCover.png diff --git a/images/down.png b/images/down.png deleted file mode 100644 index 44d91d4241b3a4dd633fcd74ece159ffa8c9a947..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 689 zcmV;i0#5yjP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00009 za7bBm000id000id0mpBsWB>pF7<5HgbW?9;ba!ELWdKlNX>N2bPDNB8b~7$BHmT?0 zB>(^d14%?dR5(waluJ)jQ51#u)Hu<<Aye+T{x(-{=tpBk>g_V?}b1Y4tm|wdaqE( zbD>}yg88&v-=93;pf^3OB5&-mk;^JDYvuxzY_r+;Wt-h{Z_Z$bL%vaq$YnFUmrX0m zb4HzzXt19J9Q5i%v&d#r{3o4MVAhyL=KFtVILOoeRHRcooK7B++GVxN(=5V%7I2Wq z(Iis42?ohu+w65Z*f;D^yIF*Nd2vR4ulVGlZ5Sy8s8b4L$8**84x&sIGx7UmK#ws5X`NpxxSDy8cT4e9N&T>XR zx8&s=9Ms!fTOC_pVNEo=%wRM0g=gfqz_%HH+o$f3iH47}x&sF}>^0Zsr^bpXUIcXE zAX&cLQFp)2=XDxOK|g<<{a6vmqJu6R>OX09DR`x;L0o@y_tx#&J2$H<0a diff --git a/images/up.png b/images/up.png deleted file mode 100644 index cae28b7e71ae843896c4925268c9305d20b55c11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 702 zcmV;v0zv(WP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00009 za7bBm000ic000ic0Tn1pfB*mh7<5HgbW?9;ba!ELWdKlNX>N2bPDNB8b~7$BHmT?0 zB>(^d5J^NqR5(wal+8~QK^Vs8YP{&b;?m-D zw-#9r3tn|d7#(!sU{4=EIHyHkf2`MQbb4Cd&RMG)+tIIXK@hqSV2NUJ<6TNqO-@Kf&V_Jkhe|Xyw$fAQT9PWS8R!qAv+0QTEzjf_K k&&{h{oq#Ml+oB7{FKSf#r{>|K4*&oF07*qoM6N<$f}U$A1ONa4 From 33f18d9d1cb40b45fbee9445610af81688788429 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 5 Mar 2026 18:52:10 +0100 Subject: [PATCH 121/187] Make the translator themeable --- YACReader/themes/builtin_classic.json | 11 ++++ YACReader/themes/builtin_dark.json | 11 ++++ YACReader/themes/builtin_light.json | 11 ++++ YACReader/themes/theme.h | 42 ++++++++++++ YACReader/themes/theme_factory.cpp | 66 +++++++++++++++++++ YACReader/translator.cpp | 85 ++++++++++++------------- YACReader/translator.h | 8 ++- YACReader/yacreader_images.qrc | 10 +-- images/dropDownArrow.png | Bin 135 -> 0 bytes images/fromTo.png | Bin 171 -> 0 bytes images/speaker.png | Bin 200 -> 0 bytes images/translator/close.svg | 15 +++++ images/translator/dropDownArrow.svg | 11 ++++ images/translator/fromTo.svg | 22 +++++++ images/translator/speaker.svg | 19 ++++++ images/translator/translatorSearch.svg | 11 ++++ images/translatorSearch.png | Bin 241 -> 0 bytes 17 files changed, 273 insertions(+), 49 deletions(-) delete mode 100644 images/dropDownArrow.png delete mode 100644 images/fromTo.png delete mode 100644 images/speaker.png create mode 100644 images/translator/close.svg create mode 100644 images/translator/dropDownArrow.svg create mode 100644 images/translator/fromTo.svg create mode 100644 images/translator/speaker.svg create mode 100644 images/translator/translatorSearch.svg delete mode 100644 images/translatorSearch.png diff --git a/YACReader/themes/builtin_classic.json b/YACReader/themes/builtin_classic.json index f3edf0886..bf1b34159 100644 --- a/YACReader/themes/builtin_classic.json +++ b/YACReader/themes/builtin_classic.json @@ -24,6 +24,17 @@ "shortcutsIcons": { "iconColor": "#404040" }, + "translator": { + "backgroundColor": "#404040", + "borderColor": "#212121", + "iconColor": "#cccccc", + "inputBackgroundColor": "#2a2a2a", + "inputDarkerBackgroundColor": "#272727", + "primaryTextColor": "#ffffff", + "scrollbarHandleColor": "#dddddd", + "secondaryTextColor": "#e3e3e3", + "selectionBackgroundColor": "#202020" + }, "toolbar": { "backgroundColor": "#f3f3f3", "checkedButtonColor": "#cccccc", diff --git a/YACReader/themes/builtin_dark.json b/YACReader/themes/builtin_dark.json index 61038dfa8..193fa0b66 100644 --- a/YACReader/themes/builtin_dark.json +++ b/YACReader/themes/builtin_dark.json @@ -24,6 +24,17 @@ "shortcutsIcons": { "iconColor": "#d0d0d0" }, + "translator": { + "backgroundColor": "#404040", + "borderColor": "#212121", + "iconColor": "#cccccc", + "inputBackgroundColor": "#2a2a2a", + "inputDarkerBackgroundColor": "#272727", + "primaryTextColor": "#ffffff", + "scrollbarHandleColor": "#dddddd", + "secondaryTextColor": "#e3e3e3", + "selectionBackgroundColor": "#202020" + }, "toolbar": { "backgroundColor": "#202020", "checkedButtonColor": "#3a3a3a", diff --git a/YACReader/themes/builtin_light.json b/YACReader/themes/builtin_light.json index dbd77f07e..a7aadc679 100644 --- a/YACReader/themes/builtin_light.json +++ b/YACReader/themes/builtin_light.json @@ -24,6 +24,17 @@ "shortcutsIcons": { "iconColor": "#606060" }, + "translator": { + "backgroundColor": "#e8e8e8", + "borderColor": "#cccccc", + "iconColor": "#404040", + "inputBackgroundColor": "#f5f5f5", + "inputDarkerBackgroundColor": "#ebebeb", + "primaryTextColor": "#1a1a1a", + "scrollbarHandleColor": "#909090", + "secondaryTextColor": "#2a2a2a", + "selectionBackgroundColor": "#dcdcdc" + }, "toolbar": { "backgroundColor": "#f3f3f3", "checkedButtonColor": "#cccccc", diff --git a/YACReader/themes/theme.h b/YACReader/themes/theme.h index 964e619f5..99715f646 100644 --- a/YACReader/themes/theme.h +++ b/YACReader/themes/theme.h @@ -21,6 +21,31 @@ struct ViewerThemeTemplates { QString infoLabelQSS = "QLabel { color : %1; font-size:%2px; }"; }; +struct TranslatorThemeTemplates { + // %1 = track color, %2 = handle color + QString scrollBarQSS = "QScrollBar:vertical { border: none; background: %1; width: 7px; margin: 0 3px 0 0; }" + "QScrollBar::handle:vertical { background: %2; width: 7px; min-height: 20px; }" + "QScrollBar::add-line:vertical { border: none; background: %1; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::sub-line:vertical { border: none; background: %1; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" + "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" + "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" + "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none; }"; + // %1 = background, %2 = text color + QString textEditQSS = "QTextEdit{border:none;background:%1;color:%2; font-size:12px; padding:6px;}"; + // %1 = background, %2 = text color, %3 = arrow icon path, %4 = list background, %5 = selection background + QString comboBoxQSS = "QComboBox {border:none;background:%1;color:%2;font-size:12px;font-family:Arial;padding-left:8px;}" + "QComboBox::down-arrow {image: url(%3);}" + "QComboBox::drop-down {border:none; padding-right:10px;}" + "QComboBox QAbstractItemView {border: none; background:%4; color:%2; selection-background-color: %5; outline:none;}" + "QComboBox QAbstractItemView::item {padding-left:8px;}"; + // %1 = border color, %2 = background, %3 = text color + QString clearButtonQSS = "QPushButton {border:1px solid %1; background:%2; color:%3; font-family:Arial; font-size:12px; padding-top:5px; padding-bottom:5px;}"; + // %1 = text color + QString titleQSS = "QLabel {font-size:18px; font-family:Arial; color:%1;}"; + QString resultsTitleQSS = "QLabel {font-family:Arial;font-size:14px;color:%1;}"; + QString resultTextQSS = "QLabel {color:%1;font-size:12px;}"; +}; + struct GoToFlowWidgetThemeTemplates { QString sliderQSS = "QSlider::groove:horizontal {" " border: 1px solid %1;" @@ -41,6 +66,22 @@ struct GoToFlowWidgetThemeTemplates { QString labelQSS = "QLabel { color: %1; }"; }; +struct TranslatorTheme { + QColor backgroundColor; + QColor inputBackgroundColor; + QString scrollBarQSS; + QString textEditQSS; + QString comboBoxQSS; + QString clearButtonQSS; + QString titleQSS; + QString resultsTitleQSS; + QString resultTextQSS; + QIcon closeIcon; + QIcon speakerIcon; + QIcon searchIcon; + QPixmap fromToPixmap; +}; + struct ToolbarTheme { QString toolbarQSS; @@ -147,6 +188,7 @@ struct Theme { ThemeMeta meta; QJsonObject sourceJson; + TranslatorTheme translator; ToolbarTheme toolbar; ViewerTheme viewer; GoToFlowWidgetTheme goToFlowWidget; diff --git a/YACReader/themes/theme_factory.cpp b/YACReader/themes/theme_factory.cpp index a0cb207f3..7b7d052ad 100644 --- a/YACReader/themes/theme_factory.cpp +++ b/YACReader/themes/theme_factory.cpp @@ -56,6 +56,20 @@ struct ShortcutsIconsParams { QColor iconColor; // Main icon color (replaces #f0f) }; +struct TranslatorParams { + TranslatorThemeTemplates t; + + QColor backgroundColor { 0x40, 0x40, 0x40 }; + QColor inputBackgroundColor { 0x2a, 0x2a, 0x2a }; + QColor inputDarkerBackgroundColor { 0x27, 0x27, 0x27 }; + QColor selectionBackgroundColor { 0x20, 0x20, 0x20 }; + QColor primaryTextColor { Qt::white }; + QColor secondaryTextColor { 0xe3, 0xe3, 0xe3 }; + QColor scrollbarHandleColor { 0xdd, 0xdd, 0xdd }; + QColor borderColor { 0x21, 0x21, 0x21 }; + QColor iconColor { 0xcc, 0xcc, 0xcc }; +}; + struct ThemeParams { ThemeMeta meta; @@ -65,6 +79,7 @@ struct ThemeParams { HelpAboutDialogTheme helpAboutDialogParams; WhatsNewDialogParams whatsNewDialogParams; ShortcutsIconsParams shortcutsIconsParams; + TranslatorParams translatorParams; }; void setToolbarIconPair(QIcon &icon, @@ -211,6 +226,43 @@ Theme makeTheme(const ThemeParams ¶ms) theme.dialogIcons.findFolderIcon = QIcon(renderSvgToPixmap(path, 13, 13, dpr)); } + // Translator + { + const auto &tr = params.translatorParams; + theme.translator.backgroundColor = tr.backgroundColor; + theme.translator.inputBackgroundColor = tr.inputBackgroundColor; + theme.translator.scrollBarQSS = tr.t.scrollBarQSS.arg( + tr.backgroundColor.name(), + tr.scrollbarHandleColor.name()); + theme.translator.textEditQSS = tr.t.textEditQSS.arg( + tr.inputBackgroundColor.name(), + tr.primaryTextColor.name()); + const QString dropDownArrowPath = recoloredSvgToThemeFile( + ":/images/translator/dropDownArrow.svg", tr.iconColor, params.meta.id); + theme.translator.comboBoxQSS = tr.t.comboBoxQSS.arg( + tr.inputBackgroundColor.name(), + tr.primaryTextColor.name(), + dropDownArrowPath, + tr.inputDarkerBackgroundColor.name(), + tr.selectionBackgroundColor.name()); + theme.translator.clearButtonQSS = tr.t.clearButtonQSS.arg( + tr.borderColor.name(), + tr.inputBackgroundColor.name(), + tr.primaryTextColor.name()); + theme.translator.titleQSS = tr.t.titleQSS.arg(tr.primaryTextColor.name()); + theme.translator.resultsTitleQSS = tr.t.resultsTitleQSS.arg(tr.secondaryTextColor.name()); + theme.translator.resultTextQSS = tr.t.resultTextQSS.arg(tr.primaryTextColor.name()); + theme.translator.closeIcon = QIcon(recoloredSvgToThemeFile( + ":/images/translator/close.svg", tr.iconColor, params.meta.id)); + theme.translator.speakerIcon = QIcon(recoloredSvgToThemeFile( + ":/images/translator/speaker.svg", tr.iconColor, params.meta.id)); + theme.translator.searchIcon = QIcon(recoloredSvgToThemeFile( + ":/images/translator/translatorSearch.svg", tr.iconColor, params.meta.id)); + theme.translator.fromToPixmap = QPixmap(recoloredSvgToThemeFile( + ":/images/translator/fromTo.svg", tr.iconColor, params.meta.id)); + } + // end Translator + return theme; } @@ -288,6 +340,20 @@ Theme makeTheme(const QJsonObject &json) p.shortcutsIconsParams.iconColor = colorFromJson(s, "iconColor", p.shortcutsIconsParams.iconColor); } + if (json.contains("translator")) { + const auto t = json["translator"].toObject(); + auto &tp = p.translatorParams; + tp.backgroundColor = colorFromJson(t, "backgroundColor", tp.backgroundColor); + tp.inputBackgroundColor = colorFromJson(t, "inputBackgroundColor", tp.inputBackgroundColor); + tp.inputDarkerBackgroundColor = colorFromJson(t, "inputDarkerBackgroundColor", tp.inputDarkerBackgroundColor); + tp.selectionBackgroundColor = colorFromJson(t, "selectionBackgroundColor", tp.selectionBackgroundColor); + tp.primaryTextColor = colorFromJson(t, "primaryTextColor", tp.primaryTextColor); + tp.secondaryTextColor = colorFromJson(t, "secondaryTextColor", tp.secondaryTextColor); + tp.scrollbarHandleColor = colorFromJson(t, "scrollbarHandleColor", tp.scrollbarHandleColor); + tp.borderColor = colorFromJson(t, "borderColor", tp.borderColor); + tp.iconColor = colorFromJson(t, "iconColor", tp.iconColor); + } + if (json.contains("meta")) { const auto o = json["meta"].toObject(); p.meta.id = o["id"].toString(p.meta.id); diff --git a/YACReader/translator.cpp b/YACReader/translator.cpp index 4822b55c9..d1a447e00 100644 --- a/YACReader/translator.cpp +++ b/YACReader/translator.cpp @@ -29,39 +29,25 @@ YACReaderTranslator::YACReaderTranslator(Viewer *parent) : QWidget(parent), drag(false) { - QString scrollBarStyle = "QScrollBar:vertical { border: none; background: #404040; width: 7px; margin: 0 3px 0 0; }" - "QScrollBar::handle:vertical { background: #DDDDDD; width: 7px; min-height: 20px; }" - "QScrollBar::add-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: bottom; subcontrol-origin: margin; margin: 0 3px 0 0;}" - - "QScrollBar::sub-line:vertical { border: none; background: #404040; height: 10px; subcontrol-position: top; subcontrol-origin: margin; margin: 0 3px 0 0;}" - "QScrollBar::up-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-up.png') center top no-repeat;}" - "QScrollBar::down-arrow:vertical {border:none;width: 9px;height: 6px;background: url(':/images/folders_view/line-down.png') center top no-repeat;}" - - "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none; }"; - this->setCursor(QCursor(Qt::ArrowCursor)); this->setAutoFillBackground(true); this->setBackgroundRole(QPalette::Window); - QPalette p(this->palette()); - p.setColor(QPalette::Window, QColor(0x404040)); - this->setPalette(p); auto layout = new QVBoxLayout(this); // TITLE BAR auto titleBar = new QHBoxLayout(); - auto close = new QPushButton(QIcon(":/images/close.svg"), ""); - close->setFlat(true); - auto title = new QLabel(tr("YACReader translator")); - title->setStyleSheet("QLabel {font-size:18px; font-family:Arial; color:white;}"); - titleBar->addWidget(title); + closeButton = new QPushButton(this); + closeButton->setFlat(true); + titleLabel = new QLabel(tr("YACReader translator")); + titleBar->addWidget(titleLabel); titleBar->addStretch(); - close->resize(14, 14); - close->setStyleSheet("QPushButton {margin:0;padding:0;border:none;}"); - titleBar->addWidget(close); + closeButton->resize(14, 14); + closeButton->setStyleSheet("QPushButton {margin:0;padding:0;border:none;}"); + titleBar->addWidget(closeButton); titleBar->setContentsMargins(0, 0, 0, 0); titleBar->setSpacing(0); - connect(close, &QAbstractButton::clicked, parent, &Viewer::animateHideTranslator); + connect(closeButton, &QAbstractButton::clicked, parent, &Viewer::animateHideTranslator); layout->addLayout(titleBar); @@ -71,32 +57,19 @@ YACReaderTranslator::YACReaderTranslator(Viewer *parent) text->setMaximumHeight(110); layout->addSpacing(12); layout->addWidget(text); - text->setStyleSheet("QTextEdit{border:none;background:#2a2a2a;color:white; font-size:12px; padding:6px;}" + scrollBarStyle); // COMBOBOXES auto combos = new QHBoxLayout(); from = new QComboBox(this); to = new QComboBox(this); - QString comboBoxStyle = "QComboBox {border:none;background:#2a2a2a;color:white;font-size:12px;font-family:Arial;padding-left:8px;}" - "QComboBox::down-arrow {image: url(:/images/dropDownArrow.png);}" - "QComboBox::drop-down {border:none; padding-right:10px;}" - "QComboBox QAbstractItemView {border: none; background:#272727; color:white; selection-background-color: #202020; outline:none;}" - "QComboBox QAbstractItemView::item {padding-left:8px;}" + - scrollBarStyle; - from->setStyleSheet(comboBoxStyle); - to->setStyleSheet(comboBoxStyle); from->setFixedHeight(22); to->setFixedHeight(22); - QLabel *arrow = new QLabel(this); - QPixmap arrowPixmap(":/images/fromTo.png"); - arrow->setPixmap(arrowPixmap); - auto searchButton = new QPushButton(this); - searchButton->setIcon(QIcon(":/images/translatorSearch.png")); - searchButton->setStyleSheet("QPushButton {border:none; background:#2a2a2a;}"); + arrowLabel = new QLabel(this); + searchButton = new QPushButton(this); searchButton->setFixedSize(22, 22); combos->addWidget(from, 1); combos->addSpacing(9); - combos->addWidget(arrow, 0); + combos->addWidget(arrowLabel, 0); combos->addSpacing(9); combos->addWidget(to, 1); combos->addSpacing(9); @@ -107,10 +80,8 @@ YACReaderTranslator::YACReaderTranslator(Viewer *parent) // RESULTS auto resultsTitleLayout = new QHBoxLayout(); resultsTitle = new QLabel(tr("Translation")); - resultsTitle->setStyleSheet("QLabel {font-family:Arial;font-size:14px;color:#e3e3e3;}"); speakButton = new QPushButton(this); speakButton->setStyleSheet("QPushButton {border:none;}"); - speakButton->setIcon(QIcon(":/images/speaker.png")); resultsTitleLayout->addWidget(resultsTitle, 0, Qt::AlignVCenter); resultsTitleLayout->addSpacing(10); resultsTitleLayout->addWidget(speakButton, 0, Qt::AlignVCenter); @@ -122,7 +93,6 @@ YACReaderTranslator::YACReaderTranslator(Viewer *parent) resultText = new QLabel(); resultText->setWordWrap(true); - resultText->setStyleSheet("QLabel {color:white;font-size:12px;}"); resultText->setText(""); layout->addWidget(resultText); @@ -132,7 +102,6 @@ YACReaderTranslator::YACReaderTranslator(Viewer *parent) clearButton = new QPushButton(tr("clear")); layout->addWidget(clearButton, 0, Qt::AlignRight); clearButton->setMinimumWidth(95); - clearButton->setStyleSheet("QPushButton {border:1px solid #212121; background:#2a2a2a; color:white; font-family:Arial; font-size:12px; padding-top:5px; padding-bottom:5px;}"); resize(400, 479); @@ -147,13 +116,41 @@ YACReaderTranslator::YACReaderTranslator(Viewer *parent) busyIndicator->move((this->width() - busyIndicator->width()) / 2, (this->height() - busyIndicator->height()) * 2 / 3); busyIndicator->hide(); - show(); - connect(searchButton, &QAbstractButton::pressed, this, &YACReaderTranslator::translate); connect(speakButton, &QAbstractButton::pressed, this, &YACReaderTranslator::play); connect(clearButton, &QAbstractButton::pressed, this, &YACReaderTranslator::clear); tts = new QTextToSpeech(this); + + initTheme(this); + + show(); +} + +void YACReaderTranslator::applyTheme(const Theme &theme) +{ + const auto &tr = theme.translator; + + QPalette p(this->palette()); + p.setColor(QPalette::Window, tr.backgroundColor); + this->setPalette(p); + + text->setStyleSheet(tr.textEditQSS + tr.scrollBarQSS); + from->setStyleSheet(tr.comboBoxQSS + tr.scrollBarQSS); + to->setStyleSheet(tr.comboBoxQSS + tr.scrollBarQSS); + + titleLabel->setStyleSheet(tr.titleQSS); + resultsTitle->setStyleSheet(tr.resultsTitleQSS); + resultText->setStyleSheet(tr.resultTextQSS); + clearButton->setStyleSheet(tr.clearButtonQSS); + + searchButton->setStyleSheet( + QString("QPushButton {border:none; background:%1;}").arg(tr.inputBackgroundColor.name())); + + closeButton->setIcon(tr.closeIcon); + speakButton->setIcon(tr.speakerIcon); + searchButton->setIcon(tr.searchIcon); + arrowLabel->setPixmap(tr.fromToPixmap); } void YACReaderTranslator::hideResults() diff --git a/YACReader/translator.h b/YACReader/translator.h index b26b2480d..3cfb7fa56 100644 --- a/YACReader/translator.h +++ b/YACReader/translator.h @@ -14,8 +14,9 @@ class QTextToSpeech; #include #include #include "viewer.h" +#include "themable.h" -class YACReaderTranslator : public QWidget +class YACReaderTranslator : public QWidget, protected Themable { Q_OBJECT public: @@ -31,6 +32,7 @@ protected slots: void clear(); protected: + void applyTheme(const Theme &theme) override; void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; @@ -48,8 +50,12 @@ protected slots: QTextEdit *text; QComboBox *from; QComboBox *to; + QLabel *titleLabel; QLabel *resultsTitle; + QLabel *arrowLabel; QPushButton *speakButton; + QPushButton *closeButton; + QPushButton *searchButton; QLabel *resultText; YACReaderBusyWidget *busyIndicator; QPushButton *clearButton; diff --git a/YACReader/yacreader_images.qrc b/YACReader/yacreader_images.qrc index a5ba0eb8f..a5b011eda 100644 --- a/YACReader/yacreader_images.qrc +++ b/YACReader/yacreader_images.qrc @@ -13,10 +13,12 @@ ../images/centerFlow.svg ../images/gotoFlow.svg ../images/defaultCover.png - ../images/fromTo.png - ../images/dropDownArrow.png - ../images/translatorSearch.png - ../images/speaker.png + + ../images/translator/close.svg + ../images/translator/dropDownArrow.svg + ../images/translator/fromTo.svg + ../images/translator/speaker.svg + ../images/translator/translatorSearch.svg ../images/shortcuts/clear_shortcut.svg ../images/shortcuts/accept_shortcut.svg ../images/shortcuts/shortcuts_group_comics.svg diff --git a/images/dropDownArrow.png b/images/dropDownArrow.png deleted file mode 100644 index db5ea8d86c0370fe18b9b2cfa16888781d22821a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^AT}!p8<4C?sm%aVk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XG(BA$Ln>}1{rLa?|DXRY2W!{_6c$J<;$SP#a0_j5HY{_^ f=rR;xWRYOdSXO+pcit2)pe6=SS3j3^P6|6H_V+Po~-c75RF)IEGZ*N=i7u^zZ-wdbuuE2@b{ui+=xCOt3fX;%)e0 z8{%wlC?)hy*@4MW>es?9$88b^Y@B&^oIm2A+whR5%hn_4!bB;}h{e(h2N*)!)<0a} SziT?sUDSr z1<%~X^wgl##FWaylc_d9MOmIMjv*Ddk`fLu{rmr4pW(>!!jpy%m>fKr754ET`M>dm zCd0>S1-}E!3>mb3%10VcxXEydBh}jBs)fOyzopr04}~nLjV8( diff --git a/images/translator/close.svg b/images/translator/close.svg new file mode 100644 index 000000000..26729e51e --- /dev/null +++ b/images/translator/close.svg @@ -0,0 +1,15 @@ + + + + + + + + \ No newline at end of file diff --git a/images/translator/dropDownArrow.svg b/images/translator/dropDownArrow.svg new file mode 100644 index 000000000..46e0d5873 --- /dev/null +++ b/images/translator/dropDownArrow.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/translator/fromTo.svg b/images/translator/fromTo.svg new file mode 100644 index 000000000..53e0843de --- /dev/null +++ b/images/translator/fromTo.svg @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/images/translator/speaker.svg b/images/translator/speaker.svg new file mode 100644 index 000000000..27fe7bf40 --- /dev/null +++ b/images/translator/speaker.svg @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/images/translator/translatorSearch.svg b/images/translator/translatorSearch.svg new file mode 100644 index 000000000..c8fddaef6 --- /dev/null +++ b/images/translator/translatorSearch.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/images/translatorSearch.png b/images/translatorSearch.png deleted file mode 100644 index 066f21e9bbcf0c0ea8884a8a02f8b06fef84d49d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 241 zcmeAS@N?(olHy`uVBq!ia0vp@K+MCz1|)ZGH@^v_BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrH1%P4;wg45_%4l+e)h|Nnn!hL6Aga}>yT2ul<&E?B}G@~~Rr z9s46T1v`Gx+5O&^Yc<3igy-{LebI1w8jDUFr^C}<6OYcEaD)GXsiBck9YYX%!wrV% zYOFbCjG7ZJ>pl1+tRWy$@I#Yfwi@$_W#0o@c>|gg9@tbVJnT}RaENJz;||kD9em7Q mrcE0dnKv@55?sTmaDbs(_O*jTpQ0Afc?_PeelF{r5}E*5WmF*m From d6331ee819ad2c7b271432190fa8ff34c82d4a5f Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 5 Mar 2026 18:58:21 +0100 Subject: [PATCH 122/187] Update what's new --- CHANGELOG.md | 2 ++ custom_widgets/whats_new_dialog.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aeda4c969..bdc88b953 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,12 @@ Version counting is based on semantic versioning (Major.Feature.Patch) ### YACReader * Add support for continuous scroll mode. +* Fix the translator. ### All GUI Apps * Migrate Flow implementation from OpenGL to QRhi. This is a full new implementation with better performance and compatibility with operating systems and hardware. * Add light/dark themes support that follow the system configuration. +* Add a theme editor and support for custom themes. ## 9.16.4 diff --git a/custom_widgets/whats_new_dialog.cpp b/custom_widgets/whats_new_dialog.cpp index d3c694076..c1467e62b 100644 --- a/custom_widgets/whats_new_dialog.cpp +++ b/custom_widgets/whats_new_dialog.cpp @@ -41,10 +41,12 @@ YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent) "
" "YACReader
" " • Add support for continuous scroll mode
" + " • Fix the translator
" "
" "All GUI Apps
" " • Migrate Flow implementation from OpenGL to QRhi. This is a full new implementation with better performance and compatibility with operating systems and hardware
" " • Add light/dark themes support that follow the system configuration
" + " • Add a theme editor and support for custom themes
" "
" "I hope you enjoy the new update. Please, if you like YACReader consider to become a patron in Patreon " "or donate some money using Pay-Pal and help keeping the project alive. " From e6364068552ac279ef686f64c8dedd4c08ec1e89 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 5 Mar 2026 21:10:52 +0100 Subject: [PATCH 123/187] Fix the magnifying glass in continuous scroll mode --- YACReader/magnifying_glass.cpp | 103 +-------------------- YACReader/viewer.cpp | 163 +++++++++++++++++++++++++++++++++ YACReader/viewer.h | 1 + 3 files changed, 167 insertions(+), 100 deletions(-) diff --git a/YACReader/magnifying_glass.cpp b/YACReader/magnifying_glass.cpp index 3c166ff38..5bc1f78df 100644 --- a/YACReader/magnifying_glass.cpp +++ b/YACReader/magnifying_glass.cpp @@ -1,10 +1,5 @@ #include "magnifying_glass.h" #include "viewer.h" -#include "configuration.h" - -#include "theme_manager.h" - -#include MagnifyingGlass::MagnifyingGlass(int w, int h, float zoomLevel, QWidget *parent) : QLabel(parent), zoomLevel(zoomLevel) @@ -34,101 +29,9 @@ void MagnifyingGlass::mouseMoveEvent(QMouseEvent *event) void MagnifyingGlass::updateImage(int x, int y) { - // image section augmented - int zoomWidth = static_cast(width() * zoomLevel); - int zoomHeight = static_cast(height() * zoomLevel); - auto *const p = qobject_cast(parentWidget()); - int currentPos = p->verticalScrollBar()->sliderPosition(); - const QPixmap image = p->pixmap(); - int iWidth = image.width(); - int iHeight = image.height(); - float wFactor = static_cast(iWidth) / p->widget()->width(); - float hFactor = static_cast(iHeight) / p->widget()->height(); - zoomWidth *= wFactor; - zoomHeight *= hFactor; - if (p->verticalScrollBar()->minimum() == p->verticalScrollBar()->maximum()) { - int xp = static_cast(((x - p->widget()->pos().x()) * wFactor) - zoomWidth / 2); - int yp = static_cast((y - p->widget()->pos().y() + currentPos) * hFactor - zoomHeight / 2); - int xOffset = 0; - int yOffset = 0; - int zw = zoomWidth; - int zh = zoomHeight; - // int wOffset,hOffset=0; - bool outImage = false; - if (xp < 0) { - xOffset = -xp; - xp = 0; - zw = zw - xOffset; - outImage = true; - } - if (yp < 0) { - yOffset = -yp; - yp = 0; - zh = zh - yOffset; - outImage = true; - } - - if (xp + zoomWidth >= image.width()) { - zw -= xp + zw - image.width(); - outImage = true; - } - if (yp + zoomHeight >= image.height()) { - zh -= yp + zh - image.height(); - outImage = true; - } - if (outImage) { - QImage img(zoomWidth, zoomHeight, QImage::Format_RGB32); - img.setDevicePixelRatio(devicePixelRatioF()); - img.fill(Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor)); - if (zw > 0 && zh > 0) { - QPainter painter(&img); - painter.drawPixmap(xOffset, yOffset, image.copy(xp, yp, zw, zh)); - } - setPixmap(QPixmap().fromImage(img)); - } else - setPixmap(image.copy(xp, yp, zoomWidth, zoomHeight)); - } else { - int xp = static_cast(((x - p->widget()->pos().x()) * wFactor) - zoomWidth / 2); - int yp = static_cast((y + currentPos) * hFactor - zoomHeight / 2); - int xOffset = 0; - int yOffset = 0; - int zw = zoomWidth; - int zh = zoomHeight; - // int wOffset,hOffset=0; - bool outImage = false; - if (xp < 0) { - xOffset = -xp; - xp = 0; - zw = zw - xOffset; - outImage = true; - } - if (yp < 0) { - yOffset = -yp; - yp = 0; - zh = zh - yOffset; - outImage = true; - } - - if (xp + zoomWidth >= image.width()) { - zw -= xp + zw - image.width(); - outImage = true; - } - if (yp + zoomHeight >= image.height()) { - zh -= yp + zh - image.height(); - outImage = true; - } - if (outImage) { - QImage img(zoomWidth, zoomHeight, QImage::Format_RGB32); - img.setDevicePixelRatio(devicePixelRatioF()); - img.fill(Configuration::getConfiguration().getBackgroundColor(ThemeManager::instance().getCurrentTheme().viewer.defaultBackgroundColor)); - if (zw > 0 && zh > 0) { - QPainter painter(&img); - painter.drawPixmap(xOffset, yOffset, image.copy(xp, yp, zw, zh)); - } - setPixmap(QPixmap().fromImage(img)); - } else - setPixmap(image.copy(xp, yp, zoomWidth, zoomHeight)); - } + auto *const viewer = qobject_cast(parentWidget()); + QImage img = viewer->grabMagnifiedRegion(QPoint(x, y), size(), zoomLevel); + setPixmap(QPixmap::fromImage(img)); move(static_cast(x - float(width()) / 2), static_cast(y - float(height()) / 2)); } diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index 6eae05adf..4533bbbef 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -16,6 +16,7 @@ #include #include +#include #include @@ -850,6 +851,168 @@ QPixmap Viewer::pixmap() const return content->pixmap(); } +QImage Viewer::grabMagnifiedRegion(const QPoint &viewerPos, const QSize &glassSize, float zoomLevel) const +{ + const int glassW = glassSize.width(); + const int glassH = glassSize.height(); + const int zoomW = static_cast(glassW * zoomLevel); + const int zoomH = static_cast(glassH * zoomLevel); + const QColor bgColor = Configuration::getConfiguration().getBackgroundColor(theme.viewer.defaultBackgroundColor); + + if (continuousScroll) { + // --- continuous mode --- + // map viewer coords to continuousWidget coords + const int scrollPos = verticalScrollBar()->sliderPosition(); + const int cwX = viewerPos.x(); + const int cwY = viewerPos.y() + scrollPos; + const int widgetW = continuousWidget->width(); + + // use the page under the cursor to derive source-to-widget scale factors, + // so the result image is sized at source resolution (like single-page mode) + int centerPageIdx = continuousViewModel->pageAtY(cwY); + centerPageIdx = qBound(0, centerPageIdx, continuousViewModel->numPages() - 1); + const QImage *centerImg = render->bufferedImage(centerPageIdx); + const QSize centerScaledSize = continuousViewModel->scaledPageSize(centerPageIdx); + + float wFactor = 1.0f, hFactor = 1.0f; + if (centerImg && !centerImg->isNull() && !centerScaledSize.isEmpty()) { + wFactor = static_cast(centerImg->width()) / centerScaledSize.width(); + hFactor = static_cast(centerImg->height()) / centerScaledSize.height(); + } + + // result image sized in source-resolution pixels (full quality) + const int resultW = static_cast(zoomW * wFactor); + const int resultH = static_cast(zoomH * hFactor); + + QImage result(resultW, resultH, QImage::Format_RGB32); + result.setDevicePixelRatio(devicePixelRatioF()); + result.fill(bgColor); + + // zoom region in widget coordinates (centered on cursor) + const int regionLeft = cwX - zoomW / 2; + const int regionTop = cwY - zoomH / 2; + const int regionRight = regionLeft + zoomW; + const int regionBottom = regionTop + zoomH; + + // find which pages overlap the zoom region + int firstPage = continuousViewModel->pageAtY(regionTop); + int lastPage = continuousViewModel->pageAtY(regionBottom); + firstPage = qBound(0, firstPage, continuousViewModel->numPages() - 1); + lastPage = qBound(0, lastPage, continuousViewModel->numPages() - 1); + + QPainter painter(&result); + for (int i = firstPage; i <= lastPage; ++i) { + const QImage *srcImg = render->bufferedImage(i); + if (!srcImg || srcImg->isNull()) { + continue; + } + + const QSize scaledSize = continuousViewModel->scaledPageSize(i); + const int pageY = continuousViewModel->yPositionForPage(i); + int pageX = (widgetW - scaledSize.width()) / 2; + if (pageX < 0) { + pageX = 0; + } + + // intersection of zoom region and page rect (widget coords) + const int isectLeft = qMax(regionLeft, pageX); + const int isectTop = qMax(regionTop, pageY); + const int isectRight = qMin(regionRight, pageX + scaledSize.width()); + const int isectBottom = qMin(regionBottom, pageY + scaledSize.height()); + + if (isectLeft >= isectRight || isectTop >= isectBottom) { + continue; + } + + // map intersection to source image coordinates (full resolution crop) + const float pageScaleX = static_cast(srcImg->width()) / scaledSize.width(); + const float pageScaleY = static_cast(srcImg->height()) / scaledSize.height(); + + const int srcX = static_cast((isectLeft - pageX) * pageScaleX); + const int srcY = static_cast((isectTop - pageY) * pageScaleY); + const int srcW = static_cast((isectRight - isectLeft) * pageScaleX); + const int srcH = static_cast((isectBottom - isectTop) * pageScaleY); + + // destination in result image (source-resolution coordinates) + const int dstX = static_cast((isectLeft - regionLeft) * wFactor); + const int dstY = static_cast((isectTop - regionTop) * hFactor); + const int dstW = static_cast((isectRight - isectLeft) * wFactor); + const int dstH = static_cast((isectBottom - isectTop) * hFactor); + + QImage cropped = srcImg->copy(srcX, srcY, srcW, srcH); + if (cropped.size() != QSize(dstW, dstH)) { + cropped = cropped.scaled(dstW, dstH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } + painter.drawImage(dstX, dstY, cropped); + } + + return result; + } + + // --- single-page mode --- + const QPixmap image = content->pixmap(); + if (image.isNull()) { + QImage result(zoomW, zoomH, QImage::Format_RGB32); + result.setDevicePixelRatio(devicePixelRatioF()); + result.fill(bgColor); + return result; + } + + const int iWidth = image.width(); + const int iHeight = image.height(); + const float wFactor = static_cast(iWidth) / widget()->width(); + const float hFactor = static_cast(iHeight) / widget()->height(); + const int zoomWScaled = static_cast(zoomW * wFactor); + const int zoomHScaled = static_cast(zoomH * hFactor); + + const int scrollPos = verticalScrollBar()->sliderPosition(); + int xp, yp; + if (verticalScrollBar()->minimum() == verticalScrollBar()->maximum()) { + xp = static_cast(((viewerPos.x() - widget()->pos().x()) * wFactor) - zoomWScaled / 2); + yp = static_cast((viewerPos.y() - widget()->pos().y() + scrollPos) * hFactor - zoomHScaled / 2); + } else { + xp = static_cast(((viewerPos.x() - widget()->pos().x()) * wFactor) - zoomWScaled / 2); + yp = static_cast((viewerPos.y() + scrollPos) * hFactor - zoomHScaled / 2); + } + + int xOffset = 0, yOffset = 0; + int zw = zoomWScaled, zh = zoomHScaled; + bool outImage = false; + if (xp < 0) { + xOffset = -xp; + xp = 0; + zw -= xOffset; + outImage = true; + } + if (yp < 0) { + yOffset = -yp; + yp = 0; + zh -= yOffset; + outImage = true; + } + if (xp + zoomWScaled >= iWidth) { + zw -= xp + zw - iWidth; + outImage = true; + } + if (yp + zoomHScaled >= iHeight) { + zh -= yp + zh - iHeight; + outImage = true; + } + + if (outImage) { + QImage img(zoomWScaled, zoomHScaled, QImage::Format_RGB32); + img.setDevicePixelRatio(devicePixelRatioF()); + img.fill(bgColor); + if (zw > 0 && zh > 0) { + QPainter painter(&img); + painter.drawPixmap(xOffset, yOffset, image.copy(xp, yp, zw, zh)); + } + return img; + } + + return image.copy(xp, yp, zoomWScaled, zoomHScaled).toImage(); +} + void Viewer::magnifyingGlassSwitch() { magnifyingGlassShown ? hideMagnifyingGlass() : showMagnifyingGlass(); diff --git a/YACReader/viewer.h b/YACReader/viewer.h index 99e6b60aa..b2393a893 100644 --- a/YACReader/viewer.h +++ b/YACReader/viewer.h @@ -214,6 +214,7 @@ public slots: Viewer(QWidget *parent = nullptr); ~Viewer(); QPixmap pixmap() const; + QImage grabMagnifiedRegion(const QPoint &viewerPos, const QSize &glassSize, float zoomLevel) const; // Comic * getComic(){return comic;} const BookmarksDialog *getBookmarksDialog() { return bd; } // returns the current index starting in 1 [1,nPages] From 0f4a1f950e94e5a962dc39bb16b5f33d2c1ef619 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 5 Mar 2026 22:03:05 +0100 Subject: [PATCH 124/187] Start signing YACReader 10 dev builds that get published --- .github/workflows/build.yml | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f93ce14ec..4df9ccc29 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,8 +13,8 @@ on: - yacreader10 env: - IS_ORIGINAL_REPO: ${{ github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') }} - IS_FORK: ${{ github.repository != 'YACReader/yacreader' || (github.ref != 'refs/heads/master' && github.ref != 'refs/heads/develop') }} + IS_ORIGINAL_REPO: ${{ github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') }} + IS_FORK: ${{ github.repository != 'YACReader/yacreader' || (github.ref != 'refs/heads/master' && github.ref != 'refs/heads/develop' && github.ref != 'refs/heads/yacreader10') }} jobs: # Build number generation @@ -141,7 +141,7 @@ jobs: npm install -g appdmg - name: Import Code Signing Certificate - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') uses: apple-actions/import-codesign-certs@v2 with: p12-file-base64: ${{ secrets.MACOS_CERTIFICATE_P12_BASE64 }} @@ -160,7 +160,7 @@ jobs: run: ctest --test-dir build --output-on-failure - name: Notarize - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') run: | xcrun notarytool submit *.dmg --apple-id "${{ secrets.MACOS_APPLE_ID }}" --team-id "${{ secrets.MACOS_TEAM_ID }}" --password "${{ secrets.MACOS_APP_PASSWORD }}" --wait xcrun stapler staple *.dmg @@ -212,7 +212,7 @@ jobs: ctest --test-dir build --output-on-failure - name: Upload executables for signing - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') uses: actions/upload-artifact@v4 id: upload_executables with: @@ -223,7 +223,7 @@ jobs: build/bin/YACReaderLibraryServer.exe - name: Sign executables with SignPath - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') uses: signpath/github-action-submit-signing-request@v1 with: api-token: ${{ secrets.SIGNPATH_API_TOKEN }} @@ -237,7 +237,7 @@ jobs: output-artifact-directory: build/bin/signed - name: Replace with signed executables - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') shell: pwsh run: | Write-Host "=== Replacing executables with signed versions ===" @@ -259,7 +259,7 @@ jobs: .\create_installer.cmd x64 7z ${{ needs.initialization.outputs.build_number }} - name: Verify installer was created - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') shell: pwsh run: | if (-not (Test-Path "ci/win/Output/YACReader*.exe")) { @@ -268,7 +268,7 @@ jobs: Get-ChildItem "ci/win/Output/YACReader*.exe" - name: Upload unsigned installer - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') uses: actions/upload-artifact@v4 id: upload_unsigned with: @@ -276,7 +276,7 @@ jobs: path: ci/win/Output/YACReader*.exe - name: Submit to SignPath - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') uses: signpath/github-action-submit-signing-request@v1 with: api-token: ${{ secrets.SIGNPATH_API_TOKEN }} @@ -290,7 +290,7 @@ jobs: output-artifact-directory: ci/win/Output/signed - name: Replace with signed installer - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') shell: pwsh run: | Write-Host "=== Files in signed directory before move ===" @@ -350,7 +350,7 @@ jobs: cmake --build build --parallel - name: Upload executables for signing - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') uses: actions/upload-artifact@v4 id: upload_executables with: @@ -361,7 +361,7 @@ jobs: build/bin/YACReaderLibraryServer.exe - name: Submit to SignPath - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') uses: signpath/github-action-submit-signing-request@v1 with: api-token: ${{ secrets.SIGNPATH_API_TOKEN }} @@ -375,7 +375,7 @@ jobs: output-artifact-directory: 'build/bin/signed' - name: Replace executables with signed versions - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') shell: pwsh run: | Copy-Item "build/bin/signed/YACReader.exe" "build/bin/YACReader.exe" -Force @@ -392,7 +392,7 @@ jobs: .\create_installer.cmd arm64 7z ${{ needs.initialization.outputs.build_number }} - name: Verify installer was created - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') shell: pwsh run: | if (-not (Test-Path "ci/win/Output/YACReader*.exe")) { @@ -401,7 +401,7 @@ jobs: Get-ChildItem "ci/win/Output/YACReader*.exe" - name: Upload unsigned installer - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') uses: actions/upload-artifact@v4 id: upload_unsigned with: @@ -409,7 +409,7 @@ jobs: path: ci/win/Output/YACReader*.exe - name: Submit to SignPath - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') uses: signpath/github-action-submit-signing-request@v1 with: api-token: ${{ secrets.SIGNPATH_API_TOKEN }} @@ -423,7 +423,7 @@ jobs: output-artifact-directory: 'ci/win/Output/signed' - name: Replace with signed installer and cleanup - if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop') + if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') shell: pwsh working-directory: ci/win/Output run: | @@ -769,7 +769,7 @@ jobs: echo " ✓ SIGNED - Signature verified successfully" osslsigncode verify -in "$installer" 2>&1 | grep -E "(Signed|Signer|Timestamp)" else - echo " ✗ UNSIGNED or INVALID - No valid signature found (expected for yacreader10 pre-releases)" + echo " ✗ UNSIGNED or INVALID - No valid signature found" osslsigncode verify -in "$installer" 2>&1 | head -20 fi echo "" From 09ae34cb10078205517d7929e5f769e5af475739 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 11:48:42 +0100 Subject: [PATCH 125/187] Include publish notes when releasing builds --- .../actions/extract-release-notes/action.yml | 31 +++ .../prepare-release-artifacts/action.yml | 61 ++++++ .github/workflows/build.yml | 183 +++--------------- 3 files changed, 119 insertions(+), 156 deletions(-) create mode 100644 .github/actions/extract-release-notes/action.yml create mode 100644 .github/actions/prepare-release-artifacts/action.yml diff --git a/.github/actions/extract-release-notes/action.yml b/.github/actions/extract-release-notes/action.yml new file mode 100644 index 000000000..0e1f49581 --- /dev/null +++ b/.github/actions/extract-release-notes/action.yml @@ -0,0 +1,31 @@ +name: Extract Release Notes +description: Extract release notes from CHANGELOG.md for a given version + +inputs: + version: + description: Version to extract notes for + required: true + +outputs: + notes: + description: Extracted release notes + value: ${{ steps.extract.outputs.notes }} + +runs: + using: composite + steps: + - id: extract + shell: bash + run: | + VERSION="${{ inputs.version }}" + MAJOR="${VERSION%%.*}" + # Try exact version match first, fall back to major version match + NOTES=$(awk "/^## ${VERSION}( |$)/{found=1; next} /^## /{if(found) exit} found{print}" CHANGELOG.md) + if [ -z "$NOTES" ]; then + NOTES=$(awk "/^## ${MAJOR}( |$)/{found=1; next} /^## /{if(found) exit} found{print}" CHANGELOG.md) + fi + { + echo "notes<> $GITHUB_OUTPUT diff --git a/.github/actions/prepare-release-artifacts/action.yml b/.github/actions/prepare-release-artifacts/action.yml new file mode 100644 index 000000000..b2280e1fe --- /dev/null +++ b/.github/actions/prepare-release-artifacts/action.yml @@ -0,0 +1,61 @@ +name: Prepare Release Artifacts +description: Download, flatten, and verify release artifacts for publishing + +runs: + using: composite + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: List downloaded artifacts + shell: bash + run: | + echo "=== All artifacts downloaded ===" + ls -lR artifacts/ + echo "" + echo "=== Windows artifacts only ===" + ls -l artifacts/windows-*/ + + - name: Flatten artifacts (exclude unsigned Windows installers) + shell: bash + run: | + mkdir -p staging + # Copy all files except those from unsigned Windows artifact directories + find artifacts -type f ! -path "*/windows-*-unsigned-*/*" -exec cp {} staging/ \; + echo "" + echo "=== Files copied to staging ===" + ls -lh staging/ + echo "" + echo "=== Windows installers in staging ===" + ls -lh staging/YACReader*.exe || echo "No Windows installers found" + + - name: Verify Windows installer signatures + shell: bash + run: | + echo "=== Installing osslsigncode to verify signatures ===" + sudo apt-get update + sudo apt-get install -y osslsigncode + + echo "" + echo "=== Checking signatures on Windows installers ===" + for installer in staging/YACReader*.exe; do + if [ -f "$installer" ]; then + echo "Checking: $(basename $installer)" + echo "File size: $(stat -c%s $installer) bytes" + + # Try to extract signature info + if osslsigncode verify -in "$installer" 2>&1 | grep -q "Signature verification: ok"; then + echo " ✓ SIGNED - Signature verified successfully" + osslsigncode verify -in "$installer" 2>&1 | grep -E "(Signed|Signer|Timestamp)" + else + echo " ✗ UNSIGNED or INVALID - No valid signature found" + osslsigncode verify -in "$installer" 2>&1 | head -20 + fi + echo "" + fi + done + + echo "=== Summary ===" + echo "Total installers in staging: $(ls staging/YACReader*.exe 2>/dev/null | wc -l)" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4df9ccc29..efa5c5d71 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -502,58 +502,8 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Download all artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - - - name: List downloaded artifacts - run: | - echo "=== All artifacts downloaded ===" - ls -lR artifacts/ - echo "" - echo "=== Windows artifacts only ===" - ls -l artifacts/windows-*/ - - - name: Flatten artifacts (exclude unsigned Windows installers) - run: | - mkdir -p staging - # Copy all files except those from unsigned Windows artifact directories - find artifacts -type f ! -path "*/windows-*-unsigned-*/*" -exec cp {} staging/ \; - echo "" - echo "=== Files copied to staging ===" - ls -lh staging/ - echo "" - echo "=== Windows installers in staging ===" - ls -lh staging/YACReader*.exe || echo "No Windows installers found" - - - name: Verify Windows installer signatures - run: | - echo "=== Installing osslsigncode to verify signatures ===" - sudo apt-get update - sudo apt-get install -y osslsigncode - - echo "" - echo "=== Checking signatures on Windows installers ===" - for installer in staging/YACReader*.exe; do - if [ -f "$installer" ]; then - echo "Checking: $(basename $installer)" - echo "File size: $(stat -c%s $installer) bytes" - - # Try to extract signature info - if osslsigncode verify -in "$installer" 2>&1 | grep -q "Signature verification: ok"; then - echo " ✓ SIGNED - Signature verified successfully" - osslsigncode verify -in "$installer" 2>&1 | grep -E "(Signed|Signer|Timestamp)" - else - echo " ✗ UNSIGNED or INVALID - No valid signature found" - osslsigncode verify -in "$installer" 2>&1 | head -20 - fi - echo "" - fi - done - - echo "=== Summary ===" - echo "Total installers in staging: $(ls staging/YACReader*.exe 2>/dev/null | wc -l)" + - name: Prepare release artifacts + uses: ./.github/actions/prepare-release-artifacts - name: Get version id: version @@ -562,6 +512,12 @@ jobs: echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" + - name: Extract release notes + id: release_notes + uses: ./.github/actions/extract-release-notes + with: + version: ${{ steps.version.outputs.version }} + - name: Login to Docker Hub uses: docker/login-action@v3 with: @@ -590,6 +546,7 @@ jobs: repository: YACReader/yacreader-dev-builds tag_name: ${{ steps.version.outputs.version }} name: ${{ steps.version.outputs.version }} + body: ${{ steps.release_notes.outputs.notes }} target_commitish: 25313e3d4d03fcbe44d3943db23bc03bbd1a5205 files: staging/* env: @@ -612,58 +569,8 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Download all artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - - - name: List downloaded artifacts - run: | - echo "=== All artifacts downloaded ===" - ls -lR artifacts/ - echo "" - echo "=== Windows artifacts only ===" - ls -l artifacts/windows-*/ - - - name: Flatten artifacts (exclude unsigned Windows installers) - run: | - mkdir -p staging - # Copy all files except those from unsigned Windows artifact directories - find artifacts -type f ! -path "*/windows-*-unsigned-*/*" -exec cp {} staging/ \; - echo "" - echo "=== Files copied to staging ===" - ls -lh staging/ - echo "" - echo "=== Windows installers in staging ===" - ls -lh staging/YACReader*.exe || echo "No Windows installers found" - - - name: Verify Windows installer signatures - run: | - echo "=== Installing osslsigncode to verify signatures ===" - sudo apt-get update - sudo apt-get install -y osslsigncode - - echo "" - echo "=== Checking signatures on Windows installers ===" - for installer in staging/YACReader*.exe; do - if [ -f "$installer" ]; then - echo "Checking: $(basename $installer)" - echo "File size: $(stat -c%s $installer) bytes" - - # Try to extract signature info - if osslsigncode verify -in "$installer" 2>&1 | grep -q "Signature verification: ok"; then - echo " ✓ SIGNED - Signature verified successfully" - osslsigncode verify -in "$installer" 2>&1 | grep -E "(Signed|Signer|Timestamp)" - else - echo " ✗ UNSIGNED or INVALID - No valid signature found" - osslsigncode verify -in "$installer" 2>&1 | head -20 - fi - echo "" - fi - done - - echo "=== Summary ===" - echo "Total installers in staging: $(ls staging/YACReader*.exe 2>/dev/null | wc -l)" + - name: Prepare release artifacts + uses: ./.github/actions/prepare-release-artifacts - name: Get version id: version @@ -672,6 +579,12 @@ jobs: echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" + - name: Extract release notes + id: release_notes + uses: ./.github/actions/extract-release-notes + with: + version: ${{ steps.version.outputs.version }} + - name: Login to Docker Hub uses: docker/login-action@v3 with: @@ -705,6 +618,7 @@ jobs: with: tag_name: ${{ steps.version.outputs.version }} name: ${{ steps.version.outputs.version }} + body: ${{ steps.release_notes.outputs.notes }} files: staging/* env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -726,58 +640,8 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Download all artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - - - name: List downloaded artifacts - run: | - echo "=== All artifacts downloaded ===" - ls -lR artifacts/ - echo "" - echo "=== Windows artifacts only ===" - ls -l artifacts/windows-*/ - - - name: Flatten artifacts (exclude unsigned Windows installers) - run: | - mkdir -p staging - # Copy all files except those from unsigned Windows artifact directories - find artifacts -type f ! -path "*/windows-*-unsigned-*/*" -exec cp {} staging/ \; - echo "" - echo "=== Files copied to staging ===" - ls -lh staging/ - echo "" - echo "=== Windows installers in staging ===" - ls -lh staging/YACReader*.exe || echo "No Windows installers found" - - - name: Verify Windows installer signatures - run: | - echo "=== Installing osslsigncode to verify signatures ===" - sudo apt-get update - sudo apt-get install -y osslsigncode - - echo "" - echo "=== Checking signatures on Windows installers ===" - for installer in staging/YACReader*.exe; do - if [ -f "$installer" ]; then - echo "Checking: $(basename $installer)" - echo "File size: $(stat -c%s $installer) bytes" - - # Try to extract signature info - if osslsigncode verify -in "$installer" 2>&1 | grep -q "Signature verification: ok"; then - echo " ✓ SIGNED - Signature verified successfully" - osslsigncode verify -in "$installer" 2>&1 | grep -E "(Signed|Signer|Timestamp)" - else - echo " ✗ UNSIGNED or INVALID - No valid signature found" - osslsigncode verify -in "$installer" 2>&1 | head -20 - fi - echo "" - fi - done - - echo "=== Summary ===" - echo "Total installers in staging: $(ls staging/YACReader*.exe 2>/dev/null | wc -l)" + - name: Prepare release artifacts + uses: ./.github/actions/prepare-release-artifacts - name: Get version id: version @@ -786,6 +650,12 @@ jobs: echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" + - name: Extract release notes + id: release_notes + uses: ./.github/actions/extract-release-notes + with: + version: ${{ steps.version.outputs.version }} + - name: Login to Docker Hub uses: docker/login-action@v3 with: @@ -815,6 +685,7 @@ jobs: repository: YACReader/yacreader-dev-builds tag_name: ${{ steps.version.outputs.version }} name: ${{ steps.version.outputs.version }} + body: ${{ steps.release_notes.outputs.notes }} prerelease: true target_commitish: 25313e3d4d03fcbe44d3943db23bc03bbd1a5205 files: staging/* From 9024ff7d0cd8843dd7d8cc3d2ad15eff43dfe33b Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 12:01:36 +0100 Subject: [PATCH 126/187] Add scripts that can be used to ensure format --- scripts/clang-format-linux.sh | 44 +++++++++++++++++++++++ scripts/clang-format-macos.sh | 44 +++++++++++++++++++++++ scripts/clang-format-windows.cmd | 6 ++++ scripts/clang-format-windows.ps1 | 62 ++++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+) create mode 100755 scripts/clang-format-linux.sh create mode 100755 scripts/clang-format-macos.sh create mode 100644 scripts/clang-format-windows.cmd create mode 100644 scripts/clang-format-windows.ps1 diff --git a/scripts/clang-format-linux.sh b/scripts/clang-format-linux.sh new file mode 100755 index 000000000..f400e2aea --- /dev/null +++ b/scripts/clang-format-linux.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" + +TEST_MODE=0 +if [[ $# -gt 1 ]]; then + echo "Unknown arguments. Supported flags: --test, -t" >&2 + exit 2 +fi + +if [[ $# -eq 1 ]]; then + if [[ "${1:-}" == "--test" || "${1:-}" == "-t" ]]; then + TEST_MODE=1 + else + echo "Unknown argument: ${1:-}. Supported flags: --test, -t" >&2 + exit 2 + fi +fi + +cd "${REPO_ROOT}" + +if ! VERSION_OUTPUT="$(clang-format --version 2>/dev/null)"; then + echo "Unable to run clang-format --version. Make sure clang-format is in PATH." >&2 + exit 127 +fi + +if [[ "${VERSION_OUTPUT}" =~ clang-format[[:space:]]+version[[:space:]]+([0-9]+(\.[0-9]+)*) ]]; then + VERSION="${BASH_REMATCH[1]}" + echo "Running using clang-format ${VERSION}" +else + echo "Running using ${VERSION_OUTPUT}" +fi + +find . \( -name '*.h' -or -name '*.cpp' -or -name '*.c' -or -name '*.mm' -or -name '*.m' \) -print0 | xargs -0 clang-format -style=file -i + +if [[ "${TEST_MODE}" -eq 1 ]]; then + BASE_SHA="$(git rev-parse HEAD)" + git diff "${BASE_SHA}" + if [[ "$(git diff "${BASE_SHA}")" != "" ]]; then + exit 1 + fi +fi diff --git a/scripts/clang-format-macos.sh b/scripts/clang-format-macos.sh new file mode 100755 index 000000000..f400e2aea --- /dev/null +++ b/scripts/clang-format-macos.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" + +TEST_MODE=0 +if [[ $# -gt 1 ]]; then + echo "Unknown arguments. Supported flags: --test, -t" >&2 + exit 2 +fi + +if [[ $# -eq 1 ]]; then + if [[ "${1:-}" == "--test" || "${1:-}" == "-t" ]]; then + TEST_MODE=1 + else + echo "Unknown argument: ${1:-}. Supported flags: --test, -t" >&2 + exit 2 + fi +fi + +cd "${REPO_ROOT}" + +if ! VERSION_OUTPUT="$(clang-format --version 2>/dev/null)"; then + echo "Unable to run clang-format --version. Make sure clang-format is in PATH." >&2 + exit 127 +fi + +if [[ "${VERSION_OUTPUT}" =~ clang-format[[:space:]]+version[[:space:]]+([0-9]+(\.[0-9]+)*) ]]; then + VERSION="${BASH_REMATCH[1]}" + echo "Running using clang-format ${VERSION}" +else + echo "Running using ${VERSION_OUTPUT}" +fi + +find . \( -name '*.h' -or -name '*.cpp' -or -name '*.c' -or -name '*.mm' -or -name '*.m' \) -print0 | xargs -0 clang-format -style=file -i + +if [[ "${TEST_MODE}" -eq 1 ]]; then + BASE_SHA="$(git rev-parse HEAD)" + git diff "${BASE_SHA}" + if [[ "$(git diff "${BASE_SHA}")" != "" ]]; then + exit 1 + fi +fi diff --git a/scripts/clang-format-windows.cmd b/scripts/clang-format-windows.cmd new file mode 100644 index 000000000..9d59fcdd0 --- /dev/null +++ b/scripts/clang-format-windows.cmd @@ -0,0 +1,6 @@ +@echo off +setlocal + +set "SCRIPT_DIR=%~dp0" +powershell -NoProfile -ExecutionPolicy Bypass -File "%SCRIPT_DIR%clang-format-windows.ps1" %* +exit /b %ERRORLEVEL% diff --git a/scripts/clang-format-windows.ps1 b/scripts/clang-format-windows.ps1 new file mode 100644 index 000000000..a905ce92e --- /dev/null +++ b/scripts/clang-format-windows.ps1 @@ -0,0 +1,62 @@ +$ErrorActionPreference = "Stop" +Set-StrictMode -Version Latest + +$test = $false +foreach ($arg in $args) { + switch ($arg) { + "--test" { $test = $true; continue } + "-test" { $test = $true; continue } + "-t" { $test = $true; continue } + default { + Write-Error "Unknown argument: $arg. Supported flags: --test, -test, -t" + exit 2 + } + } +} + +$repoRoot = (Resolve-Path "$PSScriptRoot/..").Path +Set-Location $repoRoot + +$clangFormatCommand = Get-Command clang-format -ErrorAction SilentlyContinue +if (-not $clangFormatCommand) { + Write-Error "Unable to find clang-format in PATH." + exit 127 +} + +$clangFormat = $clangFormatCommand.Source +$versionOutput = & $clangFormat --version +if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($versionOutput)) { + Write-Error "Unable to run clang-format --version. Make sure clang-format is in PATH." + exit 127 +} + +$versionMatch = [regex]::Match($versionOutput, "clang-format version ([0-9]+(\.[0-9]+)*)") +if ($versionMatch.Success) { + Write-Host "Running using clang-format $($versionMatch.Groups[1].Value)" +} +else { + Write-Host "Running using $versionOutput" +} + +$extensions = @("*.h", "*.cpp", "*.c", "*.mm", "*.m") +$files = Get-ChildItem -Path . -Recurse -File | Where-Object { + $name = $_.Name + foreach ($ext in $extensions) { + if ($name -clike $ext) { + return $true + } + } + return $false +} + +foreach ($file in $files) { + & $clangFormat -style=file -i $file.FullName +} + +if ($test) { + $baseSha = "$(git rev-parse HEAD)".Trim() + git diff $baseSha + if ("$(git diff $baseSha)" -ne "") { + exit 1 + } +} From 86b5003f07e3a11fd84f90a91a36dd70bc51441f Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 12:29:06 +0100 Subject: [PATCH 127/187] Use target app and version in themes meta --- YACReader/main.cpp | 2 +- YACReader/themes/builtin_classic.json | 4 ++- YACReader/themes/builtin_dark.json | 4 ++- YACReader/themes/builtin_light.json | 4 ++- YACReader/themes/theme_factory.cpp | 2 ++ YACReaderLibrary/main.cpp | 2 +- YACReaderLibrary/themes/builtin_classic.json | 4 ++- YACReaderLibrary/themes/builtin_dark.json | 4 ++- YACReaderLibrary/themes/builtin_light.json | 4 ++- YACReaderLibrary/themes/theme_factory.cpp | 2 ++ common/themes/appearance_tab_widget.cpp | 9 ++++-- common/themes/theme_meta.h | 2 ++ common/themes/theme_repository.cpp | 31 ++++++++++++++++---- common/themes/theme_repository.h | 5 ++-- 14 files changed, 60 insertions(+), 19 deletions(-) diff --git a/YACReader/main.cpp b/YACReader/main.cpp index d1c98e224..66b0d52ab 100644 --- a/YACReader/main.cpp +++ b/YACReader/main.cpp @@ -120,7 +120,7 @@ int main(int argc, char *argv[]) auto *appearanceConfig = new AppearanceConfiguration( YACReader::getSettingsPath() + "/YACReader.ini", qApp); auto *themeRepo = new ThemeRepository( - ":/themes", YACReader::getSettingsPath() + "/themes/user"); + ":/themes", YACReader::getSettingsPath() + "/themes/user", "YACReader"); ThemeManager::instance().initialize(appearanceConfig, themeRepo); if (QIcon::hasThemeIcon("YACReader")) { diff --git a/YACReader/themes/builtin_classic.json b/YACReader/themes/builtin_classic.json index bf1b34159..fcac45c7f 100644 --- a/YACReader/themes/builtin_classic.json +++ b/YACReader/themes/builtin_classic.json @@ -19,7 +19,9 @@ "meta": { "displayName": "Default Classic", "id": "builtin/classic", - "variant": "dark" + "targetApp": "YACReader", + "variant": "dark", + "version": "10.0.0" }, "shortcutsIcons": { "iconColor": "#404040" diff --git a/YACReader/themes/builtin_dark.json b/YACReader/themes/builtin_dark.json index 193fa0b66..7efd26aeb 100644 --- a/YACReader/themes/builtin_dark.json +++ b/YACReader/themes/builtin_dark.json @@ -19,7 +19,9 @@ "meta": { "displayName": "Default Dark", "id": "builtin/dark", - "variant": "dark" + "targetApp": "YACReader", + "variant": "dark", + "version": "10.0.0" }, "shortcutsIcons": { "iconColor": "#d0d0d0" diff --git a/YACReader/themes/builtin_light.json b/YACReader/themes/builtin_light.json index a7aadc679..dc9209f78 100644 --- a/YACReader/themes/builtin_light.json +++ b/YACReader/themes/builtin_light.json @@ -19,7 +19,9 @@ "meta": { "displayName": "Default Light", "id": "builtin/light", - "variant": "light" + "targetApp": "YACReader", + "variant": "light", + "version": "10.0.0" }, "shortcutsIcons": { "iconColor": "#606060" diff --git a/YACReader/themes/theme_factory.cpp b/YACReader/themes/theme_factory.cpp index 7b7d052ad..6f5cfa8e9 100644 --- a/YACReader/themes/theme_factory.cpp +++ b/YACReader/themes/theme_factory.cpp @@ -363,6 +363,8 @@ Theme makeTheme(const QJsonObject &json) p.meta.variant = ThemeVariant::Light; else if (variantStr == "dark") p.meta.variant = ThemeVariant::Dark; + p.meta.targetApp = o["targetApp"].toString(p.meta.targetApp); + p.meta.version = o["version"].toString(p.meta.version); } Theme theme = makeTheme(p); diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index 4d82ea863..9c339e8f5 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -145,7 +145,7 @@ int main(int argc, char **argv) auto *appearanceConfig = new AppearanceConfiguration( YACReader::getSettingsPath() + "/YACReaderLibrary.ini", qApp); auto *themeRepo = new ThemeRepository( - ":/themes", YACReader::getSettingsPath() + "/themes/user"); + ":/themes", YACReader::getSettingsPath() + "/themes/user", "YACReaderLibrary"); ThemeManager::instance().initialize(appearanceConfig, themeRepo); // Set window icon according to Freedesktop icon specification diff --git a/YACReaderLibrary/themes/builtin_classic.json b/YACReaderLibrary/themes/builtin_classic.json index ea571a116..5fb6e4776 100644 --- a/YACReaderLibrary/themes/builtin_classic.json +++ b/YACReaderLibrary/themes/builtin_classic.json @@ -106,7 +106,9 @@ "meta": { "displayName": "Default Classic", "id": "builtin/classic", - "variant": "dark" + "targetApp": "YACReaderLibrary", + "variant": "dark", + "version": "10.0.0" }, "metadataScraperDialog": { "busyIndicatorColor": "#ffffff", diff --git a/YACReaderLibrary/themes/builtin_dark.json b/YACReaderLibrary/themes/builtin_dark.json index 6a9a7a281..7d043c8f2 100644 --- a/YACReaderLibrary/themes/builtin_dark.json +++ b/YACReaderLibrary/themes/builtin_dark.json @@ -106,7 +106,9 @@ "meta": { "displayName": "Default Dark", "id": "builtin/dark", - "variant": "dark" + "targetApp": "YACReaderLibrary", + "variant": "dark", + "version": "10.0.0" }, "metadataScraperDialog": { "busyIndicatorColor": "#ffffff", diff --git a/YACReaderLibrary/themes/builtin_light.json b/YACReaderLibrary/themes/builtin_light.json index 9d514d4be..3abc1dd76 100644 --- a/YACReaderLibrary/themes/builtin_light.json +++ b/YACReaderLibrary/themes/builtin_light.json @@ -106,7 +106,9 @@ "meta": { "displayName": "Default Light", "id": "builtin/light", - "variant": "light" + "targetApp": "YACReaderLibrary", + "variant": "light", + "version": "10.0.0" }, "metadataScraperDialog": { "busyIndicatorColor": "#000000", diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index eaba930da..bf1afbcdd 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -1165,6 +1165,8 @@ Theme makeTheme(const QJsonObject &json) p.meta.variant = ThemeVariant::Light; else if (variantStr == "dark") p.meta.variant = ThemeVariant::Dark; + p.meta.targetApp = o["targetApp"].toString(p.meta.targetApp); + p.meta.version = o["version"].toString(p.meta.version); } Theme theme = makeTheme(p); diff --git a/common/themes/appearance_tab_widget.cpp b/common/themes/appearance_tab_widget.cpp index 9dcb49c26..bcf1f2185 100644 --- a/common/themes/appearance_tab_widget.cpp +++ b/common/themes/appearance_tab_widget.cpp @@ -264,10 +264,13 @@ void AppearanceTabWidget::importTheme() if (path.isEmpty() || !repository) return; - const QString id = repository->importThemeFromFile(path); + QString errorMessage; + const QString id = repository->importThemeFromFile(path, &errorMessage); if (id.isEmpty()) { - QMessageBox::warning(this, tr("Import failed"), - tr("Could not import theme from:\n%1").arg(path)); + const QString detail = errorMessage.isEmpty() + ? tr("Could not import theme from:\n%1").arg(path) + : tr("Could not import theme from:\n%1\n\n%2").arg(path, errorMessage); + QMessageBox::warning(this, tr("Import failed"), detail); return; } diff --git a/common/themes/theme_meta.h b/common/themes/theme_meta.h index e3b9c6d8f..f4f803b3b 100644 --- a/common/themes/theme_meta.h +++ b/common/themes/theme_meta.h @@ -9,6 +9,8 @@ struct ThemeMeta { QString id; QString displayName; ThemeVariant variant; + QString targetApp; + QString version; }; #endif // THEME_META_H diff --git a/common/themes/theme_repository.cpp b/common/themes/theme_repository.cpp index d76695c88..96a3e0d5c 100644 --- a/common/themes/theme_repository.cpp +++ b/common/themes/theme_repository.cpp @@ -6,8 +6,8 @@ #include #include -ThemeRepository::ThemeRepository(const QString &qrcPrefix, const QString &userThemesDir) - : qrcPrefix(qrcPrefix), userThemesDir(userThemesDir) +ThemeRepository::ThemeRepository(const QString &qrcPrefix, const QString &userThemesDir, const QString &targetApp) + : qrcPrefix(qrcPrefix), userThemesDir(userThemesDir), targetApp(targetApp) { scanBuiltins(); scanUserThemes(); @@ -64,9 +64,14 @@ QString ThemeRepository::saveUserTheme(QJsonObject themeJson) const QString uuid = QUuid::createUuid().toString(QUuid::WithoutBraces); id = "user/" + uuid; metaObj["id"] = id; - themeJson["meta"] = metaObj; } + // Always stamp targetApp so saved themes are always identifiable + if (metaObj["targetApp"].toString().isEmpty()) + metaObj["targetApp"] = targetApp; + + themeJson["meta"] = metaObj; + // Extract uuid from "user/" const QString uuid = id.mid(5); // skip "user/" const QString filePath = filePathForUserTheme(uuid); @@ -100,11 +105,23 @@ bool ThemeRepository::deleteUserTheme(const QString &themeId) return false; } -QString ThemeRepository::importThemeFromFile(const QString &filePath) +QString ThemeRepository::importThemeFromFile(const QString &filePath, QString *errorMessage) { QJsonObject json = readJsonFile(filePath); - if (json.isEmpty()) + if (json.isEmpty()) { + if (errorMessage) + *errorMessage = QObject::tr("The file could not be read or is not valid JSON."); + return { }; + } + + // Check that the theme targets the correct application + const auto metaIn = json["meta"].toObject(); + const QString themeTargetApp = metaIn["targetApp"].toString(); + if (!themeTargetApp.isEmpty() && themeTargetApp != targetApp) { + if (errorMessage) + *errorMessage = QObject::tr("This theme is for %1, not %2.").arg(themeTargetApp, targetApp); return { }; + } // Force a new user id regardless of what the file contains auto metaObj = json["meta"].toObject(); @@ -181,7 +198,9 @@ ThemeMeta ThemeRepository::extractMeta(const QJsonObject &json) return ThemeMeta { meta["id"].toString(), meta["displayName"].toString(), - (meta["variant"].toString() == "light") ? ThemeVariant::Light : ThemeVariant::Dark + (meta["variant"].toString() == "light") ? ThemeVariant::Light : ThemeVariant::Dark, + meta["targetApp"].toString(), + meta["version"].toString() }; } diff --git a/common/themes/theme_repository.h b/common/themes/theme_repository.h index e9ec4a855..e1eeaebd3 100644 --- a/common/themes/theme_repository.h +++ b/common/themes/theme_repository.h @@ -17,7 +17,7 @@ struct ThemeListEntry { class ThemeRepository { public: - explicit ThemeRepository(const QString &qrcPrefix, const QString &userThemesDir); + explicit ThemeRepository(const QString &qrcPrefix, const QString &userThemesDir, const QString &targetApp); QList availableThemes() const; bool contains(const QString &themeId) const; @@ -25,13 +25,14 @@ class ThemeRepository QString saveUserTheme(QJsonObject themeJson); bool deleteUserTheme(const QString &themeId); - QString importThemeFromFile(const QString &filePath); + QString importThemeFromFile(const QString &filePath, QString *errorMessage = nullptr); void refresh(); private: QString qrcPrefix; QString userThemesDir; + QString targetApp; struct BuiltinEntry { QString id; From 0ceba0ea74f9040dd3071d66d3c842aefe7ce58e Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 15:06:20 +0100 Subject: [PATCH 128/187] Improve theme editor usability so themes can be set from it --- common/themes/appearance_tab_widget.cpp | 16 ++++++++++++++++ common/themes/theme_editor_dialog.cpp | 19 ++++++++++++++++--- common/themes/theme_editor_dialog.h | 3 +++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/common/themes/appearance_tab_widget.cpp b/common/themes/appearance_tab_widget.cpp index bcf1f2185..387ac0944 100644 --- a/common/themes/appearance_tab_widget.cpp +++ b/common/themes/appearance_tab_widget.cpp @@ -189,6 +189,22 @@ AppearanceTabWidget::AppearanceTabWidget( themeEditor->setAttribute(Qt::WA_DeleteOnClose); connect(themeEditor, &ThemeEditorDialog::themeJsonChanged, this, [this](const QJsonObject &json) { this->applyTheme(json); }); + connect(themeEditor, &ThemeEditorDialog::saveToLibraryRequested, this, + [this](const QJsonObject &json) { + if (!this->repository) + return; + const QString id = this->repository->saveUserTheme(json); + this->repopulateCombos(); + const bool isLight = (json["meta"].toObject()["variant"].toString() == "light"); + if (isLight) + selectInCombo(this->lightCombo, id); + else + selectInCombo(this->darkCombo, id); + if (this->config && this->config->selection().mode == ThemeMode::ForcedTheme) + selectInCombo(this->customCombo, id); + if (this->themeEditor) + this->themeEditor->updateSavedId(id); + }); } themeEditor->show(); themeEditor->raise(); diff --git a/common/themes/theme_editor_dialog.cpp b/common/themes/theme_editor_dialog.cpp index 72d033276..459f9b5bd 100644 --- a/common/themes/theme_editor_dialog.cpp +++ b/common/themes/theme_editor_dialog.cpp @@ -150,14 +150,19 @@ ThemeEditorDialog::ThemeEditorDialog(const QJsonObject ¶ms, QWidget *parent) }); // --- bottom buttons --- - auto *saveBtn = new QPushButton(tr("Save to file..."), this); + auto *saveLibBtn = new QPushButton(tr("Save and apply"), this); + auto *exportBtn = new QPushButton(tr("Export to file..."), this); auto *loadBtn = new QPushButton(tr("Load from file..."), this); auto *closeBtn = new QPushButton(tr("Close"), this); - connect(saveBtn, &QPushButton::clicked, this, &ThemeEditorDialog::saveToFile); + connect(saveLibBtn, &QPushButton::clicked, this, [this]() { + emit saveToLibraryRequested(this->params); + }); + connect(exportBtn, &QPushButton::clicked, this, &ThemeEditorDialog::saveToFile); connect(loadBtn, &QPushButton::clicked, this, &ThemeEditorDialog::loadFromFile); connect(closeBtn, &QPushButton::clicked, this, &QDialog::close); auto *buttons = new QHBoxLayout(); - buttons->addWidget(saveBtn); + buttons->addWidget(saveLibBtn); + buttons->addWidget(exportBtn); buttons->addWidget(loadBtn); buttons->addStretch(); buttons->addWidget(closeBtn); @@ -373,6 +378,14 @@ void ThemeEditorDialog::syncMetaFromParams() variantCombo->setCurrentIndex(variant == "light" ? 0 : 1); } +void ThemeEditorDialog::updateSavedId(const QString &id) +{ + auto meta = params["meta"].toObject(); + meta["id"] = id; + params["meta"] = meta; + idLabel->setText(id); +} + void ThemeEditorDialog::saveToFile() { // Assign a user-scoped UUID if the current id is builtin or empty diff --git a/common/themes/theme_editor_dialog.h b/common/themes/theme_editor_dialog.h index a2f5a5e25..e889d95ac 100644 --- a/common/themes/theme_editor_dialog.h +++ b/common/themes/theme_editor_dialog.h @@ -21,8 +21,11 @@ class ThemeEditorDialog : public QDialog QJsonObject currentParams() const { return params; } + void updateSavedId(const QString &id); + signals: void themeJsonChanged(const QJsonObject ¶ms); + void saveToLibraryRequested(const QJsonObject &json); private: void populate(QTreeWidgetItem *parent, const QJsonObject &obj, const QStringList &path); From fe8e1670cbef1ac167ececd7c369ffffab647e8a Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 15:10:52 +0100 Subject: [PATCH 129/187] Add AGENTS.md and CLAUDE.md --- AGENTS.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 1 + 2 files changed, 71 insertions(+) create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..ba1653ad1 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,70 @@ +# AGENTS GUIDANCE + +This file provides guidance to AI agents when working with code in this repository. + +## Build + +Out-of-source builds are required. In-source builds will be rejected by CMake. + +```bash +cmake -B build -DCMAKE_BUILD_TYPE=Release +cmake --build build --parallel +``` + +Build options: +- `DECOMPRESSION_BACKEND`: `unarr` | `7zip` | `libarchive` (default: 7zip on Windows/macOS, unarr on Linux) +- `PDF_BACKEND`: `pdfium` | `poppler` | `pdfkit` | `no_pdf` (default: pdfium on Windows, pdfkit on macOS, poppler on Linux) +- `BUILD_SERVER_STANDALONE=ON`: builds only `YACReaderLibraryServer` (headless), requires only Qt 6.4+ +- `BUILD_TESTS=ON` (default): enables the test suite + +## Tests + +```bash +ctest --test-dir build --output-on-failure +``` + +Tests live in `tests/` and are built as Qt Test executables (`compressed_archive_test`, `concurrent_queue_test`). + +## Code Formatting + +CI enforces `clang-format`. Run it before committing. There are multiple `.clang-format` files — subdirectories for third-party code have their own to opt out of reformatting. Always run recursively from the repo root via the provided scripts: + +- Linux: `scripts/clang-format-linux.sh` +- macOS: `scripts/clang-format-macos.sh` +- Windows: `scripts\clang-format-windows.cmd` (or `.ps1`) + +Style is WebKit-based with custom brace wrapping (braces on same line for control flow, new line after functions/classes), no column limit, and `SortIncludes: false`. + +## Architecture + +The repo builds three applications that share a common set of static libraries: + +| App | Description | +|-----|-------------| +| `YACReader` | Comic viewer | +| `YACReaderLibrary` | Comic library manager (GUI) | +| `YACReaderLibraryServer` | Headless HTTP server | + +### Static library dependency layers (bottom to top) + +1. **`yr_global`** — version/global constants, no GUI, used by everything +2. **`naturalsort`, `concurrent_queue`, `worker`** — utilities +3. **`common_all`** — shared non-GUI: `ComicDB`, `Folder`, `Bookmarks`, HTTP helpers, cover utils +4. **`comic_backend`** — comic file abstraction + PDF backend (source varies by `PDF_BACKEND`) +5. **`cbx_backend`** — compressed archive abstraction (in `compressed_archive/`) +6. **`db_helper`** — SQLite database layer: schema management, reading lists, query parser +7. **`library_common`** — library scanning, bundle creation, XML metadata parsing; shared between `YACReaderLibrary` and `YACReaderLibraryServer` +8. **`common_gui`** — GUI widgets, themes infrastructure, version check (not built in `BUILD_SERVER_STANDALONE`) +9. **`rhi_flow_reader` / `rhi_flow_library`** — RHI-based 3D coverflow widget, compiled twice with different defines (`YACREADER` vs `YACREADER_LIBRARY`); shaders compiled via `qt_add_shaders()` + +### Key design notes + +- **Theme system**: `theme_manager.h/cpp` is NOT part of `common_gui` because it depends on app-specific `Theme` structs. Each app (`YACReader/themes/`, `YACReaderLibrary/themes/`) defines its own `theme.h` and includes `theme_manager` directly. +- **Compile-time app identity**: `YACREADER` or `YACREADER_LIBRARY` defines distinguish shared source compiled into different apps. +- **PDF backend**: resolved at configure time into an `INTERFACE` target `pdf_backend_iface` (see `cmake/PdfBackend.cmake`); `comic_backend` and `common_all` link against this interface. +- **Third-party code**: `third_party/` contains QsLog, KDToolBox, QtWebApp, QrCode — each has its own `.clang-format` to prevent reformatting. +- **Runtime dependencies**: Qt binaries must be in `PATH`; third-party DLLs/dylibs must be next to the executable. Check an existing YACReader installation for the required files. + +### PRs + +Target branch is always `develop`. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..c17412640 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +See AGENTS.md for project context. From 61a7e3b9c60eb26ef696d030ce58af01f4a63fba Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 17:10:59 +0100 Subject: [PATCH 130/187] Add a new module for resizing images including Lanczos --- CMakeLists.txt | 1 + YACReader/CMakeLists.txt | 1 + image_processing/CMakeLists.txt | 9 + image_processing/lancir.h | 2383 +++++++++++++++++++++++++++++ image_processing/resize_image.cpp | 60 + image_processing/resize_image.h | 19 + 6 files changed, 2473 insertions(+) create mode 100644 image_processing/CMakeLists.txt create mode 100644 image_processing/lancir.h create mode 100644 image_processing/resize_image.cpp create mode 100644 image_processing/resize_image.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e3012b62..4d28ff285 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,6 +132,7 @@ add_subdirectory(common) if(NOT BUILD_SERVER_STANDALONE) add_subdirectory(shortcuts_management) add_subdirectory(custom_widgets) + add_subdirectory(image_processing) endif() add_subdirectory(YACReaderLibrary/server) diff --git a/YACReader/CMakeLists.txt b/YACReader/CMakeLists.txt index f5e9eeec9..e7ba59473 100644 --- a/YACReader/CMakeLists.txt +++ b/YACReader/CMakeLists.txt @@ -98,6 +98,7 @@ target_link_libraries(YACReader PRIVATE custom_widgets_reader shortcuts_reader cbx_backend + image_processing QsLog ) diff --git a/image_processing/CMakeLists.txt b/image_processing/CMakeLists.txt new file mode 100644 index 000000000..7421e7e1d --- /dev/null +++ b/image_processing/CMakeLists.txt @@ -0,0 +1,9 @@ +add_library(image_processing STATIC + resize_image.h + resize_image.cpp + lancir.h +) + +target_include_directories(image_processing PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +target_link_libraries(image_processing PRIVATE Qt::Gui) diff --git a/image_processing/lancir.h b/image_processing/lancir.h new file mode 100644 index 000000000..eb3019942 --- /dev/null +++ b/image_processing/lancir.h @@ -0,0 +1,2383 @@ +/** + * @file lancir.h + * + * @version 3.1 + * + * @brief Self-contained header-only "LANCIR" image resizing algorithm. + * + * This is a self-contained inclusion file for the "LANCIR" image resizer, + * a part of the AVIR library. Features scalar, AVX, SSE2, NEON, and WASM + * SIMD128 optimizations as well as batched resizing technique which provides + * a better CPU cache performance. + * + * AVIR Copyright (c) 2015-2025 Aleksey Vaneev + * + * @mainpage + * + * @section intro_sec Introduction + * + * Description is available at https://github.com/avaneev/avir + * + * @section license License + * + * LICENSE: + * + * Copyright (c) 2015-2025 Aleksey Vaneev + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef AVIR_CLANCIR_INCLUDED +#define AVIR_CLANCIR_INCLUDED + +#include +#include + +#if __cplusplus >= 201103L + +#include + +#else // __cplusplus >= 201103L + +#include + +#endif // __cplusplus >= 201103L + +/** + * @def LANCIR_ALIGN + * @brief Address alignment (granularity) used by resizing functions, + * in bytes. + */ + +/** + * @def LANCIR_NULLPTR + * @brief Macro is defined, if `nullptr` workaround is in use, for pre-C++11 + * compilers. Undefined at the end of file. + */ + +#if defined(__AVX__) + +#include + +#define LANCIR_AVX +#define LANCIR_SSE2 // Some functions use SSE2; AVX has a higher priority. +#define LANCIR_ALIGN 32 + +#elif defined(__aarch64__) || defined(__arm64__) || \ + defined(_M_ARM64) || defined(_M_ARM64EC) + +#if defined(_MSC_VER) +#include + +#if _MSC_VER < 1925 +#define LANCIR_ARM32 // Do not use some newer NEON intrinsics. +#endif // _MSC_VER < 1925 +#else // defined( _MSC_VER ) +#include +#endif // defined( _MSC_VER ) + +#define LANCIR_NEON +#define LANCIR_ALIGN 16 + +#elif defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(_M_ARM) + +#include + +#define LANCIR_ARM32 +#define LANCIR_NEON +#define LANCIR_ALIGN 16 + +#elif defined(__SSE2__) || defined(_M_AMD64) || \ + (defined(_M_IX86_FP) && _M_IX86_FP == 2) + +#if defined(_MSC_VER) +#include +#else // defined( _MSC_VER ) +#include +#endif // defined( _MSC_VER ) + +#define LANCIR_SSE2 +#define LANCIR_ALIGN 16 + +#elif defined(__wasm_simd128__) + +#include + +#define LANCIR_WASM +#define LANCIR_ALIGN 16 + +#else // WASM + +#define LANCIR_ALIGN 4 + +#endif // WASM + +#if defined(LANCIR_SSE2) + +#define lancvec_t __m128 +#define lancvec_const_splat(v) _mm_set1_ps(v) +#define lancvec_load(m) _mm_load_ps(m) +#define lancvec_loadu(m) _mm_loadu_ps(m) +#define lancvec_store(m, v) _mm_store_ps(m, v) +#define lancvec_storeu(m, v) _mm_storeu_ps(m, v) +#define lancvec_add(v1, v2) _mm_add_ps(v1, v2) +#define lancvec_mul(v1, v2) _mm_mul_ps(v1, v2) +#define lancvec_min(v1, v2) _mm_min_ps(v1, v2) +#define lancvec_max(v1, v2) _mm_max_ps(v1, v2) +#define lancvec_madd(va, v1, v2) _mm_add_ps(va, _mm_mul_ps(v1, v2)) +#define lancvec_addhl(vl, vh) _mm_add_ps(vl, _mm_movehl_ps(vh, vh)) +#define lancvec_store32_addhl(m, v) \ + _mm_store_ss(m, _mm_add_ss(v, _mm_shuffle_ps(v, v, 1))) + +#define lancvec_store64_addhl(m, v) \ + _mm_storel_pi((__m64 *)(m), lancvec_addhl(v, v)) + +#elif defined(LANCIR_NEON) + +#define lancvec_t float32x4_t +#define lancvec_const_splat(v) vdupq_n_f32(v) +#define lancvec_load(m) vld1q_f32(m) +#define lancvec_store(m, v) vst1q_f32(m, v) +#define lancvec_add(v1, v2) vaddq_f32(v1, v2) +#define lancvec_mul(v1, v2) vmulq_f32(v1, v2) +#define lancvec_min(v1, v2) vminq_f32(v1, v2) +#define lancvec_max(v1, v2) vmaxq_f32(v1, v2) +#define lancvec_madd(va, v1, v2) vmlaq_f32(va, v1, v2) + +#if defined(LANCIR_ARM32) +#define lancvec_store32_hadd(m, v) \ + { \ + const float32x2_t v2 = vadd_f32(vget_high_f32(v), \ + vget_low_f32(v)); \ + *(m) = vget_lane_f32(v2, 0) + \ + vget_lane_f32(v2, 1); \ + } \ + (void)0 +#else // defined( LANCIR_ARM32 ) +#define lancvec_store32_hadd(m, v) *(m) = vaddvq_f32(v) +#endif // defined( LANCIR_ARM32 ) + +#define lancvec_store64_addhl(m, v) \ + vst1_f32(m, vadd_f32(vget_high_f32(v), vget_low_f32(v))); + +#elif defined(LANCIR_WASM) + +#define lancvec_t v128_t +#define lancvec_const_splat(v) wasm_f32x4_const_splat(v) +#define lancvec_load32_splat(m) wasm_v128_load32_splat(m) +#define lancvec_load(m) wasm_v128_load(m) +#define lancvec_store(m, v) wasm_v128_store(m, v) +#define lancvec_add(v1, v2) wasm_f32x4_add(v1, v2) +#define lancvec_mul(v1, v2) wasm_f32x4_mul(v1, v2) +#define lancvec_min(v1, v2) wasm_f32x4_min(v1, v2) +#define lancvec_max(v1, v2) wasm_f32x4_max(v1, v2) +#define lancvec_madd(va, v1, v2) wasm_f32x4_add(va, \ + wasm_f32x4_mul(v1, v2)) + +#define lancvec_addhl(vl, vh) wasm_f32x4_add(vl, \ + wasm_i32x4_shuffle(vh, vh, 6, 7, 2, 3)) + +#define lancvec_store32_addhl(m, v) \ + *(m) = (wasm_f32x4_extract_lane(v, 0) + \ + wasm_f32x4_extract_lane(v, 1)) + +#define lancvec_store64_addhl(m, v) \ + wasm_v128_store64_lane(m, lancvec_addhl(v, v), 0) + +#endif // defined( LANCIR_WASM ) + +#if LANCIR_ALIGN > 4 + +#if !defined(lancvec_load32_splat) +#define lancvec_load32_splat(m) lancvec_const_splat(*(m)) +#endif // !defined( lancvec_load32_splat ) + +#if !defined(lancvec_loadu) +#define lancvec_loadu(m) lancvec_load(m) +#endif // !defined( lancvec_loadu ) + +#if !defined(lancvec_storeu) +#define lancvec_storeu(m, v) lancvec_store(m, v) +#endif // !defined( lancvec_storeu ) + +#if !defined(lancvec_store32_hadd) +#define lancvec_store32_hadd(m, v) \ + { \ + const lancvec_t v2 = lancvec_addhl(v, v); \ + lancvec_store32_addhl(m, v2); \ + } \ + (void)0 +#endif // !defined( lancvec_store32_hadd ) + +#endif // LANCIR_ALIGN > 4 + +namespace avir { + +using std ::ceil; +using std ::cos; +using std ::fabs; +using std ::floor; +using std ::memcpy; +using std ::memset; +using std ::sin; +using std ::size_t; + +#if __cplusplus >= 201103L + +using std ::intptr_t; +using std ::uintptr_t; + +#else // __cplusplus >= 201103L + +// Workaround for pre-C++11 compilers. `nullptr` is a keyword, and not a +// macro, but check if such workaround is already in place. + +#if !defined(nullptr) +#define nullptr NULL +#define LANCIR_NULLPTR +#endif // !defined( nullptr ) + +#endif // __cplusplus >= 201103L + +/** + * @brief LANCIR resizing parameters class. + * + * An object of this class, which can be allocated on stack, can be used to + * pass non-default parameters to the resizing algorithm. See the constructor + * for the default values. + */ + +class CLancIRParams +{ +public: + int SrcSSize; ///< Physical size of the source scanline, in elements (not + ///< bytes). If this value is below 1, `SrcWidth * ElCount` will be + ///< used. + int NewSSize; ///< Physical size of the destination scanline, in elements + ///< (not bytes). If this value is below 1, `NewWidth * ElCount` will + ///< be used. + double kx; ///< Resizing step - horizontal (one output pixel corresponds + ///< to `k` input pixels). A downsizing factor if greater than 1.0; + ///< upsizing factor if below or equal to 1.0. Multiply by -1 if you + ///< would like to bypass `ox` and `oy` adjustment which is done by + ///< default to produce a centered image. If this step value equals 0, + ///< the step value will be chosen automatically. + double ky; ///< Resizing step - vertical. Same as `kx`. + double ox; ///< Start X pixel offset within the source image, can be + ///< negative. A positive offset moves the image to the left. + double oy; ///< Start Y pixel offset within the source image, can be + ///< negative. A positive offset moves the image to the top. + double la; ///< Lanczos window function's `a` parameter, greater or equal + ///< to 2.0. + + /** + * @brief Default constructor, with optional arguments that correspond to + * class variables. + * + * @param aSrcSSize Physical size of the source scanline. + * @param aNewSSize Physical size of the destination scanline. + * @param akx Resizing step - horizontal. + * @param aky Resizing step - vertical. + * @param aox Start X pixel offset. + * @param aoy Start Y pixel offset. + */ + + CLancIRParams(const int aSrcSSize = 0, const int aNewSSize = 0, + const double akx = 0.0, const double aky = 0.0, + const double aox = 0.0, const double aoy = 0.0) + : SrcSSize(aSrcSSize), NewSSize(aNewSSize), kx(akx), ky(aky), ox(aox), oy(aoy), la(3.0) + { + } +}; + +/** + * @brief LANCIR image resizer class. + * + * The object of this class can be used to resize 1-4 channel images to any + * required size. Resizing is performed by utilizing Lanczos filters, with + * 8-bit precision. This class offers a kind of "optimal" Lanczos resampling + * implementation. + * + * Object of this class can be allocated on stack. + * + * Note that object of this class does not free temporary buffers and + * variables after the resizeImage() function call (until object's + * destruction): these buffers are reused (or reallocated) on subsequent + * calls, thus making batch resizing of images faster. This means resizing is + * not thread-safe: a separate CLancIR object should be created for each + * thread. + */ + +class CLancIR +{ +private: + CLancIR(const CLancIR &) + { + // Unsupported. + } + + CLancIR &operator=(const CLancIR &) + { + // Unsupported. + return (*this); + } + +public: + CLancIR() + : FltBuf0(nullptr), FltBuf0Len(0), spv0(nullptr), spv0len(0), spv(nullptr) + { + } + + ~CLancIR() + { + delete[] FltBuf0; + delete[] spv0; + } + + /** + * @brief Function resizes an image. + * + * Performs input-to-output type conversion, if necessary. + * + * @param[in] SrcBuf Source image buffer. + * @param SrcWidth Source image width, in pixels. + * @param SrcHeight Source image height, in pixels. + * @param[out] NewBuf Buffer to accept the resized image. Cannot be equal + * to `SrcBuf`. + * @param NewWidth New image width, in pixels. + * @param NewHeight New image height, in pixels. + * @param ElCount The number of elements (channels) used to store each + * source and destination pixel (1-4). + * @param aParams Custom resizing parameters. Can be `nullptr`, for + * default values. + * @tparam Tin Input buffer's element type. Can be `uint8_t` (`0..255` + * value range), `uint16_t` (`0..65535` value range), `float` (`0..1` + * value range), `double` (`0..1` value range). `uint32_t` type is treated + * as `uint16_t`. Signed integer types and larger integer types are not + * supported. + * @tparam Tout Output buffer's element type, treated like `Tin`. If `Tin` + * and `Tout` types do not match, an output value scaling will be applied. + * Floating-point output will not be clamped/clipped/saturated; integer + * output is always rounded and clamped. + * @return The number of available output scanlines. Equals to + * `NewHeight`, or 0 on function parameters error. + */ + + template + int resizeImage(const Tin *const SrcBuf, const int SrcWidth, + const int SrcHeight, Tout *const NewBuf, const int NewWidth, + const int NewHeight, const int ElCount, + const CLancIRParams *const aParams = nullptr) + { + if ((SrcWidth < 0) | (SrcHeight < 0) | + (NewWidth <= 0) | (NewHeight <= 0) | + (SrcBuf == nullptr) | (NewBuf == nullptr) | + ((const void *)SrcBuf == (const void *)NewBuf)) { + return (0); + } + + static const CLancIRParams DefParams; + const CLancIRParams &Params = (aParams != nullptr ? *aParams : DefParams); + + if (Params.la < 2.0) { + return (0); + } + + const int OutSLen = NewWidth * ElCount; + const size_t NewScanlineSize = (size_t)(Params.NewSSize < 1 ? OutSLen : Params.NewSSize); + + if ((SrcWidth == 0) | (SrcHeight == 0)) { + Tout *op = NewBuf; + int i; + + for (i = 0; i < NewHeight; i++) { + memset(op, 0, (size_t)OutSLen * sizeof(Tout)); + op += NewScanlineSize; + } + + return (NewHeight); + } + + const size_t SrcScanlineSize = (size_t)(Params.SrcSSize < 1 ? SrcWidth * ElCount : Params.SrcSSize); + + double ox = Params.ox; + double oy = Params.oy; + double kx; + double ky; + + if (Params.kx >= 0.0) { + kx = (Params.kx == 0.0 ? (double)SrcWidth / NewWidth : Params.kx); + + ox += (kx - 1.0) * 0.5; + } else { + kx = -Params.kx; + } + + if (Params.ky >= 0.0) { + ky = (Params.ky == 0.0 ? (double)SrcHeight / NewHeight : Params.ky); + + oy += (ky - 1.0) * 0.5; + } else { + ky = -Params.ky; + } + + if (rfv.update(Params.la, ky, ElCount)) { + rsv.reset(); + rsh.reset(); + } + + CResizeFilters *rfh; // Pointer to resizing filters for horizontal + // resizing, may equal to `rfv` if the same stepping is in use. + + if (kx == ky) { + rfh = &rfv; + } else { + rfh = &rfh0; + + if (rfh0.update(Params.la, kx, ElCount)) { + rsh.reset(); + } + } + + rsv.update(SrcHeight, NewHeight, oy, rfv, spv); + rsh.update(SrcWidth, NewWidth, ox, *rfh); + + // Calculate vertical progressive resizing's batch size. Progressive + // batching is used to try to keep addressing within the cache + // capacity. This technique definitely works well for single-threaded + // resizing on most CPUs, but may not provide an additional benefit + // for multi-threaded resizing, or in a system-wide high-load + // situations. + + const size_t FltWidthE = (size_t)((rsh.padl + SrcWidth + + rsh.padr) * + ElCount); + + const double CacheSize = 5500000.0; // Tuned for various CPUs. + const double OpSize = (double)SrcScanlineSize * SrcHeight * + sizeof(Tin) + + (double)FltWidthE * NewHeight * sizeof(float); + + int BatchSize = (int)(NewHeight * CacheSize / (OpSize + 1.0)); + + if (BatchSize < 8) { + BatchSize = 8; + } + + if (BatchSize > NewHeight) { + BatchSize = NewHeight; + } + + // Allocate/resize intermediate buffers. + + const int svs = (rsv.padl + SrcHeight + rsv.padr) * ElCount; + float *const pspv0 = spv0; + reallocBuf(spv0, spv, spv0len, (svs > OutSLen ? svs : OutSLen)); + reallocBuf(FltBuf0, FltBuf, FltBuf0Len, + FltWidthE * (size_t)BatchSize); + + if (spv0 != pspv0) { + rsv.updateSPO(rfv, spv); + } + + // Prepare output-related constants. + + static const bool IsInFloat = ((Tin)0.25f != 0); + static const bool IsOutFloat = ((Tout)0.25f != 0); + static const bool IsUnityMul = (IsInFloat && IsOutFloat) || + (IsInFloat == IsOutFloat && sizeof(Tin) == sizeof(Tout)); + + const float Clamp = (sizeof(Tout) == 1 ? 255.0f : 65535.0f); + const float OutMul = (IsOutFloat ? 1.0f : Clamp) / + (IsInFloat ? 1.0f : (sizeof(Tin) == 1 ? 255.0f : 65535.0f)); + + // Perform batched resizing. + + const CResizePos *rpv = rsv.pos; + Tout *opn = NewBuf; + int bl = NewHeight; + + while (bl > 0) { + const int bc = (bl > BatchSize ? BatchSize : bl); + + int kl = rfv.KernelLen; + const Tin *ip = SrcBuf; + float *op = FltBuf + rsh.padl * ElCount; + + const int so = (int)rpv[0].so; + float *const sp = spv + so * ElCount; + + int cc = (int)rpv[bc - 1].so - so + kl; // Pixel copy count. + int rl = 0; // Leftmost pixel's replication count. + int rr = 0; // Rightmost pixel's replication count. + + const int socc = so + cc; + const int spe = rsv.padl + SrcHeight; + + // Calculate scanline copying and padding parameters, depending on + // the batch's size and its vertical offset. + + if (so < rsv.padl) { + if (socc <= rsv.padl) { + rl = cc; + cc = 0; + } else { + if (socc > spe) { + rr = socc - spe; + cc -= rr; + } + + rl = rsv.padl - so; + cc -= rl; + } + } else { + if (so >= spe) { + rr = cc; + cc = 0; + ip += (size_t)SrcHeight * SrcScanlineSize; + } else { + if (socc > spe) { + rr = socc - spe; + cc -= rr; + } + + ip += (size_t)(so - rsv.padl) * SrcScanlineSize; + } + } + + // Batched vertical resizing. + + int i; + + if (ElCount == 1) { + for (i = 0; i < SrcWidth; i++) { + copyScanline1v(ip, SrcScanlineSize, sp, cc, rl, rr); + resize1(nullptr, op, FltWidthE, rpv, kl, bc); + ip += 1; + op += 1; + } + } else if (ElCount == 2) { + for (i = 0; i < SrcWidth; i++) { + copyScanline2v(ip, SrcScanlineSize, sp, cc, rl, rr); + resize2(nullptr, op, FltWidthE, rpv, kl, bc); + ip += 2; + op += 2; + } + } else if (ElCount == 3) { + for (i = 0; i < SrcWidth; i++) { + copyScanline3v(ip, SrcScanlineSize, sp, cc, rl, rr); + resize3(nullptr, op, FltWidthE, rpv, kl, bc); + ip += 3; + op += 3; + } + } else // ElCount == 4 + { + for (i = 0; i < SrcWidth; i++) { + copyScanline4v(ip, SrcScanlineSize, sp, cc, rl, rr); + resize4(nullptr, op, FltWidthE, rpv, kl, bc); + ip += 4; + op += 4; + } + } + + // Perform horizontal resizing batch, and produce final output. + + float *ipf = FltBuf; + kl = rfh->KernelLen; + + if (ElCount == 1) { + for (i = 0; i < bc; i++) { + padScanline1h(ipf, rsh, SrcWidth); + resize1(ipf, spv, 1, rsh.pos, kl, NewWidth); + outputScanline(spv, opn, + OutSLen, Clamp, OutMul); + + ipf += FltWidthE; + opn += NewScanlineSize; + } + } else if (ElCount == 2) { + for (i = 0; i < bc; i++) { + padScanline2h(ipf, rsh, SrcWidth); + resize2(ipf, spv, 2, rsh.pos, kl, NewWidth); + outputScanline(spv, opn, + OutSLen, Clamp, OutMul); + + ipf += FltWidthE; + opn += NewScanlineSize; + } + } else if (ElCount == 3) { + for (i = 0; i < bc; i++) { + padScanline3h(ipf, rsh, SrcWidth); + resize3(ipf, spv, 3, rsh.pos, kl, NewWidth); + outputScanline(spv, opn, + OutSLen, Clamp, OutMul); + + ipf += FltWidthE; + opn += NewScanlineSize; + } + } else // ElCount == 4 + { + for (i = 0; i < bc; i++) { + padScanline4h(ipf, rsh, SrcWidth); + resize4(ipf, spv, 4, rsh.pos, kl, NewWidth); + outputScanline(spv, opn, + OutSLen, Clamp, OutMul); + + ipf += FltWidthE; + opn += NewScanlineSize; + } + } + + rpv += bc; + bl -= bc; + } + + return (NewHeight); + } + + /** + * @brief Legacy image resizing function. + * + * Not recommended for new projects. See the prior resizeImage() function + * and CLancIRParams class for details. + * + * @param[in] SrcBuf Source image buffer. + * @param SrcWidth Source image width, in pixels. + * @param SrcHeight Source image height, in pixels. + * @param SrcSSize Physical size of the source scanline, in elements (not + * bytes). + * @param[out] NewBuf Buffer to accept the resized image. Cannot be equal + * to SrcBuf. + * @param NewWidth New image width, in pixels. + * @param NewHeight New image height, in pixels. + * @param NewSSize Physical size of the destination scanline, in elements + * (not bytes). + * @param ElCount The number of elements (channels) used to store each + * source and destination pixel (1-4). + * @param kx0 Resizing step - horizontal. + * @param ky0 Resizing step - vertical. Same as `kx0`. + * @param ox Start X pixel offset within the source image. + * @param oy Start Y pixel offset within the source image. + * @tparam Tin Input buffer's element type. + * @tparam Tout Output buffer's element type. + * @return The number of available output scanlines. Equals to + * `NewHeight`, or 0 on function parameters error. + */ + + template + int resizeImage(const Tin *const SrcBuf, const int SrcWidth, + const int SrcHeight, const int SrcSSize, Tout *const NewBuf, + const int NewWidth, const int NewHeight, const int NewSSize, + const int ElCount, const double kx0 = 0.0, const double ky0 = 0.0, + double ox = 0.0, double oy = 0.0) + { + const CLancIRParams Params(SrcSSize, NewSSize, kx0, ky0, ox, oy); + + return (resizeImage(SrcBuf, SrcWidth, SrcHeight, NewBuf, NewWidth, + NewHeight, ElCount, &Params)); + } + +protected: + float *FltBuf0; ///< Intermediate resizing buffer. + size_t FltBuf0Len; ///< Length of `FltBuf0`. + float *FltBuf; ///< Address-aligned `FltBuf0`. + float *spv0; ///< Scanline buffer for vertical resizing, also used at the + ///< output stage. + int spv0len; ///< Length of `spv0`. + float *spv; ///< Address-aligned `spv0`. + + /** + * @brief Typed buffer reallocation function, with address alignment. + * + * Function reallocates a typed buffer if its current length is + * smaller than the required length, applies `LANCIR_ALIGN` address + * alignment to the buffer pointer. + * + * @param buf0 Reference to the pointer of the previously allocated + * buffer. + * @param buf Reference to address-aligned `buf0` pointer. + * @param len The current length of the `buf0`. + * @param newlen A new required length. + * @tparam Tb Buffer element type. + * @tparam Tl Length variable type. + */ + + template + static void reallocBuf(Tb *&buf0, Tb *&buf, Tl &len, Tl newlen) + { + newlen += LANCIR_ALIGN; + + if (newlen > len) { + if (buf0 != nullptr) { + delete[] buf0; + buf0 = nullptr; + len = 0; + } + + buf0 = new Tb[newlen]; + len = newlen; + buf = (Tb *)(((uintptr_t)buf0 + LANCIR_ALIGN - 1) & + ~(uintptr_t)(LANCIR_ALIGN - 1)); + } + } + + /** + * @brief Typed buffer reallocation function. + * + * Function reallocates a typed buffer if its current length is smaller + * than the required length. + * + * @param buf Reference to the pointer of the previously allocated buffer; + * address alignment will not be applied. + * @param len The current length of the `buf0`. + * @param newlen A new required length. + * @tparam Tb Buffer element type. + * @tparam Tl Length variable type. + */ + + template + static void reallocBuf(Tb *&buf, Tl &len, const Tl newlen) + { + if (newlen > len) { + if (buf != nullptr) { + delete[] buf; + buf = nullptr; + len = 0; + } + + buf = new Tb[newlen]; + len = newlen; + } + } + + class CResizeScanline; + + /** + * @brief Class for fractional delay filter bank storage and calculation. + */ + + class CResizeFilters + { + friend class CResizeScanline; + + public: + int KernelLen; ///< Resampling filter kernel's length, taps. Available + ///< after the update() function call. Always an even value, + ///< should not be lesser than 4. + + CResizeFilters() + : Filters(nullptr), FiltersLen(0), la(0.0) + { + memset(Bufs0, 0, sizeof(Bufs0)); + memset(Bufs0Len, 0, sizeof(Bufs0Len)); + } + + ~CResizeFilters() + { + int i; + + for (i = 0; i < BufCount; i++) { + delete[] Bufs0[i]; + } + + delete[] Filters; + } + + /** + * @brief Function updates the filter bank. + * + * @param la0 Lanczos `a` parameter value (greater or equal to 2.0), + * can be fractional. + * @param k0 Resizing step. + * @param ElCount0 Image's element count, may be used for SIMD filter + * tap replication. + * @return `true`, if an update occured and scanline resizing + * positions should be updated unconditionally. + */ + + bool update(const double la0, const double k0, const int ElCount0) + { + if (la0 == la && k0 == k && ElCount0 == ElCount) { + return (false); + } + + const double NormFreq = (k0 <= 1.0 ? 1.0 : 1.0 / k0); + Freq = 3.1415926535897932 * NormFreq; + FreqA = Freq / la0; + + Len2 = la0 / NormFreq; + fl2 = (int)ceil(Len2); + KernelLen = fl2 + fl2; + +#if LANCIR_ALIGN > 4 + + ElRepl = ElCount0; + KernelLenA = KernelLen * ElRepl; + + const int elalign = + (int)(LANCIR_ALIGN / sizeof(float)) - 1; + + KernelLenA = (KernelLenA + elalign) & ~elalign; + +#else // LANCIR_ALIGN > 4 + + ElRepl = 1; + KernelLenA = KernelLen; + +#endif // LANCIR_ALIGN > 4 + + FracCount = 1000; // Enough for Lanczos implicit 8-bit precision. + + la = 0.0; + reallocBuf(Filters, FiltersLen, FracCount + 1); + + memset(Filters, 0, (size_t)FiltersLen * sizeof(Filters[0])); + + setBuf(0); + + la = la0; + k = k0; + ElCount = ElCount0; + + return (true); + } + + /** + * @brief Filter acquisition function. + * + * Function returns filter at the specified fractional offset. This + * function can only be called after a prior update() function call. + * + * @param x Fractional offset, [0; 1]. + * @return Pointer to a previously-calculated or a new filter. + */ + + const float *getFilter(const double x) + { + const int Frac = (int)(x * FracCount + 0.5); + float *flt = Filters[Frac]; + + if (flt != nullptr) { + return (flt); + } + + flt = Bufs[CurBuf] + CurBufFill * KernelLenA; + Filters[Frac] = flt; + CurBufFill++; + + if (CurBufFill == BufLen) { + setBuf(CurBuf + 1); + } + + makeFilterNorm(flt, 1.0 - (double)Frac / FracCount); + + if (ElRepl > 1) { + replicateFilter(flt, KernelLen, ElRepl); + } + + return (flt); + } + + protected: + double Freq; ///< Circular frequency of the filter. + double FreqA; ///< Circular frequency of the window function. + double Len2; ///< Half resampling filter's length, unrounded. + int fl2; ///< Half resampling filter's length, integer. + int FracCount; ///< The number of fractional positions for which + ///< filters can be created. + int KernelLenA; ///< SIMD-aligned and replicated filter kernel's + ///< length. + int ElRepl; ///< The number of repetitions of each filter tap. + static const int BufCount = 4; ///< The maximal number of buffers + ///< (filter batches) that can be in use. + static const int BufLen = 256; ///< The number of fractional filters + ///< a single buffer (filter batch) may contain. Both the `BufLen` + ///< and `BufCount` should correspond to the `FracCount` used. + float *Bufs0[BufCount]; ///< Buffers that hold all filters, + ///< original. + int Bufs0Len[BufCount]; ///< Allocated lengthes in `Bufs0`, in + ///< `float` elements. + float *Bufs[BufCount]; ///< Address-aligned `Bufs0`. + int CurBuf; ///< Filter buffer currently being filled. + int CurBufFill; ///< The number of fractional positions filled in the + ///< current filter buffer. + float **Filters; ///< Fractional delay filters for all positions. + ///< A particular pointer equals `nullptr`, if a filter for such + ///< position has not been created yet. + int FiltersLen; ///< Allocated length of Filters, in elements. + double la; ///< Current `la`. + double k; ///< Current `k`. + int ElCount; ///< Current `ElCount`. + + /** + * @brief Current buffer (filter batch) repositioning function. + * + * Function changes the buffer currently being filled, checks its size + * and reallocates it, if necessary, then resets its fill counter. + * + * @param bi A new current buffer index. + */ + + void setBuf(const int bi) + { + reallocBuf(Bufs0[bi], Bufs[bi], Bufs0Len[bi], + BufLen * KernelLenA); + + CurBuf = bi; + CurBufFill = 0; + } + + /** + * @brief Sine-wave signal generator class. + * + * Class implements sine-wave signal generator without biasing, with + * constructor-based initialization only. This generator uses an + * oscillator instead of the `sin()` function. + */ + + class CSineGen + { + public: + /** + * @brief Constructor initializes *this* sine-wave signal + * generator. + * + * @param si Sine function increment, in radians. + * @param ph Starting phase, in radians. Add `0.5*pi` for a + * cosine function. + */ + + CSineGen(const double si, const double ph) + : svalue1(sin(ph)), svalue2(sin(ph - si)), sincr(2.0 * cos(si)) + { + } + + /** + * @brief Generates the next sine-wave sample, without biasing. + */ + + double generate() + { + const double res = svalue1; + + svalue1 = sincr * res - svalue2; + svalue2 = res; + + return (res); + } + + private: + double svalue1; ///< Current sine value. + double svalue2; ///< Previous sine value. + double sincr; ///< Sine value increment. + }; + + /** + * @brief Filter calculation function. + * + * Function creates a filter for the specified fractional delay. The + * update() function should be called prior to calling this function. + * The created filter is normalized (DC gain=1). + * + * @param[out] op Output filter buffer. + * @param FracDelay Fractional delay, 0 to 1, inclusive. + */ + + void makeFilterNorm(float *op, const double FracDelay) const + { + CSineGen f(Freq, Freq * (FracDelay - fl2)); + CSineGen fw(FreqA, FreqA * (FracDelay - fl2)); + + float *op0 = op; + double s = 0.0; + double ut; + + int t = -fl2; + + if (t + FracDelay < -Len2) { + f.generate(); + fw.generate(); + *op = 0; + op++; + t++; + } + + int IsZeroX = (fabs(FracDelay - 1.0) < 2.3e-13); + int mt = 0 - IsZeroX; + IsZeroX |= (fabs(FracDelay) < 2.3e-13); + + while (t < mt) { + ut = t + FracDelay; + *op = (float)(f.generate() * fw.generate() / (ut * ut)); + s += *op; + op++; + t++; + } + + if (IsZeroX) // t+FracDelay==0 + { + *op = (float)(Freq * FreqA); + s += *op; + f.generate(); + fw.generate(); + } else { + ut = FracDelay; // t==0 + *op = (float)(f.generate() * fw.generate() / (ut * ut)); + s += *op; + } + + mt = fl2 - 2; + + while (t < mt) { + op++; + t++; + ut = t + FracDelay; + *op = (float)(f.generate() * fw.generate() / (ut * ut)); + s += *op; + } + + op++; + ut = t + 1 + FracDelay; + + if (ut > Len2) { + *op = 0; + } else { + *op = (float)(f.generate() * fw.generate() / (ut * ut)); + s += *op; + } + + s = 1.0 / s; + t = (int)(op - op0 + 1); + + while (t != 0) { + *op0 = (float)(*op0 * s); + op0++; + t--; + } + } + + /** + * @brief Filter tap replication function, for SIMD operations. + * + * Function replicates taps of the specified filter so that it can + * be used with SIMD loading instructions. This function works + * "in-place". + * + * @param[in,out] p Filter buffer pointer, should be sized to contain + * `kl * erp` elements. + * @param kl Filter kernel's length, in taps. + * @param erp The number of repetitions to apply. + */ + + static void replicateFilter(float *const p, const int kl, + const int erp) + { + const float *ip = p + kl - 1; + float *op = p + (kl - 1) * erp; + int c = kl; + + if (erp == 2) { + while (c != 0) { + const float v = *ip; + op[0] = v; + op[1] = v; + ip--; + op -= 2; + c--; + } + } else if (erp == 3) { + while (c != 0) { + const float v = *ip; + op[0] = v; + op[1] = v; + op[2] = v; + ip--; + op -= 3; + c--; + } + } else // erp == 4 + { + while (c != 0) { + const float v = *ip; + op[0] = v; + op[1] = v; + op[2] = v; + op[3] = v; + ip--; + op -= 4; + c--; + } + } + } + }; + + /** + * @brief Structure defines source scanline positions and filters for each + * destination pixel. + */ + + struct CResizePos { + const float *flt; ///< Fractional delay filter. + intptr_t spo; ///< Source scanline's pixel offset, in bytes, or + ///< a direct pointer to scanline buffer. + intptr_t so; ///< Offset within the source scanline, in pixels. + }; + + /** + * @brief Scanline resizing positions class. + * + * Class contains resizing positions, and prepares source scanline + * positions for resize filtering. The public variables become available + * after the update() function call. + */ + + class CResizeScanline + { + public: + int padl; ///< Left-padding (in pixels) required for source scanline. + int padr; ///< Right-padding (in pixels) required for source scanline. + CResizePos *pos; ///< Source scanline positions (offsets) and filters + ///< for each destination pixel position. + + CResizeScanline() + : pos(nullptr), poslen(0), SrcLen(0) + { + } + + ~CResizeScanline() + { + delete[] pos; + } + + /** + * @brief Object's reset function. + * + * Function "resets" *this* object so that the next update() call + * fully updates the position buffer. Reset is necessary if the + * corresponding CResizeFilters object was updated. + */ + + void reset() + { + SrcLen = 0; + } + + /** + * @brief Scanline positions update function. + * + * Function updates resizing positions, updates `padl`, `padr`, and + * `pos` buffer. + * + * @param SrcLen0 Source image scanline length, used to create a + * scanline buffer without length pre-calculation. + * @param DstLen0 Destination image scanline length. + * @param o0 Initial source image offset. + * @param rf Resizing filters object. + * @param sp A pointer to scanline buffer, to use for absolute + * scanline positioning, can be `nullptr`. + */ + + void update(const int SrcLen0, const int DstLen0, const double o0, + CResizeFilters &rf, float *const sp = nullptr) + { + if (SrcLen0 == SrcLen && DstLen0 == DstLen && o0 == o) { + return; + } + + const int fl2m1 = rf.fl2 - 1; + padl = fl2m1 - (int)floor(o0); + + if (padl < 0) { + padl = 0; + } + + // Make sure `padr` and `pos` are in sync: calculate ending `pos` + // offset in advance. + + const double k = rf.k; + + const int DstLen_m1 = DstLen0 - 1; + const double oe = o0 + k * DstLen_m1; + const int ie = (int)floor(oe); + + padr = ie + rf.fl2 + 1 - SrcLen0; + + if (padr < 0) { + padr = 0; + } + + SrcLen = 0; + reallocBuf(pos, poslen, DstLen0); + + const intptr_t ElCountF = rf.ElCount * (intptr_t)sizeof(float); + const int so = padl - fl2m1; + CResizePos *rp = pos; + intptr_t rpso; + int i; + + for (i = 0; i < DstLen_m1; i++) { + const double ox = o0 + k * i; + const int ix = (int)floor(ox); + + rp->flt = rf.getFilter(ox - ix); + rpso = so + ix; + rp->spo = (intptr_t)sp + rpso * ElCountF; + rp->so = rpso; + rp++; + } + + rp->flt = rf.getFilter(oe - ie); + rpso = so + ie; + rp->spo = (intptr_t)sp + rpso * ElCountF; + rp->so = rpso; + + SrcLen = SrcLen0; + DstLen = DstLen0; + o = o0; + } + + /** + * @brief Scanline pixel offsets update function. + * + * Function updates `pos` buffer's `spo` (scanline pixel offset) + * values. + * + * @param rf Resizing filters object. + * @param sp A pointer to scanline buffer, to use for absolute + * scanline positioning, can be `nullptr`. + */ + + void updateSPO(CResizeFilters &rf, float *const sp) + { + const intptr_t ElCountF = rf.ElCount * (intptr_t)sizeof(float); + CResizePos *const rp = pos; + int i; + + for (i = 0; i < DstLen; i++) { + rp[i].spo = (intptr_t)sp + rp[i].so * ElCountF; + } + } + + protected: + int poslen; ///< Allocated `pos` buffer's length. + int SrcLen; ///< Current `SrcLen`. + int DstLen; ///< Current `DstLen`. + double o; ///< Current `o`. + }; + + CResizeFilters rfv; ///< Resizing filters for vertical resizing. + CResizeFilters rfh0; ///< Resizing filters for horizontal resizing (may + ///< not be in use). + CResizeScanline rsv; ///< Vertical resize scanline. + CResizeScanline rsh; ///< Horizontal resize scanline. + + /** + * @{ + * @brief Scanline copying function, for vertical resizing. + * + * Function copies scanline (fully or partially) from the source buffer, + * in its native format, to the internal scanline buffer, in preparation + * for vertical resizing. Variants for 1-4-channel images. + * + * @param ip Source scanline buffer pointer. + * @param ipinc `ip` increment per pixel. + * @param op Output scanline pointer. + * @param cc Source pixel copy count. + * @param repl Leftmost pixel's replication count. + * @param repr Rightmost pixel's replication count. + * @tparam T Source buffer's element type. + */ + + template + static void copyScanline1v(const T *ip, const size_t ipinc, float *op, + int cc, int repl, int repr) + { + float v0; + + if (repl > 0) { + v0 = (float)ip[0]; + + do { + op[0] = v0; + op += 1; + + } while (--repl != 0); + } + + while (cc != 0) { + op[0] = (float)ip[0]; + ip += ipinc; + op += 1; + cc--; + } + + if (repr > 0) { + const T *const ipe = ip - ipinc; + v0 = (float)ipe[0]; + + do { + op[0] = v0; + op += 1; + + } while (--repr != 0); + } + } + + template + static void copyScanline2v(const T *ip, const size_t ipinc, float *op, + int cc, int repl, int repr) + { + float v0, v1; + + if (repl > 0) { + v0 = (float)ip[0]; + v1 = (float)ip[1]; + + do { + op[0] = v0; + op[1] = v1; + op += 2; + + } while (--repl != 0); + } + + while (cc != 0) { + op[0] = (float)ip[0]; + op[1] = (float)ip[1]; + ip += ipinc; + op += 2; + cc--; + } + + if (repr > 0) { + const T *const ipe = ip - ipinc; + v0 = (float)ipe[0]; + v1 = (float)ipe[1]; + + do { + op[0] = v0; + op[1] = v1; + op += 2; + + } while (--repr != 0); + } + } + + template + static void copyScanline3v(const T *ip, const size_t ipinc, float *op, + int cc, int repl, int repr) + { + float v0, v1, v2; + + if (repl > 0) { + v0 = (float)ip[0]; + v1 = (float)ip[1]; + v2 = (float)ip[2]; + + do { + op[0] = v0; + op[1] = v1; + op[2] = v2; + op += 3; + + } while (--repl != 0); + } + + while (cc != 0) { + op[0] = (float)ip[0]; + op[1] = (float)ip[1]; + op[2] = (float)ip[2]; + ip += ipinc; + op += 3; + cc--; + } + + if (repr > 0) { + const T *const ipe = ip - ipinc; + v0 = (float)ipe[0]; + v1 = (float)ipe[1]; + v2 = (float)ipe[2]; + + do { + op[0] = v0; + op[1] = v1; + op[2] = v2; + op += 3; + + } while (--repr != 0); + } + } + + template + static void copyScanline4v(const T *ip, const size_t ipinc, float *op, + int cc, int repl, int repr) + { + float v0, v1, v2, v3; + + if (repl > 0) { + v0 = (float)ip[0]; + v1 = (float)ip[1]; + v2 = (float)ip[2]; + v3 = (float)ip[3]; + + do { + op[0] = v0; + op[1] = v1; + op[2] = v2; + op[3] = v3; + op += 4; + + } while (--repl != 0); + } + + while (cc != 0) { + op[0] = (float)ip[0]; + op[1] = (float)ip[1]; + op[2] = (float)ip[2]; + op[3] = (float)ip[3]; + ip += ipinc; + op += 4; + cc--; + } + + if (repr > 0) { + const T *const ipe = ip - ipinc; + v0 = (float)ipe[0]; + v1 = (float)ipe[1]; + v2 = (float)ipe[2]; + v3 = (float)ipe[3]; + + do { + op[0] = v0; + op[1] = v1; + op[2] = v2; + op[3] = v3; + op += 4; + + } while (--repr != 0); + } + } + + /** @} */ + + /** + * @{ + * @brief Scanline padding function, for horizontal resizing. + * + * Function pads the specified scanline buffer to the left and right by + * replicating its first and last available pixels, in preparation for + * horizontal resizing. Variants for 1-4-channel images. + * + * @param[in,out] op Scanline buffer to pad. + * @param rs Scanline resizing positions object. + * @param l Source scanline's length, in pixels. + */ + + static void padScanline1h(float *op, CResizeScanline &rs, const int l) + { + const float *ip = op + rs.padl; + + float v0 = ip[0]; + int i; + + for (i = 0; i < rs.padl; i++) { + op[i] = v0; + } + + ip += l; + op += rs.padl + l; + + v0 = ip[-1]; + + for (i = 0; i < rs.padr; i++) { + op[i] = v0; + } + } + + static void padScanline2h(float *op, CResizeScanline &rs, const int l) + { + const float *ip = op + rs.padl * 2; + + float v0 = ip[0]; + float v1 = ip[1]; + int i; + + for (i = 0; i < rs.padl; i++) { + op[0] = v0; + op[1] = v1; + op += 2; + } + + const int lc = l * 2; + ip += lc; + op += lc; + + v0 = ip[-2]; + v1 = ip[-1]; + + for (i = 0; i < rs.padr; i++) { + op[0] = v0; + op[1] = v1; + op += 2; + } + } + + static void padScanline3h(float *op, CResizeScanline &rs, const int l) + { + const float *ip = op + rs.padl * 3; + + float v0 = ip[0]; + float v1 = ip[1]; + float v2 = ip[2]; + int i; + + for (i = 0; i < rs.padl; i++) { + op[0] = v0; + op[1] = v1; + op[2] = v2; + op += 3; + } + + const int lc = l * 3; + ip += lc; + op += lc; + + v0 = ip[-3]; + v1 = ip[-2]; + v2 = ip[-1]; + + for (i = 0; i < rs.padr; i++) { + op[0] = v0; + op[1] = v1; + op[2] = v2; + op += 3; + } + } + + static void padScanline4h(float *op, CResizeScanline &rs, const int l) + { + const float *ip = op + rs.padl * 4; + + float v0 = ip[0]; + float v1 = ip[1]; + float v2 = ip[2]; + float v3 = ip[3]; + int i; + + for (i = 0; i < rs.padl; i++) { + op[0] = v0; + op[1] = v1; + op[2] = v2; + op[3] = v3; + op += 4; + } + + const int lc = l * 4; + ip += lc; + op += lc; + + v0 = ip[-4]; + v1 = ip[-3]; + v2 = ip[-2]; + v3 = ip[-1]; + + for (i = 0; i < rs.padr; i++) { + op[0] = v0; + op[1] = v1; + op[2] = v2; + op[3] = v3; + op += 4; + } + } + + /** @} */ + + /** + * @brief Rounds a value, and applies clamping. + * + * @param v Value to round and clamp. + * @param Clamp High clamp level; low level is 0. + * @return Rounded and clamped value. + */ + + static inline int roundclamp(const float v, const float Clamp) + { + return ((int)((v > Clamp ? Clamp : (v < 0.0f ? 0.0f : v)) + + 0.5f)); + } + + /** + * @brief Scanline output function. + * + * Function performs output of the scanline pixels to the destination + * image buffer, with type conversion, scaling, clamping, if necessary. + * + * @param[in] ip Input (resized) scanline. Pointer must be aligned to + * LANCIR_ALIGN bytes. + * @param[out] op Output image buffer. Must be different to `ip`. + * @param l Output scanline's length, in elements (not pixel count). + * @param Clamp Clamp high level, used if `IsOutFloat` is `false`. + * @param OutMul Output multiplier, for value range conversion, applied + * before clamping. + * @tparam IsOutFloat `true`, if floating-point output, and no clamping is + * necessary. + * @tparam IsUnityMul `true`, if multiplication is optional. However, even + * if this parameter was specified as `true`, `OutMul` must be 1. + * @tparam T Output buffer's element type. Acquired implicitly. + */ + + template + static void outputScanline(const float *ip, T *op, int l, + const float Clamp, const float OutMul) + { + if (IsOutFloat) { + if (IsUnityMul) { + if (sizeof(op[0]) == sizeof(ip[0])) { + memcpy(op, ip, (size_t)l * sizeof(op[0])); + } else { + int l4 = l >> 2; + l &= 3; + + while (l4 != 0) { + op[0] = (T)ip[0]; + op[1] = (T)ip[1]; + op[2] = (T)ip[2]; + op[3] = (T)ip[3]; + ip += 4; + op += 4; + l4--; + } + + while (l != 0) { + *op = (T)*ip; + ip++; + op++; + l--; + } + } + } else { + int l4 = l >> 2; + l &= 3; + bool DoScalar = true; + + if (sizeof(op[0]) == sizeof(ip[0])) { +#if LANCIR_ALIGN > 4 + + DoScalar = false; + const lancvec_t om = lancvec_load32_splat(&OutMul); + + while (l4 != 0) { + lancvec_storeu((float *)op, + lancvec_mul(lancvec_load(ip), om)); + + ip += 4; + op += 4; + l4--; + } + +#endif // LANCIR_ALIGN > 4 + } + + if (DoScalar) { + while (l4 != 0) { + op[0] = (T)(ip[0] * OutMul); + op[1] = (T)(ip[1] * OutMul); + op[2] = (T)(ip[2] * OutMul); + op[3] = (T)(ip[3] * OutMul); + ip += 4; + op += 4; + l4--; + } + } + + while (l != 0) { + *op = (T)(*ip * OutMul); + ip++; + op++; + l--; + } + } + } else { + int l4 = l >> 2; + l &= 3; + +#if LANCIR_ALIGN > 4 + + const lancvec_t minv = lancvec_const_splat(0.0f); + const lancvec_t maxv = lancvec_load32_splat(&Clamp); + const lancvec_t om = lancvec_load32_splat(&OutMul); + +#if defined(LANCIR_SSE2) + unsigned int prevrm = _MM_GET_ROUNDING_MODE(); + _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST); +#else // defined( LANCIR_SSE2 ) + const lancvec_t v05 = lancvec_const_splat(0.5f); +#endif // defined( LANCIR_SSE2 ) + + if (sizeof(op[0]) == 4) { + while (l4 != 0) { + const lancvec_t v = lancvec_load(ip); + const lancvec_t cv = lancvec_max(lancvec_min( + (IsUnityMul ? v : lancvec_mul(v, om)), + maxv), + minv); + +#if defined(LANCIR_SSE2) + + _mm_storeu_si128((__m128i *)op, _mm_cvtps_epi32(cv)); + +#elif defined(LANCIR_NEON) + + vst1q_u32((unsigned int *)op, vcvtq_u32_f32(vaddq_f32(cv, v05))); + +#elif defined(LANCIR_WASM) + + wasm_v128_store(op, wasm_i32x4_trunc_sat_f32x4(wasm_f32x4_add(cv, v05))); + +#endif // defined( LANCIR_WASM ) + + ip += 4; + op += 4; + l4--; + } + } else if (sizeof(op[0]) == 2) { + while (l4 != 0) { + const lancvec_t v = lancvec_load(ip); + const lancvec_t cv = lancvec_max(lancvec_min( + (IsUnityMul ? v : lancvec_mul(v, om)), + maxv), + minv); + +#if defined(LANCIR_SSE2) + + const __m128i v32 = _mm_cvtps_epi32(cv); + const __m128i v16s = _mm_shufflehi_epi16( + _mm_shufflelo_epi16(v32, 0 | 2 << 2), 0 | 2 << 2); + + const __m128i v16 = _mm_shuffle_epi32(v16s, 0 | 2 << 2); + + __m128i tmp; + _mm_store_si128(&tmp, v16); + memcpy(op, &tmp, 8); + +#elif defined(LANCIR_NEON) + + const uint32x4_t v32 = vcvtq_u32_f32( + vaddq_f32(cv, v05)); + + const uint16x4_t v16 = vmovn_u32(v32); + + vst1_u16((unsigned short *)op, v16); + +#elif defined(LANCIR_WASM) + + const v128_t v32 = wasm_i32x4_trunc_sat_f32x4( + wasm_f32x4_add(cv, v05)); + + wasm_v128_store64_lane(op, + wasm_u16x8_narrow_i32x4(v32, v32), 0); + +#endif // defined( LANCIR_WASM ) + + ip += 4; + op += 4; + l4--; + } + } else { + while (l4 != 0) { + const lancvec_t v = lancvec_load(ip); + const lancvec_t cv = lancvec_max(lancvec_min( + (IsUnityMul ? v : lancvec_mul(v, om)), + maxv), + minv); + +#if defined(LANCIR_SSE2) + + const __m128i v32 = _mm_cvtps_epi32(cv); + const __m128i v16s = _mm_shufflehi_epi16( + _mm_shufflelo_epi16(v32, 0 | 2 << 2), 0 | 2 << 2); + + const __m128i v16 = _mm_shuffle_epi32(v16s, 0 | 2 << 2); + const __m128i v8 = _mm_packus_epi16(v16, v16); + + *(int *)op = _mm_cvtsi128_si32(v8); + +#elif defined(LANCIR_NEON) + + const uint32x4_t v32 = vcvtq_u32_f32( + vaddq_f32(cv, v05)); + + const uint16x4_t v16 = vmovn_u32(v32); + const uint8x8_t v8 = vmovn_u16(vcombine_u16(v16, v16)); + + *(unsigned int *)op = vget_lane_u32((uint32x2_t)v8, 0); + +#elif defined(LANCIR_WASM) + + const v128_t v32 = wasm_i32x4_trunc_sat_f32x4( + wasm_f32x4_add(cv, v05)); + + const v128_t v16 = wasm_u16x8_narrow_i32x4(v32, v32); + + wasm_v128_store32_lane(op, + wasm_u8x16_narrow_i16x8(v16, v16), 0); + +#endif // defined( LANCIR_WASM ) + + ip += 4; + op += 4; + l4--; + } + } + +#if defined(LANCIR_SSE2) + _MM_SET_ROUNDING_MODE(prevrm); +#endif // defined( LANCIR_SSE2 ) + +#else // LANCIR_ALIGN > 4 + + if (IsUnityMul) { + while (l4 != 0) { + op[0] = (T)roundclamp(ip[0], Clamp); + op[1] = (T)roundclamp(ip[1], Clamp); + op[2] = (T)roundclamp(ip[2], Clamp); + op[3] = (T)roundclamp(ip[3], Clamp); + ip += 4; + op += 4; + l4--; + } + } else { + while (l4 != 0) { + op[0] = (T)roundclamp(ip[0] * OutMul, Clamp); + op[1] = (T)roundclamp(ip[1] * OutMul, Clamp); + op[2] = (T)roundclamp(ip[2] * OutMul, Clamp); + op[3] = (T)roundclamp(ip[3] * OutMul, Clamp); + ip += 4; + op += 4; + l4--; + } + } + +#endif // LANCIR_ALIGN > 4 + + if (IsUnityMul) { + while (l != 0) { + *op = (T)roundclamp(*ip, Clamp); + ip++; + op++; + l--; + } + } else { + while (l != 0) { + *op = (T)roundclamp(*ip * OutMul, Clamp); + ip++; + op++; + l--; + } + } + } + } + + /** + * @def LANCIR_LF_PRE + * @brief Scanline resize function prologue. + */ + +#define LANCIR_LF_PRE \ + const CResizePos *const rpe = rp + DstLen; \ + while (rp != rpe) { \ + const float *flt = rp->flt; \ + const float *ip; \ + if (UseSP) { \ + ip = (const float *)((intptr_t)sp + rp->spo); \ + } else { \ + ip = (const float *)rp->spo; \ + } + + /** + * @def LANCIR_LF_POST + * @brief Scanline resize function epilogue. + */ + +#define LANCIR_LF_POST \ + op += opinc; \ + rp++; \ + } + + /** + * @{ + * @brief Function performs scanline resizing. Variants for 1-4-channel + * images. + * + * @param[in] sp Source scanline buffer. + * @param[out] op Destination buffer. + * @param opinc `op` increment. + * @param rp Source scanline offsets and resizing filters. + * @param kl Filter kernel's length, in taps (always an even value). + * @param DstLen Destination length, in pixels. + * @tparam UseSP `true`, if `sp` pointer should be added to `spo`. + */ + + template + static void resize1(const float *const sp, float *op, const size_t opinc, + const CResizePos *rp, const int kl, const int DstLen) + { + const int ci = kl >> 2; + + if ((kl & 3) == 0) { + LANCIR_LF_PRE + + int c = ci; + +#if LANCIR_ALIGN > 4 + + lancvec_t sum = lancvec_mul( + lancvec_load(flt), lancvec_loadu(ip)); + + while (--c != 0) { + flt += 4; + ip += 4; + sum = lancvec_madd(sum, lancvec_load(flt), + lancvec_loadu(ip)); + } + + lancvec_store32_hadd(op, sum); + +#else // LANCIR_ALIGN > 4 + + float sum0 = flt[0] * ip[0]; + float sum1 = flt[1] * ip[1]; + float sum2 = flt[2] * ip[2]; + float sum3 = flt[3] * ip[3]; + + while (--c != 0) { + flt += 4; + ip += 4; + sum0 += flt[0] * ip[0]; + sum1 += flt[1] * ip[1]; + sum2 += flt[2] * ip[2]; + sum3 += flt[3] * ip[3]; + } + + op[0] = (sum0 + sum1) + (sum2 + sum3); + +#endif // LANCIR_ALIGN > 4 + + LANCIR_LF_POST + } else { + LANCIR_LF_PRE + + int c = ci; + +#if LANCIR_ALIGN > 4 + + lancvec_t sum = lancvec_mul(lancvec_load(flt), + lancvec_loadu(ip)); + + while (--c != 0) { + flt += 4; + ip += 4; + sum = lancvec_madd(sum, lancvec_load(flt), + lancvec_loadu(ip)); + } + +#if defined(LANCIR_NEON) + + float32x2_t sum2 = vadd_f32(vget_high_f32(sum), + vget_low_f32(sum)); + + sum2 = vmla_f32(sum2, vld1_f32(flt + 4), + vld1_f32(ip + 4)); + +#if defined(LANCIR_ARM32) + op[0] = vget_lane_f32(sum2, 0) + + vget_lane_f32(sum2, 1); +#else // defined( LANCIR_ARM32 ) + op[0] = vaddv_f32(sum2); +#endif // defined( LANCIR_ARM32 ) + +#else // defined( LANCIR_NEON ) + + const lancvec_t sum2 = lancvec_mul(lancvec_loadu(flt + 2), + lancvec_loadu(ip + 2)); + + sum = lancvec_addhl(sum, sum); + sum = lancvec_addhl(sum, sum2); + + lancvec_store32_addhl(op, sum); + +#endif // defined( LANCIR_NEON ) + +#else // LANCIR_ALIGN > 4 + + float sum0 = flt[0] * ip[0]; + float sum1 = flt[1] * ip[1]; + float sum2 = flt[2] * ip[2]; + float sum3 = flt[3] * ip[3]; + + while (--c != 0) { + flt += 4; + ip += 4; + sum0 += flt[0] * ip[0]; + sum1 += flt[1] * ip[1]; + sum2 += flt[2] * ip[2]; + sum3 += flt[3] * ip[3]; + } + + op[0] = (sum0 + sum1) + (sum2 + sum3) + + flt[4] * ip[4] + flt[5] * ip[5]; + +#endif // LANCIR_ALIGN > 4 + + LANCIR_LF_POST + } + } + + template + static void resize2(const float *const sp, float *op, const size_t opinc, + const CResizePos *rp, const int kl, const int DstLen) + { +#if LANCIR_ALIGN > 4 + const int ci = kl >> 2; + const int cir = kl & 3; +#else // LANCIR_ALIGN > 4 + const int ci = kl >> 1; +#endif // LANCIR_ALIGN > 4 + + LANCIR_LF_PRE + + int c = ci; + +#if defined(LANCIR_AVX) + + __m256 sum = _mm256_mul_ps(_mm256_load_ps(flt), + _mm256_loadu_ps(ip)); + + while (--c != 0) { + flt += 8; + ip += 8; + sum = _mm256_add_ps(sum, _mm256_mul_ps(_mm256_load_ps(flt), _mm256_loadu_ps(ip))); + } + + __m128 res = _mm_add_ps(_mm256_extractf128_ps(sum, 0), + _mm256_extractf128_ps(sum, 1)); + + if (cir == 2) { + res = _mm_add_ps(res, _mm_mul_ps(_mm_load_ps(flt + 8), _mm_loadu_ps(ip + 8))); + } + + _mm_storel_pi((__m64 *)op, + _mm_add_ps(res, _mm_movehl_ps(res, res))); + +#elif LANCIR_ALIGN > 4 + + lancvec_t sumA = lancvec_mul( + lancvec_load(flt), lancvec_loadu(ip)); + + lancvec_t sumB = lancvec_mul( + lancvec_load(flt + 4), lancvec_loadu(ip + 4)); + + while (--c != 0) { + flt += 8; + ip += 8; + sumA = lancvec_madd(sumA, lancvec_load(flt), + lancvec_loadu(ip)); + + sumB = lancvec_madd(sumB, lancvec_load(flt + 4), + lancvec_loadu(ip + 4)); + } + + sumA = lancvec_add(sumA, sumB); + + if (cir == 2) { + sumA = lancvec_madd(sumA, lancvec_load(flt + 8), + lancvec_loadu(ip + 8)); + } + + lancvec_store64_addhl(op, sumA); + +#else // LANCIR_ALIGN > 4 + + const float xx = flt[0]; + const float xx2 = flt[1]; + float sum0 = xx * ip[0]; + float sum1 = xx * ip[1]; + float sum2 = xx2 * ip[2]; + float sum3 = xx2 * ip[3]; + + while (--c != 0) { + flt += 2; + ip += 4; + const float xx = flt[0]; + const float xx2 = flt[1]; + sum0 += xx * ip[0]; + sum1 += xx * ip[1]; + sum2 += xx2 * ip[2]; + sum3 += xx2 * ip[3]; + } + + op[0] = sum0 + sum2; + op[1] = sum1 + sum3; + +#endif // LANCIR_ALIGN > 4 + + LANCIR_LF_POST + } + + template + static void resize3(const float *const sp, float *op, const size_t opinc, + const CResizePos *rp, const int kl, const int DstLen) + { +#if LANCIR_ALIGN > 4 + + const int ci = kl >> 2; + const int cir = kl & 3; + + LANCIR_LF_PRE + + float res[12]; + int c = ci; + +#if defined(LANCIR_AVX) + + __m128 sumA = _mm_mul_ps(_mm_load_ps(flt), _mm_loadu_ps(ip)); + __m256 sumB = _mm256_mul_ps(_mm256_loadu_ps(flt + 4), + _mm256_loadu_ps(ip + 4)); + + while (--c != 0) { + flt += 12; + ip += 12; + sumA = _mm_add_ps(sumA, _mm_mul_ps(_mm_load_ps(flt), _mm_loadu_ps(ip))); + + sumB = _mm256_add_ps(sumB, _mm256_mul_ps(_mm256_loadu_ps(flt + 4), _mm256_loadu_ps(ip + 4))); + } + + if (cir == 2) { + sumA = _mm_add_ps(sumA, _mm_mul_ps(_mm_load_ps(flt + 12), _mm_loadu_ps(ip + 12))); + } + + _mm_storeu_ps(res, sumA); + + float o0 = res[0] + res[3]; + float o1 = res[1]; + float o2 = res[2]; + + _mm256_storeu_ps(res + 4, sumB); + + o1 += res[4]; + o2 += res[5]; + +#else // defined( LANCIR_AVX ) + + lancvec_t sumA = lancvec_mul(lancvec_load(flt), + lancvec_loadu(ip)); + + lancvec_t sumB = lancvec_mul(lancvec_load(flt + 4), + lancvec_loadu(ip + 4)); + + lancvec_t sumC = lancvec_mul(lancvec_load(flt + 8), + lancvec_loadu(ip + 8)); + + while (--c != 0) { + flt += 12; + ip += 12; + sumA = lancvec_madd(sumA, lancvec_load(flt), + lancvec_loadu(ip)); + + sumB = lancvec_madd(sumB, lancvec_load(flt + 4), + lancvec_loadu(ip + 4)); + + sumC = lancvec_madd(sumC, lancvec_load(flt + 8), + lancvec_loadu(ip + 8)); + } + + if (cir == 2) { + sumA = lancvec_madd(sumA, lancvec_load(flt + 12), + lancvec_loadu(ip + 12)); + } + + lancvec_storeu(res, sumA); + lancvec_storeu(res + 4, sumB); + + float o0 = res[0] + res[3]; + float o1 = res[1] + res[4]; + float o2 = res[2] + res[5]; + + lancvec_storeu(res + 8, sumC); + +#endif // defined( LANCIR_AVX ) + + o0 += res[6] + res[9]; + o1 += res[7] + res[10]; + o2 += res[8] + res[11]; + + if (cir == 2) { + o1 += flt[16] * ip[16]; + o2 += flt[17] * ip[17]; + } + + op[0] = o0; + op[1] = o1; + op[2] = o2; + +#else // LANCIR_ALIGN > 4 + + const int ci = kl >> 1; + + LANCIR_LF_PRE + + int c = ci; + + const float xx = flt[0]; + float sum0 = xx * ip[0]; + float sum1 = xx * ip[1]; + float sum2 = xx * ip[2]; + const float xx2 = flt[1]; + float sum3 = xx2 * ip[3]; + float sum4 = xx2 * ip[4]; + float sum5 = xx2 * ip[5]; + + while (--c != 0) { + flt += 2; + ip += 6; + const float xx = flt[0]; + sum0 += xx * ip[0]; + sum1 += xx * ip[1]; + sum2 += xx * ip[2]; + const float xx2 = flt[1]; + sum3 += xx2 * ip[3]; + sum4 += xx2 * ip[4]; + sum5 += xx2 * ip[5]; + } + + op[0] = sum0 + sum3; + op[1] = sum1 + sum4; + op[2] = sum2 + sum5; + +#endif // LANCIR_ALIGN > 4 + + LANCIR_LF_POST + } + + template + static void resize4(const float *const sp, float *op, const size_t opinc, + const CResizePos *rp, const int kl, const int DstLen) + { +#if LANCIR_ALIGN > 4 + const int ci = kl >> 1; +#else // LANCIR_ALIGN > 4 + const int ci = kl; +#endif // LANCIR_ALIGN > 4 + + LANCIR_LF_PRE + + int c = ci; + +#if defined(LANCIR_AVX) + + __m256 sum = _mm256_mul_ps(_mm256_load_ps(flt), + _mm256_loadu_ps(ip)); + + while (--c != 0) { + flt += 8; + ip += 8; + sum = _mm256_add_ps(sum, _mm256_mul_ps(_mm256_load_ps(flt), _mm256_loadu_ps(ip))); + } + + _mm_store_ps(op, _mm_add_ps(_mm256_extractf128_ps(sum, 0), _mm256_extractf128_ps(sum, 1))); + +#elif LANCIR_ALIGN > 4 + + lancvec_t sumA = lancvec_mul(lancvec_load(flt), + lancvec_load(ip)); + + lancvec_t sumB = lancvec_mul(lancvec_load(flt + 4), + lancvec_load(ip + 4)); + + while (--c != 0) { + flt += 8; + ip += 8; + sumA = lancvec_madd(sumA, lancvec_load(flt), + lancvec_load(ip)); + + sumB = lancvec_madd(sumB, lancvec_load(flt + 4), + lancvec_load(ip + 4)); + } + + lancvec_store(op, lancvec_add(sumA, sumB)); + +#else // LANCIR_ALIGN > 4 + + const float xx = flt[0]; + float sum0 = xx * ip[0]; + float sum1 = xx * ip[1]; + float sum2 = xx * ip[2]; + float sum3 = xx * ip[3]; + + while (--c != 0) { + flt++; + ip += 4; + const float xx = flt[0]; + sum0 += xx * ip[0]; + sum1 += xx * ip[1]; + sum2 += xx * ip[2]; + sum3 += xx * ip[3]; + } + + op[0] = sum0; + op[1] = sum1; + op[2] = sum2; + op[3] = sum3; + +#endif // LANCIR_ALIGN > 4 + + LANCIR_LF_POST + } + + /** @} */ + +#undef LANCIR_LF_PRE +#undef LANCIR_LF_POST +}; + +#undef lancvec_t +#undef lancvec_const_splat +#undef lancvec_load32_splat +#undef lancvec_load +#undef lancvec_loadu +#undef lancvec_store +#undef lancvec_storeu +#undef lancvec_add +#undef lancvec_mul +#undef lancvec_min +#undef lancvec_max +#undef lancvec_madd +#undef lancvec_addhl +#undef lancvec_store32_addhl +#undef lancvec_store32_hadd +#undef lancvec_store64_addhl + +#if defined(LANCIR_NULLPTR) +#undef nullptr +#undef LANCIR_NULLPTR +#endif // defined( LANCIR_NULLPTR ) + +} // namespace avir + +#endif // AVIR_CLANCIR_INCLUDED diff --git a/image_processing/resize_image.cpp b/image_processing/resize_image.cpp new file mode 100644 index 000000000..7a6a94e9c --- /dev/null +++ b/image_processing/resize_image.cpp @@ -0,0 +1,60 @@ +#include "resize_image.h" + +#include "lancir.h" + +static QImage scaleImageLancir(const QImage &image, int width, int height) +{ + QImage src = (image.format() == QImage::Format_ARGB32) + ? image + : image.convertToFormat(QImage::Format_ARGB32); + + QImage dst(width, height, QImage::Format_ARGB32); + + // SrcSSize / NewSSize are in elements; for uint8_t that equals bytes, + // so bytesPerLine() covers any Qt row-alignment padding correctly. + avir::CLancIRParams params(src.bytesPerLine(), dst.bytesPerLine()); + params.la = 4.0; // Lanczos4 + + avir::CLancIR lancir; + lancir.resizeImage( + src.constBits(), src.width(), src.height(), + dst.bits(), width, height, 4, ¶ms); + + return dst; +} + +// ---- QPixmap API ------------------------------------------------------------ + +QPixmap scalePixmap(const QPixmap &pixmap, int width, int height, ScaleMethod method) +{ + if ((pixmap.width() == width && pixmap.height() == height) || pixmap.isNull()) + return pixmap; + + switch (method) { + case ScaleMethod::Nearest: + return pixmap.scaled(width, height, Qt::IgnoreAspectRatio, Qt::FastTransformation); + case ScaleMethod::Bilinear: + return pixmap.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + case ScaleMethod::Lanczos: + return QPixmap::fromImage(scaleImageLancir(pixmap.toImage(), width, height)); + } + return pixmap; +} + +// ---- QImage API (avoids QPixmap round-trip in ContinuousPageWidget) --------- + +QImage scaleImage(const QImage &image, int width, int height, ScaleMethod method) +{ + if ((image.width() == width && image.height() == height) || image.isNull()) + return image; + + switch (method) { + case ScaleMethod::Nearest: + return image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::FastTransformation); + case ScaleMethod::Bilinear: + return image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + case ScaleMethod::Lanczos: + return scaleImageLancir(image, width, height); + } + return image; +} diff --git a/image_processing/resize_image.h b/image_processing/resize_image.h new file mode 100644 index 000000000..ae3390fe1 --- /dev/null +++ b/image_processing/resize_image.h @@ -0,0 +1,19 @@ +#ifndef RESIZE_IMAGE_H +#define RESIZE_IMAGE_H + +#include +#include + +enum class ScaleMethod { + Nearest = 0, + Bilinear = 1, + Lanczos = 2 +}; + +// Base scaling API — callers are responsible for supplying the correct target dimensions. + +QPixmap scalePixmap(const QPixmap &pixmap, int width, int height, ScaleMethod method = ScaleMethod::Lanczos); + +QImage scaleImage(const QImage &image, int width, int height, ScaleMethod method = ScaleMethod::Lanczos); + +#endif // RESIZE_IMAGE_H From 80de46ce7434c093408d29dfd671a4476342cd59 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 17:16:51 +0100 Subject: [PATCH 131/187] Add a setting to control the scaling method used --- YACReader/configuration.h | 4 ++++ YACReader/options_dialog.cpp | 26 ++++++++++++++++++++++++++ YACReader/options_dialog.h | 3 +++ common/yacreader_global_gui.h | 1 + 4 files changed, 34 insertions(+) diff --git a/YACReader/configuration.h b/YACReader/configuration.h index 23cc5348f..10d499386 100644 --- a/YACReader/configuration.h +++ b/YACReader/configuration.h @@ -10,6 +10,7 @@ #include #include "yacreader_global_gui.h" +#include "resize_image.h" #define CONF_FILE_PATH "." #define SLIDE_ASPECT_RATIO 1.585 @@ -117,6 +118,9 @@ class Configuration : public QObject MouseMode getMouseMode() { return static_cast(settings->value(MOUSE_MODE, MouseMode::Normal).toInt()); } void setMouseMode(MouseMode mouseMode) { settings->setValue(MOUSE_MODE, static_cast(mouseMode)); } + + ScaleMethod getScalingMethod() { return static_cast(settings->value(SCALING_METHOD, static_cast(ScaleMethod::Lanczos)).toInt()); } + void setScalingMethod(ScaleMethod method) { settings->setValue(SCALING_METHOD, static_cast(method)); } }; } diff --git a/YACReader/options_dialog.cpp b/YACReader/options_dialog.cpp index 43f50e675..497553c07 100644 --- a/YACReader/options_dialog.cpp +++ b/YACReader/options_dialog.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "theme_manager.h" #include "theme_factory.h" @@ -198,6 +199,23 @@ OptionsDialog::OptionsDialog(QWidget *parent) doublePageBoxLayout->addWidget(coverSPCheckBox); doublePageBox->setLayout(doublePageBoxLayout); layoutImageV->addWidget(doublePageBox); + + auto scalingBox = new QGroupBox(tr("Scaling")); + auto scalingLayout = new QHBoxLayout(); + scalingLayout->addWidget(new QLabel(tr("Scaling method"))); + scalingMethodCombo = new QComboBox(); + scalingMethodCombo->addItem(tr("Nearest (fast, low quality)")); + scalingMethodCombo->addItem(tr("Bilinear")); + scalingMethodCombo->addItem(tr("Lanczos (better quality)")); + connect(scalingMethodCombo, &QComboBox::currentIndexChanged, this, [this](int index) { + Configuration::getConfiguration().setScalingMethod(static_cast(index)); + emit changedImageOptions(); + }); + scalingLayout->addWidget(scalingMethodCombo); + scalingLayout->addStretch(); + scalingBox->setLayout(scalingLayout); + layoutImageV->addWidget(scalingBox); + layoutImageV->addStretch(); // IMAGE ADJUSTMENTS END ----------------------------- @@ -294,6 +312,9 @@ void OptionsDialog::saveOptions() } Configuration::getConfiguration().setMouseMode(mouseMode); + Configuration::getConfiguration().setScalingMethod(static_cast(scalingMethodCombo->currentIndex())); + emit changedImageOptions(); + YACReaderOptionsDialog::saveOptions(); } @@ -330,6 +351,11 @@ void OptionsDialog::restoreOptions(QSettings *settings) #endif disableScrollAnimations->setChecked(settings->value(DISABLE_SCROLL_ANIMATION, defaultDisableScrollAnimationsValue).toBool()); + { + QSignalBlocker blocker(scalingMethodCombo); + scalingMethodCombo->setCurrentIndex(static_cast(Configuration::getConfiguration().getScalingMethod())); + } + auto mouseMode = Configuration::getConfiguration().getMouseMode(); switch (mouseMode) { diff --git a/YACReader/options_dialog.h b/YACReader/options_dialog.h index 20467f773..656536953 100644 --- a/YACReader/options_dialog.h +++ b/YACReader/options_dialog.h @@ -6,6 +6,7 @@ #include +class QComboBox; class QDialog; class QLabel; class QLineEdit; @@ -62,6 +63,8 @@ class OptionsDialog : public YACReaderOptionsDialog, protected Themable QColor currentColor; + QComboBox *scalingMethodCombo; + QRadioButton *normalMouseModeRadioButton; QRadioButton *leftRightNavigationMouseModeRadioButton; QRadioButton *hotAreasMouseModeRadioButton; diff --git a/common/yacreader_global_gui.h b/common/yacreader_global_gui.h index 60d455455..2065bd2d2 100644 --- a/common/yacreader_global_gui.h +++ b/common/yacreader_global_gui.h @@ -39,6 +39,7 @@ #define USE_SINGLE_SCROLL_STEP_TO_TURN_PAGE "USE_SINGLE_SCROLL_STEP_TO_TURN_PAGE" #define DISABLE_SCROLL_ANIMATION "DISABLE_SCROLL_ANIMATION" #define MOUSE_MODE "MOUSE_MODE" +#define SCALING_METHOD "SCALING_METHOD" #define FLOW_TYPE_GL "FLOW_TYPE_GL" #define Y_POSITION "Y_POSITION" From de676a0fcb0924a54edda53dbbf49a72991d0f6b Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 17:18:14 +0100 Subject: [PATCH 132/187] Use the new resize image API to resize the pages while reading --- YACReader/continuous_page_widget.cpp | 4 +++- YACReader/viewer.cpp | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/YACReader/continuous_page_widget.cpp b/YACReader/continuous_page_widget.cpp index 65e1361b1..17b3f9c3a 100644 --- a/YACReader/continuous_page_widget.cpp +++ b/YACReader/continuous_page_widget.cpp @@ -1,6 +1,7 @@ #include "continuous_page_widget.h" #include "continuous_view_model.h" #include "render.h" +#include "resize_image.h" #include #include @@ -183,7 +184,8 @@ const QImage *ContinuousPageWidget::scaledImageForPaint(int pageIndex, const QIm entry.sourceCacheKey = sourceKey; entry.sourceSize = source->size(); entry.targetSize = targetSize; - entry.scaledImage = source->scaled(targetSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + entry.scaledImage = scaleImage(*source, targetSize.width(), targetSize.height(), + Configuration::getConfiguration().getScalingMethod()); scaledPageCache.pages.insert(pageIndex, std::move(entry)); return &scaledPageCache.pages[pageIndex].scaledImage; diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index 4533bbbef..fd5adefa0 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -1,6 +1,7 @@ #include "viewer.h" #include "continuous_page_widget.h" #include "continuous_view_model.h" +#include "resize_image.h" #include "configuration.h" #include "magnifying_glass.h" #include "goto_flow_widget.h" @@ -433,16 +434,17 @@ void Viewer::updateContentSize() if (zoom != 100) { pagefit.scale(floor(pagefit.width() * zoom / 100.0f), 0, Qt::KeepAspectRatioByExpanding); } - // apply scaling + // apply size to the container content->resize(pagefit); - // TODO: updtateContentSize should only scale the pixmap once - if (devicePixelRatioF() > 1) // only in HDPI displays - { - QPixmap page = currentPage->scaled(content->width() * devicePixelRatioF(), content->height() * devicePixelRatioF(), Qt::KeepAspectRatio, Qt::SmoothTransformation); - page.setDevicePixelRatio(devicePixelRatioF()); - content->setPixmap(page); - } + // scale the pixmap to physical pixels for crisp rendering on all displays + auto dpr = devicePixelRatioF(); + QPixmap page = scalePixmap(*currentPage, + qRound(content->width() * dpr), + qRound(content->height() * dpr), + Configuration::getConfiguration().getScalingMethod()); + page.setDevicePixelRatio(dpr); + content->setPixmap(page); emit backgroundChanges(); } From 3f6235fe3223abe5596aa5e50f024f5ad6ff7c47 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 17:19:02 +0100 Subject: [PATCH 133/187] Trigger a rendering pass when the settings change --- YACReader/continuous_page_widget.cpp | 7 +++++++ YACReader/continuous_page_widget.h | 1 + YACReader/main_window_viewer.cpp | 2 +- YACReader/viewer.cpp | 9 +++++++++ YACReader/viewer.h | 1 + 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/YACReader/continuous_page_widget.cpp b/YACReader/continuous_page_widget.cpp index 17b3f9c3a..9391c1d1b 100644 --- a/YACReader/continuous_page_widget.cpp +++ b/YACReader/continuous_page_widget.cpp @@ -2,6 +2,7 @@ #include "continuous_view_model.h" #include "render.h" #include "resize_image.h" +#include "configuration.h" #include #include @@ -78,6 +79,12 @@ QSize ContinuousPageWidget::sizeHint() const return QSize(width(), continuousViewModel->totalHeight()); } +void ContinuousPageWidget::invalidateScaledImageCache() +{ + scaledPageCache.invalidateAll(); + update(); +} + void ContinuousPageWidget::onPageAvailable(int absolutePageIndex) { if (!render || !continuousViewModel || absolutePageIndex < 0 || absolutePageIndex >= continuousViewModel->numPages()) { diff --git a/YACReader/continuous_page_widget.h b/YACReader/continuous_page_widget.h index 819d7a191..16be8f2ff 100644 --- a/YACReader/continuous_page_widget.h +++ b/YACReader/continuous_page_widget.h @@ -28,6 +28,7 @@ class ContinuousPageWidget : public QWidget, protected Themable public slots: void onPageAvailable(int absolutePageIndex); + void invalidateScaledImageCache(); protected: void paintEvent(QPaintEvent *event) override; diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index f8f5a8cac..d83d44012 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -148,7 +148,7 @@ void MainWindowViewer::setupUI() connect(optionsDialog, &QDialog::accepted, viewer, &Viewer::updateOptions); connect(optionsDialog, &YACReaderOptionsDialog::optionsChanged, this, &MainWindowViewer::reloadOptions); connect(optionsDialog, &OptionsDialog::changedFilters, viewer, &Viewer::updateFilters); - connect(optionsDialog, &OptionsDialog::changedImageOptions, viewer, &Viewer::updatePage); + connect(optionsDialog, &OptionsDialog::changedImageOptions, viewer, &Viewer::onImageOptionsChanged); optionsDialog->restoreOptions(settings); // shortcutsDialog = new ShortcutsDialog(this); diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index fd5adefa0..3675b6f9d 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -358,6 +358,15 @@ void Viewer::goTo(unsigned int page) render->goTo(page); } +void Viewer::onImageOptionsChanged() +{ + if (continuousScroll) { + continuousWidget->invalidateScaledImageCache(); + } else { + updatePage(); + } +} + void Viewer::updatePage() { if (continuousScroll) { diff --git a/YACReader/viewer.h b/YACReader/viewer.h index b2393a893..0189c7f45 100644 --- a/YACReader/viewer.h +++ b/YACReader/viewer.h @@ -58,6 +58,7 @@ public slots: void goToLastPage(); void goTo(unsigned int page); void updatePage(); + void onImageOptionsChanged(); void updateContentSize(); void updateVerticalScrollBar(); void updateOptions(); From cab4a012876d3f1b1c9f8df4c23b539f0e88fbba Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 17:20:38 +0100 Subject: [PATCH 134/187] Update CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bdc88b953..994b25641 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Version counting is based on semantic versioning (Major.Feature.Patch) ### YACReader * Add support for continuous scroll mode. * Fix the translator. +* Add Lanczos interpolation for image scaling. You can control the method used via the settings under `Image adjustments`. ### All GUI Apps * Migrate Flow implementation from OpenGL to QRhi. This is a full new implementation with better performance and compatibility with operating systems and hardware. @@ -131,7 +132,7 @@ Version counting is based on semantic versioning (Major.Feature.Patch) ### YACReaderLibraryServer * Add `rescan-xml-info` command. -* Improved API to provide better integration with the clients (Android 1.4.0 and iOS 3.29.0). +* Improved API to provide better integration with the clients (Android 1.4.0 and iOS 3.29.0). ### All Apps * New universal builds for macos. From bb6378e345e751f9924b2d8fdac322ac97ab88b2 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 18:53:42 +0100 Subject: [PATCH 135/187] Remove useless verification --- .../prepare-release-artifacts/action.yml | 30 +------------------ 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/.github/actions/prepare-release-artifacts/action.yml b/.github/actions/prepare-release-artifacts/action.yml index b2280e1fe..cd56f49f0 100644 --- a/.github/actions/prepare-release-artifacts/action.yml +++ b/.github/actions/prepare-release-artifacts/action.yml @@ -1,5 +1,5 @@ name: Prepare Release Artifacts -description: Download, flatten, and verify release artifacts for publishing +description: Download and flatten release artifacts for publishing runs: using: composite @@ -31,31 +31,3 @@ runs: echo "=== Windows installers in staging ===" ls -lh staging/YACReader*.exe || echo "No Windows installers found" - - name: Verify Windows installer signatures - shell: bash - run: | - echo "=== Installing osslsigncode to verify signatures ===" - sudo apt-get update - sudo apt-get install -y osslsigncode - - echo "" - echo "=== Checking signatures on Windows installers ===" - for installer in staging/YACReader*.exe; do - if [ -f "$installer" ]; then - echo "Checking: $(basename $installer)" - echo "File size: $(stat -c%s $installer) bytes" - - # Try to extract signature info - if osslsigncode verify -in "$installer" 2>&1 | grep -q "Signature verification: ok"; then - echo " ✓ SIGNED - Signature verified successfully" - osslsigncode verify -in "$installer" 2>&1 | grep -E "(Signed|Signer|Timestamp)" - else - echo " ✗ UNSIGNED or INVALID - No valid signature found" - osslsigncode verify -in "$installer" 2>&1 | head -20 - fi - echo "" - fi - done - - echo "=== Summary ===" - echo "Total installers in staging: $(ls staging/YACReader*.exe 2>/dev/null | wc -l)" From 54a2437e488bad321a08e1225247f3814f22cd26 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 19:16:16 +0100 Subject: [PATCH 136/187] Better placement for the continuous scroll icon --- YACReader/main_window_viewer.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index d83d44012..35a270099 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -514,8 +514,10 @@ void MainWindowViewer::createToolBars() comicToolBar->addAction(adjustToFullSizeAction); auto fitToPageTBAction = wrappedToolbarAction(fitToPageAction); comicToolBar->addAction(fitToPageTBAction); - auto continuousScroollTBAction = wrappedToolbarAction(continuousScrollAction); + comicToolBar->addAction(continuousScroollTBAction); + + comicToolBar->addSeparator(); auto fitModes = new QActionGroup(this); fitModes->addAction(adjustToWidthTBAction); @@ -537,7 +539,6 @@ void MainWindowViewer::createToolBars() comicToolBar->addAction(wrappedToolbarAction(rightRotationAction)); comicToolBar->addAction(wrappedToolbarAction(doublePageAction)); comicToolBar->addAction(wrappedToolbarAction(doubleMangaPageAction)); - comicToolBar->addAction(continuousScroollTBAction); comicToolBar->addSeparator(); @@ -578,15 +579,17 @@ void MainWindowViewer::createToolBars() viewer->addAction(goToPageOnTheLeftAction); viewer->addAction(goToPageOnTheRightAction); viewer->addAction(goToPageAction); + YACReader::addSperator(viewer); viewer->addAction(adjustHeightAction); viewer->addAction(adjustWidthAction); viewer->addAction(adjustToFullSizeAction); viewer->addAction(fitToPageAction); + viewer->addAction(continuousScrollAction); + YACReader::addSperator(viewer); viewer->addAction(leftRotationAction); viewer->addAction(rightRotationAction); viewer->addAction(doublePageAction); viewer->addAction(doubleMangaPageAction); - viewer->addAction(continuousScrollAction); YACReader::addSperator(viewer); viewer->addAction(showMagnifyingGlassAction); From f323ac5243a9f73548eff3f21fa062369bb41893 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 21:34:30 +0100 Subject: [PATCH 137/187] Add a rule for the firewall automatically on windows. --- ci/win/build_installer_qt6.iss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ci/win/build_installer_qt6.iss b/ci/win/build_installer_qt6.iss index 06930e903..c71942104 100644 --- a/ci/win/build_installer_qt6.iss +++ b/ci/win/build_installer_qt6.iss @@ -118,10 +118,14 @@ LaunchYACReader=Start YACreader after finishing installation Filename: {tmp}\vc_redist.{#PLATFORM}.exe; \ Parameters: "/install /quiet /norestart"; \ StatusMsg: "Installing VC++ Redistributables..." +Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall add rule name=""YACReaderLibrary"" dir=in action=allow program=""{app}\YACReaderLibrary.exe"" enable=yes profile=private,domain"; Flags: runhidden waituntilterminated Filename: {app}\{cm:AppLibrary}.exe; Description: {cm:LaunchYACReaderLibrary,{cm:AppLibrary}}; Flags: nowait postinstall skipifsilent Filename: {app}\{cm:App}.exe; Description: {cm:LaunchYACReader,{cm:App}}; Flags: nowait postinstall skipifsilent +[UninstallRun] +Filename: "{sys}\netsh.exe"; Parameters: "advfirewall firewall delete rule name=""YACReaderLibrary"""; Flags: runhidden waituntilterminated + [Icons] Name: {group}\YACReader; Filename: {app}\YACReader.exe; WorkingDir: {app}; IconIndex: 0 Name: {group}\YACReader Library; Filename: {app}\YACReaderLibrary.exe; WorkingDir: {app}; IconIndex: 0 From b9005c4f5a351f0635c68c98089460f73b2de73f Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 6 Mar 2026 21:38:45 +0100 Subject: [PATCH 138/187] Update the what's new dialog --- custom_widgets/whats_new_dialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_widgets/whats_new_dialog.cpp b/custom_widgets/whats_new_dialog.cpp index c1467e62b..bd4a15463 100644 --- a/custom_widgets/whats_new_dialog.cpp +++ b/custom_widgets/whats_new_dialog.cpp @@ -42,6 +42,7 @@ YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent) "YACReader
" " • Add support for continuous scroll mode
" " • Fix the translator
" + " • Add Lanczos interpolation for image scaling. You can control the method used via the settings under Image adjustments
" "
" "All GUI Apps
" " • Migrate Flow implementation from OpenGL to QRhi. This is a full new implementation with better performance and compatibility with operating systems and hardware
" From d65ce375dfd0e9339be2e72a6702d770279cadad Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 7 Mar 2026 19:01:30 +0100 Subject: [PATCH 139/187] Provide more meaningful theme colors to deal with not completed and recent states --- YACReaderLibrary/themes/builtin_classic.json | 3 ++- YACReaderLibrary/themes/builtin_dark.json | 3 ++- YACReaderLibrary/themes/builtin_light.json | 3 ++- YACReaderLibrary/themes/theme.h | 3 ++- YACReaderLibrary/themes/theme_factory.cpp | 9 ++++++--- YACReaderLibrary/yacreader_folders_view.cpp | 15 +++++++++------ YACReaderLibrary/yacreader_folders_view.h | 2 ++ custom_widgets/yacreader_treeview.h | 1 - 8 files changed, 25 insertions(+), 14 deletions(-) diff --git a/YACReaderLibrary/themes/builtin_classic.json b/YACReaderLibrary/themes/builtin_classic.json index 5fb6e4776..de2ddd1b4 100644 --- a/YACReaderLibrary/themes/builtin_classic.json +++ b/YACReaderLibrary/themes/builtin_classic.json @@ -151,7 +151,8 @@ "folderIconSelectedColor": "#e0e0e0", "folderIconSelectedShadowColor": "#000000", "folderIconShadowColor": "#000000", - "folderIndicatorColor": "#edc518", + "newItemColor": "#edc518", + "folderNotCompletedColor": "#edc518", "folderReadOverlayColor": "#464646", "folderReadOverlaySelectedColor": "#464646", "scrollBackgroundColor": "#404040", diff --git a/YACReaderLibrary/themes/builtin_dark.json b/YACReaderLibrary/themes/builtin_dark.json index 7d043c8f2..203fc57f0 100644 --- a/YACReaderLibrary/themes/builtin_dark.json +++ b/YACReaderLibrary/themes/builtin_dark.json @@ -151,7 +151,8 @@ "folderIconSelectedColor": "#e0e0e0", "folderIconSelectedShadowColor": "#000000", "folderIconShadowColor": "#000000", - "folderIndicatorColor": "#edc518", + "newItemColor": "#edc518", + "folderNotCompletedColor": "#edc518", "folderReadOverlayColor": "#222222", "folderReadOverlaySelectedColor": "#222222", "scrollBackgroundColor": "#404040", diff --git a/YACReaderLibrary/themes/builtin_light.json b/YACReaderLibrary/themes/builtin_light.json index 3abc1dd76..779c1f0e2 100644 --- a/YACReaderLibrary/themes/builtin_light.json +++ b/YACReaderLibrary/themes/builtin_light.json @@ -151,7 +151,8 @@ "folderIconSelectedColor": "#ffffff", "folderIconSelectedShadowColor": "#161616", "folderIconShadowColor": "#ffffff", - "folderIndicatorColor": "#555f7f", + "newItemColor": "#555f7f", + "folderNotCompletedColor": "#555f7f", "folderReadOverlayColor": "#ffffff", "folderReadOverlaySelectedColor": "#161616", "scrollBackgroundColor": "#e0e0e0", diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index 767645088..ee173a421 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -195,7 +195,8 @@ struct NavigationTreeThemeTemplates { struct NavigationTreeTheme { QString navigationTreeQSS; - QColor folderIndicatorColor; // For incomplete folders and recently updated folders + QColor folderNotCompletedColor; // Left-edge bar for folders not yet fully read + QColor newItemColor; // Dot for recently added/updated folders // Branch indicator icon paths (used by QSS url()) QString branchClosedIconPath; diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index bf1afbcdd..4d5b6c1e4 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -101,7 +101,8 @@ struct NavigationTreeParams { QColor scrollBackgroundColor; QColor scrollHandleColor; QColor selectedTextColor; - QColor folderIndicatorColor; + QColor folderNotCompletedColor; + QColor newItemColor; // Branch indicator icon colors (independent of sidebarIcons.iconColor) QColor branchIndicatorColor; @@ -657,7 +658,8 @@ Theme makeTheme(const ThemeParams ¶ms) theme.navigationTree.branchOpenIconPath, theme.navigationTree.branchClosedIconSelectedPath, theme.navigationTree.branchOpenIconSelectedPath); - theme.navigationTree.folderIndicatorColor = nt.folderIndicatorColor; + theme.navigationTree.folderNotCompletedColor = nt.folderNotCompletedColor; + theme.navigationTree.newItemColor = nt.newItemColor; // Folder icon — normal and selected states with independent colors { @@ -1032,7 +1034,8 @@ Theme makeTheme(const QJsonObject &json) nt.scrollBackgroundColor = colorFromJson(o, "scrollBackgroundColor", nt.scrollBackgroundColor); nt.scrollHandleColor = colorFromJson(o, "scrollHandleColor", nt.scrollHandleColor); nt.selectedTextColor = colorFromJson(o, "selectedTextColor", nt.selectedTextColor); - nt.folderIndicatorColor = colorFromJson(o, "folderIndicatorColor", nt.folderIndicatorColor); + nt.folderNotCompletedColor = colorFromJson(o, "folderNotCompletedColor", nt.folderNotCompletedColor); + nt.newItemColor = colorFromJson(o, "newItemColor", nt.newItemColor); nt.branchIndicatorColor = colorFromJson(o, "branchIndicatorColor", nt.branchIndicatorColor); nt.branchIndicatorSelectedColor = colorFromJson(o, "branchIndicatorSelectedColor", nt.branchIndicatorSelectedColor); nt.folderIconColor = colorFromJson(o, "folderIconColor", nt.folderIconColor); diff --git a/YACReaderLibrary/yacreader_folders_view.cpp b/YACReaderLibrary/yacreader_folders_view.cpp index ce116bf69..27346279e 100644 --- a/YACReaderLibrary/yacreader_folders_view.cpp +++ b/YACReaderLibrary/yacreader_folders_view.cpp @@ -87,15 +87,18 @@ void YACReaderFoldersViewItemDeletegate::paint(QPainter *painter, const QStyleOp if (opt.state & QStyle::State_MouseOver) opt.state |= QStyle::State_Selected; - // Get indicator color from parent tree view - QColor indicatorColor(237, 197, 24); // Default fallback - if (auto treeView = qobject_cast(parent())) { - indicatorColor = treeView->folderIndicatorColor(); + // Get indicator colors from the theme via the owning view + QColor notCompletedColor(237, 197, 24); // Default fallback + QColor newItemDotColor(237, 197, 24); // Default fallback + if (auto foldersView = qobject_cast(parent())) { + const auto &nt = foldersView->navigationTreeTheme(); + notCompletedColor = nt.folderNotCompletedColor; + newItemDotColor = nt.newItemColor; } if (!index.data(FolderModel::CompletedRole).toBool()) { painter->save(); - painter->setBrush(QBrush(indicatorColor)); + painter->setBrush(QBrush(notCompletedColor)); painter->setPen(QPen(QBrush(), 0)); painter->drawRect(0, opt.rect.y(), 2, opt.rect.height()); painter->restore(); @@ -114,7 +117,7 @@ void YACReaderFoldersViewItemDeletegate::paint(QPainter *painter, const QStyleOp if (now - added < daysInSeconds || now - updated < daysInSeconds) { painter->save(); painter->setRenderHint(QPainter::Antialiasing); - painter->setBrush(QBrush(indicatorColor)); + painter->setBrush(QBrush(newItemDotColor)); painter->setPen(QPen(QBrush(), 0)); painter->drawEllipse(opt.rect.x() + 13, opt.rect.y() + 2, 7, 7); painter->restore(); diff --git a/YACReaderLibrary/yacreader_folders_view.h b/YACReaderLibrary/yacreader_folders_view.h index 55ea0db4d..efb8d3c79 100644 --- a/YACReaderLibrary/yacreader_folders_view.h +++ b/YACReaderLibrary/yacreader_folders_view.h @@ -2,6 +2,7 @@ #define YACREADER_FOLDERS_VIEW_H #include "yacreader_treeview.h" +#include "theme.h" #include @@ -10,6 +11,7 @@ class YACReaderFoldersView : public YACReaderTreeView Q_OBJECT public: explicit YACReaderFoldersView(QWidget *parent = nullptr); + const NavigationTreeTheme &navigationTreeTheme() const { return theme.navigationTree; } signals: // Drops diff --git a/custom_widgets/yacreader_treeview.h b/custom_widgets/yacreader_treeview.h index bf8e43f10..4a4d67306 100644 --- a/custom_widgets/yacreader_treeview.h +++ b/custom_widgets/yacreader_treeview.h @@ -10,7 +10,6 @@ class YACReaderTreeView : public QTreeView, protected Themable Q_OBJECT public: explicit YACReaderTreeView(QWidget *parent = 0); - QColor folderIndicatorColor() const { return theme.navigationTree.folderIndicatorColor; } private: void mousePressEvent(QMouseEvent *event) override; From 7103d0de3c9aa130bdcc218f771c338fd2f5a1cc Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 7 Mar 2026 19:58:24 +0100 Subject: [PATCH 140/187] Eliminate hardcoded colors from qml to make theming more flexible --- YACReaderLibrary/folder_content_view.cpp | 11 ++++ YACReaderLibrary/grid_comics_view.cpp | 13 +++++ YACReaderLibrary/info_comics_view.cpp | 6 +++ YACReaderLibrary/qml/ComicInfoView.qml | 9 +--- YACReaderLibrary/qml/FlowView.qml | 2 +- YACReaderLibrary/qml/FolderContentView.qml | 18 +++---- YACReaderLibrary/qml/GridComicsView.qml | 29 +++++----- YACReaderLibrary/qml/InfoComicsView.qml | 2 +- YACReaderLibrary/themes/builtin_classic.json | 17 +++++- YACReaderLibrary/themes/builtin_dark.json | 17 +++++- YACReaderLibrary/themes/builtin_light.json | 17 +++++- YACReaderLibrary/themes/theme.h | 27 ++++++++++ YACReaderLibrary/themes/theme_factory.cpp | 57 ++++++++++++++++++++ 13 files changed, 187 insertions(+), 38 deletions(-) diff --git a/YACReaderLibrary/folder_content_view.cpp b/YACReaderLibrary/folder_content_view.cpp index 28535922e..1fe6c384a 100644 --- a/YACReaderLibrary/folder_content_view.cpp +++ b/YACReaderLibrary/folder_content_view.cpp @@ -294,6 +294,17 @@ void FolderContentView::applyTheme(const Theme &theme) ctxt->setContextProperty("readTickUncheckedColor", giv.readTickUncheckedColor); ctxt->setContextProperty("readTickCheckedColor", giv.readTickCheckedColor); + // New item indicator, cover borders, placeholder pages, scrollbar + ctxt->setContextProperty("newItemColor", giv.newItemColor); + ctxt->setContextProperty("scrollbarColor", giv.scrollbarColor); + ctxt->setContextProperty("scrollbarBorderColor", giv.scrollbarBorderColor); + ctxt->setContextProperty("comicCoverBorderColor", giv.comicCoverBorderColor); + ctxt->setContextProperty("folderCoverBorderColor", giv.folderCoverBorderColor); + ctxt->setContextProperty("placeholderFolder1Color", giv.placeholderFolder1Color); + ctxt->setContextProperty("placeholderFolder1BorderColor", giv.placeholderFolder1BorderColor); + ctxt->setContextProperty("placeholderFolder2Color", giv.placeholderFolder2Color); + ctxt->setContextProperty("placeholderFolder2BorderColor", giv.placeholderFolder2BorderColor); + // Update zoom slider icons if (smallZoomLabel) { smallZoomLabel->setPixmap(theme.comicsViewToolbar.smallGridZoomIcon.pixmap(18, 18)); diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index 2542f85cb..83c65197b 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -517,6 +517,19 @@ void GridComicsView::applyTheme(const Theme &theme) // Current comic banner ctxt->setContextProperty("currentComicBackgroundColor", giv.currentComicBackgroundColor); + // New item indicator, button colors, links, scrollbars, cover borders, shadows + ctxt->setContextProperty("newItemColor", giv.newItemColor); + ctxt->setContextProperty("buttonColor", giv.buttonColor); + ctxt->setContextProperty("buttonTextColor", giv.buttonTextColor); + ctxt->setContextProperty("themeLinkColor", giv.linkColor); + ctxt->setContextProperty("themeLinkColorStr", giv.linkColor.name()); + ctxt->setContextProperty("scrollbarColor", giv.scrollbarColor); + ctxt->setContextProperty("scrollbarBorderColor", giv.scrollbarBorderColor); + ctxt->setContextProperty("infoScrollbarColor", giv.infoScrollbarColor); + ctxt->setContextProperty("comicCoverBorderColor", giv.comicCoverBorderColor); + ctxt->setContextProperty("currentComicCoverShadowColor", giv.currentComicCoverShadowColor); + ctxt->setContextProperty("buttonShadowColor", giv.buttonShadowColor); + // Update background config to apply theme cell colors updateBackgroundConfig(); diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp index 9aba46c9b..c79e3085d 100644 --- a/YACReaderLibrary/info_comics_view.cpp +++ b/YACReaderLibrary/info_comics_view.cpp @@ -252,4 +252,10 @@ void InfoComicsView::applyTheme(const Theme &theme) ctxt->setContextProperty("showDropShadow", QVariant(giv.showDropShadow)); ctxt->setContextProperty("backgroundBlurOverlayColor", giv.backgroundBlurOverlayColor); + + // Info panel scrollbar, comic cover border, links + ctxt->setContextProperty("infoScrollbarColor", giv.infoScrollbarColor); + ctxt->setContextProperty("comicCoverBorderColor", giv.comicCoverBorderColor); + ctxt->setContextProperty("themeLinkColor", giv.linkColor); + ctxt->setContextProperty("themeLinkColorStr", giv.linkColor.name()); } diff --git a/YACReaderLibrary/qml/ComicInfoView.qml b/YACReaderLibrary/qml/ComicInfoView.qml index 5fd4be1b1..a5f8c1665 100644 --- a/YACReaderLibrary/qml/ComicInfoView.qml +++ b/YACReaderLibrary/qml/ComicInfoView.qml @@ -260,7 +260,7 @@ Rectangle { Text { id: showInComicVine font: mainContainer.infoFont - color: "#ffcc00" + color: themeLinkColor text: "Show in Comic Vine" visible: comicInfo ? comicInfo.comicVineID ?? false : false MouseArea { @@ -284,12 +284,7 @@ Rectangle { font.pixelSize: 15 wrapMode: Text.WordWrap horizontalAlignment: Text.AlignJustify - text: '' + (comicInfo ? comicInfo.synopsis ?? "" : "") + '' + text: '' + (comicInfo ? comicInfo.synopsis ?? "" : "") + '' visible: comicInfo ? comicInfo.synopsis ?? false : false textFormat: Text.RichText } diff --git a/YACReaderLibrary/qml/FlowView.qml b/YACReaderLibrary/qml/FlowView.qml index 6ebc35a76..5038ba001 100644 --- a/YACReaderLibrary/qml/FlowView.qml +++ b/YACReaderLibrary/qml/FlowView.qml @@ -171,7 +171,7 @@ Rectangle { anchors.centerIn: coverElement color: "transparent" border { - color: "#30FFFFFF" + color: comicCoverBorderColor width: 1 } } diff --git a/YACReaderLibrary/qml/FolderContentView.qml b/YACReaderLibrary/qml/FolderContentView.qml index 015eeb141..6a2fcf33e 100644 --- a/YACReaderLibrary/qml/FolderContentView.qml +++ b/YACReaderLibrary/qml/FolderContentView.qml @@ -84,9 +84,9 @@ Rectangle { height: coverElement.height radius: 10 anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0} - color: "#20000000" + color: placeholderFolder1Color border { - color: "#20FFFFFF" + color: placeholderFolder1BorderColor width: 1 } } @@ -97,9 +97,9 @@ Rectangle { height: coverElement.height radius: 10 anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0} - color: "#88000000" + color: placeholderFolder2Color border { - color: "#20FFFFFF" + color: placeholderFolder2BorderColor width: 1 } } @@ -152,7 +152,7 @@ Rectangle { height: 10 radius: 5 anchors { left: coverElement.left; top: coverElement.top; topMargin: 10; leftMargin: 10; } - color: "#FFFFCC00" + color: newItemColor visible: (((new Date() / 1000) - added) < recent_range || ((new Date() / 1000) - updated) < recent_range) && show_recent } @@ -164,7 +164,7 @@ Rectangle { anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0} color: "transparent" border { - color: "#20FFFFFF" + color: folderCoverBorderColor width: 1 } } @@ -310,7 +310,7 @@ Rectangle { anchors.centerIn: coverElement color: "transparent" border { - color: "#30FFFFFF" + color: comicCoverBorderColor width: 1 } } @@ -433,13 +433,13 @@ Rectangle { implicitWidth: 12 implicitHeight: 26 Rectangle { - color: "#88424242" + color: scrollbarColor anchors.fill: parent anchors.topMargin: 6 anchors.leftMargin: 3 anchors.rightMargin: 2 anchors.bottomMargin: 6 - border.color: "#AA313131" + border.color: scrollbarBorderColor border.width: 1 radius: 3.5 } diff --git a/YACReaderLibrary/qml/GridComicsView.qml b/YACReaderLibrary/qml/GridComicsView.qml index 95ef165ac..69c987ba8 100644 --- a/YACReaderLibrary/qml/GridComicsView.qml +++ b/YACReaderLibrary/qml/GridComicsView.qml @@ -295,7 +295,7 @@ SplitView { height: 10 radius: 5 anchors { left: coverElement.left; top: coverElement.top; topMargin: 5; leftMargin: 5; } - color: "#FFFFCC00" + color: newItemColor visible: (((new Date() / 1000) - added_date) < recent_range) && show_recent } @@ -306,7 +306,7 @@ SplitView { anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0} color: "transparent" border { - color: "#20FFFFFF" + color: comicCoverBorderColor width: 1 } } @@ -481,7 +481,7 @@ SplitView { layer.enabled: showDropShadow layer.effect: MultiEffect { shadowEnabled: true - shadowColor: "#FF000000" + shadowColor: currentComicCoverShadowColor shadowBlur: 1.0 blurMax: 8 shadowHorizontalOffset: 0 @@ -608,7 +608,7 @@ SplitView { Text { id: currentComicInfoShowInComicVine font: currentComicDetailsFlowView.infoFont - color: "#ffcc00" + color: themeLinkColor text: "Show in Comic Vine" visible: currentComicInfo.comicVineID ? true : false MouseArea { @@ -648,12 +648,7 @@ SplitView { font.pixelSize: 14 wrapMode: Text.WordWrap - text: '' + currentComicInfo.synopsis ?? "" + '' + text: '' + (currentComicInfo.synopsis ?? "") + '' visible: currentComicInfo.synopsis ?? false textFormat: Text.RichText } @@ -673,9 +668,9 @@ SplitView { implicitWidth: 100 implicitHeight: 30 border.width: readButton.activeFocus ? 2 : 1 - border.color: "#FFCC00" + border.color: buttonColor radius: height / 2 - color: "#FFCC00" + color: buttonColor } contentItem: Text { @@ -685,14 +680,14 @@ SplitView { font.family: "Arial" font.pointSize: 12 font.bold: true - color: "white" + color: buttonTextColor text: readButton.text } layer.enabled: showDropShadow && !readButton.pressed layer.effect: MultiEffect { shadowEnabled: true - shadowColor: "#AA000000" + shadowColor: buttonShadowColor shadowBlur: 1.0 blurMax: 8 shadowHorizontalOffset: 0 @@ -782,13 +777,13 @@ SplitView { implicitWidth: 12 implicitHeight: 26 Rectangle { - color: "#88424242" + color: scrollbarColor anchors.fill: parent anchors.topMargin: 6 anchors.leftMargin: 3 anchors.rightMargin: 2 anchors.bottomMargin: 6 - border.color: "#AA313131" + border.color: scrollbarBorderColor border.width: 1 radius: 3.5 } @@ -911,7 +906,7 @@ SplitView { implicitWidth: 12 implicitHeight: 26 Rectangle { - color: "#424246" + color: infoScrollbarColor anchors.fill: parent anchors.topMargin: 6 anchors.leftMargin: 5 diff --git a/YACReaderLibrary/qml/InfoComicsView.qml b/YACReaderLibrary/qml/InfoComicsView.qml index e4adaf4bf..85c5cc5b8 100644 --- a/YACReaderLibrary/qml/InfoComicsView.qml +++ b/YACReaderLibrary/qml/InfoComicsView.qml @@ -94,7 +94,7 @@ Rectangle { implicitWidth: 12 implicitHeight: 26 Rectangle { - color: "#424246" + color: infoScrollbarColor anchors.fill: parent anchors.topMargin: 6 anchors.leftMargin: 5 diff --git a/YACReaderLibrary/themes/builtin_classic.json b/YACReaderLibrary/themes/builtin_classic.json index de2ddd1b4..ebc562266 100644 --- a/YACReaderLibrary/themes/builtin_classic.json +++ b/YACReaderLibrary/themes/builtin_classic.json @@ -65,7 +65,22 @@ "selectedColor": "#121212", "showDropShadow": true, "textColor": "#a8a8a8", - "titleColor": "#ffffff" + "titleColor": "#ffffff", + "newItemColor": "#ffffcc00", + "buttonColor": "#ffcc00", + "buttonTextColor": "#ffffff", + "linkColor": "#ffcc00", + "scrollbarColor": "#88424242", + "scrollbarBorderColor": "#aa313131", + "infoScrollbarColor": "#ff424246", + "comicCoverBorderColor": "#30ffffff", + "folderCoverBorderColor": "#20ffffff", + "placeholderFolder1Color": "#20000000", + "placeholderFolder1BorderColor": "#20ffffff", + "placeholderFolder2Color": "#88000000", + "placeholderFolder2BorderColor": "#20ffffff", + "currentComicCoverShadowColor": "#ff000000", + "buttonShadowColor": "#aa000000" }, "helpAboutDialog": { "headingColor": "#302f2d", diff --git a/YACReaderLibrary/themes/builtin_dark.json b/YACReaderLibrary/themes/builtin_dark.json index 203fc57f0..e77659106 100644 --- a/YACReaderLibrary/themes/builtin_dark.json +++ b/YACReaderLibrary/themes/builtin_dark.json @@ -65,7 +65,22 @@ "selectedColor": "#121212", "showDropShadow": true, "textColor": "#a8a8a8", - "titleColor": "#ffffff" + "titleColor": "#ffffff", + "newItemColor": "#ffffcc00", + "buttonColor": "#ffcc00", + "buttonTextColor": "#ffffff", + "linkColor": "#ffcc00", + "scrollbarColor": "#88424242", + "scrollbarBorderColor": "#aa313131", + "infoScrollbarColor": "#ff424246", + "comicCoverBorderColor": "#30ffffff", + "folderCoverBorderColor": "#20ffffff", + "placeholderFolder1Color": "#20000000", + "placeholderFolder1BorderColor": "#20ffffff", + "placeholderFolder2Color": "#88000000", + "placeholderFolder2BorderColor": "#20ffffff", + "currentComicCoverShadowColor": "#ff000000", + "buttonShadowColor": "#aa000000" }, "helpAboutDialog": { "headingColor": "#e0e0e0", diff --git a/YACReaderLibrary/themes/builtin_light.json b/YACReaderLibrary/themes/builtin_light.json index 779c1f0e2..b1da08ac0 100644 --- a/YACReaderLibrary/themes/builtin_light.json +++ b/YACReaderLibrary/themes/builtin_light.json @@ -65,7 +65,22 @@ "selectedColor": "#ffffff", "showDropShadow": true, "textColor": "#636363", - "titleColor": "#121212" + "titleColor": "#121212", + "newItemColor": "#ffffcc00", + "buttonColor": "#ffcc00", + "buttonTextColor": "#ffffff", + "linkColor": "#ffcc00", + "scrollbarColor": "#88424242", + "scrollbarBorderColor": "#aa313131", + "infoScrollbarColor": "#ff424246", + "comicCoverBorderColor": "#30ffffff", + "folderCoverBorderColor": "#20ffffff", + "placeholderFolder1Color": "#20000000", + "placeholderFolder1BorderColor": "#20ffffff", + "placeholderFolder2Color": "#88000000", + "placeholderFolder2BorderColor": "#20ffffff", + "currentComicCoverShadowColor": "#ff000000", + "buttonShadowColor": "#aa000000" }, "helpAboutDialog": { "headingColor": "#302f2d", diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index ee173a421..f44e4b578 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -247,6 +247,33 @@ struct GridAndInfoViewTheme { // Blur overlay background (FlowView always, GridView when background image enabled) QColor backgroundBlurOverlayColor; + + // New item indicator dot (cover grid and folder grid) + QColor newItemColor; + + // Button colors + QColor buttonColor; + QColor buttonTextColor; + QColor linkColor; + + // Scrollbar colors — content grid (on backgroundColor) + QColor scrollbarColor; + QColor scrollbarBorderColor; + + // Scrollbar color — info panel (on infoBackgroundColor) + QColor infoScrollbarColor; + + // Cover overlay / border effects + QColor comicCoverBorderColor; + QColor folderCoverBorderColor; + QColor placeholderFolder1Color; + QColor placeholderFolder1BorderColor; + QColor placeholderFolder2Color; + QColor placeholderFolder2BorderColor; + + // Drop shadow effects + QColor currentComicCoverShadowColor; + QColor buttonShadowColor; }; struct MainToolbarThemeTemplates { diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 4d5b6c1e4..cef847da6 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -174,6 +174,33 @@ struct GridAndInfoViewParams { // Blur overlay background (FlowView always, GridView when background image enabled) QColor backgroundBlurOverlayColor; + + // New item indicator dot + QColor newItemColor; + + // Button colors + QColor buttonColor; + QColor buttonTextColor; + QColor linkColor; + + // Scrollbar colors — content grid + QColor scrollbarColor; + QColor scrollbarBorderColor; + + // Scrollbar color — info panel + QColor infoScrollbarColor; + + // Cover overlay / border effects + QColor comicCoverBorderColor; + QColor folderCoverBorderColor; + QColor placeholderFolder1Color; + QColor placeholderFolder1BorderColor; + QColor placeholderFolder2Color; + QColor placeholderFolder2BorderColor; + + // Drop shadow effects + QColor currentComicCoverShadowColor; + QColor buttonShadowColor; }; struct MainToolbarParams { @@ -515,6 +542,21 @@ Theme makeTheme(const ThemeParams ¶ms) theme.gridAndInfoView.continueReadingBackgroundColor = giv.continueReadingBackgroundColor; theme.gridAndInfoView.continueReadingColor = giv.continueReadingColor; theme.gridAndInfoView.backgroundBlurOverlayColor = giv.backgroundBlurOverlayColor; + theme.gridAndInfoView.newItemColor = giv.newItemColor; + theme.gridAndInfoView.buttonColor = giv.buttonColor; + theme.gridAndInfoView.buttonTextColor = giv.buttonTextColor; + theme.gridAndInfoView.linkColor = giv.linkColor; + theme.gridAndInfoView.scrollbarColor = giv.scrollbarColor; + theme.gridAndInfoView.scrollbarBorderColor = giv.scrollbarBorderColor; + theme.gridAndInfoView.infoScrollbarColor = giv.infoScrollbarColor; + theme.gridAndInfoView.comicCoverBorderColor = giv.comicCoverBorderColor; + theme.gridAndInfoView.folderCoverBorderColor = giv.folderCoverBorderColor; + theme.gridAndInfoView.placeholderFolder1Color = giv.placeholderFolder1Color; + theme.gridAndInfoView.placeholderFolder1BorderColor = giv.placeholderFolder1BorderColor; + theme.gridAndInfoView.placeholderFolder2Color = giv.placeholderFolder2Color; + theme.gridAndInfoView.placeholderFolder2BorderColor = giv.placeholderFolder2BorderColor; + theme.gridAndInfoView.currentComicCoverShadowColor = giv.currentComicCoverShadowColor; + theme.gridAndInfoView.buttonShadowColor = giv.buttonShadowColor; // end GridAndInfoView // MainToolbar @@ -1094,6 +1136,21 @@ Theme makeTheme(const QJsonObject &json) giv.continueReadingBackgroundColor = colorFromJson(o, "continueReadingBackgroundColor", giv.continueReadingBackgroundColor); giv.continueReadingColor = colorFromJson(o, "continueReadingColor", giv.continueReadingColor); giv.backgroundBlurOverlayColor = colorFromJson(o, "backgroundBlurOverlayColor", giv.backgroundBlurOverlayColor); + giv.newItemColor = colorFromJson(o, "newItemColor", giv.newItemColor); + giv.buttonColor = colorFromJson(o, "buttonColor", giv.buttonColor); + giv.buttonTextColor = colorFromJson(o, "buttonTextColor", giv.buttonTextColor); + giv.linkColor = colorFromJson(o, "linkColor", giv.linkColor); + giv.scrollbarColor = colorFromJson(o, "scrollbarColor", giv.scrollbarColor); + giv.scrollbarBorderColor = colorFromJson(o, "scrollbarBorderColor", giv.scrollbarBorderColor); + giv.infoScrollbarColor = colorFromJson(o, "infoScrollbarColor", giv.infoScrollbarColor); + giv.comicCoverBorderColor = colorFromJson(o, "comicCoverBorderColor", giv.comicCoverBorderColor); + giv.folderCoverBorderColor = colorFromJson(o, "folderCoverBorderColor", giv.folderCoverBorderColor); + giv.placeholderFolder1Color = colorFromJson(o, "placeholderFolder1Color", giv.placeholderFolder1Color); + giv.placeholderFolder1BorderColor = colorFromJson(o, "placeholderFolder1BorderColor", giv.placeholderFolder1BorderColor); + giv.placeholderFolder2Color = colorFromJson(o, "placeholderFolder2Color", giv.placeholderFolder2Color); + giv.placeholderFolder2BorderColor = colorFromJson(o, "placeholderFolder2BorderColor", giv.placeholderFolder2BorderColor); + giv.currentComicCoverShadowColor = colorFromJson(o, "currentComicCoverShadowColor", giv.currentComicCoverShadowColor); + giv.buttonShadowColor = colorFromJson(o, "buttonShadowColor", giv.buttonShadowColor); } if (json.contains("comicsViewToolbar")) { From 27b59ad8a95e65b4b1326021d488288333d99203 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 7 Mar 2026 22:21:18 +0100 Subject: [PATCH 141/187] Better naming in some of the theme properties used in qml --- YACReaderLibrary/folder_content_view.cpp | 12 ++-- YACReaderLibrary/grid_comics_view.cpp | 12 ++-- YACReaderLibrary/info_comics_view.cpp | 2 +- YACReaderLibrary/qml/ComicInfoView.qml | 70 ++++++++++---------- YACReaderLibrary/qml/FolderContentView.qml | 6 +- YACReaderLibrary/qml/GridComicsView.qml | 24 +++---- YACReaderLibrary/themes/builtin_classic.json | 46 ++++++------- YACReaderLibrary/themes/builtin_dark.json | 46 ++++++------- YACReaderLibrary/themes/builtin_light.json | 46 ++++++------- YACReaderLibrary/themes/theme.h | 12 ++-- YACReaderLibrary/themes/theme_factory.cpp | 36 +++++----- 11 files changed, 156 insertions(+), 156 deletions(-) diff --git a/YACReaderLibrary/folder_content_view.cpp b/YACReaderLibrary/folder_content_view.cpp index 1fe6c384a..77106bc7a 100644 --- a/YACReaderLibrary/folder_content_view.cpp +++ b/YACReaderLibrary/folder_content_view.cpp @@ -269,22 +269,22 @@ void FolderContentView::applyTheme(const Theme &theme) // Continue reading section colors ctxt->setContextProperty("continueReadingBackgroundColor", giv.continueReadingBackgroundColor); - ctxt->setContextProperty("continueReadingColor", giv.continueReadingColor); + ctxt->setContextProperty("continueReadingTextColor", giv.continueReadingTextColor); // Grid colors ctxt->setContextProperty("backgroundColor", giv.backgroundColor); ctxt->setContextProperty("cellColor", giv.cellColor); - ctxt->setContextProperty("selectedColor", giv.selectedColor); - ctxt->setContextProperty("selectedBorderColor", giv.selectedBorderColor); + ctxt->setContextProperty("cellSelectedColor", giv.cellSelectedColor); + ctxt->setContextProperty("cellSelectedBorderColor", giv.cellSelectedBorderColor); ctxt->setContextProperty("borderColor", giv.borderColor); - ctxt->setContextProperty("titleColor", giv.titleColor); - ctxt->setContextProperty("textColor", giv.textColor); + ctxt->setContextProperty("itemTitleColor", giv.itemTitleColor); + ctxt->setContextProperty("itemDetailsColor", giv.itemDetailsColor); ctxt->setContextProperty("dropShadow", QVariant(giv.showDropShadow)); // Info panel colors ctxt->setContextProperty("infoBackgroundColor", giv.infoBackgroundColor); + ctxt->setContextProperty("infoMetadataTextColor", giv.infoMetadataTextColor); ctxt->setContextProperty("infoTextColor", giv.infoTextColor); - ctxt->setContextProperty("infoTitleColor", giv.infoTitleColor); // Rating and favorite colors ctxt->setContextProperty("ratingUnselectedColor", giv.ratingUnselectedColor); diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index 83c65197b..c93ffcd26 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -222,7 +222,7 @@ void GridComicsView::updateBackgroundConfig() const auto &giv = theme.gridAndInfoView; ctxt->setContextProperty("backgroundColor", useBackgroundImage ? giv.backgroundBlurOverlayColor : giv.backgroundColor); ctxt->setContextProperty("cellColor", useBackgroundImage ? giv.cellColorWithBackground : giv.cellColor); - ctxt->setContextProperty("selectedColor", giv.selectedColor); + ctxt->setContextProperty("cellSelectedColor", giv.cellSelectedColor); } void GridComicsView::showInfo() @@ -494,17 +494,17 @@ void GridComicsView::applyTheme(const Theme &theme) ctxt->setContextProperty("backgroundColor", giv.backgroundColor); ctxt->setContextProperty("backgroundBlurOverlayColor", giv.backgroundBlurOverlayColor); ctxt->setContextProperty("cellColor", giv.cellColor); - ctxt->setContextProperty("selectedColor", giv.selectedColor); - ctxt->setContextProperty("selectedBorderColor", giv.selectedBorderColor); + ctxt->setContextProperty("cellSelectedColor", giv.cellSelectedColor); + ctxt->setContextProperty("cellSelectedBorderColor", giv.cellSelectedBorderColor); ctxt->setContextProperty("borderColor", giv.borderColor); - ctxt->setContextProperty("titleColor", giv.titleColor); - ctxt->setContextProperty("textColor", giv.textColor); + ctxt->setContextProperty("itemTitleColor", giv.itemTitleColor); + ctxt->setContextProperty("itemDetailsColor", giv.itemDetailsColor); ctxt->setContextProperty("showDropShadow", QVariant(giv.showDropShadow)); // Info panel colors ctxt->setContextProperty("infoBackgroundColor", giv.infoBackgroundColor); + ctxt->setContextProperty("infoMetadataTextColor", giv.infoMetadataTextColor); ctxt->setContextProperty("infoTextColor", giv.infoTextColor); - ctxt->setContextProperty("infoTitleColor", giv.infoTitleColor); // Rating and favorite colors ctxt->setContextProperty("ratingUnselectedColor", giv.ratingUnselectedColor); diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp index c79e3085d..5e506d5cc 100644 --- a/YACReaderLibrary/info_comics_view.cpp +++ b/YACReaderLibrary/info_comics_view.cpp @@ -239,8 +239,8 @@ void InfoComicsView::applyTheme(const Theme &theme) ctxt->setContextProperty("topShadow", svgUrl(giv.topShadow)); ctxt->setContextProperty("infoShadow", svgUrl(giv.infoShadow)); ctxt->setContextProperty("infoIndicator", svgUrl(giv.infoIndicator)); + ctxt->setContextProperty("infoMetadataTextColor", giv.infoMetadataTextColor); ctxt->setContextProperty("infoTextColor", giv.infoTextColor); - ctxt->setContextProperty("infoTitleColor", giv.infoTitleColor); // Rating and favorite colors ctxt->setContextProperty("ratingUnselectedColor", giv.ratingUnselectedColor); diff --git a/YACReaderLibrary/qml/ComicInfoView.qml b/YACReaderLibrary/qml/ComicInfoView.qml index a5f8c1665..c65e9fe04 100644 --- a/YACReaderLibrary/qml/ComicInfoView.qml +++ b/YACReaderLibrary/qml/ComicInfoView.qml @@ -13,7 +13,7 @@ Rectangle { height: info.height + 2 * topMargin - property string infoColor: infoTextColor + property string infoColor: infoMetadataTextColor property font infoFont: Qt.font({ family: "Arial", @@ -135,7 +135,7 @@ Rectangle { id: title - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.bold: true font.pixelSize: mainContainer.compact ? 18 : 21; @@ -279,7 +279,7 @@ Rectangle { Layout.fillWidth: true id: sinopsis - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 wrapMode: Text.WordWrap @@ -294,7 +294,7 @@ Rectangle { Layout.bottomMargin: 5 id: characters_title - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 18 font.bold: true @@ -312,7 +312,7 @@ Rectangle { model: comicInfo ? comicInfo.getCharacters().length : null Text { - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -326,7 +326,7 @@ Rectangle { Layout.bottomMargin: 5 id: main_character_or_team_title - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 18 font.bold: true @@ -337,7 +337,7 @@ Rectangle { } Text { - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -351,7 +351,7 @@ Rectangle { Layout.bottomMargin: 5 id: teams_title - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 18 font.bold: true @@ -371,7 +371,7 @@ Rectangle { model: comicInfo ? comicInfo.getTeams().length : null Text { - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -385,7 +385,7 @@ Rectangle { Layout.bottomMargin: 5 id: locations_title - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 18 font.bold: true @@ -403,7 +403,7 @@ Rectangle { model: comicInfo ? comicInfo.getLocations().length : null Text { - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -417,7 +417,7 @@ Rectangle { Layout.bottomMargin: 5 id: authors_title - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 18 font.bold: true @@ -442,7 +442,7 @@ Rectangle { model: comicInfo ? comicInfo.getWriters().length : null Column{ Text { - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -450,7 +450,7 @@ Rectangle { } Text { - color: infoTextColor + color: infoMetadataTextColor font.family: "Arial" font.pixelSize: 13 font.italic: true @@ -464,7 +464,7 @@ Rectangle { model: comicInfo ? comicInfo.getPencillers().length : null Column{ Text { - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -472,7 +472,7 @@ Rectangle { } Text { - color: infoTextColor + color: infoMetadataTextColor font.family: "Arial" font.pixelSize: 13 font.italic: true @@ -486,7 +486,7 @@ Rectangle { model: comicInfo ? comicInfo.getInkers().length : null Column{ Text { - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -494,7 +494,7 @@ Rectangle { } Text { - color: infoTextColor + color: infoMetadataTextColor font.family: "Arial" font.pixelSize: 13 font.italic: true @@ -508,7 +508,7 @@ Rectangle { model: comicInfo ? comicInfo.getColorists().length : null Column{ Text { - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -516,7 +516,7 @@ Rectangle { } Text { - color: infoTextColor + color: infoMetadataTextColor font.family: "Arial" font.pixelSize: 13 font.italic: true @@ -530,7 +530,7 @@ Rectangle { model: comicInfo ? comicInfo.getLetterers().length : null Column{ Text { - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -538,7 +538,7 @@ Rectangle { } Text { - color: infoTextColor + color: infoMetadataTextColor font.family: "Arial" font.pixelSize: 13 font.italic: true @@ -552,7 +552,7 @@ Rectangle { model: comicInfo ? comicInfo.getCoverArtists().length : null Column{ Text { - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -560,7 +560,7 @@ Rectangle { } Text { - color: infoTextColor + color: infoMetadataTextColor font.family: "Arial" font.pixelSize: 13 font.italic: true @@ -574,7 +574,7 @@ Rectangle { model: comicInfo ? comicInfo.getEditors().length : null Column{ Text { - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -582,7 +582,7 @@ Rectangle { } Text { - color: infoTextColor + color: infoMetadataTextColor font.family: "Arial" font.pixelSize: 13 font.italic: true @@ -596,7 +596,7 @@ Rectangle { model: comicInfo ? comicInfo.getImprint().length : null Column{ Text { - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -604,7 +604,7 @@ Rectangle { } Text { - color: infoTextColor + color: infoMetadataTextColor font.family: "Arial" font.pixelSize: 13 font.italic: true @@ -618,7 +618,7 @@ Rectangle { Layout.topMargin: 25 id: publisher_title - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 18 font.bold: true @@ -635,7 +635,7 @@ Rectangle { Text { id: publisher - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -647,7 +647,7 @@ Rectangle { Text { id: format - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -659,7 +659,7 @@ Rectangle { Text { id: type - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -671,7 +671,7 @@ Rectangle { Text { id: color - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -683,7 +683,7 @@ Rectangle { Text { id: language - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 @@ -695,7 +695,7 @@ Rectangle { Text { id: age_rating - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 15 diff --git a/YACReaderLibrary/qml/FolderContentView.qml b/YACReaderLibrary/qml/FolderContentView.qml index 6a2fcf33e..98b705227 100644 --- a/YACReaderLibrary/qml/FolderContentView.qml +++ b/YACReaderLibrary/qml/FolderContentView.qml @@ -178,7 +178,7 @@ Rectangle { wrapMode: Text.WordWrap text: name elide: Text.ElideRight - color: titleColor + color: itemTitleColor font.letterSpacing: fontSpacing font.pointSize: fontSize font.family: fontFamily @@ -221,7 +221,7 @@ Rectangle { Text { id: continueReadingText text: qsTr("Continue Reading...") - color: continueReadingColor + color: continueReadingTextColor anchors.left: parent.left anchors.top: parent.top anchors.topMargin: 15 @@ -297,7 +297,7 @@ Rectangle { wrapMode: Text.WordWrap text: readable_title elide: Text.ElideRight - color: titleColor + color: itemTitleColor font.letterSpacing: fontSpacing font.pointSize: fontSize font.family: fontFamily diff --git a/YACReaderLibrary/qml/GridComicsView.qml b/YACReaderLibrary/qml/GridComicsView.qml index 69c987ba8..1aa16186e 100644 --- a/YACReaderLibrary/qml/GridComicsView.qml +++ b/YACReaderLibrary/qml/GridComicsView.qml @@ -108,8 +108,8 @@ SplitView { width: itemWidth height: itemHeight - color: ((dummyValue || !dummyValue) && comicsSelectionHelper.isSelectedIndex(index))?selectedColor:cellColor; - //border.color: ((dummyValue || !dummyValue) && comicsSelectionHelper.isSelectedIndex(index))?selectedBorderColor:borderColor; + color: ((dummyValue || !dummyValue) && comicsSelectionHelper.isSelectedIndex(index))?cellSelectedColor:cellColor; + //border.color: ((dummyValue || !dummyValue) && comicsSelectionHelper.isSelectedIndex(index))?cellSelectedBorderColor:borderColor; //border.width: ?1:0; anchors.horizontalCenter: parent.horizontalCenter @@ -143,7 +143,7 @@ SplitView { rightMargin : commonBorder ? -commonBorderWidth : -rBorderwidth } - border.color: selectedBorderColor + border.color: cellSelectedBorderColor border.width: 3 opacity: (dummyValue || !dummyValue) && comicsSelectionHelper.isSelectedIndex(index) ? 1 : 0 @@ -330,7 +330,7 @@ SplitView { wrapMode: Text.WordWrap text: title elide: Text.ElideRight - color: titleColor + color: itemTitleColor clip: true font.letterSpacing: fontSpacing font.pointSize: fontSize @@ -341,7 +341,7 @@ SplitView { Text { anchors {bottom: realCell.bottom; left: realCell.left; margins: 4} text: number?"#"+number:"" - color: textColor + color: itemDetailsColor font.letterSpacing: fontSpacing font.pointSize: fontSize font.family: fontFamily @@ -352,7 +352,7 @@ SplitView { id: pageImage anchors {bottom: realCell.bottom; right: realCell.right; bottomMargin: 6; rightMargin: 4; leftMargin: 4} source: "page.svg" - color: textColor + color: itemDetailsColor width: 8 height: 10 } @@ -362,7 +362,7 @@ SplitView { id: pages anchors {bottom: realCell.bottom; right: pageImage.left; margins: 4} text: has_been_opened?current_page+"/"+num_pages:num_pages - color: textColor + color: itemDetailsColor font.letterSpacing: fontSpacing font.pointSize: fontSize font.family: fontFamily @@ -373,7 +373,7 @@ SplitView { id: ratingImage anchors {bottom: realCell.bottom; right: pageImage.left; bottomMargin: 6.5; rightMargin: Math.floor(pages.width)+12} source: "star.svg" - color: textColor + color: itemDetailsColor width: 11 height: 11 @@ -423,7 +423,7 @@ SplitView { id: comicRating anchors {bottom: realCell.bottom; right: ratingImage.left; margins: 4} text: rating>0?rating:"-" - color: textColor + color: itemDetailsColor } } } @@ -511,7 +511,7 @@ SplitView { id: currentComicInfoTitleView - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.bold: true font.pixelSize: 21 @@ -531,7 +531,7 @@ SplitView { family: "Arial", pixelSize: 14 }); - property string infoFlowTextColor: infoTextColor + property string infoFlowTextColor: infoMetadataTextColor Text { id: currentComicInfoVolume @@ -643,7 +643,7 @@ SplitView { width: synopsisScroller.width id: currentComicInfoSinopsis - color: infoTitleColor + color: infoTextColor font.family: "Arial" font.pixelSize: 14 wrapMode: Text.WordWrap diff --git a/YACReaderLibrary/themes/builtin_classic.json b/YACReaderLibrary/themes/builtin_classic.json index ebc562266..e3dc64ac5 100644 --- a/YACReaderLibrary/themes/builtin_classic.json +++ b/YACReaderLibrary/themes/builtin_classic.json @@ -45,42 +45,42 @@ "backgroundBlurOverlayColor": "#2a2a2a", "backgroundColor": "#2a2a2a", "borderColor": "#121212", + "buttonColor": "#ffcc00", + "buttonShadowColor": "#aa000000", + "buttonTextColor": "#ffffff", "cellColor": "#212121", "cellColorWithBackground": "#99212121", + "cellSelectedBorderColor": "#ffcc00", + "cellSelectedColor": "#121212", + "comicCoverBorderColor": "#30ffffff", "continueReadingBackgroundColor": "#88000000", - "continueReadingColor": "#ffffff", + "continueReadingTextColor": "#ffffff", "currentComicBackgroundColor": "#88000000", + "currentComicCoverShadowColor": "#ff000000", "favCheckedColor": "#e84852", "favUncheckedColor": "#1c1c1c", + "folderCoverBorderColor": "#20ffffff", "infoBackgroundColor": "#2e2e2e", "infoBorderColor": "#404040", + "infoMetadataTextColor": "#b0b0b0", + "infoScrollbarColor": "#ff424246", "infoShadowColor": "#000000", - "infoTextColor": "#b0b0b0", - "infoTitleColor": "#ffffff", + "infoTextColor": "#ffffff", + "itemDetailsColor": "#a8a8a8", + "itemTitleColor": "#ffffff", + "linkColor": "#ffcc00", + "newItemColor": "#ffffcc00", + "placeholderFolder1BorderColor": "#20ffffff", + "placeholderFolder1Color": "#20000000", + "placeholderFolder2BorderColor": "#20ffffff", + "placeholderFolder2Color": "#88000000", "ratingSelectedColor": "#ffffff", "ratingUnselectedColor": "#1c1c1c", "readTickCheckedColor": "#e84852", "readTickUncheckedColor": "#1c1c1c", - "selectedBorderColor": "#ffcc00", - "selectedColor": "#121212", - "showDropShadow": true, - "textColor": "#a8a8a8", - "titleColor": "#ffffff", - "newItemColor": "#ffffcc00", - "buttonColor": "#ffcc00", - "buttonTextColor": "#ffffff", - "linkColor": "#ffcc00", - "scrollbarColor": "#88424242", "scrollbarBorderColor": "#aa313131", - "infoScrollbarColor": "#ff424246", - "comicCoverBorderColor": "#30ffffff", - "folderCoverBorderColor": "#20ffffff", - "placeholderFolder1Color": "#20000000", - "placeholderFolder1BorderColor": "#20ffffff", - "placeholderFolder2Color": "#88000000", - "placeholderFolder2BorderColor": "#20ffffff", - "currentComicCoverShadowColor": "#ff000000", - "buttonShadowColor": "#aa000000" + "scrollbarColor": "#88424242", + "showDropShadow": true }, "helpAboutDialog": { "headingColor": "#302f2d", @@ -166,10 +166,10 @@ "folderIconSelectedColor": "#e0e0e0", "folderIconSelectedShadowColor": "#000000", "folderIconShadowColor": "#000000", - "newItemColor": "#edc518", "folderNotCompletedColor": "#edc518", "folderReadOverlayColor": "#464646", "folderReadOverlaySelectedColor": "#464646", + "newItemColor": "#edc518", "scrollBackgroundColor": "#404040", "scrollHandleColor": "#dddddd", "selectedTextColor": "#ffffff", diff --git a/YACReaderLibrary/themes/builtin_dark.json b/YACReaderLibrary/themes/builtin_dark.json index e77659106..b625814d9 100644 --- a/YACReaderLibrary/themes/builtin_dark.json +++ b/YACReaderLibrary/themes/builtin_dark.json @@ -45,42 +45,42 @@ "backgroundBlurOverlayColor": "#2a2a2a", "backgroundColor": "#2a2a2a", "borderColor": "#121212", + "buttonColor": "#ffcc00", + "buttonShadowColor": "#aa000000", + "buttonTextColor": "#ffffff", "cellColor": "#212121", "cellColorWithBackground": "#99212121", + "cellSelectedBorderColor": "#ffcc00", + "cellSelectedColor": "#121212", + "comicCoverBorderColor": "#30ffffff", "continueReadingBackgroundColor": "#88000000", - "continueReadingColor": "#ffffff", + "continueReadingTextColor": "#ffffff", "currentComicBackgroundColor": "#55000000", + "currentComicCoverShadowColor": "#ff000000", "favCheckedColor": "#e84852", "favUncheckedColor": "#1c1c1c", + "folderCoverBorderColor": "#20ffffff", "infoBackgroundColor": "#2e2e2e", "infoBorderColor": "#404040", + "infoMetadataTextColor": "#b0b0b0", + "infoScrollbarColor": "#ff424246", "infoShadowColor": "#000000", - "infoTextColor": "#b0b0b0", - "infoTitleColor": "#ffffff", + "infoTextColor": "#ffffff", + "itemDetailsColor": "#a8a8a8", + "itemTitleColor": "#ffffff", + "linkColor": "#ffcc00", + "newItemColor": "#ffffcc00", + "placeholderFolder1BorderColor": "#20ffffff", + "placeholderFolder1Color": "#20000000", + "placeholderFolder2BorderColor": "#20ffffff", + "placeholderFolder2Color": "#88000000", "ratingSelectedColor": "#ffffff", "ratingUnselectedColor": "#1c1c1c", "readTickCheckedColor": "#e84852", "readTickUncheckedColor": "#1c1c1c", - "selectedBorderColor": "#ffcc00", - "selectedColor": "#121212", - "showDropShadow": true, - "textColor": "#a8a8a8", - "titleColor": "#ffffff", - "newItemColor": "#ffffcc00", - "buttonColor": "#ffcc00", - "buttonTextColor": "#ffffff", - "linkColor": "#ffcc00", - "scrollbarColor": "#88424242", "scrollbarBorderColor": "#aa313131", - "infoScrollbarColor": "#ff424246", - "comicCoverBorderColor": "#30ffffff", - "folderCoverBorderColor": "#20ffffff", - "placeholderFolder1Color": "#20000000", - "placeholderFolder1BorderColor": "#20ffffff", - "placeholderFolder2Color": "#88000000", - "placeholderFolder2BorderColor": "#20ffffff", - "currentComicCoverShadowColor": "#ff000000", - "buttonShadowColor": "#aa000000" + "scrollbarColor": "#88424242", + "showDropShadow": true }, "helpAboutDialog": { "headingColor": "#e0e0e0", @@ -166,10 +166,10 @@ "folderIconSelectedColor": "#e0e0e0", "folderIconSelectedShadowColor": "#000000", "folderIconShadowColor": "#000000", - "newItemColor": "#edc518", "folderNotCompletedColor": "#edc518", "folderReadOverlayColor": "#222222", "folderReadOverlaySelectedColor": "#222222", + "newItemColor": "#edc518", "scrollBackgroundColor": "#404040", "scrollHandleColor": "#dddddd", "selectedTextColor": "#ffffff", diff --git a/YACReaderLibrary/themes/builtin_light.json b/YACReaderLibrary/themes/builtin_light.json index b1da08ac0..cf6916ea8 100644 --- a/YACReaderLibrary/themes/builtin_light.json +++ b/YACReaderLibrary/themes/builtin_light.json @@ -45,42 +45,42 @@ "backgroundBlurOverlayColor": "#9e9e9e", "backgroundColor": "#f6f6f6", "borderColor": "#dbdbdb", + "buttonColor": "#ffcc00", + "buttonShadowColor": "#aa000000", + "buttonTextColor": "#ffffff", "cellColor": "#ffffff", "cellColorWithBackground": "#99ffffff", + "cellSelectedBorderColor": "#ffcc00", + "cellSelectedColor": "#ffffff", + "comicCoverBorderColor": "#30ffffff", "continueReadingBackgroundColor": "#e8e8e8", - "continueReadingColor": "#000000", + "continueReadingTextColor": "#000000", "currentComicBackgroundColor": "#88ffffff", + "currentComicCoverShadowColor": "#ff000000", "favCheckedColor": "#e84852", "favUncheckedColor": "#dedede", + "folderCoverBorderColor": "#20ffffff", "infoBackgroundColor": "#ffffff", "infoBorderColor": "#808080", + "infoMetadataTextColor": "#404040", + "infoScrollbarColor": "#ff424246", "infoShadowColor": "#444444", - "infoTextColor": "#404040", - "infoTitleColor": "#2e2e2e", + "infoTextColor": "#2e2e2e", + "itemDetailsColor": "#636363", + "itemTitleColor": "#121212", + "linkColor": "#ffcc00", + "newItemColor": "#ffffcc00", + "placeholderFolder1BorderColor": "#20ffffff", + "placeholderFolder1Color": "#20000000", + "placeholderFolder2BorderColor": "#20ffffff", + "placeholderFolder2Color": "#88000000", "ratingSelectedColor": "#2b2b2b", "ratingUnselectedColor": "#dedede", "readTickCheckedColor": "#e84852", "readTickUncheckedColor": "#dedede", - "selectedBorderColor": "#ffcc00", - "selectedColor": "#ffffff", - "showDropShadow": true, - "textColor": "#636363", - "titleColor": "#121212", - "newItemColor": "#ffffcc00", - "buttonColor": "#ffcc00", - "buttonTextColor": "#ffffff", - "linkColor": "#ffcc00", - "scrollbarColor": "#88424242", "scrollbarBorderColor": "#aa313131", - "infoScrollbarColor": "#ff424246", - "comicCoverBorderColor": "#30ffffff", - "folderCoverBorderColor": "#20ffffff", - "placeholderFolder1Color": "#20000000", - "placeholderFolder1BorderColor": "#20ffffff", - "placeholderFolder2Color": "#88000000", - "placeholderFolder2BorderColor": "#20ffffff", - "currentComicCoverShadowColor": "#ff000000", - "buttonShadowColor": "#aa000000" + "scrollbarColor": "#88424242", + "showDropShadow": true }, "helpAboutDialog": { "headingColor": "#302f2d", @@ -166,10 +166,10 @@ "folderIconSelectedColor": "#ffffff", "folderIconSelectedShadowColor": "#161616", "folderIconShadowColor": "#ffffff", - "newItemColor": "#555f7f", "folderNotCompletedColor": "#555f7f", "folderReadOverlayColor": "#ffffff", "folderReadOverlaySelectedColor": "#161616", + "newItemColor": "#555f7f", "scrollBackgroundColor": "#e0e0e0", "scrollHandleColor": "#888888", "selectedTextColor": "#ffffff", diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index f44e4b578..bc0ca8ccb 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -215,11 +215,11 @@ struct GridAndInfoViewTheme { QColor backgroundColor; QColor cellColor; QColor cellColorWithBackground; - QColor selectedColor; - QColor selectedBorderColor; + QColor cellSelectedColor; + QColor cellSelectedBorderColor; QColor borderColor; - QColor titleColor; - QColor textColor; + QColor itemTitleColor; + QColor itemDetailsColor; bool showDropShadow; // Info panel colors @@ -227,8 +227,8 @@ struct GridAndInfoViewTheme { QString topShadow; // Recolored SVG path QString infoShadow; // Recolored SVG path QString infoIndicator; // Recolored SVG path + QColor infoMetadataTextColor; QColor infoTextColor; - QColor infoTitleColor; // Rating and favorite colors QColor ratingUnselectedColor; @@ -243,7 +243,7 @@ struct GridAndInfoViewTheme { // Continue reading section (FolderContentView) QColor continueReadingBackgroundColor; - QColor continueReadingColor; + QColor continueReadingTextColor; // Blur overlay background (FlowView always, GridView when background image enabled) QColor backgroundBlurOverlayColor; diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index cef847da6..550611d87 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -143,19 +143,19 @@ struct GridAndInfoViewParams { QColor backgroundColor; QColor cellColor; QColor cellColorWithBackground; - QColor selectedColor; - QColor selectedBorderColor; + QColor cellSelectedColor; + QColor cellSelectedBorderColor; QColor borderColor; - QColor titleColor; - QColor textColor; + QColor itemTitleColor; + QColor itemDetailsColor; bool showDropShadow; // Info panel colors QColor infoBackgroundColor; QColor infoBorderColor; QColor infoShadowColor; + QColor infoMetadataTextColor; QColor infoTextColor; - QColor infoTitleColor; // Rating and favorite colors QColor ratingUnselectedColor; @@ -170,7 +170,7 @@ struct GridAndInfoViewParams { // Continue reading section (FolderContentView) QColor continueReadingBackgroundColor; - QColor continueReadingColor; + QColor continueReadingTextColor; // Blur overlay background (FlowView always, GridView when background image enabled) QColor backgroundBlurOverlayColor; @@ -520,18 +520,18 @@ Theme makeTheme(const ThemeParams ¶ms) theme.gridAndInfoView.backgroundColor = giv.backgroundColor; theme.gridAndInfoView.cellColor = giv.cellColor; theme.gridAndInfoView.cellColorWithBackground = giv.cellColorWithBackground; - theme.gridAndInfoView.selectedColor = giv.selectedColor; - theme.gridAndInfoView.selectedBorderColor = giv.selectedBorderColor; + theme.gridAndInfoView.cellSelectedColor = giv.cellSelectedColor; + theme.gridAndInfoView.cellSelectedBorderColor = giv.cellSelectedBorderColor; theme.gridAndInfoView.borderColor = giv.borderColor; - theme.gridAndInfoView.titleColor = giv.titleColor; - theme.gridAndInfoView.textColor = giv.textColor; + theme.gridAndInfoView.itemTitleColor = giv.itemTitleColor; + theme.gridAndInfoView.itemDetailsColor = giv.itemDetailsColor; theme.gridAndInfoView.showDropShadow = giv.showDropShadow; theme.gridAndInfoView.infoBackgroundColor = giv.infoBackgroundColor; theme.gridAndInfoView.topShadow = recoloredSvgToThemeFile(":/qml/info-top-shadow.svg", giv.infoBackgroundColor, giv.infoBorderColor, giv.infoShadowColor, params.meta.id); theme.gridAndInfoView.infoShadow = recoloredSvgToThemeFile(":/qml/info-shadow.svg", giv.infoBackgroundColor, giv.infoBorderColor, giv.infoShadowColor, params.meta.id); theme.gridAndInfoView.infoIndicator = recoloredSvgToThemeFile(":/qml/info-indicator.svg", giv.infoBackgroundColor, giv.infoBorderColor, giv.infoShadowColor, params.meta.id); + theme.gridAndInfoView.infoMetadataTextColor = giv.infoMetadataTextColor; theme.gridAndInfoView.infoTextColor = giv.infoTextColor; - theme.gridAndInfoView.infoTitleColor = giv.infoTitleColor; theme.gridAndInfoView.ratingUnselectedColor = giv.ratingUnselectedColor; theme.gridAndInfoView.ratingSelectedColor = giv.ratingSelectedColor; theme.gridAndInfoView.favUncheckedColor = giv.favUncheckedColor; @@ -540,7 +540,7 @@ Theme makeTheme(const ThemeParams ¶ms) theme.gridAndInfoView.readTickCheckedColor = giv.readTickCheckedColor; theme.gridAndInfoView.currentComicBackgroundColor = giv.currentComicBackgroundColor; theme.gridAndInfoView.continueReadingBackgroundColor = giv.continueReadingBackgroundColor; - theme.gridAndInfoView.continueReadingColor = giv.continueReadingColor; + theme.gridAndInfoView.continueReadingTextColor = giv.continueReadingTextColor; theme.gridAndInfoView.backgroundBlurOverlayColor = giv.backgroundBlurOverlayColor; theme.gridAndInfoView.newItemColor = giv.newItemColor; theme.gridAndInfoView.buttonColor = giv.buttonColor; @@ -1114,18 +1114,18 @@ Theme makeTheme(const QJsonObject &json) giv.backgroundColor = colorFromJson(o, "backgroundColor", giv.backgroundColor); giv.cellColor = colorFromJson(o, "cellColor", giv.cellColor); giv.cellColorWithBackground = colorFromJson(o, "cellColorWithBackground", giv.cellColorWithBackground); - giv.selectedColor = colorFromJson(o, "selectedColor", giv.selectedColor); - giv.selectedBorderColor = colorFromJson(o, "selectedBorderColor", giv.selectedBorderColor); + giv.cellSelectedColor = colorFromJson(o, "cellSelectedColor", giv.cellSelectedColor); + giv.cellSelectedBorderColor = colorFromJson(o, "cellSelectedBorderColor", giv.cellSelectedBorderColor); giv.borderColor = colorFromJson(o, "borderColor", giv.borderColor); - giv.titleColor = colorFromJson(o, "titleColor", giv.titleColor); - giv.textColor = colorFromJson(o, "textColor", giv.textColor); + giv.itemTitleColor = colorFromJson(o, "itemTitleColor", giv.itemTitleColor); + giv.itemDetailsColor = colorFromJson(o, "itemDetailsColor", giv.itemDetailsColor); if (o.contains("showDropShadow")) giv.showDropShadow = o["showDropShadow"].toBool(giv.showDropShadow); giv.infoBackgroundColor = colorFromJson(o, "infoBackgroundColor", giv.infoBackgroundColor); giv.infoBorderColor = colorFromJson(o, "infoBorderColor", giv.infoBorderColor); giv.infoShadowColor = colorFromJson(o, "infoShadowColor", giv.infoShadowColor); + giv.infoMetadataTextColor = colorFromJson(o, "infoMetadataTextColor", giv.infoMetadataTextColor); giv.infoTextColor = colorFromJson(o, "infoTextColor", giv.infoTextColor); - giv.infoTitleColor = colorFromJson(o, "infoTitleColor", giv.infoTitleColor); giv.ratingUnselectedColor = colorFromJson(o, "ratingUnselectedColor", giv.ratingUnselectedColor); giv.ratingSelectedColor = colorFromJson(o, "ratingSelectedColor", giv.ratingSelectedColor); giv.favUncheckedColor = colorFromJson(o, "favUncheckedColor", giv.favUncheckedColor); @@ -1134,7 +1134,7 @@ Theme makeTheme(const QJsonObject &json) giv.readTickCheckedColor = colorFromJson(o, "readTickCheckedColor", giv.readTickCheckedColor); giv.currentComicBackgroundColor = colorFromJson(o, "currentComicBackgroundColor", giv.currentComicBackgroundColor); giv.continueReadingBackgroundColor = colorFromJson(o, "continueReadingBackgroundColor", giv.continueReadingBackgroundColor); - giv.continueReadingColor = colorFromJson(o, "continueReadingColor", giv.continueReadingColor); + giv.continueReadingTextColor = colorFromJson(o, "continueReadingTextColor", giv.continueReadingTextColor); giv.backgroundBlurOverlayColor = colorFromJson(o, "backgroundBlurOverlayColor", giv.backgroundBlurOverlayColor); giv.newItemColor = colorFromJson(o, "newItemColor", giv.newItemColor); giv.buttonColor = colorFromJson(o, "buttonColor", giv.buttonColor); From fbbccfc6089cb8ffade7b7678753780c22d81ce3 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 7 Mar 2026 22:22:19 +0100 Subject: [PATCH 142/187] Fix drag for scrolling in continuous scroll mode --- YACReader/viewer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index 3675b6f9d..3a4143519 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -1505,6 +1505,10 @@ bool Viewer::eventFilter(QObject *obj, QEvent *event) mouseEvent->buttons(), mouseEvent->modifiers()); mouseHandler->mouseMoveEvent(&mappedEvent); + // Consume this event so we don't process the same drag movement again + // via Viewer::mouseMoveEvent() after bubbling. + event->accept(); + return true; } return QScrollArea::eventFilter(obj, event); } From 6317c3a4d0ff6673851a1eb5554aea377a29ac40 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 7 Mar 2026 22:38:33 +0100 Subject: [PATCH 143/187] Fix the continuous scroll mode in hdpi screen modes --- YACReader/continuous_page_widget.cpp | 21 +++++++++++++-------- YACReader/continuous_page_widget.h | 4 +++- YACReader/viewer.cpp | 1 - 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/YACReader/continuous_page_widget.cpp b/YACReader/continuous_page_widget.cpp index 9391c1d1b..514156c6a 100644 --- a/YACReader/continuous_page_widget.cpp +++ b/YACReader/continuous_page_widget.cpp @@ -118,7 +118,9 @@ void ContinuousPageWidget::paintEvent(QPaintEvent *event) } QPainter painter(this); - scaledPageCache.invalidateForWidth(width()); + const qreal dpr = devicePixelRatioF(); + const int effectivePixelWidth = std::max(1, qRound(width() * dpr)); + scaledPageCache.invalidateForWidth(effectivePixelWidth); QRect visibleRect = event->rect(); int firstPage = continuousViewModel->pageAtY(visibleRect.top()); @@ -143,7 +145,7 @@ void ContinuousPageWidget::paintEvent(QPaintEvent *event) const QImage *img = render->bufferedImage(i); if (img && !img->isNull()) { - const QImage *drawable = scaledImageForPaint(i, img, scaled, width()); + const QImage *drawable = scaledImageForPaint(i, img, scaled, effectivePixelWidth, dpr); if (drawable) { painter.drawImage(pageRect, *drawable); } @@ -164,15 +166,15 @@ void ContinuousPageWidget::resizeEvent(QResizeEvent *event) } } -const QImage *ContinuousPageWidget::scaledImageForPaint(int pageIndex, const QImage *source, const QSize &targetSize, int effectiveWidth) +const QImage *ContinuousPageWidget::scaledImageForPaint(int pageIndex, const QImage *source, const QSize &targetSize, int effectiveWidth, qreal devicePixelRatio) { if (!source || source->isNull() || targetSize.isEmpty()) { return nullptr; } - if (source->size() == targetSize) { - return source; - } + const qreal dpr = std::max(1.0, devicePixelRatio); + const QSize targetPixelSize(std::max(1, qRound(targetSize.width() * dpr)), + std::max(1, qRound(targetSize.height() * dpr))); scaledPageCache.invalidateForWidth(effectiveWidth); @@ -181,7 +183,7 @@ const QImage *ContinuousPageWidget::scaledImageForPaint(int pageIndex, const QIm if (it != scaledPageCache.pages.end()) { const ScaledPageCacheEntry &entry = it.value(); - const bool validEntry = entry.sourceCacheKey == sourceKey && entry.sourceSize == source->size() && entry.targetSize == targetSize && !entry.scaledImage.isNull(); + const bool validEntry = entry.sourceCacheKey == sourceKey && entry.sourceSize == source->size() && entry.targetSize == targetSize && entry.targetPixelSize == targetPixelSize && qFuzzyCompare(entry.targetDevicePixelRatio, dpr) && !entry.scaledImage.isNull(); if (validEntry) { return &it.value().scaledImage; } @@ -191,8 +193,11 @@ const QImage *ContinuousPageWidget::scaledImageForPaint(int pageIndex, const QIm entry.sourceCacheKey = sourceKey; entry.sourceSize = source->size(); entry.targetSize = targetSize; - entry.scaledImage = scaleImage(*source, targetSize.width(), targetSize.height(), + entry.targetPixelSize = targetPixelSize; + entry.targetDevicePixelRatio = dpr; + entry.scaledImage = scaleImage(*source, targetPixelSize.width(), targetPixelSize.height(), Configuration::getConfiguration().getScalingMethod()); + entry.scaledImage.setDevicePixelRatio(dpr); scaledPageCache.pages.insert(pageIndex, std::move(entry)); return &scaledPageCache.pages[pageIndex].scaledImage; diff --git a/YACReader/continuous_page_widget.h b/YACReader/continuous_page_widget.h index 16be8f2ff..aff9b809b 100644 --- a/YACReader/continuous_page_widget.h +++ b/YACReader/continuous_page_widget.h @@ -40,6 +40,8 @@ public slots: qint64 sourceCacheKey = 0; QSize sourceSize; QSize targetSize; + QSize targetPixelSize; + qreal targetDevicePixelRatio = 1.0; QImage scaledImage; }; @@ -86,7 +88,7 @@ public slots: } }; - const QImage *scaledImageForPaint(int pageIndex, const QImage *source, const QSize &targetSize, int effectiveWidth); + const QImage *scaledImageForPaint(int pageIndex, const QImage *source, const QSize &targetSize, int effectiveWidth, qreal devicePixelRatio); Render *render = nullptr; ContinuousViewModel *continuousViewModel = nullptr; diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index 3a4143519..3eb44db4d 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -896,7 +896,6 @@ QImage Viewer::grabMagnifiedRegion(const QPoint &viewerPos, const QSize &glassSi const int resultH = static_cast(zoomH * hFactor); QImage result(resultW, resultH, QImage::Format_RGB32); - result.setDevicePixelRatio(devicePixelRatioF()); result.fill(bgColor); // zoom region in widget coordinates (centered on cursor) From 82ac83ee7a93df57bf6f2eb782f00649205e540c Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 8 Mar 2026 08:45:42 +0100 Subject: [PATCH 144/187] Fix info view indicator background --- YACReaderLibrary/qml/InfoComicsView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YACReaderLibrary/qml/InfoComicsView.qml b/YACReaderLibrary/qml/InfoComicsView.qml index 85c5cc5b8..66d169ea8 100644 --- a/YACReaderLibrary/qml/InfoComicsView.qml +++ b/YACReaderLibrary/qml/InfoComicsView.qml @@ -9,7 +9,7 @@ import QtQuick.Controls.Basic Rectangle { id: main - color: infoBackgroundColor + color: "transparent" //width: parent.width //height: parent.height From 3fede5dabff07db597b319b61ae8c33d49c2228c Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Wed, 11 Mar 2026 18:21:35 +0100 Subject: [PATCH 145/187] Add a setting to select the language in the options dialog All translations have been updated, and translations of the actions in the library have been fixed. --- AGENTS.md | 34 + YACReader/CMakeLists.txt | 1 + YACReader/main.cpp | 11 +- YACReader/options_dialog.cpp | 31 +- YACReader/options_dialog.h | 1 + YACReader/yacreader_de.ts | 3984 ++++++++++++++--- YACReader/yacreader_en.ts | 3708 ++++++++++++--- YACReader/yacreader_es.ts | 3684 ++++++++++++--- YACReader/yacreader_fr.ts | 3922 +++++++++++++--- YACReader/yacreader_it.ts | 3916 +++++++++++++--- YACReader/yacreader_nl.ts | 3932 +++++++++++++--- YACReader/yacreader_pt.ts | 3916 +++++++++++++--- YACReader/yacreader_ru.ts | 3914 +++++++++++++--- YACReader/yacreader_tr.ts | 3980 +++++++++++++--- YACReader/yacreader_zh_CN.ts | 3399 ++++++++++++-- YACReader/yacreader_zh_HK.ts | 3421 ++++++++++++-- YACReader/yacreader_zh_TW.ts | 3421 ++++++++++++-- YACReaderLibrary/CMakeLists.txt | 7 + YACReaderLibrary/library_window_actions.cpp | 2 +- YACReaderLibrary/main.cpp | 14 +- YACReaderLibrary/options_dialog.cpp | 28 + YACReaderLibrary/options_dialog.h | 1 + YACReaderLibrary/yacreaderlibrary_de.ts | 2917 ++++++++---- YACReaderLibrary/yacreaderlibrary_en.ts | 3269 +++++++++----- YACReaderLibrary/yacreaderlibrary_es.ts | 2620 ++++++++--- YACReaderLibrary/yacreaderlibrary_fr.ts | 3107 +++++++++---- YACReaderLibrary/yacreaderlibrary_it.ts | 2943 ++++++++---- YACReaderLibrary/yacreaderlibrary_nl.ts | 3164 ++++++++----- YACReaderLibrary/yacreaderlibrary_pt.ts | 3289 +++++++++----- YACReaderLibrary/yacreaderlibrary_ru.ts | 2943 ++++++++---- YACReaderLibrary/yacreaderlibrary_source.ts | 3393 ++++++++++---- YACReaderLibrary/yacreaderlibrary_tr.ts | 2915 ++++++++---- YACReaderLibrary/yacreaderlibrary_zh_CN.ts | 2783 +++++++++--- YACReaderLibrary/yacreaderlibrary_zh_HK.ts | 2901 ++++++++---- YACReaderLibrary/yacreaderlibrary_zh_TW.ts | 2901 ++++++++---- YACReaderLibraryServer/CMakeLists.txt | 1 + .../yacreaderlibraryserver_de.ts | 3729 ++++++++++++++- .../yacreaderlibraryserver_es.ts | 3712 ++++++++++++++- .../yacreaderlibraryserver_fr.ts | 3730 ++++++++++++++- .../yacreaderlibraryserver_nl.ts | 3730 ++++++++++++++- .../yacreaderlibraryserver_pt.ts | 3730 ++++++++++++++- .../yacreaderlibraryserver_ru.ts | 3730 ++++++++++++++- .../yacreaderlibraryserver_tr.ts | 3731 ++++++++++++++- .../yacreaderlibraryserver_zh_CN.ts | 3730 ++++++++++++++- .../yacreaderlibraryserver_zh_HK.ts | 3730 ++++++++++++++- .../yacreaderlibraryserver_zh_TW.ts | 3730 ++++++++++++++- ci/win/build_installer_qt6.iss | 2 +- ci/win/create_installer.cmd | 3 +- common/app_language_utils.h | 131 + common/yacreader_global_gui.h | 1 + compileOSX.sh | 6 +- 51 files changed, 102621 insertions(+), 19277 deletions(-) create mode 100644 common/app_language_utils.h diff --git a/AGENTS.md b/AGENTS.md index ba1653ad1..847f487d3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,6 +17,40 @@ Build options: - `BUILD_SERVER_STANDALONE=ON`: builds only `YACReaderLibraryServer` (headless), requires only Qt 6.4+ - `BUILD_TESTS=ON` (default): enables the test suite +## Translations + +Use CMake translation targets (Qt LinguistTools integration), not ad-hoc `lupdate` calls. + +Update `.ts` files from source code (C++ + QML): + +```bash +cmake --build build --target update_translations +``` + +On multi-config generators (Visual Studio / Ninja Multi-Config), include config: + +```bash +cmake --build build --config Release --target update_translations +``` + +Build `.qm` files: + +```bash +cmake --build build --target release_translations +``` + +Multi-config variant: + +```bash +cmake --build build --config Release --target release_translations +``` + +Important: +- Do not run `lupdate` only on `qml.qrc` (or only on a subset of files), because that can mark unrelated translations as obsolete. +- In `YACReaderLibrary`, `qt_add_translations(...)` is configured to scan full target sources and include QML from `qml.qrc`. +- `update_translations` updates both locale TS files and `*_source.ts` template files for all apps. +- `*_source.ts` files are translator base templates and must not be treated as shipped locales. + ## Tests ```bash diff --git a/YACReader/CMakeLists.txt b/YACReader/CMakeLists.txt index e7ba59473..02f3cca52 100644 --- a/YACReader/CMakeLists.txt +++ b/YACReader/CMakeLists.txt @@ -79,6 +79,7 @@ qt_add_translations(YACReader yacreader_zh_TW.ts yacreader_zh_HK.ts yacreader_it.ts + yacreader_source.ts yacreader_en.ts ) diff --git a/YACReader/main.cpp b/YACReader/main.cpp index 66b0d52ab..5d1e9e77b 100644 --- a/YACReader/main.cpp +++ b/YACReader/main.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include @@ -10,6 +9,7 @@ #include "appearance_configuration.h" #include "theme_manager.h" #include "theme_repository.h" +#include "app_language_utils.h" #include "yacreader_global.h" #include "QsLog.h" @@ -175,13 +175,8 @@ int main(int argc, char *argv[]) logger.addDestination(std::move(debugDestination)); logger.addDestination(std::move(fileDestination)); - QTranslator translator; -#if defined Q_OS_UNIX && !defined Q_OS_MACOS - translator.load(QLocale(), "yacreader", "_", QString(DATADIR) + "/yacreader/languages"); -#else - translator.load(QLocale(), "yacreader", "_", "languages"); -#endif - app.installTranslator(&translator); + QSettings uiSettings(YACReader::getSettingsPath() + "/YACReader.ini", QSettings::IniFormat); + YACReader::UiLanguage::applyLanguage("yacreader", uiSettings.value(UI_LANGUAGE).toString()); auto mwv = new MainWindowViewer(); // some arguments need to be parsed after MainWindowViewer creation diff --git a/YACReader/options_dialog.cpp b/YACReader/options_dialog.cpp index 497553c07..38b7e6d3f 100644 --- a/YACReader/options_dialog.cpp +++ b/YACReader/options_dialog.cpp @@ -17,6 +17,7 @@ #include "theme_manager.h" #include "theme_factory.h" #include "appearance_tab_widget.h" +#include "app_language_utils.h" #include "yacreader_spin_slider_widget.h" #include "yacreader_3d_flow_config_widget.h" @@ -40,6 +41,19 @@ OptionsDialog::OptionsDialog(QWidget *parent) path->addWidget(pathFindButton = new QPushButton("")); pathBox->setLayout(path); + auto *languageBox = new QGroupBox(tr("Language")); + auto *languageLayout = new QHBoxLayout(); + languageLayout->addWidget(new QLabel(tr("Application language"))); + languageCombo = new QComboBox(this); + languageCombo->addItem(tr("System default"), QString()); + const auto availableLanguages = YACReader::UiLanguage::availableLanguages("yacreader"); + for (const auto &language : availableLanguages) { + languageCombo->addItem( + QString("%1 (%2)").arg(language.displayName, language.code), language.code); + } + languageLayout->addWidget(languageCombo); + languageBox->setLayout(languageLayout); + QGroupBox *displayBox = new QGroupBox(tr("Display")); auto displayLayout = new QHBoxLayout(); showTimeInInformationLabel = new QCheckBox(tr("Show time in current page information label")); @@ -105,6 +119,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) mouseModeBox->setLayout(mouseModeLayout); layoutGeneral->addWidget(pathBox); + layoutGeneral->addWidget(languageBox); layoutGeneral->addWidget(displayBox); layoutGeneral->addWidget(slideSizeBox); // layoutGeneral->addWidget(fitBox); @@ -178,7 +193,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) auto scaleLayout = new QVBoxLayout(); scaleCheckbox = new QCheckBox(tr("Enlarge images to fit width/height")); connect(scaleCheckbox, &QCheckBox::clicked, scaleCheckbox, - [=](bool checked) { + [=, this](bool checked) { Configuration::getConfiguration().setEnlargeImages(checked); emit changedImageOptions(); }); @@ -191,7 +206,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) auto doublePageBoxLayout = new QVBoxLayout(); coverSPCheckBox = new QCheckBox(tr("Show covers as single page")); connect(coverSPCheckBox, &QCheckBox::clicked, coverSPCheckBox, - [=](bool checked) { + [=, this](bool checked) { settings->setValue(COVER_IS_SP, checked); emit changedImageOptions(); }); @@ -315,6 +330,12 @@ void OptionsDialog::saveOptions() Configuration::getConfiguration().setScalingMethod(static_cast(scalingMethodCombo->currentIndex())); emit changedImageOptions(); + const auto selectedLanguage = languageCombo->currentData().toString().trimmed(); + if (selectedLanguage.isEmpty()) + settings->remove(UI_LANGUAGE); + else + settings->setValue(UI_LANGUAGE, selectedLanguage); + YACReaderOptionsDialog::saveOptions(); } @@ -326,6 +347,12 @@ void OptionsDialog::restoreOptions(QSettings *settings) pathEdit->setText(settings->value(PATH).toString()); + const auto selectedLanguage = settings->value(UI_LANGUAGE).toString().trimmed(); + int languageIndex = languageCombo->findData(selectedLanguage); + if (languageIndex < 0) + languageIndex = 0; + languageCombo->setCurrentIndex(languageIndex); + showTimeInInformationLabel->setChecked(Configuration::getConfiguration().getShowTimeInInformation()); updateColor(settings->value(BACKGROUND_COLOR, theme.viewer.defaultBackgroundColor).value()); diff --git a/YACReader/options_dialog.h b/YACReader/options_dialog.h index 656536953..874e1c9f5 100644 --- a/YACReader/options_dialog.h +++ b/YACReader/options_dialog.h @@ -29,6 +29,7 @@ class OptionsDialog : public YACReaderOptionsDialog, protected Themable // QLabel * pathLabel; QLineEdit *pathEdit; QPushButton *pathFindButton; + QComboBox *languageCombo; QCheckBox *showTimeInInformationLabel; diff --git a/YACReader/yacreader_de.ts b/YACReader/yacreader_de.ts index 5fdbbb2e1..077f25ab8 100644 --- a/YACReader/yacreader_de.ts +++ b/YACReader/yacreader_de.ts @@ -9,6 +9,196 @@ Keine + + AddLabelDialog + + + Label name: + Label-Name: + + + + Choose a color: + Wähle eine Farbe: + + + + accept + Akzeptieren + + + + cancel + Abbrechen + + + + AddLibraryDialog + + + Comics folder : + Comics-Ordner : + + + + Library name : + Bibliothek-Name : + + + + Add + Hinzufügen + + + + Cancel + Abbrechen + + + + Add an existing library + Eine vorhandene Bibliothek hinzufügen + + + + ApiKeyDialog + + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Bevor du dich mit Comic Vine verbindest, brauchst du deinen eigenen API-Schlüssel. Du kannst <a href="http://www.comicvine.com/api/">hier</a> einen kostenlosen bekommen. + + + + Paste here your Comic Vine API key + Füge hier deinen Comic Vine API-Schlüssel ein. + + + + Accept + Akzeptieren + + + + Cancel + Abbrechen + + + + AppearanceTabWidget + + + Color scheme + Farbschema + + + + System + Systemumgebung + + + + Light + Licht + + + + Dark + Dunkel + + + + Custom + Brauch + + + + Remove + Entfernen + + + + Remove this user-imported theme + Entfernen Sie dieses vom Benutzer importierte Design + + + + Light: + Licht: + + + + Dark: + Dunkel: + + + + Custom: + Benutzerdefiniert: + + + + Import theme... + Theme importieren... + + + + Theme + Thema + + + + Theme editor + Theme-Editor + + + + Open Theme Editor... + Theme-Editor öffnen... + + + + Theme editor error + Fehler im Theme-Editor + + + + The current theme JSON could not be loaded. + Der aktuelle Theme-JSON konnte nicht geladen werden. + + + + Import theme + Thema importieren + + + + JSON files (*.json);;All files (*) + JSON-Dateien (*.json);;Alle Dateien (*) + + + + Could not import theme from: +%1 + Theme konnte nicht importiert werden von: +%1 + + + + Could not import theme from: +%1 + +%2 + Theme konnte nicht importiert werden von: +%1 + +%2 + + + + Import failed + Der Import ist fehlgeschlagen + + BookmarksDialog @@ -33,6 +223,200 @@ Neueste Seite + + ClassicComicsView + + + Hide comic flow + Comic "Flow" verstecken + + + + ComicModel + + + yes + Ja + + + + no + Nein + + + + Title + Titel + + + + File Name + Dateiname + + + + Pages + Seiten + + + + Size + Größe + + + + Read + Lesen + + + + Current Page + Aktuelle Seite + + + + Publication Date + Veröffentlichungsdatum + + + + Rating + Bewertung + + + + Series + Serie + + + + Volume + Volumen + + + + Story Arc + Handlungsbogen + + + + ComicVineDialog + + + skip + überspringen + + + + back + zurück + + + + next + nächste + + + + search + suche + + + + close + schließen + + + + + comic %1 of %2 - %3 + Comic %1 von %2 - %3 + + + + + + Looking for volume... + Suche nach Band.... + + + + %1 comics selected + %1 Comic ausgewählt + + + + Error connecting to ComicVine + Fehler bei Verbindung zu ComicVine + + + + + Retrieving tags for : %1 + Herunterladen von Tags für : %1 + + + + Retrieving volume info... + Herunterladen von Info zu Ausgabe... + + + + Looking for comic... + Suche nach Comic... + + + + ContinuousPageWidget + + + Loading page %1 + Seite wird geladen %1 + + + + CreateLibraryDialog + + + Comics folder : + Comics-Ordner : + + + + Library Name : + Bibliothek-Name : + + + + Create + Erstellen + + + + Cancel + Abbrechen + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Es kann einige Minuten dauern, eine neue Bibliothek zu erstellen. Sie können den Prozess abbrechen und die Bibliothek später aktualisieren, um den Vorgang abzuschließen. + + + + Create new library + Erstelle eine neue Bibliothek + + + + Path not found + Pfad nicht gefunden + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben + + EditShortcutsDialog @@ -51,16 +435,134 @@ Kürzel-Einstellungen - + Shortcut in use Genutzte Kürzel - + The shortcut "%1" is already assigned to other function Das Kürzel "%1" ist bereits für eine andere Funktion in Verwendung + + EmptyFolderWidget + + + This folder doesn't contain comics yet + Dieser Ordner enthält noch keine Comics + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + Dieses Label enthält noch keine Comics + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + Diese Leseliste enthält noch keine Comics + + + + EmptySpecialListWidget + + + No favorites + Keine Favoriten + + + + You are not reading anything yet, come on!! + Sie lesen noch nichts, starten Sie!! + + + + There are no recent comics! + Es gibt keine aktuellen Comics! + + + + ExportComicsInfoDialog + + + Output file : + Zieldatei : + + + + Create + Erstellen + + + + Cancel + Abbrechen + + + + Export comics info + Comicinfo exportieren + + + + Destination database name + Ziel-Datenbank Name + + + + Problem found while writing + Problem beim Schreiben + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben + + + + ExportLibraryDialog + + + Output folder : + Ziel-Ordner : + + + + Create + Erstellen + + + + Cancel + Abbrechen + + + + Create covers package + Erzeuge Titelbild-Paket + + + + Problem found while writing + Problem beim Schreiben + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben + + + + Destination directory + Ziel-Verzeichnis + + FileComic @@ -116,1266 +618,3468 @@ GoToFlowToolBar - + Page : Seite : + + GridComicsView + + + Show info + Info anzeigen + + HelpAboutDialog - + Help Hilfe - + System info - + Systeminformationen - + About Über - LogWindow + ImportComicsInfoDialog - - Log window - Änderungsprotokoll-Fenster + + Import comics info + Importiere Comic-Info - - &Pause - Pause + + Info database location : + Info-Datenbank Speicherort : - - &Save - Speichern + + Import + Importieren - - C&lear - L&öschen + + Cancel + Abbrechen - - &Copy - &Kopieren + + Comics info file (*.ydb) + Comics-Info-Datei (*.ydb) + + + ImportLibraryDialog - - Level: - Level + + Library Name : + Bibliothek-Name : - - &Auto scroll - &Automatisches Scrollen + + Package location : + Paket Ort : - - - MainWindowViewer - File - Datei + + Destination folder : + Zielordner : - Help - Hilfe + + Unpack + Entpacken - Save - Speichern + + Cancel + Abbrechen - &File - &Datei + + Extract a catalog + Einen Katalog extrahieren - &Next - &Nächstes + + Compresed library covers (*.clc) + Komprimierte Bibliothek Cover (*.clc) - + + + ImportWidget + + + stop + Stopp + + + + Some of the comics being added... + Einige der Comics werden hinzugefügt... + + + + Importing comics + Comics werden importiert + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary erstellt nun eine neue Bibliothek. </p><p>Es kann einige Minuten dauern, eine neue Bibliothek zu erstellen. Sie können den Prozess abbrechen und die Bibliothek später aktualisieren, um den Vorgang abzuschließen.</p> + + + + Updating the library + Aktualisierung der Bibliothek + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>Die aktuelle Bibliothek wird gerade aktualisiert. Für eine schnellere Aktualisierung, aktualisieren Sie die Bibliothek bitte regelmäßig.</p><p>Sie können den Prozess abbrechen und mit der Aktualisierung später fortfahren.<p> + + + + Upgrading the library + Upgrade der Bibliothek + + + + <p>The current library is being upgraded, please wait.</p> + Die aktuelle Bibliothek wird gerade upgegradet, bitte warten. + + + + Scanning the library + Durchsuchen der Bibliothek + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>Die aktuelle Bibliothek wird nach alten XML-Metadateninformationen durchsucht.</p><p>Dies ist nur einmal erforderlich und nur, wenn die Bibliothek mit YACReaderLibrary 9.8.2 oder früher erstellt wurde.</p> + + + + LibraryWindow + + + YACReader Library + YACReader Bibliothek + + + + + + comic + komisch + + + + + + manga + Manga + + + + + + western manga (left to right) + Western-Manga (von links nach rechts) + + + + + + web comic + Webcomic + + + + + + 4koma (top to botom) + 4koma (von oben nach unten) + + + + + + + Set type + Typ festlegen + + + + Library + Bibliothek + + + + Folder + Ordner + + + + Comic + Komisch + + + + Upgrade failed + Update gescheitert + + + + There were errors during library upgrade in: + Beim Upgrade der Bibliothek kam es zu Fehlern in: + + + + Update needed + Update benötigt + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Diese Bibliothek wurde mit einer älteren Version von YACReader erzeugt. Sie muss geupdated werden. Jetzt updaten? + + + + Download new version + Neue Version herunterladen + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Die Bibliothek wurde mit einer neueren Version von YACReader erstellt. Die neue Version jetzt herunterladen? + + + + Library not available + Bibliothek nicht verfügbar + + + + Library '%1' is no longer available. Do you want to remove it? + Bibliothek '%1' ist nicht mehr verfügbar. Wollen Sie sie entfernen? + + + + Old library + Alte Bibliothek + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Bibliothek '%1' wurde mit einer älteren Version von YACReader erstellt. Sie muss neu erzeugt werden. Wollen Sie die Bibliothek jetzt erzeugen? + + + + + Copying comics... + Kopieren von Comics... + + + + + Moving comics... + Verschieben von Comics... + + + + Add new folder + Neuen Ordner erstellen + + + + Folder name: + Ordnername + + + + No folder selected + Kein Ordner ausgewählt + + + + Please, select a folder first + Bitte wählen Sie zuerst einen Ordner aus + + + + Error in path + Fehler im Pfad + + + + There was an error accessing the folder's path + Beim Aufrufen des Ordnerpfades kam es zu einem Fehler + + + + Delete folder + Ordner löschen + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + Der ausgewählte Ordner und sein gesamter Inhalt wird von Ihrer Festplatte gelöscht. Sind Sie sicher? + + + + + Unable to delete + Löschen nicht möglich + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Beim Löschen des ausgewählten Ordners ist ein Problem aufgetreten. Bitte überprüfen Sie die Schreibrechte und stellen Sie sicher, dass keine Anwendung diese Ordner oder die darin enthaltenen Dateien verwendet. + + + + Add new reading lists + Neue Leseliste hinzufügen + + + + + List name: + Name der Liste + + + + Delete list/label + Ausgewählte/s Liste/Label löschen + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + Das ausgewählte Element wird gelöscht; Ihre Comics oder Ordner werden NICHT von Ihrer Festplatte gelöscht. Sind Sie sicher? + + + + Rename list name + Listenname ändern + + + + Open folder... + Öffne Ordner... + + + + Update folder + Ordner aktualisieren + + + + Rescan library for XML info + Durchsuchen Sie die Bibliothek erneut nach XML-Informationen + + + + Set as uncompleted + Als nicht gelesen markieren + + + + Set as completed + Als gelesen markieren + + + + Set as read + Als gelesen markieren + + + + + Set as unread + Als ungelesen markieren + + + + Set custom cover + Legen Sie ein benutzerdefiniertes Cover fest + + + + Delete custom cover + Benutzerdefiniertes Cover löschen + + + + Save covers + Titelbilder speichern + + + + You are adding too many libraries. + Sie fügen zu viele Bibliotheken hinzu. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Sie fügen zu viele Bibliotheken hinzu. + Wahrscheinlich brauchen Sie nur eine Bibliothek in Ihrem obersten Comic-Ordner, Sie können alle Unterordner mit Hilfe des Ordnerbereichs in der linken Seitenleiste durchsuchen. + +YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen, aber Sie sollten die Anzahl der Bibliotheken gering halten. + + + + + YACReader not found + YACReader nicht gefunden + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader nicht gefunden. YACReader muss im gleichen Ordner installiert sein wie YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader nicht gefunden. Eventuell besteht ein Problem mit Ihrer YACReader-Installation. + + + + Error + Fehler + + + + Error opening comic with third party reader. + Beim Öffnen des Comics mit dem Drittanbieter-Reader ist ein Fehler aufgetreten. + + + + Library not found + Bibliothek nicht gefunden + + + + The selected folder doesn't contain any library. + Der ausgewählte Ordner enthält keine Bibliothek. + + + + Are you sure? + Sind Sie sicher? + + + + Do you want remove + Möchten Sie entfernen + + + + library? + Bibliothek? + + + + Remove and delete metadata + Entferne und lösche Metadaten + + + + Library info + Informationen zur Bibliothek + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Es gab ein Problem beim Löschen der ausgewählten Comics. Überprüfen Sie bitte die Schreibberechtigung für die ausgewählten Dateien oder Ordner. + + + + Assign comics numbers + Comics Nummern zuweisen + + + + Assign numbers starting in: + Nummern zuweisen, beginnend mit: + + + + Invalid image + Ungültiges Bild + + + + The selected file is not a valid image. + Die ausgewählte Datei ist kein gültiges Bild. + + + + Error saving cover + Fehler beim Speichern des Covers + + + + There was an error saving the cover image. + Beim Speichern des Titelbildes ist ein Fehler aufgetreten. + + + + Error creating the library + Fehler beim Erstellen der Bibliothek + + + + Error updating the library + Fehler beim Updaten der Bibliothek + + + + Error opening the library + Fehler beim Öffnen der Bibliothek + + + + Delete comics + Comics löschen + + + + All the selected comics will be deleted from your disk. Are you sure? + Alle ausgewählten Comics werden von Ihrer Festplatte gelöscht. Sind Sie sicher? + + + + Remove comics + Comics löschen + + + + Comics will only be deleted from the current label/list. Are you sure? + Comics werden nur vom aktuellen Label/der aktuellen Liste gelöscht. Sind Sie sicher? + + + + Library name already exists + Bibliothek-Name bereits vorhanden + + + + There is another library with the name '%1'. + Es gibt bereits eine Bibliothek mit dem Namen '%1'. + + + + LibraryWindowActions + + + Create a new library + Neue Bibliothek erstellen + + + + Open an existing library + Eine vorhandede Bibliothek öffnen + + + + + Export comics info + Comicinfo exportieren + + + + + Import comics info + Importiere Comic-Info + + + + Pack covers + Titelbild-Paket erzeugen + + + + Pack the covers of the selected library + Packe die Titelbilder der ausgewählten Bibliothek in ein Paket + + + + Unpack covers + Titelbilder entpacken + + + + Unpack a catalog + Katalog entpacken + + + + Update library + Bibliothek updaten + + + + Update current library + Aktuelle Bibliothek updaten + + + + Rename library + Bibliothek umbenennen + + + + Rename current library + Aktuelle Bibliothek umbenennen + + + + Remove library + Bibliothek entfernen + + + + Remove current library from your collection + Aktuelle Bibliothek aus der Sammlung entfernen + + + + Rescan library for XML info + Durchsuchen Sie die Bibliothek erneut nach XML-Informationen + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Versucht, in Comic-Dateien eingebettete XML-Informationen zu finden. Sie müssen dies nur tun, wenn die Bibliothek mit 9.8.2 oder früheren Versionen erstellt wurde oder wenn Sie Software von Drittanbietern verwenden, um XML-Informationen in die Dateien einzubetten. + + + + Show library info + Bibliotheksinformationen anzeigen + + + + Show information about the current library + Informationen zur aktuellen Bibliothek anzeigen + + + + Open current comic + Aktuellen Comic öffnen + + + + Open current comic on YACReader + Aktuellen Comic mit YACReader öffnen + + + + Save selected covers to... + Ausgewählte Titelbilder speichern in... + + + + Save covers of the selected comics as JPG files + Titelbilder der ausgewählten Comics als JPG-Datei speichern + + + + + Set as read + Als gelesen markieren + + + + Set comic as read + Comic als gelesen markieren + + + + + Set as unread + Als ungelesen markieren + + + + Set comic as unread + Comic als ungelesen markieren + + + + + manga + Manga + + + + Set issue as manga + Ausgabe als Manga festlegen + + + + + comic + komisch + + + + Set issue as normal + Ausgabe als normal festlegen + + + + western manga + Western-Manga + + + + Set issue as western manga + Ausgabe als Western-Manga festlegen + + + + + web comic + Webcomic + + + + Set issue as web comic + Ausgabe als Webcomic festlegen + + + + + yonkoma + Yonkoma + + + + Set issue as yonkoma + Stellen Sie das Problem als Yonkoma ein + + + + Show/Hide marks + Zeige/Verberge Markierungen + + + + Show or hide read marks + Gelesen-Markierungen anzeigen oder verbergen + + + + Show/Hide recent indicator + Aktuelle Anzeige ein-/ausblenden + + + + Show or hide recent indicator + Aktuelle Anzeige anzeigen oder ausblenden + + + + + Fullscreen mode on/off + Vollbildmodus an/aus + + + + Help, About YACReader + Hilfe, über YACReader + + + + Add new folder + Neuen Ordner erstellen + + + + Add new folder to the current library + Neuen Ordner in der aktuellen Bibliothek erstellen + + + + Delete folder + Ordner löschen + + + + Delete current folder from disk + Aktuellen Ordner von der Festplatte löschen + + + + Select root node + Ursprungsordner auswählen + + + + Expand all nodes + Alle Unterordner anzeigen + + + + Collapse all nodes + Alle Unterordner einklappen + + + + Show options dialog + Zeige den Optionen-Dialog + + + + Show comics server options dialog + Zeige Comic-Server-Optionen-Dialog + + + + + Change between comics views + Zwischen Comic-Anzeigemodi wechseln + + + + Open folder... + Öffne Ordner... + + + + Set as uncompleted + Als nicht gelesen markieren + + + + Set as completed + Als gelesen markieren + + + + Set custom cover + Legen Sie ein benutzerdefiniertes Cover fest + + + + Delete custom cover + Benutzerdefiniertes Cover löschen + + + + western manga (left to right) + Western-Manga (von links nach rechts) + + + + Open containing folder... + Öffne aktuellen Ordner... + + + + Reset comic rating + Comic-Bewertung zurücksetzen + + + + Select all comics + Alle Comics auswählen + + + + Edit + Ändern + + + + Assign current order to comics + Aktuele Sortierung auf Comics anwenden + + + + Update cover + Titelbild updaten + + + + Delete selected comics + Ausgewählte Comics löschen + + + + Delete metadata from selected comics + Metadaten aus ausgewählten Comics löschen + + + + Download tags from Comic Vine + Tags von Comic Vine herunterladen + + + + Focus search line + Suchzeile fokussieren + + + + Focus comics view + Fokus-Comic-Ansicht + + + + Edit shortcuts + Kürzel ändern + + + + &Quit + &Schließen + + + + Update folder + Ordner aktualisieren + + + + Update current folder + Aktuellen Ordner aktualisieren + + + + Scan legacy XML metadata + Scannen Sie ältere XML-Metadaten + + + + Add new reading list + Neue Leseliste hinzufügen + + + + Add a new reading list to the current library + Neue Leseliste zur aktuellen Bibliothek hinzufügen + + + + Remove reading list + Leseliste entfernen + + + + Remove current reading list from the library + Aktuelle Leseliste von der Bibliothek entfernen + + + + Add new label + Neues Label hinzufügen + + + + Add a new label to this library + Neues Label zu dieser Bibliothek hinzufügen + + + + Rename selected list + Ausgewählte Liste umbenennen + + + + Rename any selected labels or lists + Ausgewählte Labels oder Listen umbenennen + + + + Add to... + Hinzufügen zu... + + + + Favorites + Favoriten + + + + Add selected comics to favorites list + Ausgewählte Comics zu Favoriten hinzufügen + + + + LocalComicListModel + + + file name + Dateiname + + + + LogWindow + + Log window + Änderungsprotokoll-Fenster + + + &Pause + Pause + + + &Save + Speichern + + + C&lear + L&öschen + + + &Copy + &Kopieren + + + Level: + Level + + + &Auto scroll + &Automatisches Scrollen + + + + MainWindowViewer + + File + Datei + + + Help + Hilfe + + + Save + Speichern + + + &File + &Datei + + + &Next + &Nächstes + + &Open &Öffnen - Close - Schliessen + Close + Schliessen + + + Open Comic + Comic öffnen + + + Go To + Gehe zu + + + Open image folder + Bilder-Ordner öffnen + + + Set bookmark + Lesezeichen setzen + + + page_%1.jpg + Seite_%1.jpg + + + Switch to double page mode + Zum Doppelseiten-Modus wechseln + + + Save current page + Aktuelle Seite speichern + + + Double page mode + Doppelseiten-Modus + + + Switch Magnifying glass + Vergrößerungsglas wechseln + + + Open Folder + Ordner öffnen + + + Fit Height + Höhe anpassen + + + Comic files + Comic-Dateien + + + Not now + Nicht jetzt + + + Go to previous page + Zur vorherigen Seite gehen + + + Open a comic + Comic öffnen + + + Image files (*.jpg) + Bildateien (*.jpg) + + + Next Comic + Nächster Comic + + + Fit Width + Breite anpassen + + + Options + Optionen + + + Show Info + Info anzeigen + + + Open folder + Ordner öffnen + + + Go to page ... + Gehe zu Seite ... + + + Fit image to width + Bildbreite anpassen + + + &Previous + &Vorherige + + + Go to next page + Zur nächsten Seite gehen + + + Show keyboard shortcuts + Tastenkürzel anzeigen + + + There is a new version available + Neue Version verfügbar + + + Open next comic + Nächsten Comic öffnen + + + Remind me in 14 days + In 14 Tagen erneut erinnern + + + Show bookmarks + Lesezeichen anzeigen + + + Open previous comic + Vorherigen Comic öffnen + + + Rotate image to the left + Bild nach links drehen + + + Fit image to height + Bild an Höhe anpassen + + + Show the bookmarks of the current comic + Lesezeichen für diesen Comic anzeigen + + + Show Dictionary + Wörterbuch anzeigen + + + YACReader options + YACReader Optionen + + + Help, About YACReader + Hilfe, über YACReader + + + Show go to flow + "Go to Flow" anzeigen + + + Previous Comic + Voheriger Comic + + + Show full size + Vollansicht anzeigen + + + Magnifying glass + Vergößerungsglas + + + General + Allgemein + + + Set a bookmark on the current page + Lesezeichen auf dieser Seite setzen + + + Do you want to download the new version? + Möchten Sie die neue Version herunterladen? + + + Rotate image to the right + Bild nach rechts drehen + + + Always on top + Immer Oberste Ansicht + + + New instance + Neuer Fall + + + Open latest comic + Neuesten Comic öffnen + + + Open the latest comic opened in the previous reading session + Öffne den neuesten Comic deiner letzten Sitzung + + + Clear + Löschen + + + Clear open recent list + Lösche Liste zuletzt geöffneter Elemente + + + Fit to page + An Seite anpassen + + + Reset zoom + Zoom zurücksetzen + + + Show zoom slider + Zoomleiste anzeigen + + + Zoom+ + Vergr??ern+ + + + Zoom- + Verkleinern- + + + Double page manga mode + Doppelseiten-Manga-Modus + + + Reverse reading order in double page mode + Umgekehrte Lesereihenfolge im Doppelseiten-Modus + + + Edit shortcuts + Kürzel ändern + + + Open recent + Kürzlich geöffnet + + + Edit + Ändern + + + View + Anzeigen + + + Go + Los + + + Window + Fenster + + + Comics + Comichefte + + + Toggle fullscreen mode + Vollbild-Modus umschalten + + + Hide/show toolbar + Symbolleiste anzeigen/verstecken + + + Size up magnifying glass + Vergrößerungsglas vergrößern + + + Size down magnifying glass + Vergrößerungsglas verkleinern + + + Zoom in magnifying glass + Vergrößerungsglas reinzoomen + + + Zoom out magnifying glass + Vergrößerungsglas rauszoomen + + + Magnifiying glass + Vergrößerungsglas + + + Toggle between fit to width and fit to height + Zwischen Anpassung an Seite und Höhe wechseln + + + Page adjustement + Seitenanpassung + + + Autoscroll down + Automatisches Runterscrollen + + + Autoscroll up + Automatisches Raufscrollen + + + Autoscroll forward, horizontal first + Automatisches Vorwärtsscrollen, horizontal zuerst + + + Autoscroll backward, horizontal first + Automatisches Zurückscrollen, horizontal zuerst + + + Autoscroll forward, vertical first + Automatisches Vorwärtsscrollen, vertikal zuerst + + + Autoscroll backward, vertical first + Automatisches Zurückscrollen, vertikal zuerst + + + Move down + Nach unten + + + Move up + Nach oben + + + Move left + Nach links + + + Move right + Nach rechts + + + Go to the first page + Zur ersten Seite gehen + + + Go to the last page + Zur letzten Seite gehen + + + Reading + Lesend + + + + NoLibrariesWidget + + + You don't have any libraries yet + Sie haben aktuell noch keine Bibliothek + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Sie können eine Bibliothek in jedem beliebigen Ordner erstellen, YACReaderLibrary wird alle Comics und Unterordner von diesem Ordner importieren. Wenn Sie bereits eine Bibliothek erstellt haben, können Sie sie öffnen.</p><p>Vergessen Sie nicht, dass Sie YACReader als eigentsändige Anwendung nutzen können, um Comics auf Ihrem Computer zu lesen.</p> + + + + create your first library + Erstellen Sie Ihre erste Bibliothek + + + + add an existing one + Existierende hinzufügen + + + + NoSearchResultsWidget + + + No results + Keine Ergebnisse + + + + OptionsDialog + + + Gamma + Gammawert + + + + Reset + Zurücksetzen + + + + My comics path + Meine Comics-Pfad + + + + Scaling + Skalierung + + + + Scaling method + Skalierungsmethode + + + + Nearest (fast, low quality) + Am nächsten (schnell, niedrige Qualität) + + + + Bilinear + Bilinear-Filter + + + + Lanczos (better quality) + Lanczos (bessere Qualität) + + + + Image adjustment + Bildanpassung - Open Comic - Comic öffnen + + "Go to flow" size + "Go to flow" Größe - Go To - Gehe zu + + Choose + Auswählen - Open image folder - Bilder-Ordner öffnen + + Image options + Bilderoptionen - Set bookmark - Lesezeichen setzen + + Contrast + Kontrast - page_%1.jpg - Seite_%1.jpg + + + Libraries + Bibliotheken - Switch to double page mode - Zum Doppelseiten-Modus wechseln + + Comic Flow + Comic-Flow - Save current page - Aktuelle Seite speichern + + Grid view + Rasteransicht - Double page mode - Doppelseiten-Modus + + + Appearance + Aussehen - Switch Magnifying glass - Vergrößerungsglas wechseln + + + Options + Optionen - Open Folder - Ordner öffnen + + + Language + Sprache - Fit Height - Höhe anpassen + + + Application language + Anwendungssprache - Comic files - Comic-Dateien + + + System default + Systemstandard - Not now - Nicht jetzt + + Tray icon settings (experimental) + Taskleisten-Einstellungen (experimentell) + + + + Close to tray + In Taskleiste schließen + + + + Start into the system tray + In die Taskleiste starten + + + + Edit Comic Vine API key + Comic Vine API-Schlüssel ändern + + + + Comic Vine API key + Comic Vine API Schlüssel + + + + ComicInfo.xml legacy support + ComicInfo.xml-Legacy-Unterstützung + + + + Import metadata from ComicInfo.xml when adding new comics + Importieren Sie Metadaten aus ComicInfo.xml, wenn Sie neue Comics hinzufügen + + + + Consider 'recent' items added or updated since X days ago + Berücksichtigen Sie „neue“ Elemente, die seit X Tagen hinzugefügt oder aktualisiert wurden + + + + Third party reader + Drittanbieter-Reader + + + + Write {comic_file_path} where the path should go in the command + Schreiben Sie {comic_file_path}, wohin der Pfad im Befehl gehen soll + + + + + Clear + Löschen + + + + Update libraries at startup + Aktualisieren Sie die Bibliotheken beim Start + + + + Try to detect changes automatically + Versuchen Sie, Änderungen automatisch zu erkennen + + + + Update libraries periodically + Aktualisieren Sie die Bibliotheken regelmäßig + + + + Interval: + Intervall: + + + + 30 minutes + 30 Minuten + + + + 1 hour + 1 Stunde + + + + 2 hours + 2 Stunden + + + + 4 hours + 4 Stunden + + + + 8 hours + 8 Stunden + + + + 12 hours + 12 Stunden + + + + daily + täglich + + + + Update libraries at certain time + Aktualisieren Sie Bibliotheken zu einem bestimmten Zeitpunkt + + + + Time: + Zeit: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + WARNUNG! Während Bibliotheksaktualisierungen sind Schreibvorgänge in die Datenbank deaktiviert! +Planen Sie keine Updates, während Sie die App möglicherweise aktiv nutzen. +Bei automatischen Updates blockiert die App einige Aktionen, bis das Update abgeschlossen ist. +Um eine automatische Aktualisierung zu stoppen, tippen Sie auf die Ladeanzeige neben dem Titel „Bibliotheken“. + + + + Modifications detection + Erkennung von Änderungen + + + + Compare the modified date of files when updating a library (not recommended) + Vergleichen Sie das Änderungsdatum von Dateien beim Aktualisieren einer Bibliothek (nicht empfohlen) + + + + Enable background image + Hintergrundbild aktivieren + + + + Opacity level + Deckkraft-Stufe + + + + Blur level + Unschärfe-Stufe + + + + Use selected comic cover as background + Den ausgewählten Comic als Hintergrund verwenden + + + + Restore defautls + Standardwerte wiederherstellen + + + + Background + Hintergrund + + + + Display continue reading banner + Weiterlesen-Banner anzeigen + + + + Display current comic banner + Aktuelles Comic-Banner anzeigen + + + + Continue reading + Weiterlesen + + + + Comics directory + Comics-Verzeichnis + + + + Background color + Hintergrundfarbe + + + + Page Flow + Seitenfluss + + + + + General + Allgemein + + + + Brightness + Helligkeit + + + + + Restart is needed + Neustart erforderlich + + + + Quick Navigation Mode + Schnellnavigations-Modus + + + + Display + Anzeige + + + + Show time in current page information label + Zeit im Informationsetikett der aktuellen Seite anzeigen + + + + Scroll behaviour + Scrollverhalten + + + + Disable scroll animations and smooth scrolling + Scroll-Animationen und sanftes Scrollen deaktivieren + + + + Do not turn page using scroll + Blättern Sie nicht mit dem Scrollen um + + + + Use single scroll step to turn page + Verwenden Sie einen einzelnen Bildlaufschritt, um die Seite umzublättern + + + + Mouse mode + Mausmodus + + + + Only Back/Forward buttons can turn pages + Nur mit den Zurück-/Vorwärts-Tasten können Seiten umgeblättert werden + + + + Use the Left/Right buttons to turn pages. + Verwenden Sie die Links-/Rechts-Tasten, um Seiten umzublättern. + + + + Click left or right half of the screen to turn pages. + Klicken Sie auf die linke oder rechte Hälfte des Bildschirms, um die Seiten umzublättern. + + + + Disable mouse over activation + Aktivierung durch Maus deaktivieren + + + + Fit options + Anpassungsoptionen + + + + Enlarge images to fit width/height + Bilder vergrößern, um sie Breite/Höhe anzupassen + + + + Double Page options + Doppelseiten-Einstellungen + + + + Show covers as single page + Cover als eine Seite darstellen + + + + PropertiesDialog + + + General info + Allgemeine Info + + + + Plot + Inhalt + + + + Authors + Autoren + + + + Publishing + Veröffentlichung + + + + Notes + Notizen + + + + Cover page + Titelbild + + + + Load previous page as cover + Vorherige Seite als Cover laden + + + + Load next page as cover + Nächste Seite als Cover laden + + + + Reset cover to the default image + Cover auf das Standardbild zurücksetzen + + + + Load custom cover image + Laden Sie ein benutzerdefiniertes Titelbild + + + + Series: + Serie: + + + + Title: + Titel: + + + + + + of: + von + + + + Issue number: + Ausgabennummer: + + + + Volume: + Band: + + + + Arc number: + Handlungsbogen Nummer: + + + + Story arc: + Handlung: + + + + alt. number: + alt. Nummer: + + + + Alternate series: + Alternative Serie: + + + + Series Group: + Seriengruppe: + + + + Genre: + Gattung: + + + + Size: + Größe: + + + + Writer(s): + Autor(en): + + + + Penciller(s): + Künstler(Bleistift): + + + + Inker(s): + Künstler(Tinte): + + + + Colorist(s): + Künstler(Farbe): + + + + Letterer(s): + Künstler(Schrift): + + + + Cover Artist(s): + Titelbild-Künstler: + + + + Editor(s): + Herausgeber(n): + + + + Imprint: + Impressum: - Go to previous page - Zur vorherigen Seite gehen + + Day: + Tag: - Open a comic - Comic öffnen + + Month: + Monat: - Image files (*.jpg) - Bildateien (*.jpg) + + Year: + Jahr: - Next Comic - Nächster Comic + + Publisher: + Verlag: - Fit Width - Breite anpassen + + Format: + Formatangabe: - Options - Optionen + + Color/BW: + Farbe/Schwarz-Weiß: - Show Info - Info anzeigen + + Age rating: + Altersangabe: - Open folder - Ordner öffnen + + Type: + Typ: - Go to page ... - Gehe zu Seite ... + + Language (ISO): + Sprache (ISO): - Fit image to width - Bildbreite anpassen + + Synopsis: + Zusammenfassung: - &Previous - &Vorherige + + Characters: + Charaktere: - Go to next page - Zur nächsten Seite gehen + + Teams: + Mannschaften: - Show keyboard shortcuts - Tastenkürzel anzeigen + + Locations: + Standorte: - There is a new version available - Neue Version verfügbar + + Main character or team: + Hauptfigur oder Team: - Open next comic - Nächsten Comic öffnen + + Review: + Rezension: - Remind me in 14 days - In 14 Tagen erneut erinnern + + Notes: + Anmerkungen: - Show bookmarks - Lesezeichen anzeigen + + Tags: + Schlagworte: - Open previous comic - Vorherigen Comic öffnen + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine-Link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ansehen </a> - Rotate image to the left - Bild nach links drehen + + Not found + Nicht gefunden - Fit image to height - Bild an Höhe anpassen + + Comic not found. You should update your library. + Comic nicht gefunden. Sie sollten Ihre Bibliothek updaten. - Show the bookmarks of the current comic - Lesezeichen für diesen Comic anzeigen + + Edit comic information + Comic-Informationen bearbeiten - Show Dictionary - Wörterbuch anzeigen + + Edit selected comics information + Ausgewählte Comic-Informationen bearbeiten - YACReader options - YACReader Optionen + + Invalid cover + Ungültiger Versicherungsschutz - Help, About YACReader - Hilfe, über YACReader + + The image is invalid. + Das Bild ist ungültig. + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer ist die Headless-Version (keine GUI) von YACReaderLibrary. + +Diese Anwendung unterstützt dauerhafte Einstellungen. Um sie einzurichten, bearbeiten Sie diese Datei %1 +Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Dokumentation unter https://raw.githubusercontent.com/YACReader/yareader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + QObject - Show go to flow - "Go to Flow" anzeigen + + 7z lib not found + 7z-Verzeichnis nicht gefunden - Previous Comic - Voheriger Comic + + unable to load 7z lib from ./utils + 7z -erzeichnis kann von ./utils nicht geladen werden - Show full size - Vollansicht anzeigen + + Trace + Verfolgen - Magnifying glass - Vergößerungsglas + + Debug + Fehlersuche - General - Allgemein + + Info + Information - Set a bookmark on the current page - Lesezeichen auf dieser Seite setzen + + Warning + Warnung - Do you want to download the new version? - Möchten Sie die neue Version herunterladen? + + Error + Fehler - Rotate image to the right - Bild nach rechts drehen + + Fatal + Tödlich - Always on top - Immer Oberste Ansicht + + Select custom cover + Wählen Sie ein benutzerdefiniertes Cover - New instance - Neuer Fall + + Images (%1) + Bilder (%1) - Open latest comic - Neuesten Comic öffnen + + The file could not be read or is not valid JSON. + Die Datei konnte nicht gelesen werden oder ist kein gültiges JSON. - Open the latest comic opened in the previous reading session - Öffne den neuesten Comic deiner letzten Sitzung + + This theme is for %1, not %2. + Dieses Thema ist für %1, nicht für %2. - Clear - Löschen + + Libraries + Bibliotheken - Clear open recent list - Lösche Liste zuletzt geöffneter Elemente + + Folders + Ordner - Fit to page - An Seite anpassen + + Reading Lists + Leselisten + + + QsLogging::LogWindowModel - Reset zoom - Zoom zurücksetzen + Time + Zeit - Show zoom slider - Zoomleiste anzeigen + Level + Stufe - Zoom+ - Zoom+ + Message + NAchricht + + + QsLogging::Window - Zoom- - Zoom- + &Pause + Pause - Double page manga mode - Doppelseiten-Manga-Modus + &Resume + &Weiter - Reverse reading order in double page mode - Umgekehrte Lesereihenfolge im Doppelseiten-Modus + Save log + Protokoll speichern - Edit shortcuts - Kürzel ändern + Log file (*.log) + Protokoll-Datei (*.log) + + + RenameLibraryDialog - Open recent - Kürzlich geöffnet + + New Library Name : + Neuer Bibliotheksname : - Edit - Ändern + + Rename + Umbenennen - View - Anzeigen + + Cancel + Abbrechen - Go - Los + + Rename current library + Aktuelle Bibliothek umbenennen + + + ScraperResultsPaginator - Window - Fenster + + Number of volumes found : %1 + Anzahl der gefundenen Bände: %1 - Comics - Comics + + + page %1 of %2 + Seite %1 von %2 - Toggle fullscreen mode - Vollbild-Modus umschalten + + Number of %1 found : %2 + Anzahl von %1 gefunden : %2 + + + SearchSingleComic - Hide/show toolbar - Symbolleiste anzeigen/verstecken + + Please provide some additional information for this comic. + Bitte stellen Sie weitere Informationen zur Verfügung. - Size up magnifying glass - Vergrößerungsglas vergrößern + + Series: + Serie: - Size down magnifying glass - Vergrößerungsglas verkleinern + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Verwenden Sie die Suche nach exakten Übereinstimmungen. Deaktivieren Sie diese Option, wenn Sie Bände finden möchten, die mit einigen Wörtern im Namen übereinstimmen. + + + SearchVolume - Zoom in magnifying glass - Vergrößerungsglas reinzoomen + + Please provide some additional information. + Bitte stellen Sie weitere Informationen zur Verfügung. - Zoom out magnifying glass - Vergrößerungsglas rauszoomen + + Series: + Serie: - Magnifiying glass - Vergrößerungsglas + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Verwenden Sie die Suche nach exakten Übereinstimmungen. Deaktivieren Sie diese Option, wenn Sie Bände finden möchten, die mit einigen Wörtern im Namen übereinstimmen. + + + SelectComic - Toggle between fit to width and fit to height - Zwischen Anpassung an Seite und Höhe wechseln + + Please, select the right comic info. + Bitte wählen Sie die korrekte Comic-Information aus. - Page adjustement - Seitenanpassung + + comics + Comics - Autoscroll down - Automatisches Runterscrollen + + loading cover + Titelbild wird geladen - Autoscroll up - Automatisches Raufscrollen + + loading description + Beschreibung wird laden - Autoscroll forward, horizontal first - Automatisches Vorwärtsscrollen, horizontal zuerst + + comic description unavailable + Comic-Beschreibung nicht verfügbar + + + SelectVolume - Autoscroll backward, horizontal first - Automatisches Zurückscrollen, horizontal zuerst + + Please, select the right series for your comic. + Bitte wählen Sie die korrekte Serie für Ihre Comics aus. - Autoscroll forward, vertical first - Automatisches Vorwärtsscrollen, vertikal zuerst + + Filter: + Filteroption: - Autoscroll backward, vertical first - Automatisches Zurückscrollen, vertikal zuerst + + volumes + Bände - Move down - Nach unten + + Nothing found, clear the filter if any. + Nichts gefunden. Löschen Sie ggf. den Filter. - Move up - Nach oben + + loading cover + Titelbild wird geladen - Move left - Nach links + + loading description + Beschreibung wird laden - Move right - Nach rechts + + volume description unavailable + Bandbeschreibung nicht verfügbar + + + SeriesQuestion - Go to the first page - Zur ersten Seite gehen + + You are trying to get information for various comics at once, are they part of the same series? + Sie versuchen, Informationen zu mehreren Comics gleichzeitig zu laden, sind diese Teil einer Serie? - Go to the last page - Zur letzten Seite gehen + + yes + Ja - Reading - Lesend + + no + Nein - OptionsDialog + ServerConfigDialog - - Gamma - Gamma + + set port + Anschluss wählen - - Reset - Zurücksetzen + + Server connectivity information + Serveranschluss-Information - - My comics path - Meine Comics-Pfad + + Scan it! + Durchsuchen! - - Image adjustment - Bildanpassung + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader ist für iOS- und Android-Geräte verfügbar.<br/>Entdecken Sie es für <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> oder <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - - "Go to flow" size - "Go to flow" Größe + + Choose an IP address + IP-Adresse auswählen - - Choose - Auswählen + + Port + Anschluss - - Image options - Bilderoptionen + + enable the server + Server aktivieren + + + ShortcutsDialog - - Contrast - Kontrast + Close + Schliessen - - Options - Optionen + YACReader keyboard shortcuts + YACReader Tastaturkürzel - - Comics directory - Comics-Verzeichnis + Keyboard Shortcuts + Tastaturkürzel + + + SortVolumeComics - - Background color - Hintergrundfarbe + + Please, sort the list of comics on the left until it matches the comics' information. + Sortieren Sie bitte die Comic-Informationen links, bis die Informationen mit den Comics übereinstimmen. - - Page Flow - Page Flow + + sort comics to match comic information + Comics laut Comic-Information sortieren - - General - Allgemein + + issues + Ausgaben - - Brightness - Helligkeit + + remove selected comics + Ausgewählte Comics entfernen - - Restart is needed - Neustart erforderlich + + restore all removed comics + Alle entfernten Comics wiederherstellen + + + + ThemeEditorDialog + + + Theme Editor + Theme-Editor - - Quick Navigation Mode - Schnellnavigations-Modus + + + + + + + + + - + - + + + + i + ich - - Display - + + Expand all + Alles erweitern - - Show time in current page information label - + + Collapse all + Alles einklappen - - Scroll behaviour - + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Halten Sie gedrückt, um den ausgewählten Wert in der Benutzeroberfläche zu blinken (Magenta / umgeschaltet / 0↔10). Releases stellen das Original wieder her. - - Disable scroll animations and smooth scrolling - + + Search… + Suchen… - - Do not turn page using scroll - + + Light + Licht - - Use single scroll step to turn page - + + Dark + Dunkel - - Mouse mode - + + ID: + AUSWEIS: - - Only Back/Forward buttons can turn pages - + + Display name: + Anzeigename: - - Use the Left/Right buttons to turn pages. - + + Variant: + Variante: - - Click left or right half of the screen to turn pages. - + + Theme info + Themeninfo - - Disable mouse over activation - Aktivierung durch Maus deaktivieren + + Parameter + Parameterwert - - Fit options - Anpassungsoptionen + + Value + Wert - - Enlarge images to fit width/height - Bilder vergrößern, um sie Breite/Höhe anzupassen + + Save and apply + Speichern und bewerben - - Double Page options - Doppelseiten-Einstellungen + + Export to file... + In Datei exportieren... - - Show covers as single page - Cover als eine Seite darstellen + + Load from file... + Aus Datei laden... - - - QObject - - 7z lib not found - 7z-Verzeichnis nicht gefunden + + Close + Schliessen - - unable to load 7z lib from ./utils - 7z -erzeichnis kann von ./utils nicht geladen werden + + Double-click to edit color + Doppelklicken Sie, um die Farbe zu bearbeiten - - Trace - Verfolgen + + + + + + + true + WAHR - - Debug - Fehlersuche + + + + + false + FALSCH - - Info - Information + + Double-click to toggle + Zum Umschalten doppelklicken - - Warning - Warnung + + Double-click to edit value + Doppelklicken Sie, um den Wert zu bearbeiten - - Error - Error + + + + Edit: %1 + Bearbeiten: %1 - - Fatal - Fatal + + Save theme + Thema speichern - - Select custom cover - + + + JSON files (*.json);;All files (*) + JSON-Dateien (*.json);;Alle Dateien (*) - - Images (%1) - + + Save failed + Speichern fehlgeschlagen - - - QsLogging::LogWindowModel - - Time - Zeit + + Could not open file for writing: +%1 + Die Datei konnte nicht zum Schreiben geöffnet werden: +%1 - - Level - Level + + Load theme + Theme laden - - Message - NAchricht + + + + Load failed + Das Laden ist fehlgeschlagen - - - QsLogging::Window - - &Pause - &Pause + + Could not open file: +%1 + Datei konnte nicht geöffnet werden: +%1 - - &Resume - &Weiter + + Invalid JSON: +%1 + Ungültiger JSON: +%1 - - Save log - Protokoll speichern + + Expected a JSON object. + Es wurde ein JSON-Objekt erwartet. + + + TitleHeader - - Log file (*.log) - Protokoll-Datei (*.log) + + SEARCH + Suchen - ShortcutsDialog + UpdateLibraryDialog - Close - Schliessen + + Updating.... + Aktualisierung.... - YACReader keyboard shortcuts - YACReader Tastaturkürzel + + Cancel + Abbrechen - Keyboard Shortcuts - Tastaturkürzel + + Update library + Bibliothek updaten Viewer - + Page not available! Seite nicht verfügbar! - - + + Press 'O' to open comic. 'O' drücken, um Comic zu öffnen. - + Error opening comic Fehler beim Öffnen des Comics - + Cover! Titelseite! - + CRC Error CRC Fehler - + Comic not found Comic nicht gefunden - + Not found Nicht gefunden - + Last page! Letzte Seite! - + Loading...please wait! Ladevorgang... Bitte warten! + + VolumeComicsModel + + + title + Titel + + + + VolumesModel + + + year + Jahr + + + + issues + Ausgaben + + + + publisher + Herausgeber + + + + YACReader3DFlowConfigWidget + + + Presets: + Voreinstellungen: + + + + Classic look + Klassische Ansicht + + + + Stripe look + Streifen-Ansicht + + + + Overlapped Stripe look + Überlappende Streifen-Ansicht + + + + Modern look + Moderne Ansicht + + + + Roulette look + Zufalls-Ansicht + + + + Show advanced settings + Zeige erweiterte Einstellungen + + + + Custom: + Benutzerdefiniert: + + + + View angle + Anzeige-Winkel + + + + Position + Lage + + + + Cover gap + Titelbild-Abstand + + + + Central gap + Mittiger Abstand + + + + Zoom + Vergrößern + + + + Y offset + Y-Anpassung + + + + Z offset + Z-Anpassung + + + + Cover Angle + Titelbild Ansichtswinkel + + + + Visibility + Sichtbarkeit + + + + Light + Licht + + + + Max angle + Maximaler Winkel + + + + Low Performance + Niedrige Leistung + + + + High Performance + Hohe Leistung + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Benutze VSync (verbessert die Bildqualität im Vollanzeigemodus, schlechtere Leistung) + + + + Performance: + Leistung: + + YACReader::MainWindowViewer - + &Open - &Öffnen + &Öffnen - + Open a comic - Comic öffnen + Comic öffnen - + New instance - Neuer Fall + Neuer Fall - + Open Folder - Ordner öffnen + Ordner öffnen - + Open image folder - Bilder-Ordner öffnen + Bilder-Ordner öffnen - + Open latest comic - Neuesten Comic öffnen + Neuesten Comic öffnen - + Open the latest comic opened in the previous reading session - Öffne den neuesten Comic deiner letzten Sitzung + Öffne den neuesten Comic deiner letzten Sitzung - + Clear - Löschen + Löschen - + Clear open recent list - Lösche Liste zuletzt geöffneter Elemente + Lösche Liste zuletzt geöffneter Elemente - + Save - Speichern + Speichern - + Save current page - Aktuelle Seite speichern + Aktuelle Seite speichern Previous Comic - Voheriger Comic + Voheriger Comic - - - + + + Open previous comic - Vorherigen Comic öffnen + Vorherigen Comic öffnen - + Next Comic - Nächster Comic + Nächster Comic - - - + + + Open next comic - Nächsten Comic öffnen + Nächsten Comic öffnen - + &Previous - &Vorherige + &Vorherige - - - + + + Go to previous page - Zur vorherigen Seite gehen + Zur vorherigen Seite gehen - + &Next - &Nächstes + &Nächstes - - - + + + Go to next page - Zur nächsten Seite gehen + Zur nächsten Seite gehen - + Fit Height - Höhe anpassen + Höhe anpassen - + Fit image to height - Bild an Höhe anpassen + Bild an Höhe anpassen - + Fit Width - Breite anpassen + Breite anpassen - + Fit image to width - Bildbreite anpassen + Bildbreite anpassen - + Show full size - Vollansicht anzeigen + Vollansicht anzeigen - + Fit to page - An Seite anpassen + An Seite anpassen + + + + Continuous scroll + Kontinuierliches Scrollen + + + + Switch to continuous scroll mode + Wechseln Sie in den kontinuierlichen Bildlaufmodus - + Reset zoom - Zoom zurücksetzen + Zoom zurücksetzen - + Show zoom slider - Zoomleiste anzeigen + Zoomleiste anzeigen - + Zoom+ - Zoom+ + Vergr??ern+ - + Zoom- - Zoom- + Verkleinern- - + Rotate image to the left - Bild nach links drehen + Bild nach links drehen - + Rotate image to the right - Bild nach rechts drehen + Bild nach rechts drehen - + Double page mode - Doppelseiten-Modus + Doppelseiten-Modus - + Switch to double page mode - Zum Doppelseiten-Modus wechseln + Zum Doppelseiten-Modus wechseln - + Double page manga mode - Doppelseiten-Manga-Modus + Doppelseiten-Manga-Modus - + Reverse reading order in double page mode - Umgekehrte Lesereihenfolge im Doppelseiten-Modus + Umgekehrte Lesereihenfolge im Doppelseiten-Modus - + Go To - Gehe zu + Gehe zu - + Go to page ... - Gehe zu Seite ... + Gehe zu Seite ... - + Options - Optionen + Optionen - + YACReader options - YACReader Optionen + YACReader Optionen - - + + Help - Hilfe + Hilfe - + Help, About YACReader - Hilfe, über YACReader + Hilfe, über YACReader - + Magnifying glass - Vergößerungsglas + Vergößerungsglas - + Switch Magnifying glass - Vergrößerungsglas wechseln + Vergrößerungsglas wechseln - + Set bookmark - Lesezeichen setzen + Lesezeichen setzen - + Set a bookmark on the current page - Lesezeichen auf dieser Seite setzen + Lesezeichen auf dieser Seite setzen - + Show bookmarks - Lesezeichen anzeigen + Lesezeichen anzeigen - + Show the bookmarks of the current comic - Lesezeichen für diesen Comic anzeigen + Lesezeichen für diesen Comic anzeigen - + Show keyboard shortcuts - Tastenkürzel anzeigen + Tastenkürzel anzeigen - + Show Info - Info anzeigen + Info anzeigen - + Close - + Schliessen - + Show Dictionary - Wörterbuch anzeigen + Wörterbuch anzeigen - + Show go to flow - "Go to Flow" anzeigen + "Go to Flow" anzeigen - + Edit shortcuts - + Kürzel ändern - + &File - &Datei + &Datei - - + + Open recent - Kürzlich geöffnet + Kürzlich geöffnet - + File - Datei + Datei - + Edit - Ändern + Ändern - + View - Anzeigen + Anzeigen - + Go - Los + Los - + Window - Fenster + Fenster - - - + + + Open Comic - Comic öffnen + Comic öffnen - - - + + + Comic files - Comic-Dateien + Comic-Dateien - + Open folder - Ordner öffnen + Ordner öffnen - + page_%1.jpg - Seite_%1.jpg + Seite_%1.jpg - + Image files (*.jpg) - Bildateien (*.jpg) + Bildateien (*.jpg) + Comics - Comics + Comichefte Toggle fullscreen mode - Vollbild-Modus umschalten + Vollbild-Modus umschalten Hide/show toolbar - Symbolleiste anzeigen/verstecken + Symbolleiste anzeigen/verstecken + General - Allgemein + Allgemein Size up magnifying glass - Vergrößerungsglas vergrößern + Vergrößerungsglas vergrößern Size down magnifying glass - Vergrößerungsglas verkleinern + Vergrößerungsglas verkleinern Zoom in magnifying glass - Vergrößerungsglas reinzoomen + Vergrößerungsglas reinzoomen Zoom out magnifying glass - Vergrößerungsglas rauszoomen + Vergrößerungsglas rauszoomen Reset magnifying glass - + Lupe zurücksetzen + Magnifiying glass - Vergrößerungsglas + Vergrößerungsglas Toggle between fit to width and fit to height - Zwischen Anpassung an Seite und Höhe wechseln + Zwischen Anpassung an Seite und Höhe wechseln + Page adjustement - Seitenanpassung + Seitenanpassung - + Autoscroll down - Automatisches Runterscrollen + Automatisches Runterscrollen - + Autoscroll up - Automatisches Raufscrollen + Automatisches Raufscrollen - + Autoscroll forward, horizontal first - Automatisches Vorwärtsscrollen, horizontal zuerst + Automatisches Vorwärtsscrollen, horizontal zuerst - + Autoscroll backward, horizontal first - Automatisches Zurückscrollen, horizontal zuerst + Automatisches Zurückscrollen, horizontal zuerst - + Autoscroll forward, vertical first - Automatisches Vorwärtsscrollen, vertikal zuerst + Automatisches Vorwärtsscrollen, vertikal zuerst - + Autoscroll backward, vertical first - Automatisches Zurückscrollen, vertikal zuerst + Automatisches Zurückscrollen, vertikal zuerst - + Move down - Nach unten + Nach unten - + Move up - Nach oben + Nach oben - + Move left - Nach links + Nach links - + Move right - Nach rechts + Nach rechts - + Go to the first page - Zur ersten Seite gehen + Zur ersten Seite gehen - + Go to the last page - Zur letzten Seite gehen + Zur letzten Seite gehen - + Offset double page to the left - + Doppelseite nach links versetzt - + Offset double page to the right - + Doppelseite nach rechts versetzt - + + Reading - Lesend + Lesend - + There is a new version available - Neue Version verfügbar + Neue Version verfügbar - + Do you want to download the new version? - Möchten Sie die neue Version herunterladen? + Möchten Sie die neue Version herunterladen? - + Remind me in 14 days - In 14 Tagen erneut erinnern + In 14 Tagen erneut erinnern - + Not now - Nicht jetzt + Nicht jetzt + + + + YACReader::TrayIconController + + + &Restore + &Wiederherstellen + + + + Systray + Taskleiste + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary wird im Hintergrund weiterlaufen. Um das Programm zu schließen, wählen Sie <b>Schließen</b> im Kontextmenü des Taskleisten-Symbols. YACReader::WhatsNewDialog - Close - Schließen + Schließen @@ -1411,172 +4115,152 @@ YACReaderFlowConfigWidget - CoverFlow look - Tielseiten Ansicht + Tielseiten Ansicht - How to show covers: - Titelseiten Anzeigeoptionen: + Titelseiten Anzeigeoptionen: - Stripe look - Streifen-Ansicht + Streifen-Ansicht - Overlapped Stripe look - Überlappende Streifen-Ansicht + Überlappende Streifen-Ansicht YACReaderGLFlowConfigWidget - Zoom - Vergrößern + Vergrößern - Light - Licht + Licht - Show advanced settings - Zeige erweiterte Einstellungen + Zeige erweiterte Einstellungen - Roulette look - Zufalls-Ansicht + Zufalls-Ansicht - Cover Angle - Titelbild Ansichtswinkel + Titelbild Ansichtswinkel - Stripe look - Streifen-Ansicht + Streifen-Ansicht - Position - Position + Lage - Z offset - Z-Anpassung + Z-Anpassung - Y offset - Y-Anpassung + Y-Anpassung - Central gap - Mittiger Abstand + Mittiger Abstand - Presets: - Voreinstellungen: + Voreinstellungen: - Overlapped Stripe look - Überlappende Streifen-Ansicht + Überlappende Streifen-Ansicht - Modern look - Moderne Ansicht + Moderne Ansicht - View angle - Anzeige-Winkel + Anzeige-Winkel - Max angle - Maximaler Winkel + Maximaler Winkel - Custom: - Benutzerdefiniert: + Benutzerdefiniert: - Classic look - Klassische Ansicht + Klassische Ansicht - Cover gap - Titelbild-Abstand + Titelbild-Abstand - High Performance - Hohe Leistung + Hohe Leistung - Performance: - Leistung: + Leistung: - Use VSync (improve the image quality in fullscreen mode, worse performance) - Benutze VSync (verbessert die Bildqualität im Vollanzeigemodus, schlechtere Leistung) + Benutze VSync (verbessert die Bildqualität im Vollanzeigemodus, schlechtere Leistung) - Visibility - Sichtbarkeit + Sichtbarkeit - Low Performance - Niedrige Leistung + Niedrige Leistung YACReaderOptionsDialog - + Save Speichern - Use hardware acceleration (restart needed) - Nutze Hardwarebeschleunigung (Neustart erforderlich) + Nutze Hardwarebeschleunigung (Neustart erforderlich) - + Cancel Abbrechen - + Edit shortcuts Kürzel bearbeiten - + Shortcuts Kürzel + + YACReaderSearchLineEdit + + + type to search + tippen, um zu suchen + + YACReaderSlider @@ -1588,23 +4272,23 @@ YACReaderTranslator - + clear Löschen - + Service not available Service nicht verfügbar - - + + Translation Übersetzung - + YACReader translator YACReader Übersetzer diff --git a/YACReader/yacreader_en.ts b/YACReader/yacreader_en.ts index bd065a64c..819f47c6e 100644 --- a/YACReader/yacreader_en.ts +++ b/YACReader/yacreader_en.ts @@ -6,7 +6,197 @@ None - + None + + + + AddLabelDialog + + + Label name: + Label name: + + + + Choose a color: + Choose a color: + + + + accept + accept + + + + cancel + cancel + + + + AddLibraryDialog + + + Comics folder : + Comics folder : + + + + Library name : + Library name : + + + + Add + Add + + + + Cancel + Cancel + + + + Add an existing library + Add an existing library + + + + ApiKeyDialog + + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + + + + Paste here your Comic Vine API key + Paste here your Comic Vine API key + + + + Accept + Accept + + + + Cancel + Cancel + + + + AppearanceTabWidget + + + Color scheme + Color scheme + + + + System + System + + + + Light + Light + + + + Dark + Dark + + + + Custom + Custom + + + + Remove + Remove + + + + Remove this user-imported theme + Remove this user-imported theme + + + + Light: + Light: + + + + Dark: + Dark: + + + + Custom: + Custom: + + + + Import theme... + Import theme... + + + + Theme + Theme + + + + Theme editor + Theme editor + + + + Open Theme Editor... + Open Theme Editor... + + + + Theme editor error + Theme editor error + + + + The current theme JSON could not be loaded. + The current theme JSON could not be loaded. + + + + Import theme + Import theme + + + + JSON files (*.json);;All files (*) + JSON files (*.json);;All files (*) + + + + Could not import theme from: +%1 + Could not import theme from: +%1 + + + + Could not import theme from: +%1 + +%2 + Could not import theme from: +%1 + +%2 + + + + Import failed + Import failed @@ -14,23 +204,217 @@ Lastest Page - + Lastest Page Close - + Close Click on any image to go to the bookmark - + Click on any image to go to the bookmark Loading... - + Loading... + + + + ClassicComicsView + + + Hide comic flow + Hide comic flow + + + + ComicModel + + + yes + yes + + + + no + no + + + + Title + Title + + + + File Name + File Name + + + + Pages + Pages + + + + Size + Size + + + + Read + Read + + + + Current Page + Current Page + + + + Publication Date + Publication Date + + + + Rating + Rating + + + + Series + Series + + + + Volume + Volume + + + + Story Arc + Story Arc + + + + ComicVineDialog + + + skip + skip + + + + back + back + + + + next + next + + + + search + search + + + + close + close + + + + + comic %1 of %2 - %3 + comic %1 of %2 - %3 + + + + + + Looking for volume... + Looking for volume... + + + + %1 comics selected + %1 comics selected + + + + Error connecting to ComicVine + Error connecting to ComicVine + + + + + Retrieving tags for : %1 + Retrieving tags for : %1 + + + + Retrieving volume info... + Retrieving volume info... + + + + Looking for comic... + Looking for comic... + + + + ContinuousPageWidget + + + Loading page %1 + Loading page %1 + + + + CreateLibraryDialog + + + Comics folder : + Comics folder : + + + + Library Name : + Library Name : + + + + Create + Create + + + + Cancel + Cancel + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + + + + Create new library + Create new library + + + + Path not found + Path not found + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder @@ -38,27 +422,145 @@ Restore defaults - + Restore defaults To change a shortcut, double click in the key combination and type the new keys. - + To change a shortcut, double click in the key combination and type the new keys. Shortcuts settings - + Shortcuts settings - + Shortcut in use - + Shortcut in use - + The shortcut "%1" is already assigned to other function - + The shortcut "%1" is already assigned to other function + + + + EmptyFolderWidget + + + This folder doesn't contain comics yet + This folder doesn't contain comics yet + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + This label doesn't contain comics yet + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + This reading list does not contain any comics yet + + + + EmptySpecialListWidget + + + No favorites + No favorites + + + + You are not reading anything yet, come on!! + You are not reading anything yet, come on!! + + + + There are no recent comics! + There are no recent comics! + + + + ExportComicsInfoDialog + + + Output file : + Output file : + + + + Create + Create + + + + Cancel + Cancel + + + + Export comics info + Export comics info + + + + Destination database name + Destination database name + + + + Problem found while writing + Problem found while writing + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + + + + ExportLibraryDialog + + + Output folder : + Output folder : + + + + Create + Create + + + + Cancel + Cancel + + + + Create covers package + Create covers package + + + + Problem found while writing + Problem found while writing + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + + + + Destination directory + Destination directory @@ -66,22 +568,22 @@ CRC error on page (%1): some of the pages will not be displayed correctly - + CRC error on page (%1): some of the pages will not be displayed correctly Unknown error opening the file - + Unknown error opening the file 7z not found - + 7z not found Format not supported - + Format not supported @@ -89,899 +591,3011 @@ Page : - + Page : Go To - + Go To Cancel - + Cancel + + + + + Total pages : + Total pages : + + + + Go to... + Go to... + + + + GoToFlowToolBar + + + Page : + Page : + + + + GridComicsView + + + Show info + Show info + + + + HelpAboutDialog + + + About + About + + + + Help + Help + + + + System info + System info + + + + ImportComicsInfoDialog + + + Import comics info + Import comics info + + + + Info database location : + Info database location : + + + + Import + Import + + + + Cancel + Cancel + + + + Comics info file (*.ydb) + Comics info file (*.ydb) + + + + ImportLibraryDialog + + + Library Name : + Library Name : + + + + Package location : + Package location : + + + + Destination folder : + Destination folder : + + + + Unpack + Unpack + + + + Cancel + Cancel + + + + Extract a catalog + Extract a catalog + + + + Compresed library covers (*.clc) + Compresed library covers (*.clc) + + + + ImportWidget + + + stop + stop + + + + Some of the comics being added... + Some of the comics being added... + + + + Importing comics + Importing comics + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + + + + Updating the library + Updating the library + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + + + + Upgrading the library + Upgrading the library + + + + <p>The current library is being upgraded, please wait.</p> + <p>The current library is being upgraded, please wait.</p> + + + + Scanning the library + Scanning the library + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + + + + LibraryWindow + + + YACReader Library + YACReader Library + + + + + + comic + comic + + + + + + manga + manga + + + + + + western manga (left to right) + western manga (left to right) + + + + + + web comic + web comic + + + + + + 4koma (top to botom) + 4koma (top to botom) + + + + + + + Set type + Set type + + + + Library + Library + + + + Folder + Folder + + + + Comic + Comic + + + + Upgrade failed + Upgrade failed + + + + There were errors during library upgrade in: + There were errors during library upgrade in: + + + + Update needed + Update needed + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + + + + Download new version + Download new version + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + This library was created with a newer version of YACReaderLibrary. Download the new version now? + + + + Library not available + Library not available + + + + Library '%1' is no longer available. Do you want to remove it? + Library '%1' is no longer available. Do you want to remove it? + + + + Old library + Old library + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + + + + + Copying comics... + Copying comics... + + + + + Moving comics... + Moving comics... + + + + Add new folder + Add new folder + + + + Folder name: + Folder name: + + + + No folder selected + No folder selected + + + + Please, select a folder first + Please, select a folder first + + + + Error in path + Error in path + + + + There was an error accessing the folder's path + There was an error accessing the folder's path + + + + Delete folder + Delete folder + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + The selected folder and all its contents will be deleted from your disk. Are you sure? + + + + + Unable to delete + Unable to delete + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + + + + Add new reading lists + Add new reading lists + + + + + List name: + List name: + + + + Delete list/label + Delete list/label + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + + + + Rename list name + Rename list name + + + + Open folder... + Open folder... + + + + Update folder + Update folder + + + + Rescan library for XML info + Rescan library for XML info + + + + Set as uncompleted + Set as uncompleted + + + + Set as completed + Set as completed + + + + Set as read + Set as read + + + + + Set as unread + Set as unread + + + + Set custom cover + Set custom cover + + + + Delete custom cover + Delete custom cover + + + + Save covers + Save covers + + + + You are adding too many libraries. + You are adding too many libraries. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + + + + + YACReader not found + YACReader not found + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader not found. There might be a problem with your YACReader installation. + + + + Error + Error + + + + Error opening comic with third party reader. + Error opening comic with third party reader. + + + + Library not found + Library not found + + + + The selected folder doesn't contain any library. + The selected folder doesn't contain any library. + + + + Are you sure? + Are you sure? + + + + Do you want remove + Do you want remove + + + + library? + library? + + + + Remove and delete metadata + Remove and delete metadata + + + + Library info + Library info + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + + + + Assign comics numbers + Assign comics numbers + + + + Assign numbers starting in: + Assign numbers starting in: + + + + Invalid image + Invalid image + + + + The selected file is not a valid image. + The selected file is not a valid image. + + + + Error saving cover + Error saving cover + + + + There was an error saving the cover image. + There was an error saving the cover image. + + + + Error creating the library + Error creating the library + + + + Error updating the library + Error updating the library + + + + Error opening the library + Error opening the library + + + + Delete comics + Delete comics + + + + All the selected comics will be deleted from your disk. Are you sure? + All the selected comics will be deleted from your disk. Are you sure? + + + + Remove comics + Remove comics + + + + Comics will only be deleted from the current label/list. Are you sure? + Comics will only be deleted from the current label/list. Are you sure? + + + + Library name already exists + Library name already exists + + + + There is another library with the name '%1'. + There is another library with the name '%1'. + + + + LibraryWindowActions + + + Create a new library + Create a new library + + + + Open an existing library + Open an existing library + + + + + Export comics info + Export comics info + + + + + Import comics info + Import comics info + + + + Pack covers + Pack covers + + + + Pack the covers of the selected library + Pack the covers of the selected library + + + + Unpack covers + Unpack covers + + + + Unpack a catalog + Unpack a catalog + + + + Update library + Update library + + + + Update current library + Update current library + + + + Rename library + Rename library + + + + Rename current library + Rename current library + + + + Remove library + Remove library + + + + Remove current library from your collection + Remove current library from your collection + + + + Rescan library for XML info + Rescan library for XML info + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + + + + Show library info + Show library info + + + + Show information about the current library + Show information about the current library + + + + Open current comic + Open current comic + + + + Open current comic on YACReader + Open current comic on YACReader + + + + Save selected covers to... + Save selected covers to... + + + + Save covers of the selected comics as JPG files + Save covers of the selected comics as JPG files + + + + + Set as read + Set as read + + + + Set comic as read + Set comic as read + + + + + Set as unread + Set as unread + + + + Set comic as unread + Set comic as unread + + + + + manga + manga + + + + Set issue as manga + Set issue as manga + + + + + comic + comic + + + + Set issue as normal + Set issue as normal + + + + western manga + western manga + + + + Set issue as western manga + Set issue as western manga + + + + + web comic + web comic + + + + Set issue as web comic + Set issue as web comic + + + + + yonkoma + yonkoma + + + + Set issue as yonkoma + Set issue as yonkoma + + + + Show/Hide marks + Show/Hide marks + + + + Show or hide read marks + Show or hide read marks + + + + Show/Hide recent indicator + Show/Hide recent indicator + + + + Show or hide recent indicator + Show or hide recent indicator + + + + + Fullscreen mode on/off + Fullscreen mode on/off + + + + Help, About YACReader + Help, About YACReader + + + + Add new folder + Add new folder + + + + Add new folder to the current library + Add new folder to the current library + + + + Delete folder + Delete folder + + + + Delete current folder from disk + Delete current folder from disk + + + + Select root node + Select root node + + + + Expand all nodes + Expand all nodes + + + + Collapse all nodes + Collapse all nodes + + + + Show options dialog + Show options dialog + + + + Show comics server options dialog + Show comics server options dialog + + + + + Change between comics views + Change between comics views + + + + Open folder... + Open folder... + + + + Set as uncompleted + Set as uncompleted + + + + Set as completed + Set as completed + + + + Set custom cover + Set custom cover + + + + Delete custom cover + Delete custom cover + + + + western manga (left to right) + western manga (left to right) + + + + Open containing folder... + Open containing folder... + + + + Reset comic rating + Reset comic rating + + + + Select all comics + Select all comics + + + + Edit + Edit + + + + Assign current order to comics + Assign current order to comics + + + + Update cover + Update cover + + + + Delete selected comics + Delete selected comics + + + + Delete metadata from selected comics + Delete metadata from selected comics + + + + Download tags from Comic Vine + Download tags from Comic Vine + + + + Focus search line + Focus search line + + + + Focus comics view + Focus comics view + + + + Edit shortcuts + Edit shortcuts + + + + &Quit + &Quit + + + + Update folder + Update folder + + + + Update current folder + Update current folder + + + + Scan legacy XML metadata + Scan legacy XML metadata + + + + Add new reading list + Add new reading list + + + + Add a new reading list to the current library + Add a new reading list to the current library + + + + Remove reading list + Remove reading list + + + + Remove current reading list from the library + Remove current reading list from the library + + + + Add new label + Add new label + + + + Add a new label to this library + Add a new label to this library + + + + Rename selected list + Rename selected list + + + + Rename any selected labels or lists + Rename any selected labels or lists + + + + Add to... + Add to... + + + + Favorites + Favorites + + + + Add selected comics to favorites list + Add selected comics to favorites list + + + + LocalComicListModel + + + file name + file name + + + + NoLibrariesWidget + + + You don't have any libraries yet + You don't have any libraries yet + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + + + + create your first library + create your first library + + + + add an existing one + add an existing one + + + + NoSearchResultsWidget + + + No results + No results + + + + OptionsDialog + + + "Go to flow" size + "Go to flow" size + + + + My comics path + My comics path + + + + Background color + Background color + + + + Choose + Choose + + + + Quick Navigation Mode + Quick Navigation Mode + + + + Disable mouse over activation + Disable mouse over activation + + + + Scaling + Scaling + + + + Scaling method + Scaling method + + + + Nearest (fast, low quality) + Nearest (fast, low quality) + + + + Bilinear + Bilinear + + + + Lanczos (better quality) + Lanczos (better quality) + + + + Restart is needed + Restart is needed + + + + Brightness + Brightness + + + + Display + Display + + + + Show time in current page information label + Show time in current page information label + + + + Scroll behaviour + Scroll behaviour + + + + Disable scroll animations and smooth scrolling + Disable scroll animations and smooth scrolling + + + + Do not turn page using scroll + Do not turn page using scroll + + + + Use single scroll step to turn page + Use single scroll step to turn page + + + + Mouse mode + Mouse mode + + + + Only Back/Forward buttons can turn pages + Only Back/Forward buttons can turn pages + + + + Use the Left/Right buttons to turn pages. + Use the Left/Right buttons to turn pages. + + + + Click left or right half of the screen to turn pages. + Click left or right half of the screen to turn pages. + + + + Contrast + Contrast + + + + Gamma + Gamma + + + + Reset + Reset + + + + Image options + Image options + + + + Fit options + Fit options + + + + Enlarge images to fit width/height + Enlarge images to fit width/height + + + + Double Page options + Double Page options + + + + Show covers as single page + Show covers as single page + + + + + General + General + + + + + Libraries + Libraries + + + + Comic Flow + Comic Flow + + + + Grid view + Grid view + + + + + Appearance + Appearance + + + + Tray icon settings (experimental) + Tray icon settings (experimental) + + + + Close to tray + Close to tray + + + + Start into the system tray + Start into the system tray + + + + Edit Comic Vine API key + Edit Comic Vine API key + + + + Comic Vine API key + Comic Vine API key + + + + ComicInfo.xml legacy support + ComicInfo.xml legacy support + + + + Import metadata from ComicInfo.xml when adding new comics + Import metadata from ComicInfo.xml when adding new comics + + + + Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago + + + + Third party reader + Third party reader + + + + Write {comic_file_path} where the path should go in the command + Write {comic_file_path} where the path should go in the command + + + + + Clear + Clear + + + + Update libraries at startup + Update libraries at startup + + + + Try to detect changes automatically + Try to detect changes automatically + + + + Update libraries periodically + Update libraries periodically + + + + Interval: + Interval: + + + + 30 minutes + 30 minutes + + + + 1 hour + 1 hour + + + + 2 hours + 2 hours + + + + 4 hours + 4 hours + + + + 8 hours + 8 hours + + + + 12 hours + 12 hours + + + + daily + daily + + + + Update libraries at certain time + Update libraries at certain time + + + + Time: + Time: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + + + + Modifications detection + Modifications detection + + + + Compare the modified date of files when updating a library (not recommended) + Compare the modified date of files when updating a library (not recommended) + + + + Enable background image + Enable background image + + + + Opacity level + Opacity level + + + + Blur level + Blur level + + + + Use selected comic cover as background + Use selected comic cover as background + + + + Restore defautls + Restore defautls + + + + Background + Background + + + + Display continue reading banner + Display continue reading banner + + + + Display current comic banner + Display current comic banner + + + + Continue reading + Continue reading + + + + Page Flow + Page Flow + + + + Image adjustment + Image adjustment + + + + + Options + Options + + + + Comics directory + Comics directory + + + + PropertiesDialog + + + General info + General info + + + + Plot + Plot + + + + Authors + Authors + + + + Publishing + Publishing + + + + Notes + Notes + + + + Cover page + Cover page + + + + Load previous page as cover + Load previous page as cover + + + + Load next page as cover + Load next page as cover + + + + Reset cover to the default image + Reset cover to the default image + + + + Load custom cover image + Load custom cover image + + + + Series: + Series: + + + + Title: + Title: + + + + + + of: + of: + + + + Issue number: + Issue number: + + + + Volume: + Volume: + + + + Arc number: + Arc number: + + + + Story arc: + Story arc: + + + + alt. number: + alt. number: + + + + Alternate series: + Alternate series: + + + + Series Group: + Series Group: + + + + Genre: + Genre: + + + + Size: + Size: + + + + Writer(s): + Writer(s): + + + + Penciller(s): + Penciller(s): + + + + Inker(s): + Inker(s): + + + + Colorist(s): + Colorist(s): + + + + Letterer(s): + Letterer(s): + + + + Cover Artist(s): + Cover Artist(s): + + + + Editor(s): + Editor(s): + + + + Imprint: + Imprint: + + + + Day: + Day: + + + + Month: + Month: + + + + Year: + Year: + + + + Publisher: + Publisher: + + + + Format: + Format: + + + + Color/BW: + Color/BW: + + + + Age rating: + Age rating: + + + + Type: + Type: + + + + Language (ISO): + Language (ISO): + + + + Synopsis: + Synopsis: + + + + Characters: + Characters: + + + + Teams: + Teams: + + + + Locations: + Locations: + + + + Main character or team: + Main character or team: + + + + Review: + Review: + + + + Notes: + Notes: + + + + Tags: + Tags: + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + + + + Not found + Not found + + + + Comic not found. You should update your library. + Comic not found. You should update your library. + + + + Edit comic information + Edit comic information + + + + Edit selected comics information + Edit selected comics information + + + + Invalid cover + Invalid cover + + + + The image is invalid. + The image is invalid. + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject + + + 7z lib not found + 7z lib not found + + + + unable to load 7z lib from ./utils + unable to load 7z lib from ./utils + + + + Trace + Trace + + + + Debug + Debug + + + + Info + Info + + + + Warning + Warning + + + + Error + Error + + + + Fatal + Fatal + + + + Select custom cover + Select custom cover + + + + Images (%1) + Images (%1) + + + + The file could not be read or is not valid JSON. + The file could not be read or is not valid JSON. + + + + This theme is for %1, not %2. + This theme is for %1, not %2. + + + + Libraries + Libraries + + + + Folders + Folders + + + + Reading Lists + Reading Lists + + + + RenameLibraryDialog + + + New Library Name : + New Library Name : + + + + Rename + Rename + + + + Cancel + Cancel + + + + Rename current library + Rename current library + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + Number of volumes found : %1 + + + + + page %1 of %2 + page %1 of %2 + + + + Number of %1 found : %2 + Number of %1 found : %2 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + Please provide some additional information for this comic. + + + + Series: + Series: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + + + + SearchVolume + + + Please provide some additional information. + Please provide some additional information. + + + + Series: + Series: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + + + + SelectComic + + + Please, select the right comic info. + Please, select the right comic info. + + + + comics + comics + + + + loading cover + loading cover + + + + loading description + loading description + + + + comic description unavailable + comic description unavailable + + + + SelectVolume + + + Please, select the right series for your comic. + Please, select the right series for your comic. + + + + Filter: + Filter: + + + + volumes + volumes + + + + Nothing found, clear the filter if any. + Nothing found, clear the filter if any. + + + + loading cover + loading cover + + + + loading description + loading description + + + + volume description unavailable + volume description unavailable + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + You are trying to get information for various comics at once, are they part of the same series? + + + + yes + yes + + + + no + no + + + + ServerConfigDialog + + + set port + set port + + + + Server connectivity information + Server connectivity information + + + + Scan it! + Scan it! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + + + + Choose an IP address + Choose an IP address + + + + Port + Port + + + + enable the server + enable the server + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. + + + + sort comics to match comic information + sort comics to match comic information + + + + issues + issues + + + + remove selected comics + remove selected comics + + + + restore all removed comics + restore all removed comics + + + + ThemeEditorDialog + + + Theme Editor + Theme Editor + + + + + + + + + + + - + - + + + + i + i + + + + Expand all + Expand all - - - Total pages : - + + Collapse all + Collapse all - - Go to... - + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - - - GoToFlowToolBar - - Page : - + + Search… + Search… - - - HelpAboutDialog - - About - + + Light + Light - - Help - + + Dark + Dark - - System info - + + ID: + ID: - - - LogWindow - - Log window - + + Display name: + Display name: - - &Pause - + + Variant: + Variant: - - &Save - + + Theme info + Theme info - - C&lear - + + Parameter + Parameter - - &Copy - + + Value + Value - - Level: - + + Save and apply + Save and apply - - &Auto scroll - + + Export to file... + Export to file... - - - OptionsDialog - - "Go to flow" size - + + Load from file... + Load from file... - - My comics path - + + Close + Close - - Background color - + + Double-click to edit color + Double-click to edit color - - Choose - + + + + + + + true + true - - Quick Navigation Mode - + + + + + false + false - - Disable mouse over activation - + + Double-click to toggle + Double-click to toggle - - Restart is needed - + + Double-click to edit value + Double-click to edit value - - Brightness - + + + + Edit: %1 + Edit: %1 - - Display - + + Save theme + Save theme - - Show time in current page information label - + + + JSON files (*.json);;All files (*) + JSON files (*.json);;All files (*) - - Scroll behaviour - + + Save failed + Save failed - - Disable scroll animations and smooth scrolling - + + Could not open file for writing: +%1 + Could not open file for writing: +%1 - - Do not turn page using scroll - + + Load theme + Load theme - - Use single scroll step to turn page - + + + + Load failed + Load failed - - Mouse mode - + + Could not open file: +%1 + Could not open file: +%1 - - Only Back/Forward buttons can turn pages - + + Invalid JSON: +%1 + Invalid JSON: +%1 - - Use the Left/Right buttons to turn pages. - + + Expected a JSON object. + Expected a JSON object. + + + TitleHeader - - Click left or right half of the screen to turn pages. - + + SEARCH + SEARCH + + + UpdateLibraryDialog - - Contrast - + + Updating.... + Updating.... - - Gamma - + + Cancel + Cancel - - Reset - + + Update library + Update library + + + Viewer - - Image options - + + + Press 'O' to open comic. + Press 'O' to open comic. - - Fit options - + + Not found + Not found - - Enlarge images to fit width/height - + + Comic not found + Comic not found - - Double Page options - + + Error opening comic + Error opening comic - - Show covers as single page - + + CRC Error + CRC Error - - General - + + Loading...please wait! + Loading...please wait! - - Page Flow - + + Page not available! + Page not available! - - Image adjustment - + + Cover! + Cover! - - Options - + + Last page! + Last page! + + + VolumeComicsModel - - Comics directory - + + title + title - QObject + VolumesModel - - 7z lib not found - + + year + year - - unable to load 7z lib from ./utils - + + issues + issues - - Trace - + + publisher + publisher + + + YACReader3DFlowConfigWidget - - Debug - + + Presets: + Presets: - - Info - + + Classic look + Classic look - - Warning - + + Stripe look + Stripe look - - Error - + + Overlapped Stripe look + Overlapped Stripe look - - Fatal - + + Modern look + Modern look - - Select custom cover - + + Roulette look + Roulette look - - Images (%1) - + + Show advanced settings + Show advanced settings - - - QsLogging::LogWindowModel - - Time - + + Custom: + Custom: - - Level - + + View angle + View angle - - Message - + + Position + Position - - - QsLogging::Window - - &Pause - + + Cover gap + Cover gap - - &Resume - + + Central gap + Central gap - - Save log - + + Zoom + Zoom - - Log file (*.log) - + + Y offset + Y offset - - - Viewer - - - Press 'O' to open comic. - + + Z offset + Z offset - - Not found - + + Cover Angle + Cover Angle - - Comic not found - + + Visibility + Visibility - - Error opening comic - + + Light + Light - - CRC Error - + + Max angle + Max angle - - Loading...please wait! - + + Low Performance + Low Performance - - Page not available! - + + High Performance + High Performance - - Cover! - + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Use VSync (improve the image quality in fullscreen mode, worse performance) - - Last page! - + + Performance: + Performance: YACReader::MainWindowViewer - + &Open - + &Open - + Open a comic - + Open a comic - + New instance - + New instance - + Open Folder - + Open Folder - + Open image folder - + Open image folder - + Open latest comic - + Open latest comic - + Open the latest comic opened in the previous reading session - + Open the latest comic opened in the previous reading session - + Clear - + Clear - + Clear open recent list - + Clear open recent list - + Save - + Save - + Save current page - + Save current page Previous Comic - + Previous Comic - - - + + + Open previous comic - + Open previous comic - + Next Comic - + Next Comic - - - + + + Open next comic - + Open next comic - + &Previous - + &Previous - - - + + + Go to previous page - + Go to previous page - + &Next - + &Next - - - + + + Go to next page - + Go to next page - + Fit Height - + Fit Height - + Fit image to height - + Fit image to height - + Fit Width - + Fit Width - + Fit image to width - + Fit image to width - + Show full size - + Show full size - + Fit to page - + Fit to page - + + Continuous scroll + Continuous scroll + + + + Switch to continuous scroll mode + Switch to continuous scroll mode + + + Reset zoom - + Reset zoom - + Show zoom slider - + Show zoom slider - + Zoom+ - + Zoom+ - + Zoom- - + Zoom- - + Rotate image to the left - + Rotate image to the left - + Rotate image to the right - + Rotate image to the right - + Double page mode - + Double page mode - + Switch to double page mode - + Switch to double page mode - + Double page manga mode - + Double page manga mode - + Reverse reading order in double page mode - + Reverse reading order in double page mode - + Go To - + Go To - + Go to page ... - + Go to page ... - + Options - + Options - + YACReader options - + YACReader options - - + + Help - + Help - + Help, About YACReader - + Help, About YACReader - + Magnifying glass - + Magnifying glass - + Switch Magnifying glass - + Switch Magnifying glass - + Set bookmark - + Set bookmark - + Set a bookmark on the current page - + Set a bookmark on the current page - + Show bookmarks - + Show bookmarks - + Show the bookmarks of the current comic - + Show the bookmarks of the current comic - + Show keyboard shortcuts - + Show keyboard shortcuts - + Show Info - + Show Info - + Close - + Close - + Show Dictionary - + Show Dictionary - + Show go to flow - + Show go to flow - + Edit shortcuts - + Edit shortcuts - + &File - + &File - - + + Open recent - + Open recent - + File - + File - + Edit - + Edit - + View - + View - + Go - + Go - + Window - + Window - - - + + + Open Comic - + Open Comic - - - + + + Comic files - + Comic files - + Open folder - + Open folder - + page_%1.jpg - + page_%1.jpg - + Image files (*.jpg) - + Image files (*.jpg) + Comics - + Comics Toggle fullscreen mode - + Toggle fullscreen mode Hide/show toolbar - + Hide/show toolbar + General - + General Size up magnifying glass - + Size up magnifying glass Size down magnifying glass - + Size down magnifying glass Zoom in magnifying glass - + Zoom in magnifying glass Zoom out magnifying glass - + Zoom out magnifying glass Reset magnifying glass - + Reset magnifying glass + Magnifiying glass - + Magnifiying glass Toggle between fit to width and fit to height - + Toggle between fit to width and fit to height + Page adjustement - + Page adjustement - + Autoscroll down - + Autoscroll down - + Autoscroll up - + Autoscroll up - + Autoscroll forward, horizontal first - + Autoscroll forward, horizontal first - + Autoscroll backward, horizontal first - + Autoscroll backward, horizontal first - + Autoscroll forward, vertical first - + Autoscroll forward, vertical first - + Autoscroll backward, vertical first - + Autoscroll backward, vertical first - + Move down - + Move down - + Move up - + Move up - + Move left - + Move left - + Move right - + Move right - + Go to the first page - + Go to the first page - + Go to the last page - + Go to the last page - + Offset double page to the left - + Offset double page to the left - + Offset double page to the right - + Offset double page to the right - + + Reading - + Reading - + There is a new version available - + There is a new version available - + Do you want to download the new version? - + Do you want to download the new version? - + Remind me in 14 days - + Remind me in 14 days - + Not now - + Not now - YACReader::WhatsNewDialog + YACReader::TrayIconController - - Close - + + &Restore + &Restore + + + + Systray + Systray + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. @@ -990,12 +3604,12 @@ Click to overwrite - + Click to overwrite Restore to default - + Restore to default @@ -1006,181 +3620,43 @@ Click to overwrite - + Click to overwrite Restore to default - - - - - YACReaderFlowConfigWidget - - - How to show covers: - - - - - CoverFlow look - - - - - Stripe look - - - - - Overlapped Stripe look - - - - - YACReaderGLFlowConfigWidget - - - Presets: - - - - - Classic look - - - - - Stripe look - - - - - Overlapped Stripe look - - - - - Modern look - - - - - Roulette look - - - - - Show advanced settings - - - - - Custom: - - - - - View angle - - - - - Position - - - - - Cover gap - - - - - Central gap - - - - - Zoom - - - - - Y offset - - - - - Z offset - - - - - Cover Angle - - - - - Visibility - - - - - Light - - - - - Max angle - - - - - Low Performance - - - - - High Performance - - - - - Use VSync (improve the image quality in fullscreen mode, worse performance) - - - - - Performance: - + Restore to default YACReaderOptionsDialog - + Save - + Save - + Cancel - + Cancel - + Edit shortcuts - + Edit shortcuts - + Shortcuts - + Shortcuts + + + YACReaderSearchLineEdit - - Use hardware acceleration (restart needed) - + + type to search + type to search @@ -1188,31 +3664,31 @@ Reset - + Reset YACReaderTranslator - + YACReader translator - + YACReader translator - - + + Translation - + Translation - + clear - + clear - + Service not available - + Service not available diff --git a/YACReader/yacreader_es.ts b/YACReader/yacreader_es.ts index 56605c326..471791646 100644 --- a/YACReader/yacreader_es.ts +++ b/YACReader/yacreader_es.ts @@ -9,6 +9,192 @@ Ninguno + + AddLabelDialog + + + Label name: + Nombre de la etiqueta: + + + + Choose a color: + Elige un color: + + + + accept + aceptar + + + + cancel + Cancelar + + + + AddLibraryDialog + + + Comics folder : + Carpeta de cómics : + + + + Library name : + Nombre de la biblioteca : + + + + Add + Añadir + + + + Cancel + Cancelar + + + + Add an existing library + Añadir una biblioteca existente + + + + ApiKeyDialog + + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Antes de que te puedas conectar a Comic Vine necesitas tu propia clave API. Por favor, obtén una gratis <a href="http://www.comicvine.com/api/">aquí</a> + + + + Paste here your Comic Vine API key + Pega aquí tu clave API de Comic Vine + + + + Accept + Aceptar + + + + Cancel + Cancelar + + + + AppearanceTabWidget + + + Color scheme + Esquema de color + + + + System + Sistema + + + + Light + Luz + + + + Dark + Oscuro + + + + Custom + Personalizado + + + + Remove + Eliminar + + + + Remove this user-imported theme + Eliminar este tema importado por el usuario + + + + Light: + Claro: + + + + Dark: + Oscuro: + + + + Custom: + Personalizado: + + + + Import theme... + Importar tema... + + + + Theme + Tema + + + + Theme editor + Editor de temas + + + + Open Theme Editor... + Abrir editor de temas... + + + + Theme editor error + Error del editor de temas + + + + The current theme JSON could not be loaded. + No se ha podido cargar el JSON del tema actual. + + + + Import theme + Importar tema + + + + JSON files (*.json);;All files (*) + Archivos JSON (*.json);;Todos los archivos (*) + + + + Could not import theme from: +%1 + No se pudo importar el tema desde:\n%1 + + + + Could not import theme from: +%1 + +%2 + No se pudo importar el tema desde:\n%1\n\n%2 + + + + Import failed + Error al importar + + BookmarksDialog @@ -33,736 +219,3140 @@ Última página + + ClassicComicsView + + + Hide comic flow + Ocultar cómic flow + + + + ComicModel + + + yes + + + + + no + No + + + + Title + Título + + + + File Name + Nombre de archivo + + + + Pages + Páginas + + + + Size + Tamaño + + + + Read + Leído + + + + Current Page + Página Actual + + + + Publication Date + Fecha de publicación + + + + Rating + Nota + + + + Series + Serie + + + + Volume + Volumen + + + + Story Arc + Arco argumental + + + + ComicVineDialog + + + skip + omitir + + + + back + atrás + + + + next + siguiente + + + + search + buscar + + + + close + Cerrar + + + + + comic %1 of %2 - %3 + cómic %1 de %2 - %3 + + + + + + Looking for volume... + Buscando volumen... + + + + %1 comics selected + %1 cómics seleccionados + + + + Error connecting to ComicVine + Error conectando a ComicVine + + + + + Retrieving tags for : %1 + Recuperando etiquetas para : %1 + + + + Retrieving volume info... + Recuperando información del volumen... + + + + Looking for comic... + Buscando cómic... + + + + ContinuousPageWidget + + + Loading page %1 + Cargando página %1 + + + + CreateLibraryDialog + + + Comics folder : + Carpeta de cómics : + + + + Library Name : + Nombre de la biblioteca : + + + + Create + Crear + + + + Cancel + Cancelar + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Crear una biblioteca puede llevar varios minutos. Puedes parar el proceso en cualquier momento y completar la tarea más tarde. + + + + Create new library + Crear la nueva biblioteca + + + + Path not found + Ruta no encontrada + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + La ruta seleccionada no existe o no es válida. Asegúrate de que tienes privilegios de escritura en esta carpeta + + EditShortcutsDialog - - Restore defaults - Restaurar los valores predeterminados + + Restore defaults + Restaurar los valores predeterminados + + + + To change a shortcut, double click in the key combination and type the new keys. + Para cambiar un atajo, haz doble clic en la combinación de teclas y escribe las nuevas teclas. + + + + Shortcuts settings + Configuración de accesos directos + + + + Shortcut in use + Accesos directos en uso + + + + The shortcut "%1" is already assigned to other function + El acceso directo "%1" ya está asignado a otra función + + + + EmptyFolderWidget + + + This folder doesn't contain comics yet + Esta carpeta aún no contiene cómics + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + Esta etiqueta aún no contiene ningún cómic + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + Esta lista de tectura aún no contiene ningún cómic + + + + EmptySpecialListWidget + + + No favorites + Ningún favorito + + + + You are not reading anything yet, come on!! + No estás leyendo nada aún, ¡vamos! + + + + There are no recent comics! + ¡No hay comics recientes! + + + + ExportComicsInfoDialog + + + Output file : + Archivo de salida : + + + + Create + Crear + + + + Cancel + Cancelar + + + + Export comics info + Exportar información de los cómics + + + + Destination database name + Nombre de la base de datos de destino + + + + Problem found while writing + Problema encontrado mientras se escribía + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + La ruta seleccionada para el archivo de salida no existe o no es una ruta válida. Asegúrate de que tienes permisos de escritura en esta carpeta + + + + ExportLibraryDialog + + + Output folder : + Carpeta de destino : + + + + Create + Crear + + + + Cancel + Cancelar + + + + Create covers package + Crear paquete de portadas + + + + Problem found while writing + Problema encontrado mientras se escribía + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + La ruta seleccionada para el archivo de salida no existe o no es una ruta válida. Asegúrate de que tienes permisos de escritura en esta carpeta + + + + Destination directory + Carpeta de destino + + + + FileComic + + + Format not supported + Formato no soportado + + + + 7z not found + 7z no encontrado + + + + Unknown error opening the file + Error desconocido abriendo el archivo + + + + CRC error on page (%1): some of the pages will not be displayed correctly + Error CRC en la página (%1): algunas de las páginas no se mostrarán correctamente + + + + GoToDialog + + + Go To + Ir a + + + + Go to... + Ir a... + + + + + Total pages : + Páginas totales : + + + + Cancel + Cancelar + + + + Page : + Página : + + + + GoToFlowToolBar + + + Page : + Página : + + + + GridComicsView + + + Show info + Mostrar información + + + + HelpAboutDialog + + + Help + Ayuda + + + + System info + Información de sistema + + + + About + Acerca de + + + + ImportComicsInfoDialog + + + Import comics info + Importar información de cómics + + + + Info database location : + Ubicación de la base de datos de información : + + + + Import + Importar + + + + Cancel + Cancelar + + + + Comics info file (*.ydb) + Archivo de información de cómics (*.ydb) + + + + ImportLibraryDialog + + + Library Name : + Nombre de la biblioteca : + + + + Package location : + Ubicación del paquete : + + + + Destination folder : + Directorio de destino : + + + + Unpack + Desempaquetar + + + + Cancel + Cancelar + + + + Extract a catalog + Extraer un catálogo + + + + Compresed library covers (*.clc) + Portadas de biblioteca comprimidas (*.clc) + + + + ImportWidget + + + stop + parar + + + + Some of the comics being added... + Algunos de los cómics que estan siendo añadidos.... + + + + Importing comics + Importando cómics + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary está creando una nueva biblioteca.</p><p>Crear una biblioteca puede llevar varios minutos. Puedes parar el proceso en cualquier momento y actualizar la biblioteca más tarde para completar el proceso.</p> + + + + Updating the library + Actualizando la biblioteca + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>La biblioteca actual está siendo actualizada. Para actualizaciones más rápidas, por favor, actualiza tus bibliotecas frecuentemente.</p><p>Puedes parar el proceso y continunar la actualización más tarde.</p> + + + + Upgrading the library + Actualizando la biblioteca + + + + <p>The current library is being upgraded, please wait.</p> + <p>La biblioteca actual está siendo actualizadad, espera por favor.</p> + + + + Scanning the library + Escaneando la biblioteca + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>La biblioteca está siendo escaneada para encontrar metadatos en formato XML.</p><p>Sólo necesitas hacer esto una vez, y sólo si la biblioteca fue creada con YACReaderLibrary 9.8.2 o antes.</p> + + + + LibraryWindow + + + YACReader Library + Biblioteca YACReader + + + + + + comic + Cómic + + + + + + manga + historieta manga + + + + + + western manga (left to right) + manga occidental (izquierda a derecha) + + + + + + web comic + cómic web + + + + + + 4koma (top to botom) + 4koma (de arriba a abajo) + + + + + + + Set type + Establecer tipo + + + + Library + Librería + + + + Folder + Carpeta + + + + Comic + Cómic + + + + Upgrade failed + La actualización falló + + + + There were errors during library upgrade in: + Hubo errores durante la actualización de la biblioteca en: + + + + Update needed + Se necesita actualizar + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Esta biblioteca fue creada con una versión anterior de YACReaderLibrary. Es necesario que se actualice. ¿Deseas hacerlo ahora? + + + + Download new version + Descargar la nueva versión + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Esta biblioteca fue creada con una versión más nueva de YACReaderLibrary. ¿Deseas descargar la nueva versión ahora? + + + + Library not available + Biblioteca no disponible + + + + Library '%1' is no longer available. Do you want to remove it? + La biblioteca '%1' no está disponible. ¿Deseas eliminarla? + + + + Old library + Biblioteca antigua + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La biblioteca '%1' ha sido creada con una versión más antigua de YACReaderLibrary y debe ser creada de nuevo. ¿Deseas crear la biblioteca ahora? + + + + + Copying comics... + Copiando cómics... + + + + + Moving comics... + Moviendo cómics... + + + + Add new folder + Añadir carpeta + + + + Folder name: + Nombre de la carpeta: + + + + No folder selected + No has selecionado ninguna carpeta + + + + Please, select a folder first + Por favor, selecciona una carpeta primero + + + + Error in path + Error en la ruta + + + + There was an error accessing the folder's path + Hubo un error al acceder a la ruta de la carpeta + + + + Delete folder + Borrar carpeta + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + ¿Estás seguro de que deseas eliminar la carpeta seleccionada y todo su contenido de tu disco? + + + + + Unable to delete + No se ha podido borrar + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Se produjo un problema al intentar eliminar las carpetas seleccionadas. Por favor, verifica los permisos de escritura y asegúrate de que no haya aplicaciones usando estas carpetas o alguno de los archivos contenidos en ellas. + + + + Add new reading lists + Añadir nuevas listas de lectura + + + + + List name: + Nombre de la lista: + + + + Delete list/label + Eliminar lista/etiqueta + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + El elemento seleccionado se eliminará, tus cómics o carpetas NO se eliminarán de tu disco. ¿Estás seguro? + + + + Rename list name + Renombrar lista + + + + Open folder... + Abrir carpeta... + + + + Update folder + Actualizar carpeta + + + + Rescan library for XML info + Volver a escanear la biblioteca en busca de información XML + + + + Set as uncompleted + Marcar como incompleto + + + + Set as completed + Marcar como completo + + + + Set as read + Marcar como leído + + + + + Set as unread + Marcar como no leído + + + + Set custom cover + Establecer portada personalizada + + + + Delete custom cover + Eliminar portada personalizada + + + + Save covers + Guardar portadas + + + + You are adding too many libraries. + Estás añadiendo demasiadas bibliotecas. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Estás añadiendo demasiadas bibliotecas.\n\nProbablemente solo necesites una biblioteca en la carpeta principal de tus cómics, puedes explorar cualquier subcarpeta utilizando la sección de carpetas en la barra lateral izquierda.\n\nYACReaderLibrary no te detendrá de crear más bibliotecas, pero deberías mantener el número de bibliotecas bajo control. + + + + + YACReader not found + YACReader no encontrado + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader no encontrado. YACReader debería estar instalado en la misma carpeta que YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader no encontrado. Podría haber un problema con tu instalación de YACReader. + + + + Error + Fallo + + + + Error opening comic with third party reader. + Error al abrir el cómic con una aplicación de terceros. + + + + Library not found + Biblioteca no encontrada + + + + The selected folder doesn't contain any library. + La carpeta seleccionada no contiene ninguna biblioteca. + + + + Are you sure? + ¿Estás seguro? + + + + Do you want remove + ¿Deseas eliminar la biblioteca + + + + library? + ? + + + + Remove and delete metadata + Eliminar y borrar metadatos + + + + Library info + Información de la biblioteca + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Ha habido algún problema intentando borrar los cómics selecionados. Por favor, verifica los permisos de escritura en los arhicovs seleccionados o los directorios que los conienen. + + + + Assign comics numbers + Asignar números a los cómics + + + + Assign numbers starting in: + Asignar números comenzando en: + + + + Invalid image + Imagen inválida + + + + The selected file is not a valid image. + El archivo seleccionado no es una imagen válida. + + + + Error saving cover + Error guardando portada + + + + There was an error saving the cover image. + Hubo un error guardando la image de portada. + + + + Error creating the library + Errar creando la biblioteca + + + + Error updating the library + Error actualizando la biblioteca + + + + Error opening the library + Error abriendo la biblioteca + + + + Delete comics + Borrar cómics + + + + All the selected comics will be deleted from your disk. Are you sure? + Todos los cómics seleccionados serán borrados de tu disco. ¿Estás seguro? + + + + Remove comics + Eliminar cómics + + + + Comics will only be deleted from the current label/list. Are you sure? + Los cómics sólo se eliminarán de la etiqueta/lista actual. ¿Estás seguro? + + + + Library name already exists + Ya existe el nombre de la biblioteca + + + + There is another library with the name '%1'. + Hay otra biblioteca con el nombre '%1'. + + + + LibraryWindowActions + + + Create a new library + Crear una nueva biblioteca + + + + Open an existing library + Abrir una biblioteca existente + + + + + Export comics info + Exportar información de los cómics + + + + + Import comics info + Importar información de cómics + + + + Pack covers + Empaquetar portadas + + + + Pack the covers of the selected library + Empaquetar las portadas de la biblioteca seleccionada + + + + Unpack covers + Desempaquetar portadas + + + + Unpack a catalog + Desempaquetar un catálogo + + + + Update library + Actualizar biblioteca + + + + Update current library + Actualizar la biblioteca seleccionada + + + + Rename library + Renombrar biblioteca + + + + Rename current library + Renombrar la biblioteca seleccionada + + + + Remove library + Eliminar biblioteca + + + + Remove current library from your collection + Eliminar biblioteca de la colección + + + + Rescan library for XML info + Volver a escanear la biblioteca en busca de información XML + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Intenta encontrar información XML incrustada en los archivos de cómic. Solo necesitas hacer esto si la biblioteca fue creada con la versión 9.8.2 o versiones anteriores o si estás utilizando software de terceros para incrustar información XML en los archivos. + + + + Show library info + Mostrar información de la biblioteca + + + + Show information about the current library + Mostrar información de la biblioteca actual + + + + Open current comic + Abrir cómic actual + + + + Open current comic on YACReader + Abrir el cómic actual en YACReader + + + + Save selected covers to... + Guardar las portadas seleccionadas en... + + + + Save covers of the selected comics as JPG files + Guardar las portadas de los cómics seleccionados como archivos JPG + + + + + Set as read + Marcar como leído + + + + Set comic as read + Marcar cómic como leído + + + + + Set as unread + Marcar como no leído + + + + Set comic as unread + Marcar cómic como no leído + + + + + manga + historieta manga + + + + Set issue as manga + Marcar número como manga + + + + + comic + Cómic + + + + Set issue as normal + Marcar número como cómic + + + + western manga + manga occidental + + + + Set issue as western manga + Marcar número como manga occidental + + + + + web comic + cómic web + + + + Set issue as web comic + Marcar número como cómic web + + + + + yonkoma + tira yonkoma + + + + Set issue as yonkoma + Marcar número como yonkoma + + + + Show/Hide marks + Mostrar/Ocultar marcas + + + + Show or hide read marks + Mostrar u ocultar marcas + + + + Show/Hide recent indicator + Mostrar/Ocultar el indicador reciente + + + + Show or hide recent indicator + Mostrar o ocultar el indicador reciente + + + + + Fullscreen mode on/off + Modo a pantalla completa on/off + + + + Help, About YACReader + Ayuda, Sobre YACReader + + + + Add new folder + Añadir carpeta + + + + Add new folder to the current library + Añadir carpeta a la biblioteca actual + + + + Delete folder + Borrar carpeta + + + + Delete current folder from disk + Borrar carpeta actual del disco + + + + Select root node + Seleccionar el nodo raíz + + + + Expand all nodes + Expandir todos los nodos + + + + Collapse all nodes + Contraer todos los nodos + + + + Show options dialog + Mostrar opciones + + + + Show comics server options dialog + Mostrar el diálogo de opciones del servidor de cómics + + + + + Change between comics views + Cambiar entre vistas de cómics + + + + Open folder... + Abrir carpeta... + + + + Set as uncompleted + Marcar como incompleto + + + + Set as completed + Marcar como completo + + + + Set custom cover + Establecer portada personalizada + + + + Delete custom cover + Eliminar portada personalizada + + + + western manga (left to right) + manga occidental (izquierda a derecha) + + + + Open containing folder... + Abrir carpeta contenedora... + + + + Reset comic rating + Reseteal cómic rating + + + + Select all comics + Seleccionar todos los cómics + + + + Edit + Editar + + + + Assign current order to comics + Asignar el orden actual a los cómics + + + + Update cover + Actualizar portada + + + + Delete selected comics + Borrar los cómics seleccionados + + + + Delete metadata from selected comics + Borrar metadatos de los cómics seleccionados + + + + Download tags from Comic Vine + Descargar etiquetas de Comic Vine + + + + Focus search line + Selecionar el campo de búsqueda + + + + Focus comics view + Selecionar la vista de cómics + + + + Edit shortcuts + Editar accesos directos + + + + &Quit + &Salir + + + + Update folder + Actualizar carpeta + + + + Update current folder + Actualizar carpeta actual + + + + Scan legacy XML metadata + Escaneal metadatos XML + + + + Add new reading list + Añadir lista de lectura + + + + Add a new reading list to the current library + Añadir una nueva lista de lectura a la biblioteca actual + + + + Remove reading list + Eliminar lista de lectura + + + + Remove current reading list from the library + Eliminar la lista de lectura actual de la biblioteca + + + + Add new label + Añadir etiqueta + + + + Add a new label to this library + Añadir etiqueta a esta biblioteca + + + + Rename selected list + Renombrar la lista seleccionada + + + + Rename any selected labels or lists + Renombrar las etiquetas o listas seleccionadas + + + + Add to... + Añadir a... + + + + Favorites + Favoritos + + + + Add selected comics to favorites list + Añadir cómics seleccionados a la lista de favoritos + + + + LocalComicListModel + + + file name + Nombre de archivo + + + + MainWindowViewer + + File + Archivo + + + Help + Ayuda + + + Save + Guardar + + + &File + &Archivo + + + &Next + Siguie&nte + + + &Open + &Abrir + + + Close + Cerrar + + + Open Comic + Abrir cómic + + + Go To + Ir a + + + Open image folder + Abrir carpeta de imágenes + + + Set bookmark + Añadir marcador + + + page_%1.jpg + página_%1.jpg + + + Switch to double page mode + Cambiar a modo de doble página + + + Save current page + Guardar la página actual + + + Double page mode + Modo a doble página + + + Switch Magnifying glass + Lupa On/Off + + + Open Folder + Abrir carpeta + + + Fit Height + Ajustar altura + + + Comic files + Archivos de cómic + + + Not now + Ahora no + + + Go to previous page + Ir a la página anterior + + + Open a comic + Abrir cómic + + + Image files (*.jpg) + Archivos de imagen (*.jpg) + + + Next Comic + Siguiente Cómic + + + Fit Width + Ajustar anchura + + + Options + Opciones + + + Show Info + Mostrar información + + + Open folder + Abrir carpeta + + + Go to page ... + Ir a página... + + + Fit image to width + Ajustar página a lo ancho + + + &Previous + A&nterior + + + Go to next page + Ir a la página siguiente + + + Show keyboard shortcuts + Mostrar atajos de teclado + + + There is a new version available + Hay una nueva versión disponible + + + Open next comic + Abrir siguiente cómic + + + Remind me in 14 days + Recordar en 14 días + + + Show bookmarks + Mostrar marcadores + + + Open previous comic + Abrir cómic anterior + + + Rotate image to the left + Rotar imagen a la izquierda + + + Fit image to height + Ajustar página a lo alto + + + Show the bookmarks of the current comic + Mostrar los marcadores del cómic actual + + + Show Dictionary + Mostrar diccionario + + + YACReader options + Opciones de YACReader + + + Help, About YACReader + Ayuda, Sobre YACReader + + + Show go to flow + Mostrar flow ir a + + + Previous Comic + Cómic anterior + + + Show full size + Mostrar a tamaño original + + + Magnifying glass + Lupa + + + General + Opciones generales + + + Set a bookmark on the current page + Añadir un marcador en la página actual + + + Do you want to download the new version? + ¿Desea descargar la nueva versión? + + + Rotate image to the right + Rotar imagen a la derecha + + + Always on top + Siempre visible + + + + NoLibrariesWidget + + + You don't have any libraries yet + Aún no tienes ninguna biblioteca + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Puedes crear una biblioteca en cualquier carpeta, YACReaderLibrary importará todos las carpetas y cómics de esa carpeta. Si has creado alguna biblioteca anteriormente, puedes abrirla sin volver a crearla.</p><p>No olvides que puedes usar YACReader como una aplicación independiente para leer los cómics en tu ordenador.</p> + + + + create your first library + crea tu primera biblioteca + + + + add an existing one + añade una existente + + + + NoSearchResultsWidget + + + No results + Sin resultados + + + + OptionsDialog + + + Gamma + Gama + + + + Reset + Restablecer + + + + My comics path + Ruta a mis cómics + + + + Scaling + Escalado + + + + Scaling method + Método de escalado + + + + Nearest (fast, low quality) + Vecino más cercano (rápido, baja calidad) + + + + Bilinear + Bilineal + + + + Lanczos (better quality) + Lanczos (mejor calidad) + + + + Image adjustment + Ajustes de imagen + + + + "Go to flow" size + Tamaño de "Go to flow" + + + + Choose + Elegir + + + + Image options + Opciones de imagen + + + + Contrast + Contraste + + + + + Libraries + Bibliotecas + + + + Comic Flow + Flujo cómico + + + + Grid view + Vista en cuadrícula + + + + + Appearance + Apariencia + + + + + Options + Opciones + + + + + Language + Idioma + + + + + Application language + Idioma de la aplicación + + + + + System default + Predeterminado del sistema + + + + Tray icon settings (experimental) + Opciones de bandeja de sistema (experimental) + + + + Close to tray + Cerrar a la bandeja + + + + Start into the system tray + Comenzar en la bandeja de sistema + + + + Edit Comic Vine API key + Editar la clave API de Comic Vine + + + + Comic Vine API key + Clave API de Comic Vine + + + + ComicInfo.xml legacy support + Soporte para ComicInfo.xml + + + + Import metadata from ComicInfo.xml when adding new comics + Importar metadatos desde ComicInfo.xml al añadir nuevos cómics + + + + Consider 'recent' items added or updated since X days ago + Considerar elementos 'recientes' añadidos o actualizados desde hace X días + + + + Third party reader + Lector externo + + + + Write {comic_file_path} where the path should go in the command + Escribe {comic_file_path} donde la ruta al cómic debería ir en el comando + + + + + Clear + Limpiar + + + + Update libraries at startup + Actualizar bibliotecas al inicio + + + + Try to detect changes automatically + Intentar detectar cambios automáticamente + + + + Update libraries periodically + Actualizar bibliotecas periódicamente + + + + Interval: + Intervalo: + + + + 30 minutes + 30 minutos + + + + 1 hour + 1 hora + + + + 2 hours + 2 horas + + + + 4 hours + 4 horas + + + + 8 hours + 8 horas + + + + 12 hours + 12 horas + + + + daily + dirariamente + + + + Update libraries at certain time + Actualizar bibliotecas en un momento determinado + + + + Time: + Hora: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + ¡ADVERTENCIA! Durante las actualizaciones de la biblioteca se desactivan las escrituras en la base de datos. No programes actualizaciones mientras puedas estar usando la aplicación activamente. Durante las actualizaciones automáticas, la aplicación bloqueará algunas de las acciones hasta que la actualización esté terminada. Para detener una actualización automática, toca en el indicador de carga junto al título de Bibliotecas. + + + + Modifications detection + Detección de modificaciones + + + + Compare the modified date of files when updating a library (not recommended) + Comparar la fecha de modificación de los archivos al actualizar una biblioteca (no recomendado) + + + + Enable background image + Activar imagen de fondo + + + + Opacity level + Nivel de opacidad + + + + Blur level + Nivel de desenfoque + + + + Use selected comic cover as background + Usar la portada del cómic seleccionado como fondo + + + + Restore defautls + Restaurar valores predeterminados + + + + Background + Fondo + + + + Display continue reading banner + Mostrar banner de "Continuar leyendo" + + + + Display current comic banner + Mostar el báner del cómic actual + + + + Continue reading + Continuar leyendo + + + + Comics directory + Directorio de cómics + + + + Background color + Color de fondo + + + + Page Flow + Flujo de página + + + + + General + Opciones generales + + + + Brightness + Brillo + + + + + Restart is needed + Es necesario reiniciar + + + + Quick Navigation Mode + Modo de navegación rápida + + + + Display + Visualización + + + + Show time in current page information label + Mostrar la hora en la etiqueta de información de la página actual + + + + Scroll behaviour + Comportamiento del scroll + + + + Disable scroll animations and smooth scrolling + Desactivar animaciones de desplazamiento y desplazamiento suave + + + + Do not turn page using scroll + No cambiar de página usando el scroll + + + + Use single scroll step to turn page + Usar un solo paso de desplazamiento para cambiar de página + + + + Mouse mode + Modo del ratón + + + + Only Back/Forward buttons can turn pages + Solo los botones Atrás/Adelante pueden cambiar de página + + + + Use the Left/Right buttons to turn pages. + Usar los botones Izquierda/Derecha para cambiar de página. + + + + Click left or right half of the screen to turn pages. + Hacer clic en la mitad izquierda o derecha de la pantalla para cambiar de página. + + + + Disable mouse over activation + Desactivar activación al pasar el ratón + + + + Fit options + Opciones de ajuste + + + + Enlarge images to fit width/height + Ampliar imágenes para ajustarse al ancho/alto + + + + Double Page options + Opciones de doble página + + + + Show covers as single page + Mostrar portadas como página única + + + + PropertiesDialog + + + General info + Información general + + + + Plot + Argumento + + + + Authors + Autores + + + + Publishing + Publicación + + + + Notes + Notas + + + + Cover page + Página de portada + + + + Load previous page as cover + Cargar página anterior como portada + + + + Load next page as cover + Cargar página siguiente como portada + + + + Reset cover to the default image + Restaurar la portada por defecto + + + + Load custom cover image + Cargar portada personalizada + + + + Series: + Serie: + + + + Title: + Título: + + + + + + of: + de: + + + + Issue number: + Número: + + + + Volume: + Volumen: + + + + Arc number: + Número de arco: + + + + Story arc: + Arco argumental: + + + + alt. number: + número alternativo: + + + + Alternate series: + Serie alternativa: + + + + Series Group: + Grupo de series: + + + + Genre: + Género: - - To change a shortcut, double click in the key combination and type the new keys. - Para cambiar un atajo, haz doble clic en la combinación de teclas y escribe las nuevas teclas. + + Size: + Tamaño: - - Shortcuts settings - Configuración de accesos directos + + Writer(s): + Guionista(s): - - Shortcut in use - Accesos directos en uso + + Penciller(s): + Dibujant(es): - - The shortcut "%1" is already assigned to other function - El acceso directo "%1" ya está asignado a otra función + + Inker(s): + Entintador(es): - - - FileComic - - Format not supported - Formato no soportado + + Colorist(s): + Color: - - 7z not found - 7z no encontrado + + Letterer(s): + Rotulista(s): - - Unknown error opening the file - Error desconocido abriendo el archivo + + Cover Artist(s): + Artista(s) portada: - - CRC error on page (%1): some of the pages will not be displayed correctly - Error CRC en la página (%1): algunas de las páginas no se mostrarán correctamente + + Editor(s): + Editor(es): - - - GoToDialog - - Go To - Ir a + + Imprint: + Sello: - - Go to... - Ir a... + + Day: + Día: - - - Total pages : - Páginas totales : + + Month: + Mes: - - Cancel - Cancelar + + Year: + Año: - - Page : - Página : + + Publisher: + Editorial: - - - GoToFlowToolBar - - Page : - Página : + + Format: + Formato: - - - HelpAboutDialog - - Help - Ayuda + + Color/BW: + Color/BN: - - System info - Información de sistema + + Age rating: + Casificación edades: - - About - Acerca de + + Type: + Tipo: - - - LogWindow - - Log window - + + Language (ISO): + Idioma (ISO): - - &Pause - + + Synopsis: + Sinopsis: - - &Save - + + Characters: + Personajes: - - C&lear - + + Teams: + Equipos: - - &Copy - + + Locations: + Lugares: - - Level: - + + Main character or team: + Personaje o equipo principal: - - &Auto scroll - + + Review: + Reseña: - - - MainWindowViewer - File - Archivo + + Notes: + Notas: - Help - Ayuda + + Tags: + Etiquetas: - Save - Guardar + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ver </a> - &File - &Archivo + + Not found + No encontrado - &Next - Siguie&nte + + Comic not found. You should update your library. + Cómic no encontrado. Deberias actualizar tu biblioteca. - &Open - &Abrir + + Edit comic information + Editar la información del cócmic - Close - Cerrar + + Edit selected comics information + Editar la información de los cómics seleccionados - Open Comic - Abrir cómic + + Invalid cover + Portada inválida - Go To - Ir a + + The image is invalid. + La imagen no es válida. + + + QCoreApplication - Open image folder - Abrir carpeta de imágenes + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + \nYACReaderLibraryServer es la versión sin interfaz gráfica (headless) de YACReaderLibrary.\n\nEsta aplicación admite ajustes persistentes; para configurarlos, edita este archivo %1\nPara conocer los ajustes disponibles, consulta la documentación en https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + QObject - Set bookmark - Añadir marcador + + 7z lib not found + 7z lib no encontrado - page_%1.jpg - página_%1.jpg + + unable to load 7z lib from ./utils + imposible cargar 7z lib de ./utils - Switch to double page mode - Cambiar a modo de doble página + + Trace + Traza - Save current page - Guardar la página actual + + Debug + Depuración - Double page mode - Modo a doble página + + Info + Información - Switch Magnifying glass - Lupa On/Off + + Warning + Advertencia - Open Folder - Abrir carpeta + + Error + Fallo - Fit Height - Ajustar altura + + Fatal + Cr?tico - Comic files - Archivos de cómic + + Select custom cover + Seleccionar portada personalizada - Not now - Ahora no + + Images (%1) + Imágenes (%1) - Go to previous page - Ir a la página anterior + + The file could not be read or is not valid JSON. + No se pudo leer el archivo o no es un JSON válido. - Open a comic - Abrir cómic + + This theme is for %1, not %2. + Este tema es para %1, no para %2. - Image files (*.jpg) - Archivos de imagen (*.jpg) + + Libraries + Bibliotecas - Next Comic - Siguiente Cómic + + Folders + CARPETAS - Fit Width - Ajustar anchura + + Reading Lists + Listas de lectura + + + RenameLibraryDialog - Options - Opciones + + New Library Name : + Nuevo nombre de la biblioteca : - Show Info - Mostrar información + + Rename + Renombrar - Open folder - Abrir carpeta + + Cancel + Cancelar - Go to page ... - Ir a página... + + Rename current library + Renombrar la biblioteca seleccionada + + + ScraperResultsPaginator - Fit image to width - Ajustar página a lo ancho + + Number of volumes found : %1 + Número de volúmenes encontrados : %1 - &Previous - A&nterior + + + page %1 of %2 + página %1 de %2 - Go to next page - Ir a la página siguiente + + Number of %1 found : %2 + Número de %1 encontrados : %2 + + + SearchSingleComic - Show keyboard shortcuts - Mostrar atajos de teclado + + Please provide some additional information for this comic. + Por favor, proporciona alguna información adicional para éste cómic. - There is a new version available - Hay una nueva versión disponible + + Series: + Serie: - Open next comic - Abrir siguiente cómic + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Usar búsqueda exacta. Desactívala si quieres encontrar volúmenes que coincidan con algunas palabras del nombre. + + + SearchVolume - Remind me in 14 days - Recordar en 14 días + + Please provide some additional information. + Por favor, proporciona alguna informacion adicional. - Show bookmarks - Mostrar marcadores + + Series: + Serie: - Open previous comic - Abrir cómic anterior + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Usar búsqueda exacta. Desactívala si quieres encontrar volúmenes que coincidan con algunas palabras del nombre. + + + SelectComic - Rotate image to the left - Rotar imagen a la izquierda + + Please, select the right comic info. + Por favor, selecciona la información correcta. - Fit image to height - Ajustar página a lo alto + + comics + Cómics - Show the bookmarks of the current comic - Mostrar los marcadores del cómic actual + + loading cover + cargando portada - Show Dictionary - Mostrar diccionario + + loading description + cargando descripción - YACReader options - Opciones de YACReader + + comic description unavailable + Descripción del cómic no disponible + + + SelectVolume - Help, About YACReader - Ayuda, Sobre YACReader + + Please, select the right series for your comic. + Por favor, seleciona la serie correcta para tu cómic. - Show go to flow - Mostrar flow ir a + + Filter: + Filtro: - Previous Comic - Cómic anterior + + volumes + volúmenes - Show full size - Mostrar a tamaño original + + Nothing found, clear the filter if any. + No se encontró nada, limpia el filtro si lo hubiera. - Magnifying glass - Lupa + + loading cover + cargando portada - General - General + + loading description + cargando descripción - Set a bookmark on the current page - Añadir un marcador en la página actual + + volume description unavailable + Descripción del volumen no disponible + + + SeriesQuestion - Do you want to download the new version? - ¿Desea descargar la nueva versión? + + You are trying to get information for various comics at once, are they part of the same series? + Estás intentando obtener información de varios cómics a la vez, ¿son parte de la misma serie? - Rotate image to the right - Rotar imagen a la derecha + + yes + - Always on top - Siempre visible + + no + No - OptionsDialog + ServerConfigDialog - - Gamma - Gamma + + set port + fijar puerto - - Reset - Reset + + Server connectivity information + Infomación de conexión del servidor - - My comics path - Ruta a mis cómics + + Scan it! + ¡Escaneálo! - - Image adjustment - Ajustes de imagen + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader está disponible para iOS y Android.<br/> Descúbrela para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a>o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - - "Go to flow" size - Tamaño de "Go to flow" + + Choose an IP address + Elige una dirección IP - - Choose - Elegir + + Port + Puerto - - Image options - Opciones de imagen + + enable the server + activar el servidor + + + ShortcutsDialog - - Contrast - Contraste + Close + Cerrar - - Options - Opciones + YACReader keyboard shortcuts + Atajos de teclado de YACReader - - Comics directory - Directorio de cómics + Keyboard Shortcuts + Atajos de teclado + + + SortVolumeComics - - Background color - Color de fondo + + Please, sort the list of comics on the left until it matches the comics' information. + Por favor, ordena la lista de cómics en la izquiera hasta que coincida con la información adecuada. - - Page Flow - Page Flow + + sort comics to match comic information + ordena los cómics para coincidir con la información + + + + issues + números + + + + remove selected comics + eliminar cómics seleccionados + + + + restore all removed comics + restaurar todos los cómics eliminados + + + ThemeEditorDialog - - General - General + + Theme Editor + Editor de temas - - Brightness - Brillo + + + + + - - Restart is needed - Es necesario reiniciar + + - + - - - Quick Navigation Mode - Modo de navegación rápida + + i + ? - - Display - Visualización + + Expand all + Expandir todo - - Show time in current page information label - Mostrar la hora en la etiqueta de información de la página actual + + Collapse all + Contraer todo - - Scroll behaviour - Comportamiento del scroll + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Mantén pulsado para resaltar temporalmente el valor seleccionado en la interfaz (magenta / alternado / 0↔10). Al soltar se restaura el original. - - Disable scroll animations and smooth scrolling - Desactivar animaciones de desplazamiento y desplazamiento suave + + Search… + Buscar… - - Do not turn page using scroll - No cambiar de página usando el scroll + + Light + Luz - - Use single scroll step to turn page - Usar un solo paso de desplazamiento para cambiar de página + + Dark + Oscuro - - Mouse mode - Modo del ratón + + ID: + IDENTIFICACIÓN: - - Only Back/Forward buttons can turn pages - Solo los botones Atrás/Adelante pueden cambiar de página + + Display name: + Nombre para mostrar: - - Use the Left/Right buttons to turn pages. - Usar los botones Izquierda/Derecha para cambiar de página. + + Variant: + Variante: - - Click left or right half of the screen to turn pages. - Hacer clic en la mitad izquierda o derecha de la pantalla para cambiar de página. + + Theme info + Información del tema - - Disable mouse over activation - Desactivar activación al pasar el ratón + + Parameter + Parámetro - - Fit options - Opciones de ajuste + + Value + Valor - - Enlarge images to fit width/height - Ampliar imágenes para ajustarse al ancho/alto + + Save and apply + Guardar y aplicar - - Double Page options - Opciones de doble página + + Export to file... + Exportar a archivo... - - Show covers as single page - Mostrar portadas como página única + + Load from file... + Cargar desde archivo... - - - QObject - - 7z lib not found - 7z lib no encontrado + + Close + Cerrar - - unable to load 7z lib from ./utils - imposible cargar 7z lib de ./utils + + Double-click to edit color + Doble clic para editar el color - - Trace - + + + + + + + true + verdadero - - Debug - + + + + + false + falso - - Info - + + Double-click to toggle + Doble clic para alternar - - Warning - + + Double-click to edit value + Doble clic para editar el valor - - Error - + + + + Edit: %1 + Editar: %1 - - Fatal - + + Save theme + Guardar tema - - Select custom cover - + + + JSON files (*.json);;All files (*) + Archivos JSON (*.json);;Todos los archivos (*) - - Images (%1) - + + Save failed + Error al guardar - - - QsLogging::LogWindowModel - - Time - + + Could not open file for writing: +%1 + No se pudo abrir el archivo para escribir:\n%1 - - Level - + + Load theme + Cargar tema - - Message - + + + + Load failed + Error al cargar - - - QsLogging::Window - - &Pause - + + Could not open file: +%1 + No se pudo abrir el archivo:\n%1 - - &Resume - + + Invalid JSON: +%1 + JSON no válido:\n%1 - - Save log - + + Expected a JSON object. + Se esperaba un objeto JSON. + + + TitleHeader - - Log file (*.log) - + + SEARCH + buscar - ShortcutsDialog + UpdateLibraryDialog - Close - Cerrar + + Updating.... + Actualizado... - YACReader keyboard shortcuts - Atajos de teclado de YACReader + + Cancel + Cancelar - Keyboard Shortcuts - Atajos de teclado + + Update library + Actualizar biblioteca Viewer - + Page not available! ¡Página no disponible! - - + + Press 'O' to open comic. Pulsa 'O' para abrir un fichero. - + Error opening comic Error abriendo cómic - + Cover! ¡Portada! - + CRC Error Error CRC - + Comic not found Cómic no encontrado - + Not found No encontrado - + Last page! ¡Última página! - + Loading...please wait! Cargando...espere, por favor! + + VolumeComicsModel + + + title + Título + + + + VolumesModel + + + year + año + + + + issues + números + + + + publisher + Editorial + + + + YACReader3DFlowConfigWidget + + + Presets: + Predefinidos: + + + + Classic look + Tipo clásico + + + + Stripe look + Tipo tira + + + + Overlapped Stripe look + Tipo tira solapada + + + + Modern look + Tipo moderno + + + + Roulette look + Tipo ruleta + + + + Show advanced settings + Opciones avanzadas + + + + Custom: + Personalizado: + + + + View angle + Ángulo de vista + + + + Position + Posición + + + + Cover gap + Hueco entre portadas + + + + Central gap + Hueco central + + + + Zoom + Ampliaci?n + + + + Y offset + Desplazamiento en Y + + + + Z offset + Desplazamiento en Z + + + + Cover Angle + Ángulo de las portadas + + + + Visibility + Visibilidad + + + + Light + Luz + + + + Max angle + Ángulo máximo + + + + Low Performance + Rendimiento bajo + + + + High Performance + Alto rendimiento + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Utilizar VSync (mejora la calidad de imagen en pantalla completa, peor rendimiento) + + + + Performance: + Rendimiento: + + YACReader::MainWindowViewer - + &Open &Abrir - + Open a comic Abrir cómic - + New instance Nueva instancia - + Open Folder Abrir carpeta - + Open image folder Abrir carpeta de imágenes - + Open latest comic Abrir el cómic más reciente - + Open the latest comic opened in the previous reading session Abrir el cómic más reciente abierto en la sesión de lectura anterior - + Clear Limpiar - + Clear open recent list Limpiar lista de abiertos recientemente - + Save Guardar - + Save current page Guardar la página actual @@ -772,285 +3362,296 @@ Cómic anterior - - - + + + Open previous comic Abrir cómic anterior - + Next Comic Siguiente Cómic - - - + + + Open next comic Abrir siguiente cómic - + &Previous A&nterior - - - + + + Go to previous page Ir a la página anterior - + &Next Siguie&nte - - - + + + Go to next page Ir a la página siguiente - + Fit Height Ajustar altura - + Fit image to height Ajustar página a lo alto - + Fit Width Ajustar anchura - + Fit image to width Ajustar página a lo ancho - + Show full size Mostrar a tamaño original - + Fit to page Ajustar a página - + + Continuous scroll + Desplazamiento continuo + + + + Switch to continuous scroll mode + Cambiar al modo de desplazamiento continuo + + + Reset zoom Restablecer zoom - + Show zoom slider Mostrar control deslizante de zoom - + Zoom+ - Zoom+ + Ampliar+ - + Zoom- - Zoom- + Reducir - + Rotate image to the left Rotar imagen a la izquierda - + Rotate image to the right Rotar imagen a la derecha - + Double page mode Modo a doble página - + Switch to double page mode Cambiar a modo de doble página - + Double page manga mode Modo de manga de página doble - + Reverse reading order in double page mode Invertir el orden de lectura en modo de página doble - + Go To Ir a - + Go to page ... Ir a página... - + Options Opciones - + YACReader options Opciones de YACReader - - + + Help Ayuda - + Help, About YACReader Ayuda, Sobre YACReader - + Magnifying glass Lupa - + Switch Magnifying glass Lupa On/Off - + Set bookmark Añadir marcador - + Set a bookmark on the current page Añadir un marcador en la página actual - + Show bookmarks Mostrar marcadores - + Show the bookmarks of the current comic Mostrar los marcadores del cómic actual - + Show keyboard shortcuts Mostrar atajos de teclado - + Show Info Mostrar información - + Close Cerrar - + Show Dictionary Mostrar diccionario - + Show go to flow Mostrar flow ir a - + Edit shortcuts Editar accesos directos - + &File &Archivo - - + + Open recent Abrir reciente - + File Archivo - + Edit Editar - + View Ver - + Go Ir - + Window Ventana - - - + + + Open Comic Abrir cómic - - - + + + Comic files Archivos de cómic - + Open folder Abrir carpeta - + page_%1.jpg página_%1.jpg - + Image files (*.jpg) Archivos de imagen (*.jpg) + Comics Cómics @@ -1066,9 +3667,10 @@ Ocultar/mostrar barra de herramientas + General - General + Opciones generales @@ -1096,6 +3698,7 @@ Resetear lupa + Magnifiying glass Lupa @@ -1106,112 +3709,131 @@ Alternar entre ajuste al ancho y ajuste al alto + Page adjustement Ajuste de página - + Autoscroll down Desplazamiento automático hacia abajo - + Autoscroll up Desplazamiento automático hacia arriba - + Autoscroll forward, horizontal first Desplazamiento automático hacia adelante, primero horizontal - + Autoscroll backward, horizontal first Desplazamiento automático hacia atrás, primero horizontal - + Autoscroll forward, vertical first Desplazamiento automático hacia adelante, primero vertical - + Autoscroll backward, vertical first Desplazamiento automático hacia atrás, primero vertical - + Move down Mover abajo - + Move up Mover arriba - + Move left Mover a la izquierda - + Move right Mover a la derecha - + Go to the first page Ir a la primera página - + Go to the last page Ir a la última página - + Offset double page to the left Mover una página a la izquierda - + Offset double page to the right Mover una página a la derecha - + + Reading Leyendo - + There is a new version available Hay una nueva versión disponible - + Do you want to download the new version? ¿Desea descargar la nueva versión? - + Remind me in 14 days Recordar en 14 días - + Not now Ahora no + + YACReader::TrayIconController + + + &Restore + &Restaurar + + + + Systray + Bandeja del sistema + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary se continuará ejecutando en la bandeja del sistema. Para cerrar el programa elige <b>Cerrar</b> en el menú contextual del icono de la aplicación en la bandeja del sistema. + + YACReader::WhatsNewDialog - Close - Cerrar + Cerrar @@ -1225,7 +3847,7 @@ Click to overwrite - Click para sobreescribir + Clic para sobrescribir @@ -1241,206 +3863,186 @@ Click to overwrite - Click para sobreescribir + Clic para sobrescribir YACReaderFlowConfigWidget - CoverFlow look - Tipo CoverFlow + Tipo CoverFlow - How to show covers: - Cómo mostrar las portadas: + Cómo mostrar las portadas: - Stripe look - Tipo tira + Tipo tira - Overlapped Stripe look - Tipo tira solapada + Tipo tira solapada YACReaderGLFlowConfigWidget - Zoom - Zoom + Ampliaci?n - Light - Luz + Luz - Show advanced settings - Opciones avanzadas + Opciones avanzadas - Roulette look - Tipo ruleta + Tipo ruleta - Cover Angle - Ángulo de las portadas + Ángulo de las portadas - Stripe look - Tipo tira + Tipo tira - Position - Posición + Posición - Z offset - Desplazamiento en Z + Desplazamiento en Z - Y offset - Desplazamiento en Y + Desplazamiento en Y - Central gap - Hueco central + Hueco central - Presets: - Predefinidos: + Predefinidos: - Overlapped Stripe look - Tipo tira solapada + Tipo tira solapada - Modern look - Tipo moderno + Tipo moderno - View angle - Ángulo de vista + Ángulo de vista - Max angle - Ángulo máximo + Ángulo máximo - Custom: - Personalizado: + Personalizado: - Classic look - Tipo clásico + Tipo clásico - Cover gap - Hueco entre portadas + Hueco entre portadas - High Performance - Alto rendimiento + Alto rendimiento - Performance: - Rendimiento: + Rendimiento: - Use VSync (improve the image quality in fullscreen mode, worse performance) - Utilizar VSync (mejora la calidad de imagen en pantalla completa, peor rendimiento) + Utilizar VSync (mejora la calidad de imagen en pantalla completa, peor rendimiento) - Visibility - Visibilidad + Visibilidad - Low Performance - Rendimiento bajo + Rendimiento bajo YACReaderOptionsDialog - + Save Guardar - Use hardware acceleration (restart needed) - Utilizar aceleración por hardware (necesario reiniciar) + Utilizar aceleración por hardware (necesario reiniciar) - + Cancel Cancelar - + Edit shortcuts Editar accesos directos - + Shortcuts Accesos directos + + YACReaderSearchLineEdit + + + type to search + escribe para buscar + + YACReaderSlider Reset - Reset + Restablecer YACReaderTranslator - + clear limpiar - + Service not available Servicio no disponible - - + + Translation Traducción - + YACReader translator Traductor YACReader diff --git a/YACReader/yacreader_fr.ts b/YACReader/yacreader_fr.ts index 967308c28..70d120a19 100644 --- a/YACReader/yacreader_fr.ts +++ b/YACReader/yacreader_fr.ts @@ -9,6 +9,196 @@ Rien + + AddLabelDialog + + + Label name: + Nom de l'étiquette : + + + + Choose a color: + Choisissez une couleur: + + + + accept + accepter + + + + cancel + Annuler + + + + AddLibraryDialog + + + Comics folder : + Dossier des bandes dessinées : + + + + Library name : + Nom de la librairie : + + + + Add + Ajouter + + + + Cancel + Annuler + + + + Add an existing library + Ajouter une librairie existante + + + + ApiKeyDialog + + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Avant de pouvoir vous connecter à Comic Vine, vous avez besoin de votre propre clé API. Veuillez en obtenir une gratuitement ici: <a href="http://www.comicvine.com/api/"></a> + + + + Paste here your Comic Vine API key + Collez ici votre clé API Comic Vine + + + + Accept + Accepter + + + + Cancel + Annuler + + + + AppearanceTabWidget + + + Color scheme + Jeu de couleurs + + + + System + Système + + + + Light + Lumière + + + + Dark + Sombre + + + + Custom + Coutume + + + + Remove + Retirer + + + + Remove this user-imported theme + Supprimer ce thème importé par l'utilisateur + + + + Light: + Lumière: + + + + Dark: + Sombre: + + + + Custom: + Personnalisation: + + + + Import theme... + Importer le thème... + + + + Theme + Thème + + + + Theme editor + Éditeur de thème + + + + Open Theme Editor... + Ouvrir l'éditeur de thème... + + + + Theme editor error + Erreur de l'éditeur de thème + + + + The current theme JSON could not be loaded. + Le thème actuel JSON n'a pas pu être chargé. + + + + Import theme + Importer un thème + + + + JSON files (*.json);;All files (*) + Fichiers JSON (*.json);;Tous les fichiers (*) + + + + Could not import theme from: +%1 + Impossible d'importer le thème depuis : +%1 + + + + Could not import theme from: +%1 + +%2 + Impossible d'importer le thème depuis : +%1 + +%2 + + + + Import failed + Échec de l'importation + + BookmarksDialog @@ -33,10 +223,204 @@ Aller à la dernière page + + ClassicComicsView + + + Hide comic flow + Cacher le flux de bande dessinée + + + + ComicModel + + + yes + oui + + + + no + non + + + + Title + Titre + + + + File Name + Nom du fichier + + + + Pages + Feuilles + + + + Size + Taille + + + + Read + Lu + + + + Current Page + Page en cours + + + + Publication Date + Date de publication + + + + Rating + Note + + + + Series + Série + + + + Volume + Tome + + + + Story Arc + Arc d'histoire + + + + ComicVineDialog + + + skip + passer + + + + back + retour + + + + next + suivant + + + + search + chercher + + + + close + fermer + + + + + comic %1 of %2 - %3 + bande dessinée %1 sur %2 - %3 + + + + + + Looking for volume... + Vous cherchez du volume... + + + + %1 comics selected + %1 bande(s) dessinnée(s) sélectionnée(s) + + + + Error connecting to ComicVine + Erreur de connexion à Comic Vine + + + + + Retrieving tags for : %1 + Retrouver les infomartions de: %1 + + + + Retrieving volume info... + Récupération des informations sur le volume... + + + + Looking for comic... + Vous cherchez une bande dessinée ... + + + + ContinuousPageWidget + + + Loading page %1 + Chargement de la page %1 + + + + CreateLibraryDialog + + + Comics folder : + Dossier des bandes dessinées : + + + + Library Name : + Nom de la librairie : + + + + Create + Créer + + + + Cancel + Annuler + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et continuer plus tard. + + + + Create new library + Créer une nouvelle librairie + + + + Path not found + Chemin introuvable + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + Le chemin sélectionné n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + + EditShortcutsDialog - + Shortcut in use Raccourci en cours d'utilisation @@ -51,7 +435,7 @@ Paramètres de raccourcis - + The shortcut "%1" is already assigned to other function Le raccourci "%1" est déjà affecté à une autre fonction @@ -61,6 +445,124 @@ Pour modifier un raccourci, double-cliquez sur la combinaison de touches et tapez les nouvelles clés. + + EmptyFolderWidget + + + This folder doesn't contain comics yet + Ce dossier ne contient pas encore de bandes dessinées + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + Ce dossier ne contient pas encore de bandes dessinées + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + Cette liste de lecture ne contient aucune bande dessinée + + + + EmptySpecialListWidget + + + No favorites + Pas de favoris + + + + You are not reading anything yet, come on!! + Vous ne lisez rien encore, allez !! + + + + There are no recent comics! + Il n'y a pas de BD récente ! + + + + ExportComicsInfoDialog + + + Output file : + Fichier de sortie : + + + + Create + Créer + + + + Cancel + Annuler + + + + Export comics info + Exporter les infos des bandes dessinées + + + + Destination database name + Nom de la base de données de destination + + + + Problem found while writing + Problème durant l'écriture + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + + + + ExportLibraryDialog + + + Output folder : + Dossier de sortie : + + + + Create + Créer + + + + Cancel + Annuler + + + + Create covers package + Créer un pack de couvertures + + + + Problem found while writing + Problème durant l'écriture + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + + + + Destination directory + Répertoire de destination + + FileComic @@ -110,1264 +612,3402 @@ Page : - Page : + Feuille : GoToFlowToolBar - + Page : - Page : + Feuille : + + + + GridComicsView + + + Show info + Afficher les informations HelpAboutDialog - + Help Aide - + System info - + Informations système - + About A propos - LogWindow + ImportComicsInfoDialog + + + Import comics info + Importer les infos des bandes dessinées + + + + Info database location : + Emplacement des infos: + + + + Import + Importer + + + + Cancel + Annuler + + + + Comics info file (*.ydb) + Fichier infos BD (*.ydb) + + + + ImportLibraryDialog + + + Library Name : + Nom de la librairie : + + + + Package location : + Emplacement : + + + + Destination folder : + Dossier de destination : + + + + Unpack + Désarchiver + + + + Cancel + Annuler + + + + Extract a catalog + Extraire un catalogue + + + + Compresed library covers (*.clc) + Couvertures de bibliothèque compressées (*.clc) + + + + ImportWidget + + + stop + Arrêter + + + + Some of the comics being added... + Ajout de bande dessinée... + + + + Importing comics + Importation de bande dessinée + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary est en train de créer une nouvelle librairie.</p><p>La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et poursuivre plus tard.</p> + + + + Updating the library + Mise à jour de la librairie + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>Mise à jour de la librairie. Pour plus de rapidité lors de la mise à jour, veuillez effectuer cette dernière régulièrement.</p><p>Vous pouvez arrêter le processus et poursuivre plus tard.</p> + + + + Upgrading the library + Mise à niveau de la bibliothèque + + + + <p>The current library is being upgraded, please wait.</p> + <p>La bibliothèque actuelle est en cours de mise à niveau, veuillez patienter.</p> + + + + Scanning the library + Scanner la bibliothèque + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>La bibliothèque actuelle est en cours d'analyse pour rechercher des informations sur les métadonnées XML héritées.</p><p>Ceci n'est nécessaire qu'une seule fois, et uniquement si la bibliothèque a été créée avec YACReaderLibrary 9.8.2 ou une version antérieure.</p> + + + + LibraryWindow + + + YACReader Library + Librairie de YACReader + + + + + + comic + comique + + + + + + manga + mangas + + + + + + western manga (left to right) + manga occidental (de gauche à droite) + + + + + + web comic + bande dessinée Web + + + + + + 4koma (top to botom) + 4koma (de haut en bas) + + + + + + + Set type + Définir le type + + + + Library + Librairie + + + + Folder + Dossier + + + + Comic + Bande dessinée + + + + Upgrade failed + La mise à niveau a échoué + + + + There were errors during library upgrade in: + Des erreurs se sont produites lors de la mise à niveau de la bibliothèque dans : + + + + Update needed + Mise à jour requise + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Cette librairie a été créée avec une ancienne version de YACReaderLibrary. Mise à jour necessaire. Mettre à jour? + + + + Download new version + Téléchrger la nouvelle version + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Cette librairie a été créée avec une version plus récente de YACReaderLibrary. Télécharger la nouvelle version? + + + + Library not available + Librairie non disponible + + + + Library '%1' is no longer available. Do you want to remove it? + La librarie '%1' n'est plus disponible. Voulez-vous la supprimer? + + + + Old library + Ancienne librairie + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La librarie '%1' a été créée avec une ancienne version de YACReaderLibrary. Elle doit être re-créée. Voulez-vous créer la librairie? + + + + + Copying comics... + Copier la bande dessinée... + + + + + Moving comics... + Déplacer la bande dessinée... + + + + Add new folder + Ajouter un nouveau dossier + + + + Folder name: + Nom du dossier : + + + + No folder selected + Aucun dossier sélectionné + + + + Please, select a folder first + Veuillez d'abord sélectionner un dossier + + + + Error in path + Erreur dans le chemin + + + + There was an error accessing the folder's path + Une erreur s'est produite lors de l'accès au chemin du dossier + + + + Delete folder + Supprimer le dossier + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + Le dossier sélectionné et tout son contenu seront supprimés de votre disque. Es-tu sûr? + + + + + Unable to delete + Impossible de supprimer + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Un problème est survenu lors de la tentative de suppression des dossiers sélectionnés. Veuillez vérifier les autorisations d'écriture et assurez-vous que toutes les applications utilisent ces dossiers ou l'un des fichiers contenus. + + + + Add new reading lists + Ajouter de nouvelles listes de lecture + + + + + List name: + Nom de la liste : + + + + Delete list/label + Supprimer la liste/l'étiquette + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + L'élément sélectionné sera supprimé, vos bandes dessinées ou dossiers ne seront pas supprimés de votre disque. Êtes-vous sûr? + + + + Rename list name + Renommer le nom de la liste + + + + Open folder... + Ouvrir le dossier... + + + + Update folder + Mettre à jour le dossier + + + + Rescan library for XML info + Réanalyser la bibliothèque pour les informations XML + + + + Set as uncompleted + Marquer comme incomplet + + + + Set as completed + Marquer comme complet + + + + Set as read + Marquer comme lu + + + + + Set as unread + Marquer comme non-lu + + + + Set custom cover + Définir une couverture personnalisée + + + + Delete custom cover + Supprimer la couverture personnalisée + + + + Save covers + Enregistrer les couvertures + + + + You are adding too many libraries. + Vous ajoutez trop de bibliothèques. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Vous ajoutez trop de bibliothèques. + +Vous n'avez probablement besoin que d'une bibliothèque dans votre dossier BD de niveau supérieur, vous pouvez parcourir les sous-dossiers en utilisant la section des dossiers dans la barre latérale gauche. + +YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais vous devriez garder le nombre de bibliothèques bas. + + + + + YACReader not found + YACReader introuvable + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader introuvable. YACReader doit être installé dans le même dossier que YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader introuvable. Il se peut qu'il y ait un problème avec votre installation de YACReader. + + + + Error + Erreur + + + + Error opening comic with third party reader. + Erreur lors de l'ouverture de la bande dessinée avec un lecteur tiers. + + + + Library not found + Librairie introuvable + + + + The selected folder doesn't contain any library. + Le dossier sélectionné ne contient aucune librairie. + + + + Are you sure? + Êtes-vous sûr? + + + + Do you want remove + Voulez-vous supprimer + + + + library? + la librairie? + + + + Remove and delete metadata + Supprimer les métadata + + + + Library info + Informations sur la bibliothèque + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Un problème est survenu lors de la tentative de suppression des bandes dessinées sélectionnées. Veuillez vérifier les autorisations d'écriture dans les fichiers sélectionnés ou le dossier contenant. + + + + Assign comics numbers + Attribuer des numéros de bandes dessinées + + + + Assign numbers starting in: + Attribuez des numéros commençant par : + + + + Invalid image + Image invalide + + + + The selected file is not a valid image. + Le fichier sélectionné n'est pas une image valide. + + + + Error saving cover + Erreur lors de l'enregistrement de la couverture + + + + There was an error saving the cover image. + Une erreur s'est produite lors de l'enregistrement de l'image de couverture. + + + + Error creating the library + Erreur lors de la création de la librairie + + + + Error updating the library + Erreur lors de la mise à jour de la librairie + + + + Error opening the library + Erreur lors de l'ouverture de la librairie + + + + Delete comics + Supprimer les comics + + + + All the selected comics will be deleted from your disk. Are you sure? + Tous les comics sélectionnés vont être supprimés de votre disque. Êtes-vous sûr? + + + + Remove comics + Supprimer les bandes dessinées + + + + Comics will only be deleted from the current label/list. Are you sure? + Les bandes dessinées seront uniquement supprimées du label/liste actuelle. Es-tu sûr? + + + + Library name already exists + Le nom de la librairie existe déjà + + + + There is another library with the name '%1'. + Une autre librairie a le nom '%1'. + + + + LibraryWindowActions + + + Create a new library + Créer une nouvelle librairie + + + + Open an existing library + Ouvrir une librairie existante + + + + + Export comics info + Exporter les infos des bandes dessinées + + + + + Import comics info + Importer les infos des bandes dessinées + + + + Pack covers + Archiver les couvertures + + + + Pack the covers of the selected library + Archiver les couvertures de la librairie sélectionnée + + + + Unpack covers + Désarchiver les couvertures + + + + Unpack a catalog + Désarchiver un catalogue + + + + Update library + Mettre la librairie à jour + + + + Update current library + Mettre à jour la librairie actuelle + + + + Rename library + Renommer la librairie + + + + Rename current library + Renommer la librairie actuelle + + + + Remove library + Supprimer la librairie + + + + Remove current library from your collection + Enlever cette librairie de votre collection + + + + Rescan library for XML info + Réanalyser la bibliothèque pour les informations XML + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Essaie de trouver des informations XML intégrées dans des fichiers de bandes dessinées. Vous ne devez le faire que si la bibliothèque a été créée avec la version 9.8.2 ou des versions antérieures ou si vous utilisez un logiciel tiers pour intégrer des informations XML dans les fichiers. + + + + Show library info + Afficher les informations sur la bibliothèque + + + + Show information about the current library + Afficher des informations sur la bibliothèque actuelle + + + + Open current comic + Ouvrir cette bande dessinée + + + + Open current comic on YACReader + Ouvrir cette bande dessinée dans YACReader + + + + Save selected covers to... + Exporter la couverture vers... + + + + Save covers of the selected comics as JPG files + Enregistrer les couvertures des bandes dessinées sélectionnées en tant que fichiers JPG + + + + + Set as read + Marquer comme lu + + + + Set comic as read + Marquer cette bande dessinée comme lu + + + + + Set as unread + Marquer comme non-lu + + + + Set comic as unread + Marquer cette bande dessinée comme non-lu + + + + + manga + mangas + + + + Set issue as manga + Définir le problème comme manga + + + + + comic + comique + + + + Set issue as normal + Définir le problème comme d'habitude + + + + western manga + manga occidental + + + + Set issue as western manga + Définir le problème comme un manga occidental + + + + + web comic + bande dessinée Web + + + + Set issue as web comic + Définir le problème comme bande dessinée Web + + + + + yonkoma + Yonkoma + + + + Set issue as yonkoma + Définir le problème comme Yonkoma + + + + Show/Hide marks + Afficher/Cacher les marqueurs + + + + Show or hide read marks + Afficher ou masquer les marques de lecture + + + + Show/Hide recent indicator + Afficher/Masquer l'indicateur récent + + + + Show or hide recent indicator + Afficher ou masquer l'indicateur récent + + + + + Fullscreen mode on/off + Mode plein écran activé/désactivé + + + + Help, About YACReader + Aide, à propos de YACReader + + + + Add new folder + Ajouter un nouveau dossier + + + + Add new folder to the current library + Ajouter un nouveau dossier à la bibliothèque actuelle + + + + Delete folder + Supprimer le dossier + + + + Delete current folder from disk + Supprimer le dossier actuel du disque + + + + Select root node + Allerà la racine + + + + Expand all nodes + Afficher tous les noeuds + + + + Collapse all nodes + Réduire tous les nœuds + + + + Show options dialog + Ouvrir la boite de dialogue + + + + Show comics server options dialog + Ouvrir la boite de dialogue du serveur + + + + + Change between comics views + Changement entre les vues de bandes dessinées + + + + Open folder... + Ouvrir le dossier... + + + + Set as uncompleted + Marquer comme incomplet + + + + Set as completed + Marquer comme complet + + + + Set custom cover + Définir une couverture personnalisée + + + + Delete custom cover + Supprimer la couverture personnalisée + + + + western manga (left to right) + manga occidental (de gauche à droite) + + + + Open containing folder... + Ouvrir le dossier... + + + + Reset comic rating + Supprimer la note d'évaluation + + + + Select all comics + Sélectionner toutes les bandes dessinées + + + + Edit + Editer + + + + Assign current order to comics + Assigner l'ordre actuel aux bandes dessinées + + + + Update cover + Mise à jour des couvertures + + + + Delete selected comics + Supprimer la bande dessinée sélectionnée + + + + Delete metadata from selected comics + Supprimer les métadonnées des bandes dessinées sélectionnées + + + + Download tags from Comic Vine + Télécharger les informations de Comic Vine + + + + Focus search line + Ligne de recherche ciblée + + + + Focus comics view + Focus sur la vue des bandes dessinées + + + + Edit shortcuts + Modifier les raccourcis + + + + &Quit + &Quitter + + + + Update folder + Mettre à jour le dossier + + + + Update current folder + Mettre à jour ce dossier + + + + Scan legacy XML metadata + Analyser les métadonnées XML héritées + + + + Add new reading list + Ajouter une nouvelle liste de lecture + + + + Add a new reading list to the current library + Ajouter une nouvelle liste de lecture à la bibliothèque actuelle + + + + Remove reading list + Supprimer la liste de lecture + + + + Remove current reading list from the library + Supprimer la liste de lecture actuelle de la bibliothèque + + + + Add new label + Ajouter une nouvelle étiquette + + + + Add a new label to this library + Ajouter une nouvelle étiquette à cette bibliothèque + + + + Rename selected list + Renommer la liste sélectionnée + + + + Rename any selected labels or lists + Renommer toutes les étiquettes ou listes sélectionnées + + + + Add to... + Ajouter à... + + + + Favorites + Favoris + + + + Add selected comics to favorites list + Ajouter la bande dessinée sélectionnée à la liste des favoris + + + + LocalComicListModel + + + file name + nom de fichier + + + + MainWindowViewer + + Go + Aller + + + Edit + Editer + + + File + Fichier + + + Help + Aide + + + Save + Sauvegarder + + + View + Vue + + + &File + &Fichier + + + &Next + &Suivant + + + &Open + &Ouvrir + + + Close + Fermer + + + Open Comic + Ouvrir la bande dessinée + + + Go To + Aller à + + + Zoom+ + Agrandir + + + Zoom- + R?duire + + + Open image folder + Ouvrir un dossier d'images + + + Size down magnifying glass + Réduire la taille de la loupe + + + Zoom out magnifying glass + Dézoomer + + + Open latest comic + Ouvrir la dernière bande dessinée + + + Autoscroll up + Défilement automatique vers le haut + + + Set bookmark + Placer un marque-page + + + page_%1.jpg + feuille_%1.jpg + + + Autoscroll forward, vertical first + Défilement automatique en avant, vertical + + + Switch to double page mode + Passer en mode double page + + + Save current page + Sauvegarder la page actuelle + + + Size up magnifying glass + Augmenter la taille de la loupe + + + Double page mode + Mode double page + + + Move up + Monter + + + Switch Magnifying glass + Utiliser la loupe + + + Open Folder + Ouvrir un dossier + + + Comics + Bandes dessinées + + + Fit Height + Ajuster la hauteur + + + Autoscroll backward, vertical first + Défilement automatique en arrière, verticak + + + Comic files + Bande dessinée + + + Not now + Pas maintenant + + + Go to the first page + Aller à la première page + + + Go to previous page + Aller à la page précédente + + + Window + Fenêtre + + + Open the latest comic opened in the previous reading session + Ouvrir la dernière bande dessinée ouverte lors de la session de lecture précédente + + + Open a comic + Ouvrir une bande dessinée + + + Image files (*.jpg) + Image(*.jpg) + + + Next Comic + Bande dessinée suivante + + + Fit Width + Ajuster la largeur + + + Options + Possibilités + + + Show Info + Voir les infos + + + Open folder + Ouvirir le dossier + + + Go to page ... + Aller à la page ... + + + Magnifiying glass + Loupe + + + Fit image to width + Ajuster l'image à la largeur + + + Toggle fullscreen mode + Basculer en mode plein écran + + + Toggle between fit to width and fit to height + Basculer entre adapter à la largeur et adapter à la hauteur + + + Move right + Déplacer à droite + + + Zoom in magnifying glass + Zoomer + + + Open recent + Ouvrir récent + + + Reading + Lecture + + + &Previous + &Précédent + + + Autoscroll forward, horizontal first + Défilement automatique en avant, horizontal + + + Go to next page + Aller à la page suivante + + + Show keyboard shortcuts + Voir les raccourcis + + + Double page manga mode + Mode manga en double page + + + There is a new version available + Une nouvelle version est disponible + + + Autoscroll down + Défilement automatique vers le bas + + + Open next comic + Ouvrir la bande dessinée suivante + + + Remind me in 14 days + Rappelez-moi dans 14 jours + + + Fit to page + Ajuster à la page + + + Show bookmarks + Voir les marque-pages + + + Open previous comic + Ouvrir la bande dessiné précédente + + + Rotate image to the left + Rotation à gauche + + + Fit image to height + Ajuster l'image à la hauteur + + + Reset zoom + Réinitialiser le zoom + + + Show the bookmarks of the current comic + Voir les marque-pages de cette bande dessinée + + + Show Dictionary + Dictionnaire + + + Move down + Descendre + + + Move left + Déplacer à gauche + + + Reverse reading order in double page mode + Ordre de lecture inversée en mode double page + + + YACReader options + Options de YACReader + + + Clear open recent list + Vider la liste d'ouverture récente + + + Help, About YACReader + Aide, à propos de YACReader + + + Show go to flow + Afficher le flux + + + Previous Comic + Bande dessinée précédente + + + Show full size + Plein écran + + + Hide/show toolbar + Masquer / afficher la barre d'outils + + + Magnifying glass + Loupe + + + Edit shortcuts + Modifier les raccourcis + + + General + Général + + + Set a bookmark on the current page + Placer un marque-page sur la page actuelle + + + Page adjustement + Ajustement de la page + + + Show zoom slider + Afficher le curseur de zoom + + + Go to the last page + Aller à la dernière page + + + Do you want to download the new version? + Voulez-vous télécharger la nouvelle version? + + + Rotate image to the right + Rotation à droite + + + Always on top + Toujours au dessus + + + Autoscroll backward, horizontal first + Défilement automatique en arrière horizontal + + + + NoLibrariesWidget + + + You don't have any libraries yet + Vous n'avez pas encore de librairie + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Vous pouvez creer une librairie dans n'importe quel dossierr, YACReaderLibrary importera les dossiers et les bandes dessinées contenus dans ce dossier. Si vous avez déjà crer des librairies, vous pouvez les ouvrir.</p><p>N'oubliez pas que vous pouvez utiliser YACReader en tant que stand alone pour lire vos bandes dessinées sur votre ordinateur.</p> + + + + create your first library + Créez votre première librairie + + + + add an existing one + Ajouter une librairie existante + + + + NoSearchResultsWidget + + + No results + Aucun résultat + + + + OptionsDialog + + + Gamma + Valeur gamma + + + + Reset + Remise à zéro + + + + My comics path + Chemin de mes bandes dessinées + + + + Image adjustment + Ajustement de l'image + + + + "Go to flow" size + Taille du flux + + + + Choose + Choisir + + + + Image options + Option de l'image + + + + Contrast + Contraste + + + + + Libraries + Bibliothèques + + + + Comic Flow + Flux comique + + + + Grid view + Vue grille + + + + + Appearance + Apparence + + + + + Options + Possibilités + + + + + Language + Langue + + + + + Application language + Langue de l'application + + + + + System default + Par défaut du système + + + + Tray icon settings (experimental) + Paramètres de l'icône de la barre d'état (expérimental) + + + + Close to tray + Près du plateau + + + + Start into the system tray + Commencez dans la barre d'état système + + + + Edit Comic Vine API key + Modifier la clé API Comic Vine + + + + Comic Vine API key + Clé API Comic Vine + + + + ComicInfo.xml legacy support + Prise en charge héritée de ComicInfo.xml + + + + Import metadata from ComicInfo.xml when adding new comics + Importer des métadonnées depuis ComicInfo.xml lors de l'ajout de nouvelles bandes dessinées + + + + Consider 'recent' items added or updated since X days ago + Considérez les éléments « récents » ajoutés ou mis à jour depuis X jours + + + + Third party reader + Lecteur tiers + + + + Write {comic_file_path} where the path should go in the command + Écrivez {comic_file_path} où le chemin doit aller dans la commande + + + + + Clear + Clair + + + + Update libraries at startup + Mettre à jour les bibliothèques au démarrage + + + + Try to detect changes automatically + Essayez de détecter automatiquement les changements + + + + Update libraries periodically + Mettre à jour les bibliothèques périodiquement + + + + Interval: + Intervalle: + + + + 30 minutes + 30 min + + + + 1 hour + 1 heure + + + + 2 hours + 2 heures + + + + 4 hours + 4 heures + + + + 8 hours + 8 heures + + + + 12 hours + 12 heures + + + + daily + tous les jours + + + + Update libraries at certain time + Mettre à jour les bibliothèques à un certain moment + + + + Time: + Temps: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + AVERTISSEMENT! Lors des mises à jour de la bibliothèque, les écritures dans la base de données sont désactivées ! +Ne planifiez pas de mises à jour pendant que vous utilisez activement l'application. +Lors des mises à jour automatiques, l'application bloquera certaines actions jusqu'à ce que la mise à jour soit terminée. +Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de chargement à côté du titre Bibliothèques. + + + + Modifications detection + Détection des modifications + + + + Compare the modified date of files when updating a library (not recommended) + Comparer la date de modification des fichiers lors de la mise à jour d'une bibliothèque (déconseillé) + + + + Enable background image + Activer l'image d'arrière-plan + + + + Opacity level + Niveau d'opacité + + + + Blur level + Niveau de flou + + + + Use selected comic cover as background + Utiliser la couverture de bande dessinée sélectionnée comme arrière-plan + + + + Restore defautls + Restaurer les valeurs par défaut + + + + Background + Arrière-plan + + + + Display continue reading banner + Afficher la bannière de lecture continue + + + + Display current comic banner + Afficher la bannière de bande dessinée actuelle + + + + Continue reading + Continuer la lecture + + + + Comics directory + Répertoire des bandes dessinées + + + + Quick Navigation Mode + Mode navigation rapide + + + + Display + Afficher + + + + Show time in current page information label + Afficher l'heure dans l'étiquette d'information de la page actuelle + + + + Background color + Couleur d'arrière plan + + + + Scroll behaviour + Comportement de défilement + + + + Disable scroll animations and smooth scrolling + Désactiver les animations de défilement et le défilement fluide + + + + Do not turn page using scroll + Ne tournez pas la page en utilisant le défilement + + + + Use single scroll step to turn page + Utilisez une seule étape de défilement pour tourner la page + + + + Mouse mode + Mode souris + + + + Only Back/Forward buttons can turn pages + Seuls les boutons Précédent/Avant peuvent tourner les pages + + + + Use the Left/Right buttons to turn pages. + Utilisez les boutons Gauche/Droite pour tourner les pages. + + + + Click left or right half of the screen to turn pages. + Cliquez sur la moitié gauche ou droite de l'écran pour tourner les pages. + + + + Disable mouse over activation + Désactiver la souris sur l'activation + + + + Scaling + Mise à l'échelle + + + + Scaling method + Méthode de mise à l'échelle + + + + Nearest (fast, low quality) + Le plus proche (rapide, mauvaise qualité) + + + + Bilinear + Bilinéaire + + + + Lanczos (better quality) + Lanczos (meilleure qualité) + + + + Page Flow + Flux des pages + + + + + General + Général + + + + Brightness + Luminosité + + + + + Restart is needed + Redémarrage nécessaire + + + + Fit options + Options d'ajustement + + + + Enlarge images to fit width/height + Agrandir les images pour les adapter à la largeur/hauteur + + + + Double Page options + Options de double page + + + + Show covers as single page + Afficher les couvertures sur une seule page + + + + PropertiesDialog - - Log window - + + General info + Infos générales - - &Pause - + + Plot + Intrigue - - &Save - + + Authors + Auteurs - - C&lear - + + Publishing + Publication - - &Copy - + + Notes + Remarques - - Level: - + + Cover page + Couverture - - &Auto scroll - + + Load previous page as cover + Charger la page précédente comme couverture - - - MainWindowViewer - Go - Aller + + Load next page as cover + Charger la page suivante comme couverture - Edit - Editer + + Reset cover to the default image + Réinitialiser la couverture à l'image par défaut - File - Fichier + + Load custom cover image + Charger une image de couverture personnalisée - Help - Aide + + Series: + Série: - Save - Sauvegarder + + Title: + Titre: - View - Vue + + + + of: + sur: - &File - &Fichier + + Issue number: + Numéro: - &Next - &Suivant + + Volume: + Tome : - &Open - &Ouvrir + + Arc number: + Arc numéro: - Close - Fermer + + Story arc: + Arc narratif: - Open Comic - Ouvrir la bande dessinée + + alt. number: + alt. nombre: - Go To - Aller à + + Alternate series: + Série alternative : - Zoom+ - Zoom+ + + Series Group: + Groupe de séries : - Zoom- - Zoom- + + Genre: + Genre : - Open image folder - Ouvrir un dossier d'images + + Size: + Taille: - Size down magnifying glass - Réduire la taille de la loupe + + Writer(s): + Scénariste(s): - Zoom out magnifying glass - Dézoomer + + Penciller(s): + Dessinateur(s): - Open latest comic - Ouvrir la dernière bande dessinée + + Inker(s): + Encreur(s): - Autoscroll up - Défilement automatique vers le haut + + Colorist(s): + Coloriste(s): - Set bookmark - Placer un marque-page + + Letterer(s): + Lettreur(s): - page_%1.jpg - page_%1.jpg + + Cover Artist(s): + Artiste(s) de couverture: - Autoscroll forward, vertical first - Défilement automatique en avant, vertical + + Editor(s): + Editeur(s) : - Switch to double page mode - Passer en mode double page + + Imprint: + Imprimer: - Save current page - Sauvegarder la page actuelle + + Day: + Jour: - Size up magnifying glass - Augmenter la taille de la loupe + + Month: + Mois: - Double page mode - Mode double page + + Year: + Année: - Move up - Monter + + Publisher: + Editeur: - Switch Magnifying glass - Utiliser la loupe + + Format: + Format : - Open Folder - Ouvrir un dossier + + Color/BW: + Couleur/Noir et blanc: - Comics - Bandes dessinées + + Age rating: + Limite d'âge: - Fit Height - Ajuster la hauteur + + Type: + Taper: - Autoscroll backward, vertical first - Défilement automatique en arrière, verticak + + Language (ISO): + Langue (ISO) : - Comic files - Bande dessinée + + Synopsis: + Synopsis : - Not now - Pas maintenant + + Characters: + Personnages: - Go to the first page - Aller à la première page + + Teams: + Équipes : - Go to previous page - Aller à la page précédente + + Locations: + Emplacements : - Window - Fenêtre + + Main character or team: + Personnage principal ou équipe : - Open the latest comic opened in the previous reading session - Ouvrir la dernière bande dessinée ouverte lors de la session de lecture précédente + + Review: + Revoir: - Open a comic - Ouvrir une bande dessinée + + Notes: + Remarques : - Image files (*.jpg) - Image(*.jpg) + + Tags: + Balises : - Next Comic - Bande dessinée suivante + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Lien Comic Vine : <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> vue </a> - Fit Width - Ajuster la largeur + + Not found + Introuvable - Options - Options + + Comic not found. You should update your library. + Comic introuvable. Vous devriez mettre à jour votre librairie. - Show Info - Voir les infos + + Edit comic information + Editer les informations du comic - Open folder - Ouvirir le dossier + + Edit selected comics information + Editer les informations du comic sélectionné - Go to page ... - Aller à la page ... + + Invalid cover + Couverture invalide - Magnifiying glass - Loupe + + The image is invalid. + L'image n'est pas valide. + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer est la version sans tête (sans interface graphique) de YACReaderLibrary. + +Cette application prend en charge les paramètres persistants, pour les configurer, modifiez ce fichier %1 +Pour en savoir plus sur les paramètres disponibles, veuillez consulter la documentation sur https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + QObject - Fit image to width - Ajuster l'image à la largeur + + 7z lib not found + lib 7z introuvable - Toggle fullscreen mode - Basculer en mode plein écran + + unable to load 7z lib from ./utils + impossible de charger 7z depuis ./utils - Toggle between fit to width and fit to height - Basculer entre adapter à la largeur et adapter à la hauteur + + Trace + Tracer - Move right - Déplacer à droite + + Debug + Déboguer - Zoom in magnifying glass - Zoomer + + Info + Informations - Open recent - Ouvrir récent + + Warning + Avertissement - Reading - Lecture + + Error + Erreur - &Previous - &Précédent + + Fatal + Critique - Autoscroll forward, horizontal first - Défilement automatique en avant, horizontal + + Select custom cover + Sélectionnez une couverture personnalisée - Go to next page - Aller à la page suivante + + Images (%1) + Illustrations (%1) - Show keyboard shortcuts - Voir les raccourcis + + The file could not be read or is not valid JSON. + Le fichier n'a pas pu être lu ou n'est pas un JSON valide. - Double page manga mode - Mode manga en double page + + This theme is for %1, not %2. + Ce thème est pour %1, pas pour %2. - There is a new version available - Une nouvelle version est disponible + + Libraries + Bibliothèques - Autoscroll down - Défilement automatique vers le bas + + Folders + Dossiers - Open next comic - Ouvrir la bande dessinée suivante + + Reading Lists + Listes de lecture + + + RenameLibraryDialog - Remind me in 14 days - Rappelez-moi dans 14 jours + + New Library Name : + Nouveau nom de librairie: - Fit to page - Ajuster à la page + + Rename + Renommer - Show bookmarks - Voir les marque-pages + + Cancel + Annuler - Open previous comic - Ouvrir la bande dessiné précédente + + Rename current library + Renommer la librairie actuelle + + + ScraperResultsPaginator - Rotate image to the left - Rotation à gauche + + Number of volumes found : %1 + Nombre de volumes trouvés : %1 - Fit image to height - Ajuster l'image à la hauteur + + + page %1 of %2 + page %1 de %2 - Reset zoom - Réinitialiser le zoom + + Number of %1 found : %2 + Nombre de %1 trouvés : %2 + + + SearchSingleComic - Show the bookmarks of the current comic - Voir les marque-pages de cette bande dessinée + + Please provide some additional information for this comic. + Veuillez fournir des informations supplémentaires pour cette bande dessinée. - Show Dictionary - Dictionnaire + + Series: + Série: - Move down - Descendre + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Utilisez la recherche de correspondance exacte. Désactivez-la si vous souhaitez rechercher des volumes correspondant à certains mots du nom. + + + SearchVolume - Move left - Déplacer à gauche + + Please provide some additional information. + Veuillez fournir quelques informations supplémentaires. - Reverse reading order in double page mode - Ordre de lecture inversée en mode double page + + Series: + Série: - YACReader options - Options de YACReader + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Utilisez la recherche de correspondance exacte. Désactivez-la si vous souhaitez rechercher des volumes correspondant à certains mots du nom. + + + SelectComic - Clear open recent list - Vider la liste d'ouverture récente + + Please, select the right comic info. + Veuillez sélectionner les bonnes informations sur la bande dessinée. - Help, About YACReader - Aide, à propos de YACReader + + comics + bandes dessinées - Show go to flow - Afficher le flux + + loading cover + couvercle de chargement - Previous Comic - Bande dessinée précédente + + loading description + description du chargement - Show full size - Plein écran + + comic description unavailable + description de la bande dessinée indisponible + + + SelectVolume - Hide/show toolbar - Masquer / afficher la barre d'outils + + Please, select the right series for your comic. + Veuillez sélectionner la bonne série pour votre bande dessinée. - Magnifying glass - Loupe + + Filter: + Filtre: - Edit shortcuts - Modifier les raccourcis + + volumes + tomes - General - Général + + Nothing found, clear the filter if any. + Rien trouvé, effacez le filtre le cas échéant. - Set a bookmark on the current page - Placer un marque-page sur la page actuelle + + loading cover + couvercle de chargement - Page adjustement - Ajustement de la page + + loading description + description du chargement - Show zoom slider - Afficher le curseur de zoom + + volume description unavailable + description du volume indisponible + + + SeriesQuestion - Go to the last page - Aller à la dernière page + + You are trying to get information for various comics at once, are they part of the same series? + Vous essayez d’obtenir des informations sur plusieurs bandes dessinées à la fois, font-elles partie de la même série ? - Do you want to download the new version? - Voulez-vous télécharger la nouvelle version? + + yes + oui - Rotate image to the right - Rotation à droite + + no + non + + + + ServerConfigDialog + + + set port + Configurer le port - Always on top - Toujours au dessus + + Server connectivity information + Informations sur la connectivité du serveur - Autoscroll backward, horizontal first - Défilement automatique en arrière horizontal + + Scan it! + Scannez-le ! - - - OptionsDialog - - Gamma - Gamma + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader est disponible pour les appareils iOS et Android.<br/>Découvrez-le pour <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - - Reset - Remise à zéro + + Choose an IP address + Choisissez une adresse IP - - My comics path - Chemin de mes bandes dessinées + + Port + Port r?seau - - Image adjustment - Ajustement de l'image + + enable the server + Autoriser le serveur + + + ShortcutsDialog - - "Go to flow" size - Taille du flux + Close + Fermer - - Choose - Choisir + YACReader keyboard shortcuts + Raccourcis clavier de YACReader - - Image options - Option de l'image + Keyboard Shortcuts + Raccourcis clavier + + + SortVolumeComics - - Contrast - Contraste + + Please, sort the list of comics on the left until it matches the comics' information. + Veuillez trier la liste des bandes dessinées sur la gauche jusqu'à ce qu'elle corresponde aux informations des bandes dessinées. - - Options - Options + + sort comics to match comic information + trier les bandes dessinées pour qu'elles correspondent aux informations sur les bandes dessinées - - Comics directory - Répertoire des bandes dessinées + + issues + problèmes - - Quick Navigation Mode - Mode navigation rapide + + remove selected comics + supprimer les bandes dessinées sélectionnées - - Display - + + restore all removed comics + restaurer toutes les bandes dessinées supprimées + + + ThemeEditorDialog - - Show time in current page information label - + + Theme Editor + Éditeur de thème - - Background color - Couleur d'arrière plan + + + + + - - Scroll behaviour - + + - + - - - Disable scroll animations and smooth scrolling - + + i + je - - Do not turn page using scroll - + + Expand all + Tout développer - - Use single scroll step to turn page - + + Collapse all + Tout réduire - - Mouse mode - + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Maintenez enfoncé pour faire clignoter la valeur sélectionnée dans l'interface utilisateur (magenta / basculé / 0↔10). Les versions restaurent l'original. - - Only Back/Forward buttons can turn pages - + + Search… + Rechercher… - - Use the Left/Right buttons to turn pages. - + + Light + Lumière - - Click left or right half of the screen to turn pages. - + + Dark + Sombre - - Disable mouse over activation - Désactiver la souris sur l'activation + + ID: + IDENTIFIANT: - - Page Flow - Flux des pages + + Display name: + Nom d'affichage : - - General - Général + + Variant: + Variante: - - Brightness - Luminosité + + Theme info + Informations sur le thème - - Restart is needed - Redémarrage nécessaire + + Parameter + Paramètre - - Fit options - + + Value + Valeur - - Enlarge images to fit width/height - + + Save and apply + Enregistrer et postuler - - Double Page options - + + Export to file... + Exporter vers un fichier... - - Show covers as single page - + + Load from file... + Charger à partir du fichier... - - - QObject - - 7z lib not found - lib 7z introuvable + + Close + Fermer - - unable to load 7z lib from ./utils - impossible de charger 7z depuis ./utils + + Double-click to edit color + Double-cliquez pour modifier la couleur - - Trace - + + + + + + + true + vrai - - Debug - + + + + + false + FAUX - - Info - + + Double-click to toggle + Double-cliquez pour basculer - - Warning - + + Double-click to edit value + Double-cliquez pour modifier la valeur - - Error - + + + + Edit: %1 + Modifier : %1 - - Fatal - + + Save theme + Enregistrer le thème - - Select custom cover - + + + JSON files (*.json);;All files (*) + Fichiers JSON (*.json);;Tous les fichiers (*) - - Images (%1) - + + Save failed + Échec de l'enregistrement - - - QsLogging::LogWindowModel - - Time - + + Could not open file for writing: +%1 + Impossible d'ouvrir le fichier en écriture : +%1 - - Level - + + Load theme + Charger le thème - - Message - + + + + Load failed + Échec du chargement - - - QsLogging::Window - - &Pause - + + Could not open file: +%1 + Impossible d'ouvrir le fichier : +%1 - - &Resume - + + Invalid JSON: +%1 + JSON invalide : +%1 - - Save log - + + Expected a JSON object. + Attendu un objet JSON. + + + TitleHeader - - Log file (*.log) - + + SEARCH + RECHERCHE - ShortcutsDialog + UpdateLibraryDialog - Close - Fermer + + Updating.... + Mise à jour... - YACReader keyboard shortcuts - Raccourcis clavier de YACReader + + Cancel + Annuler - Keyboard Shortcuts - Raccourcis clavier + + Update library + Mettre la librairie à jour Viewer - + Page not available! Page non disponible ! - - + + Press 'O' to open comic. Appuyez sur "O" pour ouvrir une bande dessinée. - + Error opening comic Erreur d'ouverture de la bande dessinée - + Cover! Couverture! - + CRC Error Erreur CRC - + Comic not found Bande dessinée introuvable - + Not found Introuvable - + Last page! Dernière page! - + Loading...please wait! Chargement... Patientez + + VolumeComicsModel + + + title + titre + + + + VolumesModel + + + year + année + + + + issues + problèmes + + + + publisher + éditeur + + + + YACReader3DFlowConfigWidget + + + Presets: + Réglages: + + + + Classic look + Vue classique + + + + Stripe look + Vue alignée + + + + Overlapped Stripe look + Vue superposée + + + + Modern look + Vue moderne + + + + Roulette look + Vue roulette + + + + Show advanced settings + Voir les paramètres avancés + + + + Custom: + Personnalisation: + + + + View angle + Angle de vue + + + + Position + Positionnement + + + + Cover gap + Espace entre les couvertures + + + + Central gap + Espace couverture centrale + + + + Zoom + Agrandissement + + + + Y offset + Axe Y + + + + Z offset + Axe Z + + + + Cover Angle + Angle des couvertures + + + + Visibility + Visibilité + + + + Light + Lumière + + + + Max angle + Angle Maximum + + + + Low Performance + Faible performance + + + + High Performance + Haute performance + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Utiliser VSync (Améliore la qualité d'image en mode plein écran, ralentit la performance) + + + + Performance: + Performance : + + YACReader::MainWindowViewer - + &Open - &Ouvrir + &Ouvrir - + Open a comic - Ouvrir une bande dessinée + Ouvrir une bande dessinée - + New instance - + Nouvelle instance - + Open Folder - Ouvrir un dossier + Ouvrir un dossier - + Open image folder - Ouvrir un dossier d'images + Ouvrir un dossier d'images - + Open latest comic - Ouvrir la dernière bande dessinée + Ouvrir la dernière bande dessinée - + Open the latest comic opened in the previous reading session - Ouvrir la dernière bande dessinée ouverte lors de la session de lecture précédente + Ouvrir la dernière bande dessinée ouverte lors de la session de lecture précédente - + Clear - + Clair - + Clear open recent list - Vider la liste d'ouverture récente + Vider la liste d'ouverture récente - + Save - Sauvegarder + Sauvegarder - + Save current page - Sauvegarder la page actuelle + Sauvegarder la page actuelle Previous Comic - Bande dessinée précédente + Bande dessinée précédente - - - + + + Open previous comic - Ouvrir la bande dessiné précédente + Ouvrir la bande dessiné précédente - + Next Comic - Bande dessinée suivante + Bande dessinée suivante - - - + + + Open next comic - Ouvrir la bande dessinée suivante + Ouvrir la bande dessinée suivante - + &Previous - &Précédent + &Précédent - - - + + + Go to previous page - Aller à la page précédente + Aller à la page précédente - + &Next - &Suivant + &Suivant - - - + + + Go to next page - Aller à la page suivante + Aller à la page suivante - + Fit Height - Ajuster la hauteur + Ajuster la hauteur - + Fit image to height - Ajuster l'image à la hauteur + Ajuster l'image à la hauteur - + Fit Width - Ajuster la largeur + Ajuster la largeur - + Fit image to width - Ajuster l'image à la largeur + Ajuster l'image à la largeur - + Show full size - Plein écran + Plein écran - + Fit to page - Ajuster à la page + Ajuster à la page + + + + Continuous scroll + Défilement continu - + + Switch to continuous scroll mode + Passer en mode défilement continu + + + Reset zoom - Réinitialiser le zoom + Réinitialiser le zoom - + Show zoom slider - Afficher le curseur de zoom + Afficher le curseur de zoom - + Zoom+ - Zoom+ + Agrandir - + Zoom- - Zoom- + R?duire - + Rotate image to the left - Rotation à gauche + Rotation à gauche - + Rotate image to the right - Rotation à droite + Rotation à droite - + Double page mode - Mode double page + Mode double page - + Switch to double page mode - Passer en mode double page + Passer en mode double page - + Double page manga mode - Mode manga en double page + Mode manga en double page - + Reverse reading order in double page mode - Ordre de lecture inversée en mode double page + Ordre de lecture inversée en mode double page - + Go To - Aller à + Aller à - + Go to page ... - Aller à la page ... + Aller à la page ... - + Options - Options + Possibilités - + YACReader options - Options de YACReader + Options de YACReader - - + + Help - Aide + Aide - + Help, About YACReader - Aide, à propos de YACReader + Aide, à propos de YACReader - + Magnifying glass - Loupe + Loupe - + Switch Magnifying glass - Utiliser la loupe + Utiliser la loupe - + Set bookmark - Placer un marque-page + Placer un marque-page - + Set a bookmark on the current page - Placer un marque-page sur la page actuelle + Placer un marque-page sur la page actuelle - + Show bookmarks - Voir les marque-pages + Voir les marque-pages - + Show the bookmarks of the current comic - Voir les marque-pages de cette bande dessinée + Voir les marque-pages de cette bande dessinée - + Show keyboard shortcuts - Voir les raccourcis + Voir les raccourcis - + Show Info - Voir les infos + Voir les infos - + Close - Fermer + Fermer - + Show Dictionary - Dictionnaire + Dictionnaire - + Show go to flow - Afficher le flux + Afficher le flux - + Edit shortcuts - Modifier les raccourcis + Modifier les raccourcis - + &File - &Fichier + &Fichier - - + + Open recent - Ouvrir récent + Ouvrir récent - + File - Fichier + Fichier - + Edit - Editer + Editer - + View - Vue + Vue - + Go - Aller + Aller - + Window - Fenêtre + Fenêtre - - - + + + Open Comic - Ouvrir la bande dessinée + Ouvrir la bande dessinée - - - + + + Comic files - Bande dessinée + Bande dessinée - + Open folder - Ouvirir le dossier + Ouvirir le dossier - + page_%1.jpg - page_%1.jpg + feuille_%1.jpg - + Image files (*.jpg) - Image(*.jpg) + Image(*.jpg) + Comics - Bandes dessinées + Bandes dessinées Toggle fullscreen mode - Basculer en mode plein écran + Basculer en mode plein écran Hide/show toolbar - Masquer / afficher la barre d'outils + Masquer / afficher la barre d'outils + General - Général + Général Size up magnifying glass - Augmenter la taille de la loupe + Augmenter la taille de la loupe Size down magnifying glass - Réduire la taille de la loupe + Réduire la taille de la loupe Zoom in magnifying glass - Zoomer + Zoomer Zoom out magnifying glass - Dézoomer + Dézoomer Reset magnifying glass - + Réinitialiser la loupe + Magnifiying glass - Loupe + Loupe Toggle between fit to width and fit to height - Basculer entre adapter à la largeur et adapter à la hauteur + Basculer entre adapter à la largeur et adapter à la hauteur + Page adjustement - Ajustement de la page + Ajustement de la page - + Autoscroll down - Défilement automatique vers le bas + Défilement automatique vers le bas - + Autoscroll up - Défilement automatique vers le haut + Défilement automatique vers le haut - + Autoscroll forward, horizontal first - Défilement automatique en avant, horizontal + Défilement automatique en avant, horizontal - + Autoscroll backward, horizontal first - Défilement automatique en arrière horizontal + Défilement automatique en arrière horizontal - + Autoscroll forward, vertical first - Défilement automatique en avant, vertical + Défilement automatique en avant, vertical - + Autoscroll backward, vertical first - Défilement automatique en arrière, verticak + Défilement automatique en arrière, verticak - + Move down - Descendre + Descendre - + Move up - Monter + Monter - + Move left - Déplacer à gauche + Déplacer à gauche - + Move right - Déplacer à droite + Déplacer à droite - + Go to the first page - Aller à la première page + Aller à la première page - + Go to the last page - Aller à la dernière page + Aller à la dernière page - + Offset double page to the left - + Double page décalée vers la gauche - + Offset double page to the right - + Double page décalée à droite - + + Reading - Lecture + Lecture - + There is a new version available - Une nouvelle version est disponible + Une nouvelle version est disponible - + Do you want to download the new version? - Voulez-vous télécharger la nouvelle version? + Voulez-vous télécharger la nouvelle version? - + Remind me in 14 days - Rappelez-moi dans 14 jours + Rappelez-moi dans 14 jours - + Not now - Pas maintenant + Pas maintenant + + + + YACReader::TrayIconController + + + &Restore + &Restaurer + + + + Systray + Zone de notification + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quit</b> dans le menu contextuel de l'icône de la barre d'état système. YACReader::WhatsNewDialog - Close - Fermer + Fermer @@ -1403,172 +4043,152 @@ YACReaderFlowConfigWidget - CoverFlow look - Vue CoverFlow + Vue CoverFlow - How to show covers: - Comment voir les couvertures: + Comment voir les couvertures: - Stripe look - Vue alignée + Vue alignée - Overlapped Stripe look - Vue superposée + Vue superposée YACReaderGLFlowConfigWidget - Zoom - Zoom + Agrandissement - Light - Lumière + Lumière - Show advanced settings - Voir les paramètres avancés + Voir les paramètres avancés - Roulette look - Vue roulette + Vue roulette - Cover Angle - Angle des couvertures + Angle des couvertures - Stripe look - Vue alignée + Vue alignée - Position - Position + Positionnement - Z offset - Axe Z + Axe Z - Y offset - Axe Y + Axe Y - Central gap - Espace couverture centrale + Espace couverture centrale - Presets: - Réglages: + Réglages: - Overlapped Stripe look - Vue superposée + Vue superposée - Modern look - Vue moderne + Vue moderne - View angle - Angle de vue + Angle de vue - Max angle - Angle Maximum + Angle Maximum - Custom: - Personnalisation: + Personnalisation: - Classic look - Vue classique + Vue classique - Cover gap - Espace entre les couvertures + Espace entre les couvertures - High Performance - Haute performance + Haute performance - Performance: - Performance: + Performance : - Use VSync (improve the image quality in fullscreen mode, worse performance) - Utiliser VSync (Améliore la qualité d'image en mode plein écran, ralentit la performance) + Utiliser VSync (Améliore la qualité d'image en mode plein écran, ralentit la performance) - Visibility - Visibilité + Visibilité - Low Performance - Faible performance + Faible performance YACReaderOptionsDialog - + Save Sauvegarder - Use hardware acceleration (restart needed) - Utiliser accélération hardware (redémarrage nécessaire) + Utiliser accélération hardware (redémarrage nécessaire) - + Cancel Annuler - + Shortcuts Raccourcis - + Edit shortcuts Modifier les raccourcis + + YACReaderSearchLineEdit + + + type to search + tapez pour rechercher + + YACReaderSlider @@ -1580,23 +4200,23 @@ YACReaderTranslator - + clear effacer - + Service not available Service non disponible - - + + Translation Traduction - + YACReader translator Traducteur YACReader diff --git a/YACReader/yacreader_it.ts b/YACReader/yacreader_it.ts index 902b65ff0..b3ee44186 100644 --- a/YACReader/yacreader_it.ts +++ b/YACReader/yacreader_it.ts @@ -9,6 +9,196 @@ Nessuno + + AddLabelDialog + + + Label name: + Nome etichetta: + + + + Choose a color: + Seleziona un colore: + + + + accept + Accetta + + + + cancel + Cancella + + + + AddLibraryDialog + + + Comics folder : + Cartella fumetti: + + + + Library name : + Nome della biblioteca: + + + + Add + Aggiungi + + + + Cancel + Annulla + + + + Add an existing library + Aggiungi ad una libreria esistente + + + + ApiKeyDialog + + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Prima di conneterti a "Comic Vine" devi avere la tua chiave API. Per favore recuperane una da <a href="http://www.comicvine.com/api/">QUI</a + + + + Paste here your Comic Vine API key + Incolla qui la tua chiave API di "Comic Vine" + + + + Accept + Accetta + + + + Cancel + Annulla + + + + AppearanceTabWidget + + + Color scheme + Combinazione di colori + + + + System + Sistema + + + + Light + Luce + + + + Dark + Buio + + + + Custom + Costume + + + + Remove + Rimuovere + + + + Remove this user-imported theme + Rimuovi questo tema importato dall'utente + + + + Light: + Leggero: + + + + Dark: + Buio: + + + + Custom: + Personalizzazione: + + + + Import theme... + Importa tema... + + + + Theme + Tema + + + + Theme editor + Redattore del tema + + + + Open Theme Editor... + Apri l'editor del tema... + + + + Theme editor error + Errore nell'editor del tema + + + + The current theme JSON could not be loaded. + Impossibile caricare il tema corrente JSON. + + + + Import theme + Importa tema + + + + JSON files (*.json);;All files (*) + File JSON (*.json);;Tutti i file (*) + + + + Could not import theme from: +%1 + Impossibile importare il tema da: +%1 + + + + Could not import theme from: +%1 + +%2 + Impossibile importare il tema da: +%1 + +%2 + + + + Import failed + Importazione non riuscita + + BookmarksDialog @@ -33,10 +223,204 @@ Ultima Pagina + + ClassicComicsView + + + Hide comic flow + Nascondi il flusso dei fumetti + + + + ComicModel + + + yes + Si + + + + no + No + + + + Title + Titolo + + + + File Name + Nome file + + + + Pages + Pagine + + + + Size + Dimensione + + + + Read + Leggi + + + + Current Page + Pagina corrente + + + + Publication Date + Data di pubblicazione + + + + Rating + Valutazione + + + + Series + Serie + + + + Volume + Tomo + + + + Story Arc + Arco narrativo + + + + ComicVineDialog + + + skip + Salta + + + + back + Indietro + + + + next + Prossimo + + + + search + Cerca + + + + close + Chiudi + + + + + comic %1 of %2 - %3 + Fumetto %1 di %2 - %3 + + + + + + Looking for volume... + Sto cercando il fumetto... + + + + %1 comics selected + Fumetto %1 selezionato + + + + Error connecting to ComicVine + Errore durante la connessione a ComicVine + + + + + Retrieving tags for : %1 + Ricezione tag per: %1 + + + + Retrieving volume info... + Sto ricevendo le informazioni per l'abum... + + + + Looking for comic... + Sto cercando il fumetto... + + + + ContinuousPageWidget + + + Loading page %1 + Caricamento pagina %1 + + + + CreateLibraryDialog + + + Comics folder : + Cartella fumetti: + + + + Library Name : + Nome libreria: + + + + Create + Crea + + + + Cancel + Annulla + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Creare una Libreria può aver bisogno di alcuni minuti. Puoi fermare il processo ed aggiornare la libreria più tardi. + + + + Create new library + Crea una nuova libreria + + + + Path not found + Percorso non trovato + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + Il percorso selezionato non esiste oppure non è valido. Controlla di avere i permessi di scrittura per questa cartella + + EditShortcutsDialog - + Shortcut in use Scorciatoia in uso @@ -51,7 +435,7 @@ impostazione scorciatoie - + The shortcut "%1" is already assigned to other function La scorciatoia "%1" è già assegnata ad un'altra funzione @@ -61,6 +445,124 @@ Per cambiare una scorciatoia doppio click sulla combinazione tasti e digita la nuova combinazione. + + EmptyFolderWidget + + + This folder doesn't contain comics yet + Questa cartella non contiene ancora fumetti + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + Per ora questa etichetta non contiene fumetti + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + Per ora questa lista non contiene fumetti + + + + EmptySpecialListWidget + + + No favorites + Nessun Favorito + + + + You are not reading anything yet, come on!! + Non stai ancora leggendo nulla, Forza!! + + + + There are no recent comics! + Non ci sono fumetti recenti! + + + + ExportComicsInfoDialog + + + Output file : + File di Output: + + + + Create + Crea + + + + Cancel + Annulla + + + + Export comics info + Esporta informazioni fumetto + + + + Destination database name + Nome database di destinazione + + + + Problem found while writing + Trovato problema durante la scrittura + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Il percorso selezionato per il file di Output non esiste oppure non è valido. Controlla di avere i permessi di scrittura per questa cartella + + + + ExportLibraryDialog + + + Output folder : + Cartella di Output: + + + + Create + Crea + + + + Cancel + Annulla + + + + Create covers package + Crea pacchetto delle copertine + + + + Problem found while writing + Trovato problema durante la scrittura + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Il percorso selezionato per il file di Output non esiste oppure non è valido. Controlla di avere i permessi di scrittura per questa cartella + + + + Destination directory + Cartella di destinazione + + FileComic @@ -116,1262 +618,3400 @@ GoToFlowToolBar - + Page : Pagina: + + GridComicsView + + + Show info + Mostra informazioni + + HelpAboutDialog - + Help Aiuto - + System info - + Informazioni di sistema - + About - About + Informazioni + + + + ImportComicsInfoDialog + + + Import comics info + Importa informazioni fumetto + + + + Info database location : + Informazioni posizione database: + + + + Import + Importa + + + + Cancel + Annulla + + + + Comics info file (*.ydb) + File informazioni fumetto (*.ydb) - LogWindow + ImportLibraryDialog - - Log window - + + Library Name : + Nome libreria: - - &Pause - + + Package location : + Posizione PAcchetto: - - &Save - + + Destination folder : + Cartella di destinazione: - - C&lear - + + Unpack + Decomprimi - - &Copy - + + Cancel + Annulla - - Level: - + + Extract a catalog + Estrai un catalogo - - &Auto scroll - + + Compresed library covers (*.clc) + Libreria di copertine compresse (*.clc) - MainWindowViewer + ImportWidget - Go - Vai + + stop + Ferma + + + + Some of the comics being added... + Alcuni fumetti che sto aggiungendo... + + + + Importing comics + Sto importando i fumetti + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YacReader sta creando una nuova libreria.</p><p>La creazione di una libreria può durare diversi minuti. Puoi fermare l'attività ed aggiornare la libreria più tardi, completando l'attività</p> + + + + Updating the library + Sto aggiornando la Libreria + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>Quest alibreria si sta aggiornando. Per aggiornamenti più veloci aggiorna la tua libreria di frequente.</p><p>Puoi fermare il processo ed aggiornare la libreria più tardi.</p> + + + + Upgrading the library + Aggiornamento della biblioteca + + + + <p>The current library is being upgraded, please wait.</p> + <p>È in corso l'aggiornamento della libreria corrente, attendi.</p> + + + + Scanning the library + Scansione della libreria + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>Scansione della libreria corrente per informazioni sui metadati XML legacy.</p><p>Questa operazione è necessaria solo una volta e solo se la libreria è stata creata con YACReaderLibrary 9.8.2 o versioni precedenti.</p> + + + + LibraryWindow + + + YACReader Library + Libreria YACReader + + + + + + comic + comico + + + + + + manga + Manga + + + + + + western manga (left to right) + manga occidentale (da sinistra a destra) + + + + + + web comic + fumetto web + + + + + + 4koma (top to botom) + 4koma (dall'alto verso il basso) + + + + + + + Set type + Imposta il tipo + + + + Library + Libreria + + + + Folder + Cartella + + + + Comic + Fumetto + + + + Upgrade failed + Aggiornamento non riuscito + + + + There were errors during library upgrade in: + Si sono verificati errori durante l'aggiornamento della libreria in: + + + + Update needed + Devi aggiornarmi + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Questa libreria è stata creata con una versione precedente di YACREaderLibrary. Deve essere aggiornata. Aggiorno ora? + + + + Download new version + Scarica la nuova versione + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Questa libreria è stata creata con una verisone più recente di YACReaderLibrary. Scarico la versione aggiornata ora? + + + + Library not available + Libreria non disponibile + + + + Library '%1' is no longer available. Do you want to remove it? + La libreria '%1' non è più disponibile, la vuoi cancellare? + + + + Old library + Vecchia libreria + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La libreria '%1' è stata creata con una versione precedente di YACREaderLibrary. Deve essere ricreata. Lo vuoi fare ora? + + + + + Copying comics... + Sto copiando i fumetti... + + + + + Moving comics... + Sto muovendo i fumetti... + + + + Add new folder + Aggiungi una nuova cartella + + + + Folder name: + Nome della cartella: + + + + No folder selected + Nessuna cartella selezionata + + + + Please, select a folder first + Per cortesia prima seleziona una cartella + + + + Error in path + Errore nel percorso + + + + There was an error accessing the folder's path + C'è stato un errore nell'accesso al percorso della cartella + + + + Delete folder + Cancella Cartella + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + La cartella seleziona e tutto il suo contenuto verranno cancellati dal tuo disco. Sei sicuro? + + + + + Unable to delete + Non posso cancellare + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + C'è stato un problema cancellando le cartelle selezionate. Per favore controlla i tuoi permessi di scrittura e sii sicuro che non ci siano altre applicazioni che usano le stesse cartelle. + + + + Add new reading lists + Aggiungi una lista di lettura + + + + + List name: + Nome lista: + + + + Delete list/label + Cancella Lista/Etichetta + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + Gli elementi selezionati verranno cancellati, i tuoi fumetti o cartella NON verranno cancellati dal tuo disco. Sei sicuro? + + + + Rename list name + Rinomina la lista + + + + Open folder... + Apri Cartella... + + + + Update folder + Aggiorna Cartella + + + + Rescan library for XML info + Eseguire nuovamente la scansione della libreria per informazioni XML + + + + Set as uncompleted + Segna come non completo + + + + Set as completed + Segna come completo + + + + Set as read + Setta come letto + + + + + Set as unread + Setta come non letto + + + + Set custom cover + Imposta la copertina personalizzata + + + + Delete custom cover + Elimina la copertina personalizzata + + + + Save covers + Salva Copertine + + + + You are adding too many libraries. + Stai aggiungendto troppe librerie. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Stai aggiungendo troppe Libreire + +Hai probabilemnte bisogno di una sola Libreria al livello superiore, puoi poi navigare qualsiasi sotto cartella usando la selezione delle cartella a sinistra + +YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il numero di librerie basso. + + + + + YACReader not found + YACReader non trovato + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader non trovato. YACReader deve essere installato nella stessa cartella di YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader non trovato. Potrebbe esserci un problema con l'installazione di YACReader. + + + + Error + Errore + + + + Error opening comic with third party reader. + Errore nell'apertura del fumetto con un lettore di terze parti. + + + + Library not found + Libreria non trovata + + + + The selected folder doesn't contain any library. + La cartella selezionata non contiene nessuna Libreria. + + + + Are you sure? + Sei sicuro? + + + + Do you want remove + Vuoi rimuovere + + + + library? + Libreria? + + + + Remove and delete metadata + Rimuovi e cancella i Metadati + + + + Library info + Informazioni sulla biblioteca + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + C'è un problema nel cancellare i fumetti selezionati. Per favore controlla i tuoi permessi di scrittura sui file o sulla cartella. + + + + Assign comics numbers + Assegna un numero ai fumetti + + + + Assign numbers starting in: + Assegna numeri partendo da: + + + + Invalid image + Immagine non valida + + + + The selected file is not a valid image. + Il file selezionato non è un'immagine valida. + + + + Error saving cover + Errore durante il salvataggio della copertina + + + + There was an error saving the cover image. + Si è verificato un errore durante il salvataggio dell'immagine di copertina. + + + + Error creating the library + Errore creando la libreria + + + + Error updating the library + Errore aggiornando la libreria + + + + Error opening the library + Errore nell'apertura della libreria + + + + Delete comics + Cancella i fumetti + + + + All the selected comics will be deleted from your disk. Are you sure? + Tutti i fumetti selezionati saranno cancellati dal tuo disco. Sei sicuro? + + + + Remove comics + Rimuovi i fumetti + + + + Comics will only be deleted from the current label/list. Are you sure? + I fumetti verranno cancellati dall'etichetta/lista corrente. Sei sicuro? + + + + Library name already exists + Esiste già una libreria con lo stesso nome + + + + There is another library with the name '%1'. + Esiste già una libreria con il nome '%1'. + + + + LibraryWindowActions + + + Create a new library + Crea una nuova libreria + + + + Open an existing library + Apri una libreria esistente + + + + + Export comics info + Esporta informazioni fumetto + + + + + Import comics info + Importa informazioni fumetto + + + + Pack covers + Compatta Copertine + + + + Pack the covers of the selected library + Compatta le copertine della libreria selezionata + + + + Unpack covers + Scompatta le Copertine + + + + Unpack a catalog + Scompatta un catalogo + + + + Update library + Aggiorna Libreria + + + + Update current library + Aggiorna la Libreria corrente + + + + Rename library + Rinomina la libreria + + + + Rename current library + Rinomina la libreria corrente + + + + Remove library + Rimuovi la libreria + + + + Remove current library from your collection + Rimuovi la libreria corrente dalla tua collezione + + + + Rescan library for XML info + Eseguire nuovamente la scansione della libreria per informazioni XML + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Cerca di trovare informazioni XML incorporate nei file dei fumetti. Devi farlo solo se la libreria è stata creata con la versione 9.8.2 o precedente o se utilizzi software di terze parti per incorporare informazioni XML nei file. + + + + Show library info + Mostra informazioni sulla biblioteca + + + + Show information about the current library + Mostra informazioni sulla libreria corrente + + + + Open current comic + Apri il fumetto corrente + + + + Open current comic on YACReader + Apri il fumetto corrente con YACReader + + + + Save selected covers to... + Salva le copertine selezionate in... + + + + Save covers of the selected comics as JPG files + Salva le copertine dei fumetti selezionati come file JPG + + + + + Set as read + Setta come letto + + + + Set comic as read + Setta il fumetto come letto + + + + + Set as unread + Setta come non letto + + + + Set comic as unread + Setta il fumetto come non letto + + + + + manga + Manga + + + + Set issue as manga + Imposta il problema come manga + + + + + comic + comico + + + + Set issue as normal + Imposta il problema come normale + + + + western manga + manga occidentali + + + + Set issue as western manga + Imposta il problema come manga occidentale + + + + + web comic + fumetto web + + + + Set issue as web comic + Imposta il problema come fumetto web + + + + + yonkoma + Yonkoma + + + + Set issue as yonkoma + Imposta il problema come Yonkoma + + + + Show/Hide marks + Mostra/Nascondi + + + + Show or hide read marks + Mostra o nascondi lo stato di lettura + + + + Show/Hide recent indicator + Mostra/Nascondi l'indicatore recente + + + + Show or hide recent indicator + Mostra o nascondi l'indicatore recente + + + + + Fullscreen mode on/off + Modalità a schermo interno on/off + + + + Help, About YACReader + Aiuto, crediti YACReader + + + + Add new folder + Aggiungi una nuova cartella + + + + Add new folder to the current library + Aggiungi una nuova cartella alla libreria corrente + + + + Delete folder + Cancella Cartella + + + + Delete current folder from disk + Cancella la cartella corrente dal disco + + + + Select root node + Seleziona il nodo principale + + + + Expand all nodes + Espandi tutti i nodi + + + + Collapse all nodes + Compatta tutti i nodi + + + + Show options dialog + Mostra le opzioni + + + + Show comics server options dialog + Mostra le opzioni per il server dei fumetti + + + + + Change between comics views + Cambia tra i modi di visualizzazione dei fumetti + + + + Open folder... + Apri Cartella... + + + + Set as uncompleted + Segna come non completo + + + + Set as completed + Segna come completo + + + + Set custom cover + Imposta la copertina personalizzata + + + + Delete custom cover + Elimina la copertina personalizzata + + + + western manga (left to right) + manga occidentale (da sinistra a destra) + + + + Open containing folder... + Apri la cartella dei contenuti... + + + + Reset comic rating + Resetta la valutazione dei fumetti + + + + Select all comics + Seleziona tutti i fumetti + + + + Edit + Edita + + + + Assign current order to comics + Assegna l'ordinamento corrente ai fumetti + + + + Update cover + Aggiorna copertina + + + + Delete selected comics + Cancella i fumetti selezionati + + + + Delete metadata from selected comics + Elimina i metadati dai fumetti selezionati + + + + Download tags from Comic Vine + Scarica i Tag da Comic Vine + + + + Focus search line + Mettere a fuoco la linea di ricerca + + + + Focus comics view + Focus sulla visualizzazione dei fumetti + + + + Edit shortcuts + Edita scorciatoie + + + + &Quit + &Esci + + + + Update folder + Aggiorna Cartella + + + + Update current folder + Aggiorna la cartella corrente + + + + Scan legacy XML metadata + Scansione dei metadati XML legacy + + + + Add new reading list + Aggiorna la lista di lettura + + + + Add a new reading list to the current library + Aggiungi una lista di lettura alla libreria corrente + + + + Remove reading list + Rimuovi la lista di lettura + + + + Remove current reading list from the library + Rimuovi la lista di lettura dalla libreria + + + + Add new label + Aggiungi una nuova etichetta + + + + Add a new label to this library + Aggiungi una nuova etichetta a questa libreria + + + + Rename selected list + Rinomina la lista selezionata + + + + Rename any selected labels or lists + Rinomina qualsiasi etichetta o lista selezionata + + + + Add to... + Aggiungi a... + + + + Favorites + Favoriti + + + + Add selected comics to favorites list + Aggiungi i fumetti selezionati alla lista dei favoriti + + + + LocalComicListModel + + + file name + Nome file + + + + MainWindowViewer + + Go + Vai + + + Edit + Edita + + + File + Documento + + + Help + Aiuto + + + Save + Salva + + + View + Mostra + + + &File + &Documento + + + &Next + &Prossimo + + + &Open + &Apri + + + Clear + Cancella + + + Close + Chiudi + + + Open Comic + Apri Fumetto + + + Go To + Vai a + + + Zoom+ + Aumenta + + + Zoom- + Riduci + + + Open image folder + Apri la crettal immagini + + + Size down magnifying glass + Riduci lente ingrandimento + + + Zoom out magnifying glass + Riduci in lente di ingrandimento + + + Open latest comic + Apri l'ultimo fumetto + + + Autoscroll up + Autoscorri Sù + + + Set bookmark + Imposta Segnalibro + + + page_%1.jpg + Pagina_%1.jpg + + + Autoscroll forward, vertical first + Autoscorri avanti, priorità Verticale + + + Switch to double page mode + Passa alla modalità doppia pagina + + + Save current page + Salva la pagina corrente + + + Size up magnifying glass + Ingrandisci lente ingrandimento + + + Double page mode + Modalita doppia pagina + + + Move up + Muovi Sù + + + Switch Magnifying glass + Passa a lente ingrandimento + + + Open Folder + Apri una cartella + + + Comics + Fumetto + + + Fit Height + Adatta altezza + + + Autoscroll backward, vertical first + Autoscorri indietro, priorità Verticale + + + Comic files + File Fumetto + + + Not now + Non ora + + + Go to the first page + Vai alla pagina iniziale + + + Go to previous page + Vai alla pagina precedente + + + Window + Finestra + + + Open the latest comic opened in the previous reading session + Apri l'ultimo fumetto aperto nella sessione precedente + + + Open a comic + Apri un Fumetto + + + Image files (*.jpg) + File immagine (*.jpg) + + + Next Comic + Prossimo fumetto + + + Fit Width + Adatta Larghezza + + + Options + Opzioni + + + Show Info + Mostra info + + + Open folder + Apri cartella + + + Go to page ... + Vai a Pagina ... + + + Magnifiying glass + Lente ingrandimento + + + Fit image to width + Adatta immagine in larghezza + + + Toggle fullscreen mode + Attiva/Disattiva schermo intero + + + Toggle between fit to width and fit to height + Passa tra adatta in larghezza ad altezza + + + Move right + Muovi Destra + + + Zoom in magnifying glass + Ingrandisci in lente di ingrandimento + + + Open recent + Apri i recenti + + + Reading + Leggi + + + &Previous + &Precedente + + + Autoscroll forward, horizontal first + Autoscorri avanti, priorità Orizzontale + + + Go to next page + Vai alla prossima Pagina + + + Show keyboard shortcuts + Mostra scorciatoie da tastiera + + + Double page manga mode + Modalità doppia pagina Manga + + + There is a new version available + Nuova versione disponibile + + + Autoscroll down + Autoscorri Giù + + + Open next comic + Apri il prossimo fumetto + + + Remind me in 14 days + Ricordamelo in 14 giorni + + + Fit to page + Adatta alla pagina + + + Show bookmarks + Mostra segnalibro + + + Open previous comic + Apri il fumetto precendente + + + Rotate image to the left + Ruota immagine a sinistra + + + Fit image to height + Adatta immagine all'altezza + + + Reset zoom + Resetta Zoom + + + Show the bookmarks of the current comic + Mostra il segnalibro del fumetto corrente + + + Show Dictionary + Mostra dizionario + + + Move down + Muovi Giù + + + Move left + Muovi Sinistra + + + Reverse reading order in double page mode + Ordine lettura inverso in modo doppia pagina + + + YACReader options + Opzioni YACReader + + + Clear open recent list + Svuota la lista degli aperti + + + Help, About YACReader + Aiuto, crediti YACReader + + + Show go to flow + Mostra vai all'elenco + + + Previous Comic + Fumetto precendente + + + Show full size + Mostra dimesioni reali + + + Hide/show toolbar + Mostra/Nascondi Barra strumenti + + + Magnifying glass + Lente ingrandimento + + + Edit shortcuts + Edita scorciatoie + + + General + Generale + + + Set a bookmark on the current page + Imposta segnalibro a pagina corrente + + + Page adjustement + Correzioni di pagna + + + Show zoom slider + Mostra cursore di zoom + + + Go to the last page + Vai all'ultima pagina + + + Do you want to download the new version? + Vuoi scaricare la nuova versione? + + + Rotate image to the right + Ruota immagine a destra + + + Always on top + Sempre in primo piano + + + Autoscroll backward, horizontal first + Autoscorri indietro, priorità Orizzontale + + + + NoLibrariesWidget + + + You don't have any libraries yet + Per ora non hai ancora nessuna libreria + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Puoi creare una libreria in qualsiasi cartella, YACReader importerà tutti i fumetti e struttura da questa certella. Se hai creato una qualsiasia libreria nel passato la puoi aprire. </p><p>Non dimenticare che puoi usare YACReader come applicazione stand alone per leggere i fumetti sul tuo PC.</p> + + + + create your first library + Crea la tua prima libreria + + + + add an existing one + Aggiungine una esistente + + + + NoSearchResultsWidget + + + No results + Nessun risultato + + + + OptionsDialog + + + Gamma + Valore gamma + + + + Reset + Resetta + + + + My comics path + Percorso dei miei fumetti + + + + Image adjustment + Correzioni immagine + + + + "Go to flow" size + Dimensione "Vai all'elenco" + + + + Choose + Scegli + + + + Image options + Opzione immagine + + + + Contrast + Contrasto + + + + + Libraries + Librerie + + + + Comic Flow + Flusso dei fumetti + + + + Grid view + Vista a Griglia + + + + + Appearance + Aspetto + + + + + Options + Opzioni + + + + + Language + Lingua + + + + + Application language + Lingua dell'applicazione + + + + + System default + Predefinita del sistema + + + + Tray icon settings (experimental) + Impostazioni dell'icona nella barra delle applicazioni (sperimentale) + + + + Close to tray + Vicino al vassoio + + + + Start into the system tray + Inizia nella barra delle applicazioni + + + + Edit Comic Vine API key + Edita l'API di ComicVine + + + + Comic Vine API key + API di ComicVine + + + + ComicInfo.xml legacy support + Supporto legacy ComicInfo.xml + + + + Import metadata from ComicInfo.xml when adding new comics + Importa metadati da ComicInfo.xml quando aggiungi nuovi fumetti + + + + Consider 'recent' items added or updated since X days ago + Considera gli elementi "recenti" aggiunti o aggiornati da X giorni fa + + + + Third party reader + Lettore di terze parti + + + + Write {comic_file_path} where the path should go in the command + Scrivi {comic_file_path} dove dovrebbe andare il percorso nel comando + + + + + Clear + Cancella + + + + Update libraries at startup + Aggiorna le librerie all'avvio + + + + Try to detect changes automatically + Prova a rilevare automaticamente le modifiche + + + + Update libraries periodically + Aggiorna periodicamente le librerie + + + + Interval: + Intervallo: + + + + 30 minutes + 30 minuti + + + + 1 hour + 1 ora + + + + 2 hours + 2 ore + + + + 4 hours + 4 ore + + + + 8 hours + 8 ore + + + + 12 hours + 12 ore + + + + daily + quotidiano + + + + Update libraries at certain time + Aggiorna le librerie in determinati orari + + + + Time: + Tempo: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + AVVERTIMENTO! Durante gli aggiornamenti della libreria le scritture sul database sono disabilitate! +Non pianificare gli aggiornamenti mentre potresti utilizzare l'app attivamente. +Durante gli aggiornamenti automatici l'app bloccherà alcune azioni fino al termine dell'aggiornamento. +Per interrompere un aggiornamento automatico, tocca l'indicatore di caricamento accanto al titolo Librerie. + + + + Modifications detection + Rilevamento delle modifiche + + + + Compare the modified date of files when updating a library (not recommended) + Confronta la data di modifica dei file durante l'aggiornamento di una libreria (non consigliato) + + + + Enable background image + Abilita l'immagine di sfondo + + + + Opacity level + Livello di opacità + + + + Blur level + Livello di sfumatura + + + + Use selected comic cover as background + Usa la cover del fumetto selezionato come sfondo + + + + Restore defautls + Resetta al Default + + + + Background + Sfondo + + + + Display continue reading banner + Visualizza il banner continua a leggere + + + + Display current comic banner + Visualizza il banner del fumetto corrente + + + + Continue reading + Continua a leggere + + + + Comics directory + Cartella Fumetti + + + + Quick Navigation Mode + Modo navigazione rapida + + + + Display + Visualizzazione + + + + Show time in current page information label + Mostra l'ora nell'etichetta delle informazioni della pagina corrente + + + + Background color + Colore di sfondo + + + + Scroll behaviour + Comportamento di scorrimento + + + + Disable scroll animations and smooth scrolling + Disabilita le animazioni di scorrimento e lo scorrimento fluido + + + + Do not turn page using scroll + Non voltare pagina utilizzando lo scorrimento + + + + Use single scroll step to turn page + Utilizzare un singolo passaggio di scorrimento per voltare pagina + + + + Mouse mode + Modalità mouse + + + + Only Back/Forward buttons can turn pages + Solo i pulsanti Indietro/Avanti possono girare le pagine + + + + Use the Left/Right buttons to turn pages. + Utilizzare i pulsanti Sinistra/Destra per girare le pagine. + + + + Click left or right half of the screen to turn pages. + Fare clic sulla metà sinistra o destra dello schermo per girare le pagine. + + + + Disable mouse over activation + Disabilita il mouse all'attivazione + + + + Scaling + Ridimensionamento + + + + Scaling method + Metodo di scala + + + + Nearest (fast, low quality) + Più vicino (veloce, bassa qualità) + + + + Bilinear + Bilineare + + + + Lanczos (better quality) + Lanczos (qualità migliore) + + + + Page Flow + Flusso pagine + + + + + General + Generale + + + + Brightness + Luminosità + + + + + Restart is needed + Riavvio Necessario + + + + Fit options + Opzioni di adattamento + + + + Enlarge images to fit width/height + Ingrandisci le immagini per adattarle alla larghezza/altezza + + + + Double Page options + Opzioni doppia pagina + + + + Show covers as single page + Mostra le copertine come pagina singola + + + + PropertiesDialog + + + General info + Informazioni generali + + + + Plot + Trama + + + + Authors + Autori + + + + Publishing + Pubblicazione + + + + Notes + Note - Edit - Edit + + Cover page + Pagina Copertina - File - File + + Load previous page as cover + Carica la pagina precedente come copertina - Help - Aiuto + + Load next page as cover + Carica la pagina successiva come copertina - Save - Salva + + Reset cover to the default image + Ripristina la copertina sull'immagine predefinita - View - Mostra + + Load custom cover image + Carica l'immagine di copertina personalizzata - &File - &File + + Series: + Serie: - &Next - &Prossimo + + Title: + Titolo: - &Open - &Apri + + + + of: + Di: - Clear - Cancella + + Issue number: + Numeri emessi: - Close - Chiudi + + Volume: + Album: - Open Comic - Apri Fumetto + + Arc number: + Numero dell'arco: - Go To - Vai a + + Story arc: + Arco Narrativo: - Zoom+ - Zoom+ + + alt. number: + alt. numero: - Zoom- - Zoom- + + Alternate series: + Serie alternative: - Open image folder - Apri la crettal immagini + + Series Group: + Gruppo di serie: - Size down magnifying glass - Riduci lente ingrandimento + + Genre: + Genere: - Zoom out magnifying glass - Riduci in lente di ingrandimento + + Size: + Dimesioni: - Open latest comic - Apri l'ultimo fumetto + + Writer(s): + Scrittore(i): - Autoscroll up - Autoscorri Sù + + Penciller(s): + Mine: - Set bookmark - Imposta Segnalibro + + Inker(s): + Inchiostratore(i): - page_%1.jpg - Pagina_%1.jpg + + Colorist(s): + Colorista(i): - Autoscroll forward, vertical first - Autoscorri avanti, priorità Verticale + + Letterer(s): + Letterista(i): - Switch to double page mode - Passa alla modalità doppia pagina + + Cover Artist(s): + Artista(i) copertina: - Save current page - Salva la pagina corrente + + Editor(s): + Redattore(i): - Size up magnifying glass - Ingrandisci lente ingrandimento + + Imprint: + Impronta: - Double page mode - Modalita doppia pagina + + Day: + Giorno: - Move up - Muovi Sù + + Month: + Mese: - Switch Magnifying glass - Passa a lente ingrandimento + + Year: + Anno: - Open Folder - Apri una cartella + + Publisher: + Editore: - Comics - Fumetto + + Format: + Formato: - Fit Height - Adatta altezza + + Color/BW: + Colore o B/N: - Autoscroll backward, vertical first - Autoscorri indietro, priorità Verticale + + Age rating: + Valutazione età: - Comic files - File Fumetto + + Type: + Tipo: - Not now - Non ora + + Language (ISO): + Lingua (ISO): - Go to the first page - Vai alla pagina iniziale + + Synopsis: + Sinossi: - Go to previous page - Vai alla pagina precedente + + Characters: + Personaggi: - Window - Finestra + + Teams: + Squadre: - Open the latest comic opened in the previous reading session - Apri l'ultimo fumetto aperto nella sessione precedente + + Locations: + Posizioni: - Open a comic - Apri un Fumetto + + Main character or team: + Personaggio principale o squadra: - Image files (*.jpg) - File immagine (*.jpg) + + Review: + Revisione: - Next Comic - Prossimo fumetto + + Notes: + Note: - Fit Width - Adatta Larghezza + + Tags: + tag: - Options - Opzioni + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Vai </a> - Show Info - Mostra info + + Not found + Non trovato - Open folder - Apri cartella + + Comic not found. You should update your library. + Fumetto non trovato, dovresti aggiornare la Libreria. - Go to page ... - Vai a Pagina ... + + Edit comic information + Edita le informazioni del fumetto - Magnifiying glass - Lente ingrandimento + + Edit selected comics information + Edita le informazioni del fumetto selezionato - Fit image to width - Adatta immagine in larghezza + + Invalid cover + Copertina non valida - Toggle fullscreen mode - Attiva/Disattiva schermo intero + + The image is invalid. + L'immagine non è valida. + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer è la versione headless (senza GUI) di YACReaderLibrary. + +Questa applicazione supporta le impostazioni persistenti, per configurarle modifica questo file %1 +Per conoscere le impostazioni disponibili, consultare la documentazione su https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + QObject - Toggle between fit to width and fit to height - Passa tra adatta in larghezza ad altezza + + 7z lib not found + Libreria 7z non trovata - Move right - Muovi Destra + + unable to load 7z lib from ./utils + Impossibile caricare 7z da ./utils - Zoom in magnifying glass - Ingrandisci in lente di ingrandimento + + Trace + Traccia - Open recent - Apri i recenti + + Debug + Diagnostica - Reading - Leggi + + Info + Informazioni - &Previous - &Precedente + + Warning + Avvertimento - Autoscroll forward, horizontal first - Autoscorri avanti, priorità Orizzontale + + Error + Errore - Go to next page - Vai alla prossima Pagina + + Fatal + Fatale - Show keyboard shortcuts - Mostra scorciatoie da tastiera + + Select custom cover + Seleziona la copertina personalizzata - Double page manga mode - Modalità doppia pagina Manga + + Images (%1) + Immagini (%1) - There is a new version available - Nuova versione disponibile + + The file could not be read or is not valid JSON. + Impossibile leggere il file o non è un JSON valido. - Autoscroll down - Autoscorri Giù + + This theme is for %1, not %2. + Questo tema è per %1, non %2. - Open next comic - Apri il prossimo fumetto + + Libraries + Librerie - Remind me in 14 days - Ricordamelo in 14 giorni + + Folders + Cartelle - Fit to page - Adatta alla pagina + + Reading Lists + Lista di lettura + + + RenameLibraryDialog - Show bookmarks - Mostra segnalibro + + New Library Name : + Nome della nuova libreria: - Open previous comic - Apri il fumetto precendente + + Rename + Rinomina - Rotate image to the left - Ruota immagine a sinistra + + Cancel + Annulla - Fit image to height - Adatta immagine all'altezza + + Rename current library + Rinomina la libreria corrente + + + ScraperResultsPaginator - Reset zoom - Resetta Zoom + + Number of volumes found : %1 + Numero di volumi trovati: %1 - Show the bookmarks of the current comic - Mostra il segnalibro del fumetto corrente + + + page %1 of %2 + pagina %1 di %2 - Show Dictionary - Mostra dizionario + + Number of %1 found : %2 + Numero di %1 trovati; %2 + + + SearchSingleComic - Move down - Muovi Giù + + Please provide some additional information for this comic. + Per favore aggiugi informazioni addizionali. - Move left - Muovi Sinistra + + Series: + Serie: - Reverse reading order in double page mode - Ordine lettura inverso in modo doppia pagina + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Utilizza la ricerca con corrispondenza esatta. Disabilitare se si desidera trovare volumi che corrispondono ad alcune delle parole nel nome. + + + SearchVolume - YACReader options - Opzioni YACReader + + Please provide some additional information. + Per favore aggiugi informazioni addizionali. - Clear open recent list - Svuota la lista degli aperti + + Series: + Serie: - Help, About YACReader - Aiuto, crediti YACReader + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Utilizza la ricerca con corrispondenza esatta. Disabilitare se si desidera trovare volumi che corrispondono ad alcune delle parole nel nome. + + + SelectComic - Show go to flow - Mostra vai all'elenco + + Please, select the right comic info. + Per favore seleziona le informazioni corrette per il fumetto. - Previous Comic - Fumetto precendente + + comics + Fumetti - Show full size - Mostra dimesioni reali + + loading cover + Caricamento copertine - Hide/show toolbar - Mostra/Nascondi Barra strumenti + + loading description + Caricamento descrizione - Magnifying glass - Lente ingrandimento + + comic description unavailable + descrizione del fumetto non disponibile + + + SelectVolume - Edit shortcuts - Edita scorciatoie + + Please, select the right series for your comic. + Per favore seleziona la serie corretta per il fumetto. - General - Generale + + Filter: + Filtro: - Set a bookmark on the current page - Imposta segnalibro a pagina corrente + + volumes + Volumi - Page adjustement - Correzioni di pagna + + Nothing found, clear the filter if any. + Non è stato trovato nulla, cancella il filtro se presente. - Show zoom slider - Mostra cursore di zoom + + loading cover + Caricamento copertine - Go to the last page - Vai all'ultima pagina + + loading description + Caricamento descrizione - Do you want to download the new version? - Vuoi scaricare la nuova versione? + + volume description unavailable + descrizione del volume non disponibile + + + SeriesQuestion - Rotate image to the right - Ruota immagine a destra + + You are trying to get information for various comics at once, are they part of the same series? + Stai cercando di recuperare informazioni per diversi fumetti in una sola volta, sono parte della stessa serie? - Always on top - Sempre in primo piano + + yes + Si - Autoscroll backward, horizontal first - Autoscorri indietro, priorità Orizzontale + + no + No - OptionsDialog + ServerConfigDialog - - Gamma - Gamma + + set port + Configura porta - - Reset - Reset + + Server connectivity information + Informazioni sulla connettività del server - - My comics path - Percorso dei miei fumetti + + Scan it! + Scansiona! - - Image adjustment - Correzioni immagine + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader è disponibile per dispositivi iOS e Android.<br/>Scoprilo per <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - - "Go to flow" size - Dimensione "Vai all'elenco" + + Choose an IP address + Scegli un indirizzo IP - - Choose - Scegli + + Port + Porta - - Image options - Opzione immagine + + enable the server + Abilita il server + + + ShortcutsDialog - - Contrast - Contrasto + Close + Chiudi - - Options - Opzioni + YACReader keyboard shortcuts + Scorciatoie da tastiera di YACReader + + + Keyboard Shortcuts + Scorciatoia da tastiera + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + Per favore ordina la lista dei fumetti a sinistra sino a che corrisponde alle informazioni dei fumetti. + + + + sort comics to match comic information + Ordina i fumetti per far corrispondere le informazioni - - Comics directory - Cartella Fumetti + + issues + Emissione - - Quick Navigation Mode - Modo navigazione rapida + + remove selected comics + Rimuovi i fumetti selezionati - - Display - + + restore all removed comics + Ripristina tutti i fumetti rimossi + + + ThemeEditorDialog - - Show time in current page information label - + + Theme Editor + Redattore del tema - - Background color - Colore di sfondo + + + + + - - Scroll behaviour - + + - + - - - Disable scroll animations and smooth scrolling - + + i + io - - Do not turn page using scroll - + + Expand all + Espandi tutto - - Use single scroll step to turn page - + + Collapse all + Comprimi tutto - - Mouse mode - + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Tieni premuto per far lampeggiare il valore selezionato nell'interfaccia utente (magenta / alternato / 0↔10). Le versioni ripristinano l'originale. - - Only Back/Forward buttons can turn pages - + + Search… + Ricerca… - - Use the Left/Right buttons to turn pages. - + + Light + Luce - - Click left or right half of the screen to turn pages. - + + Dark + Buio - - Disable mouse over activation - Disabilita il mouse all'attivazione + + ID: + Identificativo: - - Page Flow - Flusso pagine + + Display name: + Nome da visualizzare: - - General - Generale + + Variant: + Variante: - - Brightness - Luminosità + + Theme info + Informazioni sul tema - - Restart is needed - Riavvio Necessario + + Parameter + Parametro - - Fit options - + + Value + Valore - - Enlarge images to fit width/height - + + Save and apply + Salva e applica - - Double Page options - + + Export to file... + Esporta su file... - - Show covers as single page - + + Load from file... + Carica da file... - - - QObject - - 7z lib not found - Libreria 7z non trovata + + Close + Chiudi - - unable to load 7z lib from ./utils - Impossibile caricare 7z da ./utils + + Double-click to edit color + Fare doppio clic per modificare il colore - - Trace - + + + + + + + true + VERO - - Debug - + + + + + false + falso - - Info - + + Double-click to toggle + Fare doppio clic per attivare/disattivare - - Warning - + + Double-click to edit value + Fare doppio clic per modificare il valore - - Error - + + + + Edit: %1 + Modifica: %1 - - Fatal - + + Save theme + Salva tema - - Select custom cover - + + + JSON files (*.json);;All files (*) + File JSON (*.json);;Tutti i file (*) - - Images (%1) - + + Save failed + Salvataggio non riuscito - - - QsLogging::LogWindowModel - - Time - + + Could not open file for writing: +%1 + Impossibile aprire il file per la scrittura: +%1 - - Level - + + Load theme + Carica tema - - Message - + + + + Load failed + Caricamento non riuscito - - - QsLogging::Window - - &Pause - + + Could not open file: +%1 + Impossibile aprire il file: +%1 - - &Resume - + + Invalid JSON: +%1 + JSON non valido: +%1 - - Save log - + + Expected a JSON object. + Era previsto un oggetto JSON. + + + TitleHeader - - Log file (*.log) - + + SEARCH + CERCA - ShortcutsDialog + UpdateLibraryDialog - Close - Chiudi + + Updating.... + Aggiornamento... - YACReader keyboard shortcuts - Scorciatoie da tastiera di YACReader + + Cancel + Annulla - Keyboard Shortcuts - Scorciatoia da tastiera + + Update library + Aggiorna Libreria Viewer - + Page not available! Pagina non disponibile! - - + + Press 'O' to open comic. Premi "O" per aprire il fumettto. - + Error opening comic Errore nell'apertura - + Cover! Copertina! - + CRC Error Errore CRC - + Comic not found Fumetto non trovato - + Not found Non trovato - + Last page! Ultima pagina! - + Loading...please wait! In caricamento...Attendi! + + VolumeComicsModel + + + title + Titolo + + + + VolumesModel + + + year + Anno + + + + issues + Emissione + + + + publisher + Pubblicato da + + + + YACReader3DFlowConfigWidget + + + Presets: + Preselezioni: + + + + Classic look + Aspetto Classico + + + + Stripe look + Aspetto a strisce + + + + Overlapped Stripe look + Aspetto a strisce sovrapposto + + + + Modern look + Aspetto moderno + + + + Roulette look + Aspetto Roulette + + + + Show advanced settings + Mostra opzioni avanzate + + + + Custom: + Personalizzazione: + + + + View angle + Angolo di vista + + + + Position + Posizione + + + + Cover gap + Distanza Copertine + + + + Central gap + Distanza centrale + + + + Zoom + Ingrandimento + + + + Y offset + Compensazione Y + + + + Z offset + Compensazione Z + + + + Cover Angle + Angolo copertine + + + + Visibility + Visibilità + + + + Light + Luce + + + + Max angle + Angolo massimo + + + + Low Performance + Prestazioni Basse + + + + High Performance + Prestazioni Alte + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Usa VSync (migliora la qualtà a tutto schermo, peggiora le prestazioni) + + + + Performance: + Prestazioni: + + YACReader::MainWindowViewer - + &Open - &Apri + &Apri - + Open a comic - Apri un Fumetto + Apri un Fumetto - + New instance - + Nuova istanza - + Open Folder - Apri una cartella + Apri una cartella - + Open image folder - Apri la crettal immagini + Apri la crettal immagini - + Open latest comic - Apri l'ultimo fumetto + Apri l'ultimo fumetto - + Open the latest comic opened in the previous reading session - Apri l'ultimo fumetto aperto nella sessione precedente + Apri l'ultimo fumetto aperto nella sessione precedente - + Clear - Cancella + Cancella - + Clear open recent list - Svuota la lista degli aperti + Svuota la lista degli aperti - + Save - Salva + Salva - + Save current page - Salva la pagina corrente + Salva la pagina corrente Previous Comic - Fumetto precendente + Fumetto precendente - - - + + + Open previous comic - Apri il fumetto precendente + Apri il fumetto precendente - + Next Comic - Prossimo fumetto + Prossimo fumetto - - - + + + Open next comic - Apri il prossimo fumetto + Apri il prossimo fumetto - + &Previous - &Precedente + &Precedente - - - + + + Go to previous page - Vai alla pagina precedente + Vai alla pagina precedente - + &Next - &Prossimo + &Prossimo - - - + + + Go to next page - Vai alla prossima Pagina + Vai alla prossima Pagina - + Fit Height - Adatta altezza + Adatta altezza - + Fit image to height - Adatta immagine all'altezza + Adatta immagine all'altezza - + Fit Width - Adatta Larghezza + Adatta Larghezza - + Fit image to width - Adatta immagine in larghezza + Adatta immagine in larghezza - + Show full size - Mostra dimesioni reali + Mostra dimesioni reali - + Fit to page - Adatta alla pagina + Adatta alla pagina + + + + Continuous scroll + Scorrimento continuo + + + + Switch to continuous scroll mode + Passa alla modalità di scorrimento continuo - + Reset zoom - Resetta Zoom + Resetta Zoom - + Show zoom slider - Mostra cursore di zoom + Mostra cursore di zoom - + Zoom+ - Zoom+ + Aumenta - + Zoom- - Zoom- + Riduci - + Rotate image to the left - Ruota immagine a sinistra + Ruota immagine a sinistra - + Rotate image to the right - Ruota immagine a destra + Ruota immagine a destra - + Double page mode - Modalita doppia pagina + Modalita doppia pagina - + Switch to double page mode - Passa alla modalità doppia pagina + Passa alla modalità doppia pagina - + Double page manga mode - Modalità doppia pagina Manga + Modalità doppia pagina Manga - + Reverse reading order in double page mode - Ordine lettura inverso in modo doppia pagina + Ordine lettura inverso in modo doppia pagina - + Go To - Vai a + Vai a - + Go to page ... - Vai a Pagina ... + Vai a Pagina ... - + Options - Opzioni + Opzioni - + YACReader options - Opzioni YACReader + Opzioni YACReader - - + + Help - Aiuto + Aiuto - + Help, About YACReader - Aiuto, crediti YACReader + Aiuto, crediti YACReader - + Magnifying glass - Lente ingrandimento + Lente ingrandimento - + Switch Magnifying glass - Passa a lente ingrandimento + Passa a lente ingrandimento - + Set bookmark - Imposta Segnalibro + Imposta Segnalibro - + Set a bookmark on the current page - Imposta segnalibro a pagina corrente + Imposta segnalibro a pagina corrente - + Show bookmarks - Mostra segnalibro + Mostra segnalibro - + Show the bookmarks of the current comic - Mostra il segnalibro del fumetto corrente + Mostra il segnalibro del fumetto corrente - + Show keyboard shortcuts - Mostra scorciatoie da tastiera + Mostra scorciatoie da tastiera - + Show Info - Mostra info + Mostra info - + Close - Chiudi + Chiudi - + Show Dictionary - Mostra dizionario + Mostra dizionario - + Show go to flow - Mostra vai all'elenco + Mostra vai all'elenco - + Edit shortcuts - + Edita scorciatoie - + &File - &File + &Documento - - + + Open recent - Apri i recenti + Apri i recenti - + File - File + Documento - + Edit - Edit + Edita - + View - Mostra + Mostra - + Go - Vai + Vai - + Window - Finestra + Finestra - - - + + + Open Comic - Apri Fumetto + Apri Fumetto - - - + + + Comic files - File Fumetto + File Fumetto - + Open folder - Apri cartella + Apri cartella - + page_%1.jpg - Pagina_%1.jpg + Pagina_%1.jpg - + Image files (*.jpg) - File immagine (*.jpg) + File immagine (*.jpg) + Comics - Fumetto + Fumetto Toggle fullscreen mode - Attiva/Disattiva schermo intero + Attiva/Disattiva schermo intero Hide/show toolbar - Mostra/Nascondi Barra strumenti + Mostra/Nascondi Barra strumenti + General - Generale + Generale Size up magnifying glass - Ingrandisci lente ingrandimento + Ingrandisci lente ingrandimento Size down magnifying glass - Riduci lente ingrandimento + Riduci lente ingrandimento Zoom in magnifying glass - Ingrandisci in lente di ingrandimento + Ingrandisci in lente di ingrandimento Zoom out magnifying glass - Riduci in lente di ingrandimento + Riduci in lente di ingrandimento Reset magnifying glass - + Reimposta la lente d'ingrandimento + Magnifiying glass - Lente ingrandimento + Lente ingrandimento Toggle between fit to width and fit to height - Passa tra adatta in larghezza ad altezza + Passa tra adatta in larghezza ad altezza + Page adjustement - Correzioni di pagna + Correzioni di pagna - + Autoscroll down - Autoscorri Giù + Autoscorri Giù - + Autoscroll up - Autoscorri Sù + Autoscorri Sù - + Autoscroll forward, horizontal first - Autoscorri avanti, priorità Orizzontale + Autoscorri avanti, priorità Orizzontale - + Autoscroll backward, horizontal first - Autoscorri indietro, priorità Orizzontale + Autoscorri indietro, priorità Orizzontale - + Autoscroll forward, vertical first - Autoscorri avanti, priorità Verticale + Autoscorri avanti, priorità Verticale - + Autoscroll backward, vertical first - Autoscorri indietro, priorità Verticale + Autoscorri indietro, priorità Verticale - + Move down - Muovi Giù + Muovi Giù - + Move up - Muovi Sù + Muovi Sù - + Move left - Muovi Sinistra + Muovi Sinistra - + Move right - Muovi Destra + Muovi Destra - + Go to the first page - Vai alla pagina iniziale + Vai alla pagina iniziale - + Go to the last page - Vai all'ultima pagina + Vai all'ultima pagina - + Offset double page to the left - + Doppia pagina spostata a sinistra - + Offset double page to the right - + Doppia pagina spostata a destra - + + Reading - Leggi + Leggi - + There is a new version available - Nuova versione disponibile + Nuova versione disponibile - + Do you want to download the new version? - Vuoi scaricare la nuova versione? + Vuoi scaricare la nuova versione? - + Remind me in 14 days - Ricordamelo in 14 giorni + Ricordamelo in 14 giorni - + Not now - Non ora + Non ora + + + + YACReader::TrayIconController + + + &Restore + &Rnegozio + + + + Systray + Area di notifica + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary continuerà a essere eseguito nella barra delle applicazioni. Per terminare il programma, scegli <b>Esci</b> nel menu contestuale dell'icona nella barra delle applicazioni. YACReader::WhatsNewDialog - Close - Chiudi + Chiudi @@ -1407,172 +4047,152 @@ YACReaderFlowConfigWidget - CoverFlow look - Aspetto flusso Copertine + Aspetto flusso Copertine - How to show covers: - Come mostrare le copertine: + Come mostrare le copertine: - Stripe look - Aspetto a strisce + Aspetto a strisce - Overlapped Stripe look - Aspetto a strisce sovrapposto + Aspetto a strisce sovrapposto YACReaderGLFlowConfigWidget - Zoom - Zoom + Ingrandimento - Light - Luce + Luce - Show advanced settings - Mostra opzioni avanzate + Mostra opzioni avanzate - Roulette look - Aspetto Roulette + Aspetto Roulette - Cover Angle - Angolo copertine + Angolo copertine - Stripe look - Aspetto a strisce + Aspetto a strisce - Position - Posizione + Posizione - Z offset - Compensazione Z + Compensazione Z - Y offset - Compensazione Y + Compensazione Y - Central gap - Distanza centrale + Distanza centrale - Presets: - Preselezioni: + Preselezioni: - Overlapped Stripe look - Aspetto a strisce sovrapposto + Aspetto a strisce sovrapposto - Modern look - Aspetto moderno + Aspetto moderno - View angle - Angolo di vista + Angolo di vista - Max angle - Angolo massimo + Angolo massimo - Custom: - Personalizzazione: + Personalizzazione: - Classic look - Aspetto Classico + Aspetto Classico - Cover gap - Distanza Copertine + Distanza Copertine - High Performance - Prestazioni Alte + Prestazioni Alte - Performance: - Prestazioni: + Prestazioni: - Use VSync (improve the image quality in fullscreen mode, worse performance) - Usa VSync (migliora la qualtà a tutto schermo, peggiora le prestazioni) + Usa VSync (migliora la qualtà a tutto schermo, peggiora le prestazioni) - Visibility - Visibilità + Visibilità - Low Performance - Prestazioni Basse + Prestazioni Basse YACReaderOptionsDialog - + Save Salva - Use hardware acceleration (restart needed) - Usa accelerazione Hardware (necessita restart) + Usa accelerazione Hardware (necessita restart) - + Cancel Cancella - + Shortcuts Scorciatoia - + Edit shortcuts Edita Scorciatoia + + YACReaderSearchLineEdit + + + type to search + Digita per cercare + + YACReaderSlider @@ -1584,23 +4204,23 @@ YACReaderTranslator - + clear Cancella - + Service not available Servizio non disponibile - - + + Translation Traduzione - + YACReader translator Traduttore YACReader diff --git a/YACReader/yacreader_nl.ts b/YACReader/yacreader_nl.ts index 30db16399..8d389ff04 100644 --- a/YACReader/yacreader_nl.ts +++ b/YACReader/yacreader_nl.ts @@ -6,1196 +6,3836 @@ None - + Geen - BookmarksDialog + AddLabelDialog - - Close - Sluiten + + Label name: + Labelnaam: - - - Loading... - Inladen... + + Choose a color: + Kies een kleur: - - Click on any image to go to the bookmark - Klik op een afbeelding om naar de bladwijzer te gaan + + accept + accepteren - - Lastest Page - Laatste Pagina + + cancel + annuleren - EditShortcutsDialog + AddLibraryDialog - - Restore defaults - + + Comics folder : + Strips map: - - To change a shortcut, double click in the key combination and type the new keys. - + + Library name : + Bibliotheek Naam : - - Shortcuts settings - + + Add + Toevoegen - - Shortcut in use - + + Cancel + Annuleren - - The shortcut "%1" is already assigned to other function - + + Add an existing library + Voeg een bestaand bibliotheek toe - FileComic + ApiKeyDialog - - 7z not found - 7Z Archiefbestand niet gevonden + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Voordat je verbinding kunt maken met Comic Vine, heb je een eigen API-sleutel nodig. Vraag er <a href="http://www.comicvine.com/api/">hier</a> één gratis aan - - CRC error on page (%1): some of the pages will not be displayed correctly - + + Paste here your Comic Vine API key + Plak hier uw Comic Vine API-sleutel - - Unknown error opening the file - + + Accept + Accepteren - - Format not supported - + + Cancel + Annuleren - GoToDialog + AppearanceTabWidget - - Go To - Ga Naar + + Color scheme + Kleurenschema - - Go to... - Ga naar... + + System + Systeem - - - Total pages : - Totaal aantal pagina's : + + Light + Licht - - Cancel - Annuleren + + Dark + Donker - - Page : - Pagina : + + Custom + Aangepast - - - GoToFlowToolBar - - Page : - Pagina : + + Remove + Verwijderen + + + + Remove this user-imported theme + Verwijder dit door de gebruiker geïmporteerde thema + + + + Light: + Licht: + + + + Dark: + Donker: + + + + Custom: + Aangepast: + + + + Import theme... + Thema importeren... + + + + Theme + Thema + + + + Theme editor + Thema-editor + + + + Open Theme Editor... + Thema-editor openen... + + + + Theme editor error + Fout in de thema-editor + + + + The current theme JSON could not be loaded. + De huidige thema-JSON kan niet worden geladen. + + + + Import theme + Thema importeren + + + + JSON files (*.json);;All files (*) + JSON-bestanden (*.json);;Alle bestanden (*) + + + + Could not import theme from: +%1 + Kan thema niet importeren uit: +%1 + + + + Could not import theme from: +%1 + +%2 + Kan thema niet importeren uit: +%1 + +%2 + + + + Import failed + Importeren is mislukt - HelpAboutDialog + BookmarksDialog - - Help - Help + + Close + Sluiten - - System info - + + + Loading... + Inladen... - - About - Over + + Click on any image to go to the bookmark + Klik op een afbeelding om naar de bladwijzer te gaan + + + + Lastest Page + Laatste Pagina - LogWindow + ClassicComicsView - - Log window - + + Hide comic flow + Sluit de Omslagbrowser + + + ComicModel - - &Pause - + + yes + Ja - - &Save - + + no + neen - - C&lear - + + Title + Titel - - &Copy - + + File Name + Bestandsnaam - - Level: - + + Pages + Pagina's - - &Auto scroll - + + Size + Grootte(MB) - - - MainWindowViewer - Help - Help + + Read + Gelezen - Save - Bewaar + + Current Page + Huidige pagina - &File - &Bestand + + Publication Date + Publicatiedatum - &Next - &Volgende + + Rating + Beoordeling - &Open - &Open + + Series + Serie - Close - Sluiten + + Volume + Deel - Open Comic - Open een Strip + + Story Arc + Verhaalboog + + + ComicVineDialog - Go To - Ga Naar + + skip + overslaan - Open image folder - Open afbeeldings map + + back + rug - Set bookmark - Bladwijzer instellen + + next + volgende - page_%1.jpg - pagina_%1.jpg + + search + zoekopdracht - Switch to double page mode - Naar dubbele bladzijde modus + + close + dichtbij - Save current page - Bewaren huidige pagina + + + comic %1 of %2 - %3 + strip %1 van %2 - %3 - Double page mode - Dubbele bladzijde modus + + + + Looking for volume... + Op zoek naar volumes... - Switch Magnifying glass - Overschakelen naar Vergrootglas + + %1 comics selected + %1 strips geselecteerd - Open Folder - Map Openen + + Error connecting to ComicVine + Fout bij verbinden met ComicVine - Comic files - Strip bestanden + + + Retrieving tags for : %1 + Tags ophalen voor: %1 - Go to previous page - Ga naar de vorige pagina + + Retrieving volume info... + Volume-informatie ophalen... - Open a comic - Open een strip + + Looking for comic... + Op zoek naar komische... + + + ContinuousPageWidget - Image files (*.jpg) - Afbeelding bestanden (*.jpg) + + Loading page %1 + Pagina laden %1 + + + CreateLibraryDialog - Next Comic - Volgende Strip + + Comics folder : + Strips map: - Fit Width - Vensterbreedte aanpassen + + Library Name : + Bibliotheek Naam : - Options - Opties + + Create + Aanmaken - Show Info - Info tonen + + Cancel + Annuleren - Open folder - Open een Map + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Een bibliotheek aanmaken kan enkele minuten duren. U kunt het proces stoppen en de bibliotheek later voltooien. - Go to page ... - Ga naar bladzijde ... + + Create new library + Een nieuwe Bibliotheek aanmaken - Fit image to width - Afbeelding aanpassen aan breedte + + Path not found + Pad niet gevonden - &Previous - &Vorige + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + De geselecteerde pad bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map + + + EditShortcutsDialog - Go to next page - Ga naar de volgende pagina + + Restore defaults + Standaardwaarden herstellen - Show keyboard shortcuts - Toon de sneltoetsen + + To change a shortcut, double click in the key combination and type the new keys. + Om een ​​snelkoppeling te wijzigen, dubbelklikt u op de toetsencombinatie en typt u de nieuwe toetsen. - There is a new version available - Er is een nieuwe versie beschikbaar + + Shortcuts settings + Instellingen voor snelkoppelingen - Open next comic - Open volgende strip + + Shortcut in use + Snelkoppeling in gebruik - Show bookmarks - Bladwijzers weergeven + + The shortcut "%1" is already assigned to other function + De sneltoets "%1" is al aan een andere functie toegewezen + + + EmptyFolderWidget - Open previous comic - Open de vorige strip + + This folder doesn't contain comics yet + Deze map bevat nog geen strips + + + EmptyLabelWidget - Rotate image to the left - Links omdraaien + + This label doesn't contain comics yet + Dit label bevat nog geen strips + + + EmptyReadingListWidget - Fit image to height - Afbeelding aanpassen aan hoogte + + This reading list does not contain any comics yet + Deze leeslijst bevat nog geen strips + + + EmptySpecialListWidget - Show the bookmarks of the current comic - Toon de bladwijzers van de huidige strip + + No favorites + Geen favorieten - Show Dictionary - Woordenlijst weergeven + + You are not reading anything yet, come on!! + Je leest nog niets, kom op!! - YACReader options - YACReader opties + + There are no recent comics! + Er zijn geen recente strips! + + + + ExportComicsInfoDialog + + + Output file : + Uitvoerbestand: - Help, About YACReader - Help, Over YACReader + + Create + Aanmaken - Show go to flow - Toon ga naar de Omslagbrowser + + Cancel + Annuleren - Previous Comic - Vorige Strip + + Export comics info + Strip info exporteren - Show full size - Volledig Scherm + + Destination database name + Bestemmingsdatabase naam - Magnifying glass - Vergrootglas + + Problem found while writing + Probleem bij het schrijven - General - Algemeen + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Het gekozen pad voor het uitvoerbestand bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map + + + ExportLibraryDialog - Set a bookmark on the current page - Een bladwijzer toevoegen aan de huidige pagina + + Output folder : + Uitvoermap : - Do you want to download the new version? - Wilt u de nieuwe versie downloaden? + + Create + Aanmaken - Rotate image to the right - Rechts omdraaien + + Cancel + Annuleren + + + + Create covers package + Aanmaken omslag pakket + + + + Problem found while writing + Probleem bij het schrijven + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Het gekozen pad voor het uitvoerbestand bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map + + + + Destination directory + Doeldirectory + + + + FileComic + + + 7z not found + 7Z Archiefbestand niet gevonden + + + + CRC error on page (%1): some of the pages will not be displayed correctly + CRC-fout op pagina (%1): sommige pagina's worden niet correct weergegeven + + + + Unknown error opening the file + Onbekende fout bij het openen van het bestand + + + + Format not supported + Formaat niet ondersteund + + + + GoToDialog + + + Go To + Ga Naar + + + + Go to... + Ga naar... + + + + + Total pages : + Totaal aantal pagina's : + + + + Cancel + Annuleren + + + + Page : + Pagina : + + + + GoToFlowToolBar + + + Page : + Pagina : + + + + GridComicsView + + + Show info + Toon informatie + + + + HelpAboutDialog + + + Help + Hulp + + + + System info + Systeeminformatie + + + + About + Over + + + + ImportComicsInfoDialog + + + Import comics info + Strip info Importeren + + + + Info database location : + Info database locatie : + + + + Import + Importeren + + + + Cancel + Annuleren + + + + Comics info file (*.ydb) + Strips info bestand ( * .ydb) + + + + ImportLibraryDialog + + + Library Name : + Bibliotheek Naam : + + + + Package location : + Arrangement locatie : + + + + Destination folder : + Doelmap: + + + + Unpack + Uitpakken + + + + Cancel + Annuleren + + + + Extract a catalog + Een catalogus uitpakken + + + + Compresed library covers (*.clc) + Compresed omslag- bibliotheek ( * .clc) + + + + ImportWidget + + + stop + Stoppen + + + + Some of the comics being added... + Enkele strips zijn toegevoegd ... + + + + Importing comics + Strips importeren + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <P>YACReaderLibrary maak nu een nieuwe bibliotheek. < /p> <p>Een bibliotheek aanmaken kan enkele minuten duren. U kunt het proces stoppen en de bibliotheek later voltooien. < /p> + + + + Updating the library + Actualisering van de bibliotheek + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <P>De huidige bibliotheek wordt bijgewerkt. Voor snellere updates, update uw bibliotheken regelmatig. < /p> <p>u kunt het proces stoppen om later bij te werken. < /p> + + + + Upgrading the library + Het upgraden van de bibliotheek + + + + <p>The current library is being upgraded, please wait.</p> + <p>De huidige bibliotheek wordt geüpgraded. Een ogenblik geduld.</p> + + + + Scanning the library + De bibliotheek scannen + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>De huidige bibliotheek wordt gescand op oudere XML-metadata-informatie.</p><p>Dit is slechts één keer nodig en alleen als de bibliotheek is ingepakt met YACReaderLibrary 9.8.2 of eerder.</p> + + + + LibraryWindow + + + YACReader Library + YACReader Bibliotheek + + + + + + comic + grappig + + + + + + manga + Manga + + + + + + western manga (left to right) + westerse manga (van links naar rechts) + + + + + + web comic + web-strip + + + + + + 4koma (top to botom) + 4koma (van boven naar beneden) + + + + + + + Set type + Soort instellen + + + + Library + Bibliotheek + + + + Folder + Map + + + + Comic + Grappig + + + + Upgrade failed + Upgrade mislukt + + + + There were errors during library upgrade in: + Er zijn fouten opgetreden tijdens de bibliotheekupgrade in: + + + + Update needed + Bijwerken is nodig + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Deze bibliotheek is gemaakt met een vorige versie van YACReaderLibrary. Het moet worden bijgewerkt. Nu bijwerken? + + + + Download new version + Nieuwe versie ophalen + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Deze bibliotheek is gemaakt met een nieuwere versie van YACReaderLibrary. Download de nieuwe versie? + + + + Library not available + Bibliotheek niet beschikbaar + + + + Library '%1' is no longer available. Do you want to remove it? + Bibliotheek ' %1' is niet langer beschikbaar. Wilt u het verwijderen? + + + + Old library + Oude Bibliotheek + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Bibliotheek ' %1' is gemaakt met een oudere versie van YACReaderLibrary. Zij moet opnieuw worden aangemaakt. Wilt u de bibliotheek nu aanmaken? + + + + + Copying comics... + Strips kopiëren... + + + + + Moving comics... + Strips verplaatsen... + + + + Add new folder + Nieuwe map toevoegen + + + + Folder name: + Mapnaam: + + + + No folder selected + Geen map geselecteerd + + + + Please, select a folder first + Selecteer eerst een map + + + + Error in path + Fout in pad + + + + There was an error accessing the folder's path + Er is een fout opgetreden bij het verkrijgen van toegang tot het pad van de map + + + + Delete folder + Map verwijderen + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + De geselecteerde map en de volledige inhoud ervan worden van uw schijf verwijderd. Weet je het zeker? + + + + + Unable to delete + Kan niet verwijderen + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Er is een probleem opgetreden bij het verwijderen van de geselecteerde mappen. Controleer of er schrijfrechten zijn en zorg ervoor dat alle toepassingen deze mappen of een van de daarin opgenomen bestanden gebruiken. + + + + Add new reading lists + Voeg nieuwe leeslijsten toe + + + + + List name: + Lijstnaam: + + + + Delete list/label + Lijst/label verwijderen + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + Het geselecteerde item wordt verwijderd, uw strips of mappen worden NIET van uw schijf verwijderd. Weet je het zeker? + + + + Rename list name + Hernoem de lijstnaam + + + + Open folder... + Map openen ... + + + + Update folder + Map bijwerken + + + + Rescan library for XML info + Bibliotheek opnieuw scannen op XML-info + + + + Set as uncompleted + Ingesteld als onvoltooid + + + + Set as completed + Instellen als voltooid + + + + Set as read + Instellen als gelezen + + + + + Set as unread + Instellen als ongelezen + + + + Set custom cover + Aangepaste omslag instellen + + + + Delete custom cover + Aangepaste omslag verwijderen + + + + Save covers + Bewaar hoesjes + + + + You are adding too many libraries. + U voegt te veel bibliotheken toe. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + U voegt te veel bibliotheken toe. + +Je hebt waarschijnlijk maar één bibliotheek nodig in je stripmap op het hoogste niveau. Je kunt door alle submappen bladeren met behulp van het mappengedeelte in de linkerzijbalk. + +YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, maar u moet het aantal bibliotheken laag houden. + + + + + YACReader not found + YACReader niet gevonden + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader niet gevonden. YACReader moet in dezelfde map worden geïnstalleerd als YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader niet gevonden. Er is mogelijk een probleem met uw YACReader-installatie. + + + + Error + Fout + + + + Error opening comic with third party reader. + Fout bij het openen van een strip met een lezer van een derde partij. + + + + Library not found + Bibliotheek niet gevonden + + + + The selected folder doesn't contain any library. + De geselecteerde map bevat geen bibliotheek. + + + + Are you sure? + Weet u het zeker? + + + + Do you want remove + Wilt u verwijderen + + + + library? + Bibliotheek? + + + + Remove and delete metadata + Verwijder metagegevens + + + + Library info + Bibliotheekinformatie + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Er is een probleem opgetreden bij het verwijderen van de geselecteerde strips. Controleer of er schrijfrechten zijn voor de geselecteerde bestanden of de map waarin deze zich bevinden. + + + + Assign comics numbers + Wijs stripnummers toe + + + + Assign numbers starting in: + Nummers toewijzen beginnend met: + + + + Invalid image + Ongeldige afbeelding + + + + The selected file is not a valid image. + Het geselecteerde bestand is geen geldige afbeelding. + + + + Error saving cover + Fout bij opslaan van dekking + + + + There was an error saving the cover image. + Er is een fout opgetreden bij het opslaan van de omslagafbeelding. + + + + Error creating the library + Fout bij aanmaken Bibliotheek + + + + Error updating the library + Fout bij bijwerken Bibliotheek + + + + Error opening the library + Fout bij openen Bibliotheek + + + + Delete comics + Strips verwijderen + + + + All the selected comics will be deleted from your disk. Are you sure? + Alle geselecteerde strips worden verwijderd van uw schijf. Weet u het zeker? + + + + Remove comics + Verwijder strips + + + + Comics will only be deleted from the current label/list. Are you sure? + Strips worden alleen verwijderd van het huidige label/de huidige lijst. Weet je het zeker? + + + + Library name already exists + Bibliotheek naam bestaat al + + + + There is another library with the name '%1'. + Er is al een bibliotheek met de naam ' %1 '. + + + + LibraryWindowActions + + + Create a new library + Maak een nieuwe Bibliotheek + + + + Open an existing library + Open een bestaande Bibliotheek + + + + + Export comics info + Strip info exporteren + + + + + Import comics info + Strip info Importeren + + + + Pack covers + Inpakken strip voorbladen + + + + Pack the covers of the selected library + Inpakken alle strip voorbladen van de geselecteerde Bibliotheek + + + + Unpack covers + Uitpakken voorbladen + + + + Unpack a catalog + Uitpaken van een catalogus + + + + Update library + Bibliotheek bijwerken + + + + Update current library + Huidige Bibliotheek bijwerken + + + + Rename library + Bibliotheek hernoemen + + + + Rename current library + Huidige Bibliotheek hernoemen + + + + Remove library + Bibliotheek verwijderen + + + + Remove current library from your collection + De huidige Bibliotheek verwijderen uit uw verzameling + + + + Rescan library for XML info + Bibliotheek opnieuw scannen op XML-info + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Probeert XML-informatie te vinden die is ingebed in stripbestanden. U hoeft dit alleen te doen als de bibliotheek is gemaakt met versie 9.8.2 of eerdere versies of als u software van derden gebruikt om XML-informatie in de bestanden in te sluiten. + + + + Show library info + Bibliotheekinfo tonen + + + + Show information about the current library + Toon informatie over de huidige bibliotheek + + + + Open current comic + Huidige strip openen + + + + Open current comic on YACReader + Huidige strip openen in YACReader + + + + Save selected covers to... + Geselecteerde omslagen opslaan in... + + + + Save covers of the selected comics as JPG files + Sla covers van de geselecteerde strips op als JPG-bestanden + + + + + Set as read + Instellen als gelezen + + + + Set comic as read + Strip Instellen als gelezen + + + + + Set as unread + Instellen als ongelezen + + + + Set comic as unread + Strip Instellen als ongelezen + + + + + manga + Manga + + + + Set issue as manga + Stel het probleem in als manga + + + + + comic + grappig + + + + Set issue as normal + Stel het probleem in als normaal + + + + western manga + westerse manga + + + + Set issue as western manga + Stel het probleem in als westerse manga + + + + + web comic + web-strip + + + + Set issue as web comic + Stel het probleem in als webstrip + + + + + yonkoma + yokoma + + + + Set issue as yonkoma + Stel het probleem in als yonkoma + + + + Show/Hide marks + Toon/Verberg markeringen + + + + Show or hide read marks + Toon of verberg leesmarkeringen + + + + Show/Hide recent indicator + Recente indicator tonen/verbergen + + + + Show or hide recent indicator + Toon of verberg recente indicator + + + + + Fullscreen mode on/off + Volledig scherm modus aan/of + + + + Help, About YACReader + Help, Over YACReader + + + + Add new folder + Nieuwe map toevoegen + + + + Add new folder to the current library + Voeg een nieuwe map toe aan de huidige bibliotheek + + + + Delete folder + Map verwijderen + + + + Delete current folder from disk + Verwijder de huidige map van schijf + + + + Select root node + Selecteer de hoofd categorie + + + + Expand all nodes + Alle categorieën uitklappen + + + + Collapse all nodes + Vouw alle knooppunten samen + + + + Show options dialog + Toon opties dialoog + + + + Show comics server options dialog + Toon strips-server opties dialoog + + + + + Change between comics views + Wisselen tussen stripweergaven + + + + Open folder... + Map openen ... + + + + Set as uncompleted + Ingesteld als onvoltooid + + + + Set as completed + Instellen als voltooid + + + + Set custom cover + Aangepaste omslag instellen + + + + Delete custom cover + Aangepaste omslag verwijderen + + + + western manga (left to right) + westerse manga (van links naar rechts) + + + + Open containing folder... + Open map ... + + + + Reset comic rating + Stripbeoordeling opnieuw instellen + + + + Select all comics + Selecteer alle strips + + + + Edit + Bewerken + + + + Assign current order to comics + Wijs de huidige volgorde toe aan strips + + + + Update cover + Strip omslagen bijwerken + + + + Delete selected comics + Geselecteerde strips verwijderen + + + + Delete metadata from selected comics + Verwijder metadata uit geselecteerde strips + + + + Download tags from Comic Vine + Tags downloaden van Comic Vine + + + + Focus search line + Focus zoeklijn + + + + Focus comics view + Focus stripweergave + + + + Edit shortcuts + Snelkoppelingen bewerken + + + + &Quit + &Afsluiten + + + + Update folder + Map bijwerken + + + + Update current folder + Werk de huidige map bij + + + + Scan legacy XML metadata + Scan oudere XML-metagegevens + + + + Add new reading list + Nieuwe leeslijst toevoegen + + + + Add a new reading list to the current library + Voeg een nieuwe leeslijst toe aan de huidige bibliotheek + + + + Remove reading list + Leeslijst verwijderen + + + + Remove current reading list from the library + Verwijder de huidige leeslijst uit de bibliotheek + + + + Add new label + Nieuw etiket toevoegen + + + + Add a new label to this library + Voeg een nieuw label toe aan deze bibliotheek + + + + Rename selected list + Hernoem de geselecteerde lijst + + + + Rename any selected labels or lists + Hernoem alle geselecteerde labels of lijsten + + + + Add to... + Toevoegen aan... + + + + Favorites + Favorieten + + + + Add selected comics to favorites list + Voeg geselecteerde strips toe aan de favorietenlijst + + + + LocalComicListModel + + + file name + bestandsnaam + + + + MainWindowViewer + + Help + Hulp + + + Save + Bewaar + + + &File + &Bestand + + + &Next + &Volgende + + + &Open + &Openen + + + Close + Sluiten + + + Open Comic + Open een Strip + + + Go To + Ga Naar + + + Open image folder + Open afbeeldings map + + + Set bookmark + Bladwijzer instellen + + + page_%1.jpg + pagina_%1.jpg + + + Switch to double page mode + Naar dubbele bladzijde modus + + + Save current page + Bewaren huidige pagina + + + Double page mode + Dubbele bladzijde modus + + + Switch Magnifying glass + Overschakelen naar Vergrootglas + + + Open Folder + Map Openen + + + Comic files + Strip bestanden + + + Go to previous page + Ga naar de vorige pagina + + + Open a comic + Open een strip + + + Image files (*.jpg) + Afbeelding bestanden (*.jpg) + + + Next Comic + Volgende Strip + + + Fit Width + Vensterbreedte aanpassen + + + Options + Opties + + + Show Info + Info tonen + + + Open folder + Open een Map + + + Go to page ... + Ga naar bladzijde ... + + + Fit image to width + Afbeelding aanpassen aan breedte + + + &Previous + &Vorige + + + Go to next page + Ga naar de volgende pagina + + + Show keyboard shortcuts + Toon de sneltoetsen + + + There is a new version available + Er is een nieuwe versie beschikbaar + + + Open next comic + Open volgende strip + + + Show bookmarks + Bladwijzers weergeven + + + Open previous comic + Open de vorige strip + + + Rotate image to the left + Links omdraaien + + + Fit image to height + Afbeelding aanpassen aan hoogte + + + Show the bookmarks of the current comic + Toon de bladwijzers van de huidige strip + + + Show Dictionary + Woordenlijst weergeven + + + YACReader options + YACReader opties + + + Help, About YACReader + Help, Over YACReader + + + Show go to flow + Toon ga naar de Omslagbrowser + + + Previous Comic + Vorige Strip + + + Show full size + Volledig Scherm + + + Magnifying glass + Vergrootglas + + + General + Algemeen + + + Set a bookmark on the current page + Een bladwijzer toevoegen aan de huidige pagina + + + Do you want to download the new version? + Wilt u de nieuwe versie downloaden? + + + Rotate image to the right + Rechts omdraaien + + + Always on top + Altijd op voorgrond + + + + NoLibrariesWidget + + + You don't have any libraries yet + Je hebt geen nog libraries + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <P>u kunt een bibliotheek maken in een willekeurige map, YACReaderLibrary importeert alle strips en mappen uit deze map. Alle bibliotheek aangemaakt in het verleden kan je openen. < /p> <p>vergeet niet dat u YACReader kan gebruiken als stand-alone applicatie voor het lezen van de strips op de computer. < /p> + + + + create your first library + Maak uw eerste bibliotheek + + + + add an existing one + voeg een bestaande bibliotheek toe + + + + NoSearchResultsWidget + + + No results + Geen resultaten + + + + OptionsDialog + + + Gamma + Gammawaarde + + + + Reset + Standaardwaarden terugzetten + + + + My comics path + Pad naar mijn strips + + + + Scaling + Schalen + + + + Scaling method + Schaalmethode + + + + Nearest (fast, low quality) + Dichtstbijzijnde (snel, lage kwaliteit) + + + + Bilinear + Bilineair + + + + Lanczos (better quality) + Lanczos (betere kwaliteit) + + + + Image adjustment + Beeldaanpassing + + + + "Go to flow" size + "Naar Omslagbrowser" afmetingen + + + + Choose + Kies + + + + Image options + Afbeelding opties + + + + Contrast + Contrastwaarde + + + + + Libraries + Bibliotheken + + + + Comic Flow + Komische stroom + + + + Grid view + Rasterweergave + + + + + Appearance + Verschijning + + + + + Options + Opties + + + + + Language + Taal + + + + + Application language + Applicatietaal + + + + + System default + Standaard van het systeem + + + + Tray icon settings (experimental) + Instellingen voor ladepictogram (experimenteel) + + + + Close to tray + Dicht bij lade + + + + Start into the system tray + Begin in het systeemvak + + + + Edit Comic Vine API key + Bewerk de Comic Vine API-sleutel + + + + Comic Vine API key + Comic Vine API-sleutel + + + + ComicInfo.xml legacy support + ComicInfo.xml verouderde ondersteuning + + + + Import metadata from ComicInfo.xml when adding new comics + Importeer metagegevens uit ComicInfo.xml wanneer u nieuwe strips toevoegt + + + + Consider 'recent' items added or updated since X days ago + Overweeg 'recente' items die sinds X dagen geleden zijn toegevoegd of bijgewerkt + + + + Third party reader + Lezer van derden + + + + Write {comic_file_path} where the path should go in the command + Schrijf {comic_file_path} waar het pad naartoe moet in de opdracht + + + + + Clear + Duidelijk + + + + Update libraries at startup + Update bibliotheken bij het opstarten + + + + Try to detect changes automatically + Probeer wijzigingen automatisch te detecteren + + + + Update libraries periodically + Update bibliotheken regelmatig + + + + Interval: + Tijdsinterval: + + + + 30 minutes + 30 minuten + + + + 1 hour + 1 uur + + + + 2 hours + 2 uur + + + + 4 hours + 4 uur + + + + 8 hours + 8 uur + + + + 12 hours + 12 uur + + + + daily + dagelijks + + + + Update libraries at certain time + Update bibliotheken op een bepaald tijdstip + + + + Time: + Tijd: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + WAARSCHUWING! Tijdens bibliotheekupdates is schrijven naar de database uitgeschakeld! +Plan geen updates terwijl u de app mogelijk actief gebruikt. +During automatic updates the app will block some of the actions until the update is finished. +Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de titel van Bibliotheken. + + + + Modifications detection + Detectie van wijzigingen + + + + Compare the modified date of files when updating a library (not recommended) + Vergelijk de wijzigingsdatum van bestanden bij het updaten van een bibliotheek (niet aanbevolen) + + + + Enable background image + Achtergrondafbeelding inschakelen + + + + Opacity level + Dekkingsniveau + + + + Blur level + Vervagingsniveau + + + + Use selected comic cover as background + Gebruik geselecteerde stripomslag als achtergrond + + + + Restore defautls + Standaardwaarden herstellen + + + + Background + Achtergrond + + + + Display continue reading banner + Toon de banner voor verder lezen + + + + Display current comic banner + Toon huidige stripbanner + + + + Continue reading + Lees verder + + + + Comics directory + Strips map + + + + Background color + Achtergrondkleur + + + + Page Flow + Omslagbrowser + + + + + General + Algemeen + + + + Brightness + Helderheid + + + + + Restart is needed + Herstart is nodig + + + + Quick Navigation Mode + Snelle navigatiemodus + + + + Display + Weergave + + + + Show time in current page information label + Toon de tijd in het informatielabel van de huidige pagina + + + + Scroll behaviour + Scrollgedrag + + + + Disable scroll animations and smooth scrolling + Schakel scrollanimaties en soepel scrollen uit + + + + Do not turn page using scroll + Sla de pagina niet om met scrollen + + + + Use single scroll step to turn page + Gebruik een enkele scrollstap om de pagina om te slaan + + + + Mouse mode + Muismodus + + + + Only Back/Forward buttons can turn pages + Alleen de knoppen Terug/Vooruit kunnen pagina's omslaan + + + + Use the Left/Right buttons to turn pages. + Gebruik de knoppen Links/Rechts om pagina's om te slaan. + + + + Click left or right half of the screen to turn pages. + Klik op de linker- of rechterhelft van het scherm om pagina's om te slaan. + + + + Disable mouse over activation + Schakel muis-over-activering uit + + + + Fit options + Pas opties + + + + Enlarge images to fit width/height + Vergroot afbeeldingen zodat ze in de breedte/hoogte passen + + + + Double Page options + Opties voor dubbele pagina's + + + + Show covers as single page + Toon omslagen als enkele pagina + + + + PropertiesDialog + + + General info + Algemene Info + + + + Plot + Verhaal + + + + Authors + Auteurs + + + + Publishing + Uitgever + + + + Notes + Opmerkingen + + + + Cover page + Omslag + + + + Load previous page as cover + Laad de vorige pagina als omslag + + + + Load next page as cover + Laad de volgende pagina als omslag + + + + Reset cover to the default image + Zet de omslag terug naar de standaardafbeelding + + + + Load custom cover image + Aangepaste omslagafbeelding laden + + + + Series: + Serie: + + + + Title: + Titel: + + + + + + of: + van: + + + + Issue number: + Ids: + + + + Volume: + Inhoud: + + + + Arc number: + Boognummer: + + + + Story arc: + Verhaallijn: + + + + alt. number: + alt. nummer: + + + + Alternate series: + Alternatieve serie: + + + + Series Group: + Seriegroep: + + + + Genre: + Genretype: + + + + Size: + Grootte(MB): + + + + Writer(s): + Schrijver(s): + + + + Penciller(s): + Tekenaar(s): + + + + Inker(s): + Inkt(en): + + + + Colorist(s): + Inkleurder(s): + + + + Letterer(s): + Letterzetter(s): + + + + Cover Artist(s): + Omslag ontwikkelaar(s): + + + + Editor(s): + Redacteur(en): + + + + Imprint: + Opdruk: + + + + Day: + Dag: + + + + Month: + Maand: + + + + Year: + Jaar: + + + + Publisher: + Uitgever: + + + + Format: + Formaat: + + + + Color/BW: + Kleur/ZW: + + + + Age rating: + Leeftijdsbeperking: + + + + Type: + Soort: + + + + Language (ISO): + Taal (ISO): + + + + Synopsis: + Samenvatting: + + + + Characters: + Personages: + + + + Teams: + Ploegen: + + + + Locations: + Locaties: + + + + Main character or team: + Hoofdpersoon of team: + + + + Review: + Beoordeling: + + + + Notes: + Opmerkingen: + + + + Tags: + Labels: + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine-link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> bekijken </a> + + + + Not found + Niet gevonden + + + + Comic not found. You should update your library. + Strip niet gevonden. U moet uw bibliotheek.bijwerken. + + + + Edit comic information + Strip informatie bijwerken + + + + Edit selected comics information + Geselecteerde strip informatie bijwerken + + + + Invalid cover + Ongeldige dekking + + + + The image is invalid. + De afbeelding is ongeldig. + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer is de headless (geen gui) versie van YACReaderLibrary. + +Deze applicatie ondersteunt permanente instellingen. Om ze in te stellen, bewerk dit bestand %1 +Voor meer informatie over de beschikbare instellingen kunt u de documentatie raadplegen op https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject + + + 7z lib not found + 7z-lib niet gevonden + + + + unable to load 7z lib from ./utils + kan 7z lib niet laden vanuit ./utils + + + + Trace + Spoor + + + + Debug + Foutopsporing + + + + Info + Informatie + + + + Warning + Waarschuwing + + + + Error + Fout + + + + Fatal + Fataal + + + + Select custom cover + Selecteer een aangepaste omslag + + + + Images (%1) + Afbeeldingen (%1) + + + + The file could not be read or is not valid JSON. + Het bestand kan niet worden gelezen of is geen geldige JSON. + + + + This theme is for %1, not %2. + Dit thema is voor %1, niet voor %2. + + + + Libraries + Bibliotheken + + + + Folders + Mappen + + + + Reading Lists + Leeslijsten + + + + RenameLibraryDialog + + + New Library Name : + Nieuwe Bibliotheek Naam : + + + + Rename + Hernoem + + + + Cancel + Annuleren + + + + Rename current library + Huidige Bibliotheek hernoemen + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + Aantal gevonden volumes: %1 + + + + + page %1 of %2 + pagina %1 van %2 + + + + Number of %1 found : %2 + Aantal %1 gevonden: %2 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + Geef wat aanvullende informatie op voor deze strip. + + + + Series: + Serie: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Gebruik exacte matchzoekopdrachten. Schakel dit uit als u volumes wilt vinden die overeenkomen met enkele woorden in de naam. + + + + SearchVolume + + + Please provide some additional information. + Geef alstublieft wat aanvullende informatie op. + + + + Series: + Serie: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Gebruik exacte matchzoekopdrachten. Schakel dit uit als u volumes wilt vinden die overeenkomen met enkele woorden in de naam. + + + + SelectComic + + + Please, select the right comic info. + Selecteer de juiste stripinformatie. + + + + comics + strips + + + + loading cover + laaddeksel + + + + loading description + beschrijving laden + + + + comic description unavailable + komische beschrijving niet beschikbaar + + + + SelectVolume + + + Please, select the right series for your comic. + Selecteer de juiste serie voor jouw strip. + + + + Filter: + Selectiefilter: + + + + volumes + delen + + + + Nothing found, clear the filter if any. + Niets gevonden. Wis eventueel het filter. + + + + loading cover + laaddeksel + + + + loading description + beschrijving laden + + + + volume description unavailable + volumebeschrijving niet beschikbaar + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + Je probeert informatie voor verschillende strips tegelijk te krijgen. Maken ze deel uit van dezelfde serie? + + + + yes + Ja + + + + no + neen + + + + ServerConfigDialog + + + set port + Poort instellen + + + + Server connectivity information + Informatie over serverconnectiviteit + + + + Scan it! + Scan het! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is beschikbaar voor iOS- en Android-apparaten.<br/>Ontdek het voor <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> of <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + + + + Choose an IP address + Kies een IP-adres + + + + Port + Poort + + + + enable the server + De server instellen + + + + ShortcutsDialog + + Close + Sluiten + + + YACReader keyboard shortcuts + YACReader sneltoetsen + + + Keyboard Shortcuts + Sneltoetsen + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + Sorteer de lijst met strips aan de linkerkant totdat deze overeenkomt met de informatie over de strips. + + + + sort comics to match comic information + sorteer strips zodat ze overeenkomen met stripinformatie + + + + issues + problemen + + + + remove selected comics + verwijder geselecteerde strips + + + + restore all removed comics + herstel alle verwijderde strips + + + + ThemeEditorDialog + + + Theme Editor + Thema-editor + + + + + + + + + + + - + - + + + + i + ? + + + + Expand all + Alles uitvouwen + + + + Collapse all + Alles samenvouwen + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Houd ingedrukt om de geselecteerde waarde in de gebruikersinterface te laten knipperen (magenta / geschakeld / 0↔10). Releases herstellen het origineel. - Always on top - Altijd op voorgrond + + Search… + Zoekopdracht… - - - OptionsDialog - - Gamma - Gamma + + Light + Licht - - Reset - Standaardwaarden terugzetten + + Dark + Donker - - My comics path - Pad naar mijn strips + + ID: + Identiteitskaart: - - Image adjustment - Beeldaanpassing + + Display name: + Weergavenaam: - - "Go to flow" size - "Naar Omslagbrowser" afmetingen + + Variant: + Variatie: - - Choose - Kies + + Theme info + Thema-informatie - - Image options - Afbeelding opties + + Parameter + Instelwaarde - - Contrast - Contrast + + Value + Waarde - - Options - Opties + + Save and apply + Opslaan en toepassen - - Comics directory - Strips map + + Export to file... + Exporteren naar bestand... - - Background color - Achtergrondkleur + + Load from file... + Laden uit bestand... - - Page Flow - Omslagbrowser + + Close + Sluiten - - General - Algemeen + + Double-click to edit color + Dubbelklik om de kleur te bewerken - - Brightness - Helderheid + + + + + + + true + WAAR - - Restart is needed - Herstart is nodig + + + + + false + vals - - Quick Navigation Mode - + + Double-click to toggle + Dubbelklik om te schakelen - - Display - + + Double-click to edit value + Dubbelklik om de waarde te bewerken - - Show time in current page information label - + + + + Edit: %1 + Bewerken: %1 - - Scroll behaviour - + + Save theme + Thema opslaan - - Disable scroll animations and smooth scrolling - + + + JSON files (*.json);;All files (*) + JSON-bestanden (*.json);;Alle bestanden (*) - - Do not turn page using scroll - + + Save failed + Opslaan mislukt - - Use single scroll step to turn page - + + Could not open file for writing: +%1 + Kan bestand niet openen om te schrijven: +%1 - - Mouse mode - + + Load theme + Thema laden - - Only Back/Forward buttons can turn pages - + + + + Load failed + Laden mislukt - - Use the Left/Right buttons to turn pages. - + + Could not open file: +%1 + Kan bestand niet openen: +%1 - - Click left or right half of the screen to turn pages. - + + Invalid JSON: +%1 + Ongeldige JSON: +%1 - - Disable mouse over activation - + + Expected a JSON object. + Er werd een JSON-object verwacht. + + + TitleHeader - - Fit options - + + SEARCH + ZOEKOPDRACHT + + + UpdateLibraryDialog - - Enlarge images to fit width/height - + + Updating.... + Bijwerken.... - - Double Page options - + + Cancel + Annuleren - - Show covers as single page - + + Update library + Bibliotheek bijwerken - QObject + Viewer - - 7z lib not found - + + + Press 'O' to open comic. + Druk 'O' om een strip te openen. - - unable to load 7z lib from ./utils - + + Cover! + Omslag! - - Trace - + + Comic not found + Strip niet gevonden - - Debug - + + Not found + Niet gevonden - - Info - + + Last page! + Laatste pagina! - - Warning - + + Loading...please wait! + Inladen...even wachten! - - Error - + + Error opening comic + Fout bij openen strip - - Fatal - + + CRC Error + CRC-fout - - Select custom cover - + + Page not available! + Pagina niet beschikbaar! + + + VolumeComicsModel - - Images (%1) - + + title + titel - QsLogging::LogWindowModel + VolumesModel - - Time - + + year + jaar - - Level - + + issues + problemen - - Message - + + publisher + uitgever - QsLogging::Window + YACReader3DFlowConfigWidget - - &Pause - + + Presets: + Voorinstellingen: - - &Resume - + + Classic look + Klassiek - - Save log - + + Stripe look + Brede band - - Log file (*.log) - + + Overlapped Stripe look + Overlappende band - - - ShortcutsDialog - Close - Sluiten + + Modern look + Modern - YACReader keyboard shortcuts - YACReader sneltoetsen + + Roulette look + Roulette - Keyboard Shortcuts - Sneltoetsen + + Show advanced settings + Toon geavanceerde instellingen - - - Viewer - - - Press 'O' to open comic. - Druk 'O' om een strip te openen. + + Custom: + Aangepast: - - Cover! - Omslag! + + View angle + Kijkhoek - - Comic not found - Strip niet gevonden + + Position + Positie - - Not found - Niet gevonden + + Cover gap + Ruimte tss Omslag - - Last page! - Laatste pagina! + + Central gap + Centrale ruimte - - Loading...please wait! - Inladen...even wachten! + + Zoom + Vergroting - - Error opening comic - + + Y offset + Y-positie - - CRC Error - + + Z offset + Z- positie - - Page not available! - + + Cover Angle + Omslag hoek + + + + Visibility + Zichtbaarheid + + + + Light + Licht + + + + Max angle + Maximale hoek + + + + Low Performance + Lage Prestaties + + + + High Performance + Hoge Prestaties + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Gebruik VSync (verbetering van de beeldkwaliteit in de modus volledig scherm, slechtere prestatie) + + + + Performance: + Prestatie: YACReader::MainWindowViewer - + &Open - &Open + &Openen - + Open a comic - Open een strip + Open een strip - + New instance - + Nieuw exemplaar - + Open Folder - Map Openen + Map Openen - + Open image folder - Open afbeeldings map + Open afbeeldings map - + Open latest comic - + Open de nieuwste strip - + Open the latest comic opened in the previous reading session - + Open de nieuwste strip die in de vorige leessessie is geopend - + Clear - + Duidelijk - + Clear open recent list - + Wis geopende recente lijst - + Save - Bewaar + Bewaar - + Save current page - Bewaren huidige pagina + Bewaren huidige pagina Previous Comic - Vorige Strip + Vorige Strip - - - + + + Open previous comic - Open de vorige strip + Open de vorige strip - + Next Comic - Volgende Strip + Volgende Strip - - - + + + Open next comic - Open volgende strip + Open volgende strip - + &Previous - &Vorige + &Vorige - - - + + + Go to previous page - Ga naar de vorige pagina + Ga naar de vorige pagina - + &Next - &Volgende + &Volgende - - - + + + Go to next page - Ga naar de volgende pagina + Ga naar de volgende pagina - + Fit Height - + Geschikte hoogte - + Fit image to height - Afbeelding aanpassen aan hoogte + Afbeelding aanpassen aan hoogte - + Fit Width - Vensterbreedte aanpassen + Vensterbreedte aanpassen - + Fit image to width - Afbeelding aanpassen aan breedte + Afbeelding aanpassen aan breedte - + Show full size - Volledig Scherm + Volledig Scherm - + Fit to page - + Aanpassen aan pagina + + + + Continuous scroll + Continu scrollen + + + + Switch to continuous scroll mode + Schakel over naar de continue scrollmodus - + Reset zoom - + Zoom opnieuw instellen - + Show zoom slider - + Zoomschuifregelaar tonen - + Zoom+ - + Inzoomen - + Zoom- - + Uitzoomen - + Rotate image to the left - Links omdraaien + Links omdraaien - + Rotate image to the right - Rechts omdraaien + Rechts omdraaien - + Double page mode - Dubbele bladzijde modus + Dubbele bladzijde modus - + Switch to double page mode - Naar dubbele bladzijde modus + Naar dubbele bladzijde modus - + Double page manga mode - + Manga-modus met dubbele pagina - + Reverse reading order in double page mode - + Omgekeerde leesvolgorde in dubbele paginamodus - + Go To - Ga Naar + Ga Naar - + Go to page ... - Ga naar bladzijde ... + Ga naar bladzijde ... - + Options - Opties + Opties - + YACReader options - YACReader opties + YACReader opties - - + + Help - Help + Hulp - + Help, About YACReader - Help, Over YACReader + Help, Over YACReader - + Magnifying glass - Vergrootglas + Vergrootglas - + Switch Magnifying glass - Overschakelen naar Vergrootglas + Overschakelen naar Vergrootglas - + Set bookmark - Bladwijzer instellen + Bladwijzer instellen - + Set a bookmark on the current page - Een bladwijzer toevoegen aan de huidige pagina + Een bladwijzer toevoegen aan de huidige pagina - + Show bookmarks - Bladwijzers weergeven + Bladwijzers weergeven - + Show the bookmarks of the current comic - Toon de bladwijzers van de huidige strip + Toon de bladwijzers van de huidige strip - + Show keyboard shortcuts - Toon de sneltoetsen + Toon de sneltoetsen - + Show Info - Info tonen + Info tonen - + Close - Sluiten + Sluiten - + Show Dictionary - Woordenlijst weergeven + Woordenlijst weergeven - + Show go to flow - Toon ga naar de Omslagbrowser + Toon ga naar de Omslagbrowser - + Edit shortcuts - + Snelkoppelingen bewerken - + &File - &Bestand + &Bestand - - + + Open recent - + Recent geopend - + File - + Bestand - + Edit - + Bewerken - + View - + Weergave - + Go - + Gaan - + Window - + Raam - - - + + + Open Comic - Open een Strip + Open een Strip - - - + + + Comic files - Strip bestanden + Strip bestanden - + Open folder - Open een Map + Open een Map - + page_%1.jpg - pagina_%1.jpg + pagina_%1.jpg - + Image files (*.jpg) - Afbeelding bestanden (*.jpg) + Afbeelding bestanden (*.jpg) + Comics - + Strips Toggle fullscreen mode - + Schakel de modus Volledig scherm in Hide/show toolbar - + Werkbalk verbergen/tonen + General - Algemeen + Algemeen Size up magnifying glass - + Vergrootglas vergroten Size down magnifying glass - + Vergrootglas kleiner maken Zoom in magnifying glass - + Zoom in vergrootglas Zoom out magnifying glass - + Uitzoomen vergrootglas Reset magnifying glass - + Vergrootglas opnieuw instellen + Magnifiying glass - + Vergrootglas Toggle between fit to width and fit to height - + Schakel tussen Aanpassen aan breedte en Aanpassen aan hoogte + Page adjustement - + Pagina-aanpassing - + Autoscroll down - + Automatisch naar beneden scrollen - + Autoscroll up - + Automatisch omhoog scrollen - + Autoscroll forward, horizontal first - + Automatisch vooruit scrollen, eerst horizontaal - + Autoscroll backward, horizontal first - + Automatisch achteruit scrollen, eerst horizontaal - + Autoscroll forward, vertical first - + Automatisch vooruit scrollen, eerst verticaal - + Autoscroll backward, vertical first - + Automatisch achteruit scrollen, eerst verticaal - + Move down - + Ga naar beneden - + Move up - + Ga omhoog - + Move left - + Ga naar links - + Move right - + Ga naar rechts - + Go to the first page - + Ga naar de eerste pagina - + Go to the last page - + Ga naar de laatste pagina - + Offset double page to the left - + Dubbele pagina naar links verschoven - + Offset double page to the right - + Offset dubbele pagina naar rechts - + + Reading - + Lezing - + There is a new version available - Er is een nieuwe versie beschikbaar + Er is een nieuwe versie beschikbaar - + Do you want to download the new version? - Wilt u de nieuwe versie downloaden? + Wilt u de nieuwe versie downloaden? - + Remind me in 14 days - + Herinner mij er over 14 dagen aan - + Not now - + Niet nu + + + + YACReader::TrayIconController + + + &Restore + &Herstellen + + + + Systray + Systeemvak + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary blijft actief in het systeemvak. Om het programma te beëindigen, kiest u <b>Quit</b> in het contextmenu van het systeemvakpictogram. YACReader::WhatsNewDialog - Close - Sluiten + Sluiten @@ -1231,170 +3871,150 @@ YACReaderFlowConfigWidget - CoverFlow look - Omslagbrowser uiterlijk + Omslagbrowser uiterlijk - How to show covers: - Omslagbladen bekijken: + Omslagbladen bekijken: - Stripe look - Brede band + Brede band - Overlapped Stripe look - Overlappende band + Overlappende band YACReaderGLFlowConfigWidget - Zoom - Zoom + Vergroting - Light - Licht + Licht - Show advanced settings - Toon geavanceerde instellingen + Toon geavanceerde instellingen - Roulette look - Roulette + Roulette - Cover Angle - Omslag hoek + Omslag hoek - Stripe look - Brede band + Brede band - Position - Positie + Positie - Z offset - Z- positie + Z- positie - Y offset - Y-positie + Y-positie - Central gap - Centrale ruimte + Centrale ruimte - Presets: - Voorinstellingen: + Voorinstellingen: - Overlapped Stripe look - Overlappende band + Overlappende band - Modern look - Modern + Modern - View angle - Kijkhoek + Kijkhoek - Max angle - Maximale hoek + Maximale hoek - Custom: - Aangepast: + Aangepast: - Classic look - Klassiek + Klassiek - Cover gap - Ruimte tss Omslag + Ruimte tss Omslag - High Performance - Hoge Prestaties + Hoge Prestaties - Performance: - Prestatie: + Prestatie: - Use VSync (improve the image quality in fullscreen mode, worse performance) - Gebruik VSync (verbetering van de beeldkwaliteit in de modus volledig scherm, slechtere prestatie) + Gebruik VSync (verbetering van de beeldkwaliteit in de modus volledig scherm, slechtere prestatie) - Visibility - Zichtbaarheid + Zichtbaarheid - Low Performance - Lage Prestaties + Lage Prestaties YACReaderOptionsDialog - + Save Bewaar - Use hardware acceleration (restart needed) - Gebruik hardware versnelling (opnieuw opstarten vereist) + Gebruik hardware versnelling (opnieuw opstarten vereist) - + Cancel Annuleren - + Edit shortcuts - + Snelkoppelingen bewerken - + Shortcuts - + Snelkoppelingen + + + + YACReaderSearchLineEdit + + + type to search + typ om te zoeken @@ -1408,25 +4028,25 @@ YACReaderTranslator - + YACReader translator - + YACReader-vertaler - - + + Translation - + Vertaling - + clear - + duidelijk - + Service not available - + Dienst niet beschikbaar diff --git a/YACReader/yacreader_pt.ts b/YACReader/yacreader_pt.ts index fce9c111e..12d6d5106 100644 --- a/YACReader/yacreader_pt.ts +++ b/YACReader/yacreader_pt.ts @@ -6,7 +6,197 @@ None - + Nenhum + + + + AddLabelDialog + + + Label name: + Nome da etiqueta: + + + + Choose a color: + Escolha uma cor: + + + + accept + aceitar + + + + cancel + cancelar + + + + AddLibraryDialog + + + Comics folder : + Pasta dos quadrinhos : + + + + Library name : + Nome da Biblioteca : + + + + Add + Adicionar + + + + Cancel + Cancelar + + + + Add an existing library + Adicionar uma biblioteca existente + + + + ApiKeyDialog + + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Antes de se conectar ao Comic Vine, você precisa de sua própria chave de API. Por favor, ganhe um <a href="http://www.comicvine.com/api/">aqui</a> grátis + + + + Paste here your Comic Vine API key + Cole aqui sua chave API do Comic Vine + + + + Accept + Aceitar + + + + Cancel + Cancelar + + + + AppearanceTabWidget + + + Color scheme + Esquema de cores + + + + System + Sistema + + + + Light + Luz + + + + Dark + Escuro + + + + Custom + Personalizado + + + + Remove + Remover + + + + Remove this user-imported theme + Remova este tema importado pelo usuário + + + + Light: + Luz: + + + + Dark: + Escuro: + + + + Custom: + Personalizado: + + + + Import theme... + Importar tema... + + + + Theme + Tema + + + + Theme editor + Editor de tema + + + + Open Theme Editor... + Abra o Editor de Tema... + + + + Theme editor error + Erro no editor de tema + + + + The current theme JSON could not be loaded. + O tema atual JSON não pôde ser carregado. + + + + Import theme + Importar tema + + + + JSON files (*.json);;All files (*) + Arquivos JSON (*.json);;Todos os arquivos (*) + + + + Could not import theme from: +%1 + Não foi possível importar o tema de: +%1 + + + + Could not import theme from: +%1 + +%2 + Não foi possível importar o tema de: +%1 + +%2 + + + + Import failed + Falha na importação @@ -34,1124 +224,3574 @@ - EditShortcutsDialog + ClassicComicsView - - Restore defaults - + + Hide comic flow + Ocultar fluxo de quadrinhos + + + ComicModel - - To change a shortcut, double click in the key combination and type the new keys. - + + yes + sim - - Shortcuts settings - + + no + não - - Shortcut in use - + + Title + Título - - The shortcut "%1" is already assigned to other function - + + File Name + Nome do arquivo - - - FileComic - - 7z not found - 7z não encontrado + + Pages + Páginas - - CRC error on page (%1): some of the pages will not be displayed correctly - + + Size + Tamanho - - Unknown error opening the file - + + Read + Ler - - Format not supported - + + Current Page + Página atual - - - GoToDialog - - Go To - Ir Para + + Publication Date + Data de publicação - - Go to... - Ir para... + + Rating + Avaliação - - - Total pages : - Total de páginas : + + Series + Série - - Cancel - Cancelar + + Volume + Tomo - - Page : - Página : + + Story Arc + Arco de história - GoToFlowToolBar + ComicVineDialog - - Page : - Página : + + skip + pular - - - HelpAboutDialog - - Help - Ajuda + + back + voltar - - System info - + + next + próximo - - About - + + search + procurar - - - LogWindow - - Log window - + + close + fechar - - &Pause - + + + comic %1 of %2 - %3 + história em quadrinhos %1 de %2 - %3 - - &Save - + + + + Looking for volume... + Procurando volume... - - C&lear - + + %1 comics selected + %1 quadrinhos selecionados - - &Copy - + + Error connecting to ComicVine + Erro ao conectar-se ao ComicVine - - Level: - + + + Retrieving tags for : %1 + Recuperando tags para: %1 - - &Auto scroll - + + Retrieving volume info... + Recuperando informações de volume... + + + + Looking for comic... + Procurando quadrinhos... - MainWindowViewer + ContinuousPageWidget - Help - Ajuda + + Loading page %1 + Carregando página %1 + + + CreateLibraryDialog - Save - Salvar + + Comics folder : + Pasta dos quadrinhos : - &File - &Arquivo + + Library Name : + Nome da Biblioteca : - &Next - &Próxima + + Create + Criar - &Open - &Abrir + + Cancel + Cancelar - Close - Fechar + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Criar uma biblioteca pode levar vários minutos. Você pode interromper o processo e atualizar a biblioteca posteriormente para concluir a tarefa. - Open Comic - Abrir Quadrinho + + Create new library + Criar uma nova biblioteca - Go To - Ir Para + + Path not found + Caminho não encontrado - Set bookmark - Definir marcador + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + O caminho selecionado não existe ou não é um caminho válido. Certifique-se de ter acesso de gravação a esta pasta + + + EditShortcutsDialog - Switch to double page mode - Alternar para o modo dupla página + + Restore defaults + Restaurar padrões - Save current page - Salvar página atual + + To change a shortcut, double click in the key combination and type the new keys. + Para alterar um atalho, clique duas vezes na combinação de teclas e digite as novas teclas. - Double page mode - Modo dupla página + + Shortcuts settings + Configurações de atalhos - Switch Magnifying glass - Alternar Lupa + + Shortcut in use + Atalho em uso - Open Folder - Abrir Pasta + + The shortcut "%1" is already assigned to other function + O atalho "%1" já está atribuído a outra função + + + EmptyFolderWidget - Go to previous page - Ir para a página anterior + + This folder doesn't contain comics yet + Esta pasta ainda não contém quadrinhos + + + EmptyLabelWidget - Open a comic - Abrir um quadrinho + + This label doesn't contain comics yet + Este rótulo ainda não contém quadrinhos + + + EmptyReadingListWidget - Image files (*.jpg) - Arquivos de imagem (*.jpg) + + This reading list does not contain any comics yet + Esta lista de leitura ainda não contém quadrinhos + + + EmptySpecialListWidget - Next Comic - Próximo Quadrinho + + No favorites + Sem favoritos - Fit Width - Ajustar à Largura + + You are not reading anything yet, come on!! + Você ainda não está lendo nada, vamos lá!! - Options - Opções + + There are no recent comics! + Não há quadrinhos recentes! + + + ExportComicsInfoDialog - Show Info - Mostrar Informações + + Output file : + Arquivo de saída: - Open folder - Abrir pasta + + Create + Criar - Go to page ... - Ir para a página... + + Cancel + Cancelar - &Previous - A&nterior + + Export comics info + Exportar informações de quadrinhos - Go to next page - Ir para a próxima página + + Destination database name + Nome do banco de dados de destino - Show keyboard shortcuts - Mostrar teclas de atalhos + + Problem found while writing + Problema encontrado ao escrever - There is a new version available - Há uma nova versão disponível + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + O caminho selecionado para o arquivo de saída não existe ou não é um caminho válido. Certifique-se de ter acesso de gravação a esta pasta + + + ExportLibraryDialog - Open next comic - Abrir próximo quadrinho + + Output folder : + Pasta de saída : - Show bookmarks - Mostrar marcadores + + Create + Criar - Open previous comic - Abrir quadrinho anterior + + Cancel + Cancelar - Rotate image to the left - Girar imagem à esquerda + + Create covers package + Criar pacote de capas - Show the bookmarks of the current comic - Mostrar os marcadores do quadrinho atual + + Problem found while writing + Problema encontrado ao escrever - YACReader options - Opções do YACReader + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + O caminho selecionado para o arquivo de saída não existe ou não é um caminho válido. Certifique-se de ter acesso de gravação a esta pasta - Help, About YACReader - Ajuda, Sobre o YACReader + + Destination directory + Diretório de destino + + + FileComic - Previous Comic - Quadrinho Anterior + + 7z not found + 7z não encontrado - Magnifying glass - Lupa + + CRC error on page (%1): some of the pages will not be displayed correctly + Erro CRC na página (%1): algumas páginas não serão exibidas corretamente - Set a bookmark on the current page - Definir um marcador na página atual + + Unknown error opening the file + Erro desconhecido ao abrir o arquivo - Do you want to download the new version? - Você deseja baixar a nova versão? + + Format not supported + Formato não suportado + + + + GoToDialog + + + Go To + Ir Para + + + + Go to... + Ir para... + + + + + Total pages : + Total de páginas : + + + + Cancel + Cancelar + + + + Page : + Página : + + + + GoToFlowToolBar + + + Page : + Página : + + + + GridComicsView + + + Show info + Mostrar informações + + + + HelpAboutDialog + + + Help + Ajuda + + + + System info + Informações do sistema + + + + About + Sobre + + + + ImportComicsInfoDialog + + + Import comics info + Importar informações de quadrinhos + + + + Info database location : + Localização do banco de dados de informações: + + + + Import + Importar + + + + Cancel + Cancelar + + + + Comics info file (*.ydb) + Arquivo de informações de quadrinhos (*.ydb) + + + + ImportLibraryDialog + + + Library Name : + Nome da Biblioteca : + + + + Package location : + Local do pacote : + + + + Destination folder : + Pasta de destino : + + + + Unpack + Desempacotar + + + + Cancel + Cancelar + + + + Extract a catalog + Extrair um catálogo + + + + Compresed library covers (*.clc) + Capas da biblioteca compactada (*.clc) + + + + ImportWidget + + + stop + parar + + + + Some of the comics being added... + Alguns dos quadrinhos sendo adicionados... + + + + Importing comics + Importando quadrinhos + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary está criando uma nova biblioteca.</p><p>A criação de uma biblioteca pode levar vários minutos. Você pode interromper o processo e atualizar a biblioteca posteriormente para concluir a tarefa.</p> + + + + Updating the library + Atualizando a biblioteca + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>A biblioteca atual está sendo atualizada. Para atualizações mais rápidas, atualize suas bibliotecas com frequência.</p><p>Você pode interromper o processo e continuar atualizando esta biblioteca mais tarde.</p> + + + + Upgrading the library + Atualizando a biblioteca + + + + <p>The current library is being upgraded, please wait.</p> + <p>A biblioteca atual está sendo atualizada. Aguarde.</p> + + + + Scanning the library + Digitalizando a biblioteca + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>A biblioteca atual está sendo verificada em busca de informações de metadados XML legados.</p><p>Isso só será necessário uma vez e somente se a biblioteca tiver sido criada com YACReaderLibrary 9.8.2 ou anterior.</p> + + + + LibraryWindow + + + YACReader Library + Biblioteca YACReader + + + + + + comic + cômico + + + + + + manga + mangá + + + + + + western manga (left to right) + mangá ocidental (da esquerda para a direita) + + + + + + web comic + quadrinhos da web + + + + + + 4koma (top to botom) + 4koma (de cima para baixo) + + + + + + + Set type + Definir tipo + + + + Library + Biblioteca + + + + Folder + Pasta + + + + Comic + Quadrinhos + + + + Upgrade failed + Falha na atualização + + + + There were errors during library upgrade in: + Ocorreram erros durante a atualização da biblioteca em: + + + + Update needed + Atualização necessária + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Esta biblioteca foi criada com uma versão anterior do YACReaderLibrary. Ele precisa ser atualizado. Atualizar agora? + + + + Download new version + Baixe a nova versão + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Esta biblioteca foi criada com uma versão mais recente do YACReaderLibrary. Baixe a nova versão agora? + + + + Library not available + Biblioteca não disponível + + + + Library '%1' is no longer available. Do you want to remove it? + A biblioteca '%1' não está mais disponível. Você quer removê-lo? + + + + Old library + Biblioteca antiga + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + A biblioteca '%1' foi criada com uma versão mais antiga do YACReaderLibrary. Deve ser criado novamente. Deseja criar a biblioteca agora? + + + + + Copying comics... + Copiando quadrinhos... + + + + + Moving comics... + Quadrinhos em movimento... + + + + Add new folder + Adicionar nova pasta + + + + Folder name: + Nome da pasta: + + + + No folder selected + Nenhuma pasta selecionada + + + + Please, select a folder first + Por favor, selecione uma pasta primeiro + + + + Error in path + Erro no caminho + + + + There was an error accessing the folder's path + Ocorreu um erro ao acessar o caminho da pasta + + + + Delete folder + Excluir pasta + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + A pasta selecionada e todo o seu conteúdo serão excluídos do disco. Tem certeza? + + + + + Unable to delete + Não foi possível excluir + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Ocorreu um problema ao tentar excluir as pastas selecionadas. Por favor, verifique as permissões de gravação e certifique-se de que algum aplicativo esteja usando essas pastas ou qualquer um dos arquivos contidos. + + + + Add new reading lists + Adicione novas listas de leitura + + + + + List name: + Nome da lista: + + + + Delete list/label + Excluir lista/rótulo + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + O item selecionado será excluído, seus quadrinhos ou pastas NÃO serão excluídos do disco. Tem certeza? + + + + Rename list name + Renomear nome da lista + + + + Open folder... + Abrir pasta... + + + + Update folder + Atualizar pasta + + + + Rescan library for XML info + Digitalizar novamente a biblioteca em busca de informações XML + + + + Set as uncompleted + Definir como incompleto + + + + Set as completed + Definir como concluído + + + + Set as read + Definir como lido + + + + + Set as unread + Definir como não lido + + + + Set custom cover + Definir capa personalizada + + + + Delete custom cover + Excluir capa personalizada + + + + Save covers + Salvar capas + + + + You are adding too many libraries. + Você está adicionando muitas bibliotecas. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Você está adicionando muitas bibliotecas. + +Você provavelmente só precisa de uma biblioteca em sua pasta de quadrinhos de nível superior. Você pode navegar em qualquer subpasta usando a seção de pastas na barra lateral esquerda. + +YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve manter o número de bibliotecas baixo. + + + + + YACReader not found + YACReader não encontrado + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader não encontrado. YACReader deve ser instalado na mesma pasta que YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader não encontrado. Pode haver um problema com a instalação do YACReader. + + + + Error + Erro + + + + Error opening comic with third party reader. + Erro ao abrir o quadrinho com leitor de terceiros. + + + + Library not found + Biblioteca não encontrada + + + + The selected folder doesn't contain any library. + A pasta selecionada não contém nenhuma biblioteca. + + + + Are you sure? + Você tem certeza? + + + + Do you want remove + Você deseja remover + + + + library? + biblioteca? + + + + Remove and delete metadata + Remover e excluir metadados + + + + Library info + Informações da biblioteca + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Ocorreu um problema ao tentar excluir os quadrinhos selecionados. Por favor, verifique as permissões de gravação nos arquivos selecionados ou na pasta que os contém. + + + + Assign comics numbers + Atribuir números de quadrinhos + + + + Assign numbers starting in: + Atribua números começando em: + + + + Invalid image + Imagem inválida + + + + The selected file is not a valid image. + O arquivo selecionado não é uma imagem válida. + + + + Error saving cover + Erro ao salvar a capa + + + + There was an error saving the cover image. + Ocorreu um erro ao salvar a imagem da capa. + + + + Error creating the library + Erro ao criar a biblioteca + + + + Error updating the library + Erro ao atualizar a biblioteca + + + + Error opening the library + Erro ao abrir a biblioteca + + + + Delete comics + Excluir quadrinhos + + + + All the selected comics will be deleted from your disk. Are you sure? + Todos os quadrinhos selecionados serão excluídos do seu disco. Tem certeza? + + + + Remove comics + Remover quadrinhos + + + + Comics will only be deleted from the current label/list. Are you sure? + Os quadrinhos serão excluídos apenas do rótulo/lista atual. Tem certeza? + + + + Library name already exists + O nome da biblioteca já existe + + + + There is another library with the name '%1'. + Existe outra biblioteca com o nome '%1'. + + + + LibraryWindowActions + + + Create a new library + Criar uma nova biblioteca + + + + Open an existing library + Abrir uma biblioteca existente + + + + + Export comics info + Exportar informações de quadrinhos + + + + + Import comics info + Importar informações de quadrinhos + + + + Pack covers + Capas de pacote + + + + Pack the covers of the selected library + Pacote de capas da biblioteca selecionada + + + + Unpack covers + Desembale as capas + + + + Unpack a catalog + Desempacotar um catálogo + + + + Update library + Atualizar biblioteca + + + + Update current library + Atualizar biblioteca atual + + + + Rename library + Renomear biblioteca + + + + Rename current library + Renomear biblioteca atual + + + + Remove library + Remover biblioteca + + + + Remove current library from your collection + Remover biblioteca atual da sua coleção + + + + Rescan library for XML info + Digitalizar novamente a biblioteca em busca de informações XML + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Tenta encontrar informações XML incorporadas em arquivos de quadrinhos. Você só precisa fazer isso se a biblioteca foi criada com versões 9.8.2 ou anteriores ou se você estiver usando software de terceiros para incorporar informações XML nos arquivos. + + + + Show library info + Mostrar informações da biblioteca + + + + Show information about the current library + Mostrar informações sobre a biblioteca atual + + + + Open current comic + Abrir quadrinho atual + + + + Open current comic on YACReader + Abrir quadrinho atual no YACReader + + + + Save selected covers to... + Salvar capas selecionadas em... + + + + Save covers of the selected comics as JPG files + Salve as capas dos quadrinhos selecionados como arquivos JPG + + + + + Set as read + Definir como lido + + + + Set comic as read + Definir quadrinhos como lidos + + + + + Set as unread + Definir como não lido + + + + Set comic as unread + Definir quadrinhos como não lidos + + + + + manga + mangá + + + + Set issue as manga + Definir problema como mangá + + + + + comic + cômico + + + + Set issue as normal + Defina o problema como normal + + + + western manga + mangá ocidental + + + + Set issue as western manga + Definir problema como mangá ocidental + + + + + web comic + quadrinhos da web + + + + Set issue as web comic + Definir o problema como web comic + + + + + yonkoma + tira yonkoma + + + + Set issue as yonkoma + Definir problema como yonkoma + + + + Show/Hide marks + Mostrar/ocultar marcas + + + + Show or hide read marks + Mostrar ou ocultar marcas de leitura + + + + Show/Hide recent indicator + Mostrar/ocultar indicador recente + + + + Show or hide recent indicator + Mostrar ou ocultar indicador recente + + + + + Fullscreen mode on/off + Modo tela cheia ativado/desativado + + + + Help, About YACReader + Ajuda, Sobre o YACReader + + + + Add new folder + Adicionar nova pasta + + + + Add new folder to the current library + Adicionar nova pasta à biblioteca atual + + + + Delete folder + Excluir pasta + + + + Delete current folder from disk + Exclua a pasta atual do disco + + + + Select root node + Selecionar raiz + + + + Expand all nodes + Expandir todos + + + + Collapse all nodes + Recolher todos os nós + + + + Show options dialog + Mostrar opções + + + + Show comics server options dialog + Mostrar caixa de diálogo de opções do servidor de quadrinhos + + + + + Change between comics views + Alterar entre visualizações de quadrinhos + + + + Open folder... + Abrir pasta... + + + + Set as uncompleted + Definir como incompleto + + + + Set as completed + Definir como concluído + + + + Set custom cover + Definir capa personalizada + + + + Delete custom cover + Excluir capa personalizada + + + + western manga (left to right) + mangá ocidental (da esquerda para a direita) + + + + Open containing folder... + Abrir a pasta contendo... + + + + Reset comic rating + Redefinir classificação de quadrinhos + + + + Select all comics + Selecione todos os quadrinhos + + + + Edit + Editar + + + + Assign current order to comics + Atribuir ordem atual aos quadrinhos + + + + Update cover + Atualizar capa + + + + Delete selected comics + Excluir quadrinhos selecionados + + + + Delete metadata from selected comics + Excluir metadados dos quadrinhos selecionados + + + + Download tags from Comic Vine + Baixe tags do Comic Vine + + + + Focus search line + Linha de pesquisa de foco + + + + Focus comics view + Visualização de quadrinhos em foco + + + + Edit shortcuts + Editar atalhos + + + + &Quit + &Qfato + + + + Update folder + Atualizar pasta + + + + Update current folder + Atualizar pasta atual + + + + Scan legacy XML metadata + Digitalize metadados XML legados + + + + Add new reading list + Adicionar nova lista de leitura + + + + Add a new reading list to the current library + Adicione uma nova lista de leitura à biblioteca atual + + + + Remove reading list + Remover lista de leitura + + + + Remove current reading list from the library + Remover lista de leitura atual da biblioteca + + + + Add new label + Adicionar novo rótulo + + + + Add a new label to this library + Adicione um novo rótulo a esta biblioteca + + + + Rename selected list + Renomear lista selecionada + + + + Rename any selected labels or lists + Renomeie quaisquer rótulos ou listas selecionados + + + + Add to... + Adicionar à... + + + + Favorites + Favoritos + + + + Add selected comics to favorites list + Adicione quadrinhos selecionados à lista de favoritos + + + + LocalComicListModel + + + file name + nome do arquivo + + + + MainWindowViewer + + Help + Ajuda + + + Save + Salvar + + + &File + &Arquivo + + + &Next + &Próxima + + + &Open + &Abrir + + + Close + Fechar + + + Open Comic + Abrir Quadrinho + + + Go To + Ir Para + + + Set bookmark + Definir marcador + + + Switch to double page mode + Alternar para o modo dupla página + + + Save current page + Salvar página atual + + + Double page mode + Modo dupla página + + + Switch Magnifying glass + Alternar Lupa + + + Open Folder + Abrir Pasta + + + Go to previous page + Ir para a página anterior + + + Open a comic + Abrir um quadrinho + + + Image files (*.jpg) + Arquivos de imagem (*.jpg) + + + Next Comic + Próximo Quadrinho + + + Fit Width + Ajustar à Largura + + + Options + Opções + + + Show Info + Mostrar Informações + + + Open folder + Abrir pasta + + + Go to page ... + Ir para a página... + + + &Previous + A&nterior + + + Go to next page + Ir para a próxima página + + + Show keyboard shortcuts + Mostrar teclas de atalhos + + + There is a new version available + Há uma nova versão disponível + + + Open next comic + Abrir próximo quadrinho + + + Show bookmarks + Mostrar marcadores + + + Open previous comic + Abrir quadrinho anterior + + + Rotate image to the left + Girar imagem à esquerda + + + Show the bookmarks of the current comic + Mostrar os marcadores do quadrinho atual + + + YACReader options + Opções do YACReader + + + Help, About YACReader + Ajuda, Sobre o YACReader + + + Previous Comic + Quadrinho Anterior + + + Magnifying glass + Lupa + + + Set a bookmark on the current page + Definir um marcador na página atual + + + Do you want to download the new version? + Você deseja baixar a nova versão? + + + Rotate image to the right + Girar imagem à direita + + + + NoLibrariesWidget + + + You don't have any libraries yet + Você ainda não tem nenhuma biblioteca + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Você pode criar uma biblioteca em qualquer pasta, YACReaderLibrary importará todos os quadrinhos e pastas desta pasta. Se você já criou alguma biblioteca, poderá abri-la.</p><p>Não se esqueça de que você pode usar o YACReader como um aplicativo independente para ler quadrinhos em seu computador.</p> + + + + create your first library + crie sua primeira biblioteca + + + + add an existing one + adicione um existente + + + + NoSearchResultsWidget + + + No results + Nenhum resultado + + + + OptionsDialog + + + My comics path + Meu caminho de quadrinhos + + + + "Go to flow" size + Tamanho do "Ir para cheia" + + + + + Libraries + Bibliotecas + + + + Comic Flow + Fluxo de quadrinhos + + + + Grid view + Visualização em grade + + + + + Appearance + Aparência + + + + + Options + Opções + + + + + Language + Idioma + + + + + Application language + Idioma do aplicativo + + + + + System default + Padrão do sistema + + + + Tray icon settings (experimental) + Configurações do ícone da bandeja (experimental) + + + + Close to tray + Perto da bandeja + + + + Start into the system tray + Comece na bandeja do sistema + + + + Edit Comic Vine API key + Editar chave da API Comic Vine + + + + Comic Vine API key + Chave de API do Comic Vine + + + + ComicInfo.xml legacy support + Suporte legado ComicInfo.xml + + + + Import metadata from ComicInfo.xml when adding new comics + Importe metadados de ComicInfo.xml ao adicionar novos quadrinhos + + + + Consider 'recent' items added or updated since X days ago + Considere itens 'recentes' adicionados ou atualizados há X dias + + + + Third party reader + Leitor de terceiros + + + + Write {comic_file_path} where the path should go in the command + Escreva {comic_file_path} onde o caminho deve ir no comando + + + + + Clear + Claro + + + + Update libraries at startup + Atualizar bibliotecas na inicialização + + + + Try to detect changes automatically + Tente detectar alterações automaticamente + + + + Update libraries periodically + Atualize bibliotecas periodicamente + + + + Interval: + Intervalo: + + + + 30 minutes + 30 minutos + + + + 1 hour + 1 hora + + + + 2 hours + 2 horas + + + + 4 hours + 4 horas + + + + 8 hours + 8 horas + + + + 12 hours + 12 horas + + + + daily + diário + + + + Update libraries at certain time + Atualizar bibliotecas em determinado momento + + + + Time: + Tempo: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + AVISO! Durante as atualizações da biblioteca, as gravações no banco de dados são desativadas! +Não agende atualizações enquanto estiver usando o aplicativo ativamente. +Durante as atualizações automáticas, o aplicativo bloqueará algumas ações até que a atualização seja concluída. +Para interromper uma atualização automática, toque no indicador de carregamento próximo ao título Bibliotecas. + + + + Modifications detection + Detecção de modificações + + + + Compare the modified date of files when updating a library (not recommended) + Compare a data de modificação dos arquivos ao atualizar uma biblioteca (não recomendado) + + + + Enable background image + Ativar imagem de fundo + + + + Opacity level + Nível de opacidade + + + + Blur level + Nível de desfoque + + + + Use selected comic cover as background + Use a capa de quadrinhos selecionada como plano de fundo + + + + Restore defautls + Restaurar padrões + + + + Background + Fundo + + + + Display continue reading banner + Exibir banner para continuar lendo + + + + Display current comic banner + Exibir banner de quadrinhos atual + + + + Continue reading + Continuar lendo + + + + Comics directory + Diretório de quadrinhos + + + + + Restart is needed + Reiniciar é necessário + + + + Display + Mostrar + + + + Show time in current page information label + Mostrar hora no rótulo de informações da página atual + + + + Background color + Cor de fundo + + + + Choose + Escolher + + + + Scroll behaviour + Comportamento de rolagem + + + + Disable scroll animations and smooth scrolling + Desative animações de rolagem e rolagem suave + + + + Do not turn page using scroll + Não vire a página usando scroll + + + + Use single scroll step to turn page + Use uma única etapa de rolagem para virar a página + + + + Mouse mode + Modo mouse + + + + Only Back/Forward buttons can turn pages + Apenas os botões Voltar/Avançar podem virar páginas + + + + Use the Left/Right buttons to turn pages. + Use os botões Esquerda/Direita para virar as páginas. + + + + Click left or right half of the screen to turn pages. + Clique na metade esquerda ou direita da tela para virar as páginas. + + + + Quick Navigation Mode + Modo de navegação rápida + + + + Disable mouse over activation + Desativar ativação do mouse sobre + + + + Brightness + Brilho + + + + Contrast + Contraste + + + + Gamma + Gama + + + + Reset + Reiniciar + + + + Image options + Opções de imagem + + + + Fit options + Opções de ajuste + + + + Enlarge images to fit width/height + Amplie as imagens para caber na largura/altura + + + + Double Page options + Opções de página dupla + + + + Show covers as single page + Mostrar capas como página única + + + + Scaling + Dimensionamento + + + + Scaling method + Método de dimensionamento + + + + Nearest (fast, low quality) + Mais próximo (rápido, baixa qualidade) + + + + Bilinear + Interpola??o bilinear + + + + Lanczos (better quality) + Lanczos (melhor qualidade) + + + + + General + Em geral + + + + Page Flow + Fluxo de página + + + + Image adjustment + Ajuste de imagem + + + + PropertiesDialog + + + General info + Informações gerais + + + + Plot + Trama + + + + Authors + Autores + + + + Publishing + Publicação + + + + Notes + Notas + + + + Cover page + Página de rosto + + + + Load previous page as cover + Carregar página anterior como capa + + + + Load next page as cover + Carregar a próxima página como capa + + + + Reset cover to the default image + Redefinir a capa para a imagem padrão + + + + Load custom cover image + Carregar imagem de capa personalizada + + + + Series: + Série: + + + + Title: + Título: + + + + + + of: + de: + + + + Issue number: + Número de emissão: + + + + Volume: + Tomo: + + + + Arc number: + Número do arco: + + + + Story arc: + Arco da história: + + + + alt. number: + alt. número: - Rotate image to the right - Girar imagem à direita + + Alternate series: + Série alternativa: + + + + Series Group: + Grupo de séries: + + + + Genre: + Gênero: + + + + Size: + Tamanho: + + + + Writer(s): + Escritor(es): + + + + Penciller(s): + Desenhador(es): + + + + Inker(s): + Tinteiro(s): + + + + Colorist(s): + Colorista(s): + + + + Letterer(s): + Letrista(s): + + + + Cover Artist(s): + Artista(s) da capa: + + + + Editor(s): + Editor(es): + + + + Imprint: + Imprimir: + + + + Day: + Dia: + + + + Month: + Mês: + + + + Year: + Ano: + + + + Publisher: + Editor: + + + + Format: + Formatar: + + + + Color/BW: + Cor/PB: + + + + Age rating: + Classificação etária: + + + + Type: + Tipo: + + + + Language (ISO): + Idioma (ISO): + + + + Synopsis: + Sinopse: + + + + Characters: + Personagens: + + + + Teams: + Equipes: + + + + Locations: + Locais: + + + + Main character or team: + Personagem principal ou equipe: + + + + Review: + Análise: + + + + Notes: + Notas: + + + + Tags: + Etiquetas: + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Link do Comic Vine: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> visualizar </a> + + + + Not found + Não encontrado + + + + Comic not found. You should update your library. + Quadrinho não encontrado. Você deve atualizar sua biblioteca. + + + + Edit comic information + Editar informações dos quadrinhos + + + + Edit selected comics information + Edite as informações dos quadrinhos selecionados + + + + Invalid cover + Capa inválida + + + + The image is invalid. + A imagem é inválida. - OptionsDialog + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer é a versão sem cabeça (sem interface gráfica) do YACReaderLibrary. + +Este aplicativo suporta configurações persistentes, para configurá-las edite este arquivo %1 +Para saber mais sobre as configurações disponíveis, verifique a documentação em https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject - - My comics path - Meu caminho de quadrinhos + + 7z lib not found + Biblioteca 7z não encontrada + + + + unable to load 7z lib from ./utils + não é possível carregar 7z lib de ./utils + + + + Trace + Rastreamento + + + + Debug + Depurar + + + + Info + Informações + + + + Warning + Aviso + + + + Error + Erro + + + + Fatal + Cr?tico + + + + Select custom cover + Selecione a capa personalizada + + + + Images (%1) + Imagens (%1) + + + + The file could not be read or is not valid JSON. + O arquivo não pôde ser lido ou não é JSON válido. + + + + This theme is for %1, not %2. + Este tema é para %1, não %2. + + + + Libraries + Bibliotecas + + + + Folders + Pastas + + + + Reading Lists + Listas de leitura + + + + RenameLibraryDialog + + + New Library Name : + Novo nome da biblioteca : + + + + Rename + Renomear + + + + Cancel + Cancelar + + + + Rename current library + Renomear biblioteca atual + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + Número de volumes encontrados: %1 + + + + + page %1 of %2 + página %1 de %2 + + + + Number of %1 found : %2 + Número de %1 encontrado: %2 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + Forneça algumas informações adicionais para esta história em quadrinhos. + + + + Series: + Série: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Use a pesquisa de correspondência exata. Desative se quiser encontrar volumes que correspondam a algumas das palavras do nome. + + + + SearchVolume + + + Please provide some additional information. + Forneça algumas informações adicionais. + + + + Series: + Série: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Use a pesquisa de correspondência exata. Desative se quiser encontrar volumes que correspondam a algumas das palavras do nome. + + + + SelectComic + + + Please, select the right comic info. + Por favor, selecione as informações corretas dos quadrinhos. + + + + comics + quadrinhos + + + + loading cover + tampa de carregamento + + + + loading description + descrição de carregamento + + + + comic description unavailable + descrição do quadrinho indisponível + + + + SelectVolume + + + Please, select the right series for your comic. + Por favor, selecione a série certa para o seu quadrinho. + + + + Filter: + Filtro: + + + + volumes + tomos + + + + Nothing found, clear the filter if any. + Nada encontrado, limpe o filtro, se houver. + + + + loading cover + tampa de carregamento + + + + loading description + descrição de carregamento + + + + volume description unavailable + descrição do volume indisponível + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + Você está tentando obter informações sobre vários quadrinhos ao mesmo tempo. Eles fazem parte da mesma série? + + + + yes + sim + + + + no + não + + + + ServerConfigDialog + + + set port + definir porta + + + + Server connectivity information + Informações de conectividade do servidor + + + + Scan it! + Digitalize! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + O YACReader está disponível para dispositivos iOS e Android.<br/>Descubra-o para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + + + + Choose an IP address + Escolha um endereço IP + + + + Port + Porta + + + + enable the server + habilitar o servidor + + + + ShortcutsDialog + + Close + Fechar + + + YACReader keyboard shortcuts + Teclas de atalhos do YACReader + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + Por favor, classifique a lista de quadrinhos à esquerda até que corresponda às informações dos quadrinhos. + + + + sort comics to match comic information + classifique os quadrinhos para corresponder às informações dos quadrinhos + + + + issues + problemas + + + + remove selected comics + remover quadrinhos selecionados + + + + restore all removed comics + restaurar todos os quadrinhos removidos + + + + ThemeEditorDialog + + + Theme Editor + Editor de Tema + + + + + + + + + + + - + - + + + + i + eu + + + + Expand all + Expandir tudo + + + + Collapse all + Recolher tudo + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Segure para piscar o valor selecionado na UI (magenta/alternado/0↔10). Os lançamentos restauram o original. + + + + Search… + Procurar… + + + + Light + Luz - - "Go to flow" size - Tamanho do "Ir para cheia" + + Dark + Escuro - - Options - Opções + + ID: + EU IA: - - Comics directory - Diretório de quadrinhos + + Display name: + Nome de exibição: - - Restart is needed - Reiniciar é necessário + + Variant: + Variante: - - Display - + + Theme info + Informações do tema - - Show time in current page information label - + + Parameter + Parâmetro - - Background color - + + Value + Valor - - Choose - + + Save and apply + Salvar e aplicar - - Scroll behaviour - + + Export to file... + Exportar para arquivo... - - Disable scroll animations and smooth scrolling - + + Load from file... + Carregar do arquivo... - - Do not turn page using scroll - + + Close + Fechar - - Use single scroll step to turn page - + + Double-click to edit color + Clique duas vezes para editar a cor - - Mouse mode - + + + + + + + true + verdadeiro - - Only Back/Forward buttons can turn pages - + + + + + false + falso - - Use the Left/Right buttons to turn pages. - + + Double-click to toggle + Clique duas vezes para alternar - - Click left or right half of the screen to turn pages. - + + Double-click to edit value + Clique duas vezes para editar o valor - - Quick Navigation Mode - + + + + Edit: %1 + Editar: %1 - - Disable mouse over activation - + + Save theme + Salvar tema - - Brightness - + + + JSON files (*.json);;All files (*) + Arquivos JSON (*.json);;Todos os arquivos (*) - - Contrast - + + Save failed + Falha ao salvar - - Gamma - + + Could not open file for writing: +%1 + Não foi possível abrir o arquivo para gravação: +%1 - - Reset - + + Load theme + Carregar tema - - Image options - + + + + Load failed + Falha no carregamento - - Fit options - + + Could not open file: +%1 + Não foi possível abrir o arquivo: +%1 - - Enlarge images to fit width/height - + + Invalid JSON: +%1 + JSON inválido: +%1 - - Double Page options - + + Expected a JSON object. + Esperava um objeto JSON. + + + TitleHeader - - Show covers as single page - + + SEARCH + PROCURAR + + + UpdateLibraryDialog - - General - + + Updating.... + Atualizando.... - - Page Flow - + + Cancel + Cancelar - - Image adjustment - + + Update library + Atualizar biblioteca - QObject + Viewer - - 7z lib not found - + + + Press 'O' to open comic. + Pressione 'O' para abrir um quadrinho. - - unable to load 7z lib from ./utils - + + Loading...please wait! + Carregando... por favor, aguarde! - - Trace - + + Not found + Não encontrado - - Debug - + + Comic not found + Quadrinho não encontrado - - Info - + + Error opening comic + Erro ao abrir quadrinho - - Warning - + + CRC Error + Erro CRC - - Error - + + Page not available! + Página não disponível! - - Fatal - + + Cover! + Cobrir! - - Select custom cover - + + Last page! + Última página! + + + VolumeComicsModel - - Images (%1) - + + title + título - QsLogging::LogWindowModel + VolumesModel - - Time - + + year + ano - - Level - + + issues + problemas - - Message - + + publisher + editor - QsLogging::Window + YACReader3DFlowConfigWidget - - &Pause - + + Presets: + Predefinições: - - &Resume - + + Classic look + Aparência clássica - - Save log - + + Stripe look + Olhar lista - - Log file (*.log) - + + Overlapped Stripe look + Olhar lista sobreposta - - - ShortcutsDialog - Close - Fechar + + Modern look + Aparência moderna - YACReader keyboard shortcuts - Teclas de atalhos do YACReader + + Roulette look + Aparência de roleta - - - Viewer - - - Press 'O' to open comic. - Pressione 'O' para abrir um quadrinho. + + Show advanced settings + Mostrar configurações avançadas - - Loading...please wait! - Carregando... por favor, aguarde! + + Custom: + Personalizado: - - Not found - + + View angle + Ângulo de visão - - Comic not found - + + Position + Posição - - Error opening comic - + + Cover gap + Cubra a lacuna - - CRC Error - + + Central gap + Lacuna central - - Page not available! - + + Zoom + Amplia??o - - Cover! - + + Y offset + Deslocamento Y - - Last page! - + + Z offset + Deslocamento Z + + + + Cover Angle + Ângulo de cobertura + + + + Visibility + Visibilidade + + + + Light + Luz + + + + Max angle + Ângulo máximo + + + + Low Performance + Baixo desempenho + + + + High Performance + Alto desempenho + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Use VSync (melhora a qualidade da imagem em modo tela cheia, pior desempenho) + + + + Performance: + Desempenho: YACReader::MainWindowViewer - + &Open - &Abrir + &Abrir - + Open a comic - Abrir um quadrinho + Abrir um quadrinho - + New instance - + Nova instância - + Open Folder - Abrir Pasta + Abrir Pasta - + Open image folder - + Abra a pasta de imagens - + Open latest comic - + Abra o último quadrinho - + Open the latest comic opened in the previous reading session - + Abra o último quadrinho aberto na sessão de leitura anterior - + Clear - + Claro - + Clear open recent list - + Limpar lista recente aberta - + Save - Salvar + Salvar - + Save current page - Salvar página atual + Salvar página atual Previous Comic - Quadrinho Anterior + Quadrinho Anterior - - - + + + Open previous comic - Abrir quadrinho anterior + Abrir quadrinho anterior - + Next Comic - Próximo Quadrinho + Próximo Quadrinho - - - + + + Open next comic - Abrir próximo quadrinho + Abrir próximo quadrinho - + &Previous - A&nterior + A&nterior - - - + + + Go to previous page - Ir para a página anterior + Ir para a página anterior - + &Next - &Próxima + &Próxima - - - + + + Go to next page - Ir para a próxima página + Ir para a próxima página - + Fit Height - + Ajustar Altura - + Fit image to height - + Ajustar imagem à altura - + Fit Width - Ajustar à Largura + Ajustar à Largura - + Fit image to width - + Ajustar imagem à largura - + Show full size - + Mostrar tamanho grande - + Fit to page - + Ajustar à página + + + + Continuous scroll + Rolagem contínua + + + + Switch to continuous scroll mode + Mudar para o modo de rolagem contínua - + Reset zoom - + Redefinir zoom - + Show zoom slider - + Mostrar controle deslizante de zoom - + Zoom+ - + Ampliar - + Zoom- - + Reduzir - + Rotate image to the left - Girar imagem à esquerda + Girar imagem à esquerda - + Rotate image to the right - Girar imagem à direita + Girar imagem à direita - + Double page mode - Modo dupla página + Modo dupla página - + Switch to double page mode - Alternar para o modo dupla página + Alternar para o modo dupla página - + Double page manga mode - + Modo mangá de página dupla - + Reverse reading order in double page mode - + Ordem de leitura inversa no modo de página dupla - + Go To - Ir Para + Ir Para - + Go to page ... - Ir para a página... + Ir para a página... - + Options - Opções + Opções - + YACReader options - Opções do YACReader + Opções do YACReader - - + + Help - Ajuda + Ajuda - + Help, About YACReader - Ajuda, Sobre o YACReader + Ajuda, Sobre o YACReader - + Magnifying glass - Lupa + Lupa - + Switch Magnifying glass - Alternar Lupa + Alternar Lupa - + Set bookmark - Definir marcador + Definir marcador - + Set a bookmark on the current page - Definir um marcador na página atual + Definir um marcador na página atual - + Show bookmarks - Mostrar marcadores + Mostrar marcadores - + Show the bookmarks of the current comic - Mostrar os marcadores do quadrinho atual + Mostrar os marcadores do quadrinho atual - + Show keyboard shortcuts - Mostrar teclas de atalhos + Mostrar teclas de atalhos - + Show Info - Mostrar Informações + Mostrar Informações - + Close - Fechar + Fechar - + Show Dictionary - + Mostrar dicionário - + Show go to flow - + Mostrar ir para o fluxo - + Edit shortcuts - + Editar atalhos - + &File - &Arquivo + &Arquivo - - + + Open recent - + Abrir recente - + File - + Arquivo - + Edit - + Editar - + View - + Visualizar - + Go - + Ir - + Window - + Janela - - - + + + Open Comic - Abrir Quadrinho + Abrir Quadrinho - - - + + + Comic files - + Arquivos de quadrinhos - + Open folder - Abrir pasta + Abrir pasta - + page_%1.jpg - + página_%1.jpg - + Image files (*.jpg) - Arquivos de imagem (*.jpg) + Arquivos de imagem (*.jpg) + Comics - + Quadrinhos Toggle fullscreen mode - + Alternar modo de tela cheia Hide/show toolbar - + Ocultar/mostrar barra de ferramentas + General - + Em geral Size up magnifying glass - + Dimensione a lupa Size down magnifying glass - + Diminuir o tamanho da lupa Zoom in magnifying glass - + Zoom na lupa Zoom out magnifying glass - + Diminuir o zoom da lupa Reset magnifying glass - + Redefinir lupa + Magnifiying glass - + Lupa Toggle between fit to width and fit to height - + Alternar entre ajustar à largura e ajustar à altura + Page adjustement - + Ajuste de página - + Autoscroll down - + Rolagem automática para baixo - + Autoscroll up - + Rolagem automática para cima - + Autoscroll forward, horizontal first - + Rolagem automática para frente, horizontal primeiro - + Autoscroll backward, horizontal first - + Rolagem automática para trás, horizontal primeiro - + Autoscroll forward, vertical first - + Rolagem automática para frente, vertical primeiro - + Autoscroll backward, vertical first - + Rolagem automática para trás, vertical primeiro - + Move down - + Mover para baixo - + Move up - + Subir - + Move left - + Mover para a esquerda - + Move right - + Mover para a direita - + Go to the first page - + Vá para a primeira página - + Go to the last page - + Ir para a última página - + Offset double page to the left - + Deslocar página dupla para a esquerda - + Offset double page to the right - + Deslocar página dupla para a direita - + + Reading - + Leitura - + There is a new version available - Há uma nova versão disponível + Há uma nova versão disponível - + Do you want to download the new version? - Você deseja baixar a nova versão? + Você deseja baixar a nova versão? - + Remind me in 14 days - + Lembre-me em 14 dias - + Not now - + Agora não + + + + YACReader::TrayIconController + + + &Restore + &Rloja + + + + Systray + Bandeja do sistema + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary continuará em execução na bandeja do sistema. Para encerrar o programa, escolha <b>Quit</b> no menu de contexto do ícone da bandeja do sistema. YACReader::WhatsNewDialog - Close - Fechar + Fechar @@ -1160,12 +3800,12 @@ Click to overwrite - + Clique para substituir Restore to default - + Restaurar para o padrão @@ -1176,181 +3816,69 @@ Click to overwrite - + Clique para substituir Restore to default - + Restaurar para o padrão YACReaderFlowConfigWidget - CoverFlow look - Olhar capa cheia + Olhar capa cheia - Stripe look - Olhar lista + Olhar lista - Overlapped Stripe look - Olhar lista sobreposta - - - - How to show covers: - + Olhar lista sobreposta YACReaderGLFlowConfigWidget - Stripe look - Olhar lista + Olhar lista - Overlapped Stripe look - Olhar lista sobreposta - - - - Presets: - - - - - Classic look - - - - - Modern look - - - - - Roulette look - - - - - Show advanced settings - - - - - Custom: - - - - - View angle - - - - - Position - - - - - Cover gap - - - - - Central gap - - - - - Zoom - - - - - Y offset - - - - - Z offset - - - - - Cover Angle - - - - - Visibility - - - - - Light - - - - - Max angle - - - - - Low Performance - - - - - High Performance - - - - - Use VSync (improve the image quality in fullscreen mode, worse performance) - - - - - Performance: - + Olhar lista sobreposta YACReaderOptionsDialog - + Save Salvar - + Cancel Cancelar - + Edit shortcuts - + Editar atalhos - + Shortcuts - + Atalhos + + + YACReaderSearchLineEdit - - Use hardware acceleration (restart needed) - + + type to search + digite para pesquisar @@ -1358,31 +3886,31 @@ Reset - + Reiniciar YACReaderTranslator - + YACReader translator - + Tradutor YACReader - - + + Translation - + Tradução - + clear - + claro - + Service not available - + Serviço não disponível diff --git a/YACReader/yacreader_ru.ts b/YACReader/yacreader_ru.ts index 875b78020..62c6c5ac2 100644 --- a/YACReader/yacreader_ru.ts +++ b/YACReader/yacreader_ru.ts @@ -6,7 +6,197 @@ None - + Никто + + + + AddLabelDialog + + + Label name: + Название ярлыка: + + + + Choose a color: + Выбрать цвет: + + + + accept + добавить + + + + cancel + отменить + + + + AddLibraryDialog + + + Comics folder : + Папка комиксов : + + + + Library name : + Имя библиотеки : + + + + Add + Добавить + + + + Cancel + Отмена + + + + Add an existing library + Добавить в существующую библиотеку + + + + ApiKeyDialog + + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Для подключения к Comic Vine вам потребуется ваш личный API ключ. Приобретите его бесплатно вот <a href="http://www.comicvine.com/api/">здесь</a> + + + + Paste here your Comic Vine API key + Вставьте сюда ваш Comic Vine API ключ + + + + Accept + Принять + + + + Cancel + Отмена + + + + AppearanceTabWidget + + + Color scheme + Цветовая гамма + + + + System + Система + + + + Light + Осветить + + + + Dark + Темный + + + + Custom + Обычай + + + + Remove + Удалять + + + + Remove this user-imported theme + Удалить эту импортированную пользователем тему + + + + Light: + Свет: + + + + Dark: + Темный: + + + + Custom: + Пользовательский: + + + + Import theme... + Импортировать тему... + + + + Theme + Тема + + + + Theme editor + Редактор тем + + + + Open Theme Editor... + Открыть редактор тем... + + + + Theme editor error + Ошибка редактора темы + + + + The current theme JSON could not be loaded. + Не удалось загрузить JSON текущей темы. + + + + Import theme + Импортировать тему + + + + JSON files (*.json);;All files (*) + Файлы JSON (*.json);;Все файлы (*) + + + + Could not import theme from: +%1 + Не удалось импортировать тему из: +%1 + + + + Could not import theme from: +%1 + +%2 + Не удалось импортировать тему из: +%1 + +%2 + + + + Import failed + Импорт не удался @@ -33,10 +223,204 @@ Последняя страница + + ClassicComicsView + + + Hide comic flow + Показать/скрыть поток комиксов + + + + ComicModel + + + yes + да + + + + no + нет + + + + Title + Заголовок + + + + File Name + Имя файла + + + + Pages + Всего страниц + + + + Size + Размер + + + + Read + Прочитано + + + + Current Page + Текущая страница + + + + Publication Date + Дата публикации + + + + Rating + Рейтинг + + + + Series + Ряд + + + + Volume + Объем + + + + Story Arc + Сюжетная арка + + + + ComicVineDialog + + + skip + пропустить + + + + back + назад + + + + next + дальше + + + + search + искать + + + + close + закрыть + + + + + comic %1 of %2 - %3 + комикс %1 of %2 - %3 + + + + + + Looking for volume... + Поиск информации... + + + + %1 comics selected + %1 было выбрано + + + + Error connecting to ComicVine + Ошибка поключения к ComicVine + + + + + Retrieving tags for : %1 + Получение тегов для : %1 + + + + Retrieving volume info... + Получение информации... + + + + Looking for comic... + Поиск комикса... + + + + ContinuousPageWidget + + + Loading page %1 + Загрузка страницы %1 + + + + CreateLibraryDialog + + + Comics folder : + Папка комиксов : + + + + Library Name : + Имя библиотеки: + + + + Create + Создать + + + + Cancel + Отмена + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Создание библиотеки может занять несколько минут. Вы можете остановить процесс и обновить библиотеку позже для завершения задачи. + + + + Create new library + Создать новую библиотеку + + + + Path not found + Путь не найден + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + Выбранный путь отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке + + EditShortcutsDialog - + Shortcut in use Горячая клавиша уже занята @@ -51,7 +435,7 @@ Горячие клавиши - + The shortcut "%1" is already assigned to other function Сочетание клавиш "%1" уже назначено для другой функции @@ -61,6 +445,124 @@ Чтобы изменить горячую клавишу дважды щелкните по выбранной комбинации клавиш и введите новые сочетания клавиш. + + EmptyFolderWidget + + + This folder doesn't contain comics yet + В этой папке еще нет комиксов + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + Этот ярлык пока ничего не содержит + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + Этот список чтения пока ничего не содержит + + + + EmptySpecialListWidget + + + No favorites + Нет избранного + + + + You are not reading anything yet, come on!! + Вы пока ничего не читаете. Может самое время почитать? + + + + There are no recent comics! + Свежих комиксов нет! + + + + ExportComicsInfoDialog + + + Output file : + Выходной файл (*.ydb) : + + + + Create + Создать + + + + Cancel + Отмена + + + + Export comics info + Экспортировать информацию комикса + + + + Destination database name + Имя этой базы данных + + + + Problem found while writing + Обнаружена Ошибка записи + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Выбранный путь для импортируемого файла отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке + + + + ExportLibraryDialog + + + Output folder : + Папка вывода : + + + + Create + Создать + + + + Cancel + Отмена + + + + Create covers package + Создать комплект обложек + + + + Problem found while writing + Обнаружена Ошибка записи + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Выбранный путь для импортируемого файла отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке + + + + Destination directory + Назначенная директория + + FileComic @@ -116,1262 +618,3400 @@ GoToFlowToolBar - + Page : Страница : + + GridComicsView + + + Show info + Показать информацию + + HelpAboutDialog - + Help Справка - + System info - + Информация о системе - + About О программе - LogWindow + ImportComicsInfoDialog + + + Import comics info + Импортировать информацию комикса + + + + Info database location : + Путь к файлу (*.ydb) : + + + + Import + Импортировать + + + + Cancel + Отмена + + + + Comics info file (*.ydb) + Инфо файл комикса (*.ydb) + + + + ImportLibraryDialog - - Log window - + + Library Name : + Имя библиотеки: - - &Pause - + + Package location : + Местоположение комплекта : - - &Save - + + Destination folder : + Папка назначения : - - C&lear - + + Unpack + Распаковать - - &Copy - + + Cancel + Отмена - - Level: - + + Extract a catalog + Извлечь каталог - - &Auto scroll - + + Compresed library covers (*.clc) + Сжатая библиотека обложек (*.clc) - MainWindowViewer + ImportWidget - Go - Перейти + + stop + Остановить - Edit - Редактировать + + Some of the comics being added... + Поиск новых комиксов... - File - Файл + + Importing comics + Импорт комиксов - Help - Справка + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary сейчас создает библиотеку.</p><p> Создание библиотеки может занять несколько минут. Вы можете остановить процесс и обновить библиотеку позже для завершения задачи.</p> - Save - Сохранить + + Updating the library + Обновление библиотеки - View - Посмотреть + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>Текущая библиотека обновляется. Для более быстрого обновления в дальнейшем старайтесь почаще обновлять вашу библиотеку после добавления новых комиксов.</p><p>Вы можете остановить этот процесс и продолжить обновление этой библиотеки позже.</p> - &File + + Upgrading the library + Обновление библиотеки + + + + <p>The current library is being upgraded, please wait.</p> + <p>Текущая библиотека обновляется, подождите.</p> + + + + Scanning the library + Сканирование библиотеки + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>Текущая библиотека сканируется на предмет устаревших метаданных XML.</p><p>Это необходимо только один раз и только в том случае, если библиотека была создана с помощью YACReaderLibrary 9.8.2 или более ранней версии.</p> + + + + LibraryWindow + + + YACReader Library + Библиотека YACReader + + + + + + comic + комикс + + + + + + manga + манга + + + + + + western manga (left to right) + западная манга (слева направо) + + + + + + web comic + веб-комикс + + + + + + 4koma (top to botom) + 4кома (сверху вниз) + + + + + + + Set type + Тип установки + + + + Library + Библиотека + + + + Folder + Папка + + + + Comic + Комикс + + + + Upgrade failed + Обновление не удалось + + + + There were errors during library upgrade in: + При обновлении библиотеки возникли ошибки: + + + + Update needed + Необходимо обновление + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Эта библиотека была создана с предыдущей версией YACReaderLibrary. Она должна быть обновлена. Обновить сейчас? + + + + Download new version + Загрузить новую версию + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Эта библиотека была создана новой версией YACReaderLibrary. Скачать новую версию сейчас? + + + + Library not available + Библиотека не доступна + + + + Library '%1' is no longer available. Do you want to remove it? + Библиотека '%1' больше не доступна. Вы хотите удалить ее? + + + + Old library + Библиотека из старой версии YACreader + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Библиотека '%1' была создана старой версией YACReaderLibrary. Она должна быть вновь создана. Вы хотите создать библиотеку сейчас? + + + + + Copying comics... + Скопировать комиксы... + + + + + Moving comics... + Переместить комиксы... + + + + Add new folder + Добавить новую папку + + + + Folder name: + Имя папки: + + + + No folder selected + Ни одна папка не была выбрана + + + + Please, select a folder first + Пожалуйста, сначала выберите папку + + + + Error in path + Ошибка в пути + + + + There was an error accessing the folder's path + Ошибка доступа к пути папки + + + + Delete folder + Удалить папку + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + Выбранная папка и все ее содержимое будет удалено с вашего жёсткого диска. Вы уверены? + + + + + Unable to delete + Не удалось удалить + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Возникла проблема при удалении выбранных папок. Пожалуйста, проверьте права на запись и убедитесь что другие приложения не используют эти папки или файлы. + + + + Add new reading lists + Добавить новый список чтения + + + + + List name: + Имя списка: + + + + Delete list/label + Удалить список/ярлык + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + Выбранные элементы будут удалены, ваши комиксы или папки НЕ БУДУТ удалены с вашего жёсткого диска. Вы уверены? + + + + Rename list name + Изменить имя списка + + + + Open folder... + Открыть папку... + + + + Update folder + Обновить папку + + + + Rescan library for XML info + Повторное сканирование библиотеки для получения информации XML + + + + Set as uncompleted + Отметить как не завершено + + + + Set as completed + Отметить как завершено + + + + Set as read + Отметить как прочитано + + + + + Set as unread + Отметить как не прочитано + + + + Set custom cover + Установить собственную обложку + + + + Delete custom cover + Удалить пользовательскую обложку + + + + Save covers + Сохранить обложки + + + + You are adding too many libraries. + Вы добавляете слишком много библиотек. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Вы добавляете слишком много библиотек. + +Вероятно, вам нужна только одна библиотека в папке комиксов верхнего уровня, вы можете просматривать любые подпапки, используя раздел папок на левой боковой панели. + +YACReaderLibrary не помешает вам создать больше библиотек, но вы должны иметь не большое количество библиотек. + + + + + YACReader not found + YACReader не найден + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader не найден. YACReader должен быть установлен в ту же папку, что и YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader не найден. Возможно, возникла проблема с установкой YACReader. + + + + Error + Ошибка + + + + Error opening comic with third party reader. + Ошибка при открытии комикса с помощью сторонней программы чтения. + + + + Library not found + Библиотека не найдена + + + + The selected folder doesn't contain any library. + Выбранная папка не содержит ни одной библиотеки. + + + + Are you sure? + Вы уверены? + + + + Do you want remove + Вы хотите удалить библиотеку + + + + library? + ? + + + + Remove and delete metadata + Удаление метаданных + + + + Library info + Информация о библиотеке + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Возникла проблема при удалении выбранных комиксов. Пожалуйста, проверьте права на запись для выбранных файлов или содержащую их папку. + + + + Assign comics numbers + Порядковый номер + + + + Assign numbers starting in: + Назначить порядковый номер начиная с: + + + + Invalid image + Неверное изображение + + + + The selected file is not a valid image. + Выбранный файл не является допустимым изображением. + + + + Error saving cover + Не удалось сохранить обложку. + + + + There was an error saving the cover image. + Не удалось сохранить изображение обложки. + + + + Error creating the library + Ошибка создания библиотеки + + + + Error updating the library + Ошибка обновления библиотеки + + + + Error opening the library + Ошибка открытия библиотеки + + + + Delete comics + Удалить комиксы + + + + All the selected comics will be deleted from your disk. Are you sure? + Все выбранные комиксы будут удалены с вашего жёсткого диска. Вы уверены? + + + + Remove comics + Убрать комиксы + + + + Comics will only be deleted from the current label/list. Are you sure? + Комиксы будут удалены только из выбранного списка/ярлыка. Вы уверены? + + + + Library name already exists + Имя папки уже используется + + + + There is another library with the name '%1'. + Уже существует другая папка с именем '%1'. + + + + LibraryWindowActions + + + Create a new library + Создать новую библиотеку + + + + Open an existing library + Открыть существующую библиотеку + + + + + Export comics info + Экспортировать информацию комикса + + + + + Import comics info + Импортировать информацию комикса + + + + Pack covers + Запаковать обложки + + + + Pack the covers of the selected library + Запаковать обложки выбранной библиотеки + + + + Unpack covers + Распаковать обложки + + + + Unpack a catalog + Распаковать каталог + + + + Update library + Обновить библиотеку + + + + Update current library + Обновить эту библиотеку + + + + Rename library + Переименовать библиотеку + + + + Rename current library + Переименовать эту библиотеку + + + + Remove library + Удалить библиотеку + + + + Remove current library from your collection + Удалить эту библиотеку из своей коллекции + + + + Rescan library for XML info + Повторное сканирование библиотеки для получения информации XML + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Пытается найти информацию XML, встроенную в файлы комиксов. Это необходимо делать только в том случае, если библиотека была создана с помощью версии 9.8.2 или более ранней, или если вы используете стороннее программное обеспечение для встраивания информации XML в файлы. + + + + Show library info + Показать информацию о библиотеке + + + + Show information about the current library + Показать информацию о текущей библиотеке + + + + Open current comic + Открыть выбранный комикс + + + + Open current comic on YACReader + Открыть комикс в YACReader + + + + Save selected covers to... + Сохранить выбранные обложки в... + + + + Save covers of the selected comics as JPG files + Сохранить обложки выбранных комиксов как JPG файлы + + + + + Set as read + Отметить как прочитано + + + + Set comic as read + Отметить комикс как прочитано + + + + + Set as unread + Отметить как не прочитано + + + + Set comic as unread + Отметить комикс как не прочитано + + + + + manga + манга + + + + Set issue as manga + Установить выпуск как мангу + + + + + comic + комикс + + + + Set issue as normal + Установите проблему как обычно + + + + western manga + вестерн манга + + + + Set issue as western manga + Установить выпуск как западную мангу + + + + + web comic + веб-комикс + + + + Set issue as web comic + Установить выпуск как веб-комикс + + + + + yonkoma + йонкома + + + + Set issue as yonkoma + Установить проблему как йонкома + + + + Show/Hide marks + Показать/Спрятать пометки + + + + Show or hide read marks + Показать или спрятать отметку прочтено + + + + Show/Hide recent indicator + Показать/скрыть индикатор последних событий + + + + Show or hide recent indicator + Показать или скрыть недавний индикатор + + + + + Fullscreen mode on/off + Полноэкранный режим включить/выключить + + + + Help, About YACReader + Справка + + + + Add new folder + Добавить новую папку + + + + Add new folder to the current library + Добавить новую папку в текущую библиотеку + + + + Delete folder + Удалить папку + + + + Delete current folder from disk + Удалить выбранную папку с жёсткого диска + + + + Select root node + Домашняя папка + + + + Expand all nodes + Раскрыть все папки + + + + Collapse all nodes + Свернуть все папки + + + + Show options dialog + Настройки + + + + Show comics server options dialog + Настройки сервера YACReader + + + + + Change between comics views + Изменение внешнего вида потока комиксов + + + + Open folder... + Открыть папку... + + + + Set as uncompleted + Отметить как не завершено + + + + Set as completed + Отметить как завершено + + + + Set custom cover + Установить собственную обложку + + + + Delete custom cover + Удалить пользовательскую обложку + + + + western manga (left to right) + западная манга (слева направо) + + + + Open containing folder... + Открыть выбранную папку... + + + + Reset comic rating + Сбросить рейтинг комикса + + + + Select all comics + Выбрать все комиксы + + + + Edit + Редактировать + + + + Assign current order to comics + Назначить порядковый номер + + + + Update cover + Обновить обложки + + + + Delete selected comics + Удалить выбранное + + + + Delete metadata from selected comics + Удалить метаданные из выбранных комиксов + + + + Download tags from Comic Vine + Скачать теги из Comic Vine + + + + Focus search line + Строка поиска фокуса + + + + Focus comics view + Просмотр комиксов в фокусе + + + + Edit shortcuts + Редактировать горячие клавиши + + + + &Quit + &Qкостюм + + + + Update folder + Обновить папку + + + + Update current folder + Обновить выбранную папку + + + + Scan legacy XML metadata + Сканировать устаревшие метаданные XML + + + + Add new reading list + Создать новый список чтения + + + + Add a new reading list to the current library + Создать новый список чтения + + + + Remove reading list + Удалить список чтения + + + + Remove current reading list from the library + Удалить выбранный ярлык/список чтения + + + + Add new label + Создать новый ярлык + + + + Add a new label to this library + Создать новый ярлык + + + + Rename selected list + Переименовать выбранный список + + + + Rename any selected labels or lists + Переименовать выбранный ярлык/список чтения + + + + Add to... + Добавить в... + + + + Favorites + Избранное + + + + Add selected comics to favorites list + Добавить выбранные комиксы в список избранного + + + + LocalComicListModel + + + file name + имя файла + + + + MainWindowViewer + + Go + Перейти + + + Edit + Редактировать + + + File + Файл + + + Help + Справка + + + Save + Сохранить + + + View + Посмотреть + + + &File &Отображать панель инструментов - &Next - &Следующий + &Next + &Следующий + + + &Open + &Открыть + + + Clear + Очистить + + + Close + Закрыть + + + Open Comic + Открыть комикс + + + Go To + Перейти к странице... + + + Zoom+ + Увеличить масштаб + + + Zoom- + Уменьшить масштаб + + + Open image folder + Открыть папку с изображениями + + + Size down magnifying glass + Уменьшение размера окошка увеличительного стекла + + + Zoom out magnifying glass + Уменьшить + + + Open latest comic + Открыть последний комикс + + + Autoscroll up + Автопрокрутка вверх + + + Set bookmark + Установить закладку + + + page_%1.jpg + страница_%1.jpg + + + Autoscroll forward, vertical first + Автопрокрутка вперед, вертикальная + + + Switch to double page mode + Двухстраничный режим + + + Save current page + Сохранить текущию страницу + + + Size up magnifying glass + Увеличение размера окошка увеличительного стекла + + + Double page mode + Двухстраничный режим + + + Move up + Переместить вверх + + + Switch Magnifying glass + Увеличительное стекло + + + Open Folder + Открыть папку + + + Comics + Комикс + + + Fit Height + Подогнать по высоте + + + Autoscroll backward, vertical first + Автопрокрутка назад, вертикальная + + + Comic files + Файлы комикса + + + Not now + Не сейчас + + + Go to the first page + Перейти к первой странице + + + Go to previous page + Перейти к предыдущей странице + + + Window + Окно + + + Open the latest comic opened in the previous reading session + Открыть комикс открытый в предыдущем сеансе чтения + + + Open a comic + Открыть комикс + + + Image files (*.jpg) + Файлы изображений (*.jpg) + + + Next Comic + Следующий комикс + + + Fit Width + Подогнать по ширине + + + Options + Настройки + + + Show Info + Показать/скрыть номер страницы и текущее время + + + Open folder + Открыть папку + + + Go to page ... + Перейти к странице... + + + Magnifiying glass + Увеличительное стекло + + + Fit image to width + Подогнать по ширине + + + Toggle fullscreen mode + Полноэкранный режим включить/выключить + + + Toggle between fit to width and fit to height + Переключение режима подгонки страницы по ширине/высоте + + + Move right + Переместить вправо + + + Zoom in magnifying glass + Увеличить + + + Open recent + Открыть недавние + + + Reading + Чтение + + + &Previous + &Предыдущий + + + Autoscroll forward, horizontal first + Автопрокрутка вперед, горизонтальная + + + Go to next page + Перейти к следующей странице + + + Show keyboard shortcuts + Показать горячие клавиши + + + Double page manga mode + Двухстраничный режим манги + + + There is a new version available + Доступна новая версия + + + Autoscroll down + Автопрокрутка вниз + + + Open next comic + Открыть следующий комикс + + + Remind me in 14 days + Напомнить через 14 дней + + + Fit to page + Подогнать под размер страницы + + + Show bookmarks + Показать закладки + + + Open previous comic + Открыть предыдуший комикс + + + Rotate image to the left + Повернуть изображение против часовой стрелки + + + Fit image to height + Подогнать по высоте + + + Reset zoom + Сбросить масштаб + + + Show the bookmarks of the current comic + Показать закладки в текущем комиксе + + + Show Dictionary + Переводчик YACreader + + + Move down + Переместить вниз + + + Move left + Переместить влево + + + Reverse reading order in double page mode + Двухстраничный режим манги + + + YACReader options + Настройки + + + Clear open recent list + Очистить список недавно открытых файлов + + + Help, About YACReader + Справка + + + Show go to flow + Показать поток страниц + + + Previous Comic + Предыдущий комикс + + + Show full size + Показать в полном размере + + + Hide/show toolbar + Показать/скрыть панель инструментов + + + Magnifying glass + Увеличительное стекло + + + Edit shortcuts + Редактировать горячие клавиши + + + General + Общие + + + Set a bookmark on the current page + Установить закладку на текущей странице + + + Page adjustement + Настройка страницы + + + Show zoom slider + Показать ползунок масштабирования + + + Go to the last page + Перейти к последней странице + + + Do you want to download the new version? + Хотите загрузить новую версию ? + + + Rotate image to the right + Повернуть изображение по часовой стрелке + + + Always on top + Всегда сверху + + + Autoscroll backward, horizontal first + Автопрокрутка назад, горизонтальная + + + + NoLibrariesWidget + + + You don't have any libraries yet + У вас нет ни одной библиотеки + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Вы можете создать библиотеку в любой папке, YACReaderLibrary будет импортировать все комиксы и папки из этой папки. Если вы уже ранее создавали библиотеки, их можно будет открыть.< / p > <p>Не забывайте, что Вы можете использовать YACReader в качестве отдельного приложения для чтения комиксов на вашем компьютере.</п> + + + + create your first library + создайте свою первую библиотеку + + + + add an existing one + добавить уже существующую + + + + NoSearchResultsWidget + + + No results + Нет результатов + + + + OptionsDialog + + + Gamma + Гамма + + + + Reset + Вернуть к первоначальным значениям + + + + My comics path + Папка комиксов + + + + Image adjustment + Настройка изображения + + + + "Go to flow" size + Размер потока страниц + + + + Choose + Выбрать + + + + Image options + Настройки изображения + + + + Contrast + Контраст + + + + + Libraries + Библиотеки + + + + Comic Flow + Поток комиксов + + + + Grid view + Фоновое изображение + + + + + Appearance + Появление + + + + + Options + Настройки + + + + + Language + Язык + + + + + Application language + Язык приложения + + + + + System default + Системный по умолчанию + + + + Tray icon settings (experimental) + Настройки значков в трее (экспериментально) + + + + Close to tray + Рядом с лотком + + + + Start into the system tray + Запустите в системном трее + + + + Edit Comic Vine API key + Редактировать Comic Vine API ключ + + + + Comic Vine API key + Comic Vine API ключ + + + + ComicInfo.xml legacy support + Поддержка устаревших версий ComicInfo.xml + + + + Import metadata from ComicInfo.xml when adding new comics + Импортируйте метаданные из ComicInfo.xml при добавлении новых комиксов. + + + + Consider 'recent' items added or updated since X days ago + Учитывайте «недавние» элементы, добавленные или обновленные X дней назад. + + + + Third party reader + Сторонний читатель + + + + Write {comic_file_path} where the path should go in the command + Напишите {comic_file_path}, где должен идти путь в команде. + + + + + Clear + Очистить + + + + Update libraries at startup + Обновлять библиотеки при запуске + + + + Try to detect changes automatically + Попробуйте обнаружить изменения автоматически + + + + Update libraries periodically + Периодически обновляйте библиотеки + + + + Interval: + Интервал: + + + + 30 minutes + 30 минут + + + + 1 hour + 1 час + + + + 2 hours + 2 часа + + + + 4 hours + 4 часа + + + + 8 hours + 8 часов + + + + 12 hours + 12 часов + + + + daily + ежедневно + + + + Update libraries at certain time + Обновлять библиотеки в определенное время + + + + Time: + Время: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + ПРЕДУПРЕЖДЕНИЕ! Во время обновления библиотеки запись в базу данных отключена! +Не планируйте обновления, пока вы активно используете приложение. +Во время автоматического обновления приложение будет блокировать некоторые действия до завершения обновления. +Чтобы остановить автоматическое обновление, нажмите на индикатор загрузки рядом с названием «Библиотеки». + + + + Modifications detection + Обнаружение модификаций + + + + Compare the modified date of files when updating a library (not recommended) + Сравните дату изменения файлов при обновлении библиотеки (не рекомендуется) + + + + Enable background image + Включить фоновое изображение + + + + Opacity level + Уровень непрозрачности + + + + Blur level + Уровень размытия + + + + Use selected comic cover as background + Обложка комикса фоновое изображение + + + + Restore defautls + Вернуть к первоначальным значениям + + + + Background + Фоновое изображение + + + + Display continue reading banner + Отображение баннера продолжения чтения + + + + Display current comic banner + Отображать текущий комикс-баннер + + + + Continue reading + Продолжить чтение + + + + Comics directory + Папка комиксов + + + + Quick Navigation Mode + Ползунок для быстрой навигации по страницам + + + + Display + Отображать + + + + Show time in current page information label + Показывать время в информационной метке текущей страницы + + + + Background color + Фоновый цвет + + + + Scroll behaviour + Поведение прокрутки + + + + Disable scroll animations and smooth scrolling + Отключить анимацию прокрутки и плавную прокрутку + + + + Do not turn page using scroll + Не переворачивайте страницу с помощью прокрутки + + + + Use single scroll step to turn page + Используйте один шаг прокрутки, чтобы перевернуть страницу + + + + Mouse mode + Режим мыши + + + + Only Back/Forward buttons can turn pages + Только кнопки «Назад/Вперед» могут перелистывать страницы. + + + + Use the Left/Right buttons to turn pages. + Используйте кнопки «Влево/Вправо», чтобы перелистывать страницы. + + + + Click left or right half of the screen to turn pages. + Нажмите левую или правую половину экрана, чтобы перелистывать страницы. + + + + Disable mouse over activation + Отключить активацию потока при наведении мыши + + + + Scaling + Масштабирование + + + + Scaling method + Метод масштабирования + + + + Nearest (fast, low quality) + Ближайший (быстро, низкое качество) + + + + Bilinear + Билинейный + + + + Lanczos (better quality) + Ланцос (лучшее качество) + + + + Page Flow + Поток Страниц + + + + + General + Общие + + + + Brightness + Яркость + + + + + Restart is needed + Требуется перезагрузка + + + + Fit options + Варианты подгонки + + + + Enlarge images to fit width/height + Увеличьте изображения по ширине/высоте + + + + Double Page options + Параметры двойной страницы + + + + Show covers as single page + Показывать обложки на одной странице + + + + PropertiesDialog + + + General info + Общая информация + + + + Plot + Сюжет + + + + Authors + Авторы + + + + Publishing + Издатели + + + + Notes + Примечания + + + + Cover page + Страница обложки + + + + Load previous page as cover + Загрузить предыдущую страницу в качестве обложки + + + + Load next page as cover + Загрузить следующую страницу в качестве обложки + + + + Reset cover to the default image + Сбросить обложку к изображению по умолчанию + + + + Load custom cover image + Загрузить собственное изображение обложки + + + + Series: + Серия: + + + + Title: + Заголовок: - &Open - &Открыть + + + + of: + из: - Clear - Очистить + + Issue number: + Номер выпуска - Close - Закрыть + + Volume: + Объём : - Open Comic - Открыть комикс + + Arc number: + Номер дуги: - Go To - Перейти к странице... + + Story arc: + Сюжетная арка: - Zoom+ - Увеличить масштаб + + alt. number: + альт. число: - Zoom- - Уменьшить масштаб + + Alternate series: + Альтернативный сериал: - Open image folder - Открыть папку с изображениями + + Series Group: + Группа серий: - Size down magnifying glass - Уменьшение размера окошка увеличительного стекла + + Genre: + Жанр: - Zoom out magnifying glass - Уменьшить + + Size: + Размер: - Open latest comic - Открыть последний комикс + + Writer(s): + Писатель(и): - Autoscroll up - Автопрокрутка вверх + + Penciller(s): + Художник(и): - Set bookmark - Установить закладку + + Inker(s): + Контуровщик(и): - page_%1.jpg - страница_%1.jpg + + Colorist(s): + Колорист(ы): - Autoscroll forward, vertical first - Автопрокрутка вперед, вертикальная + + Letterer(s): + Гравёр-шрифтовик(и): - Switch to double page mode - Двухстраничный режим + + Cover Artist(s): + Художник(и) Обложки: - Save current page - Сохранить текущию страницу + + Editor(s): + Редактор(ы): - Size up magnifying glass - Увеличение размера окошка увеличительного стекла + + Imprint: + Выходные данные: - Double page mode - Двухстраничный режим + + Day: + День: - Move up - Переместить вверх + + Month: + Месяц: - Switch Magnifying glass - Увеличительное стекло + + Year: + Год: - Open Folder - Открыть папку + + Publisher: + Издатель: - Comics - Комикс + + Format: + Формат: - Fit Height - Подогнать по высоте + + Color/BW: + Цвет/BW: - Autoscroll backward, vertical first - Автопрокрутка назад, вертикальная + + Age rating: + Возрастной рейтинг: - Comic files - Файлы комикса + + Type: + Тип: - Not now - Не сейчас + + Language (ISO): + Язык (ISO): - Go to the first page - Перейти к первой странице + + Synopsis: + Описание: - Go to previous page - Перейти к предыдущей странице + + Characters: + Персонажи: - Window - Окно + + Teams: + Команды: - Open the latest comic opened in the previous reading session - Открыть комикс открытый в предыдущем сеансе чтения + + Locations: + Местоположение: - Open a comic - Открыть комикс + + Main character or team: + Главный герой или команда: - Image files (*.jpg) - Файлы изображений (*.jpg) + + Review: + Обзор: - Next Comic - Следующий комикс + + Notes: + Заметки: - Fit Width - Подогнать по ширине + + Tags: + Теги: - Options - Настройки + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + <a style='color: ##666666; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Открыть страницу этого комикса на сайте Comic Vine </a> - Show Info - Показать/скрыть номер страницы и текущее время + + Not found + Не найдено - Open folder - Открыть папку + + Comic not found. You should update your library. + Комикс не найден. Обновите вашу библиотеку. - Go to page ... - Перейти к странице... + + Edit comic information + Редактировать информацию комикса - Magnifiying glass - Увеличительное стекло + + Edit selected comics information + Редактировать информацию выбранного комикса - Fit image to width - Подогнать по ширине + + Invalid cover + Неверное покрытие - Toggle fullscreen mode - Полноэкранный режим включить/выключить + + The image is invalid. + Изображение недействительно. + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer — это безголовая (без графического интерфейса) версия YACReaderLibrary. + +Это приложение поддерживает постоянные настройки. Чтобы настроить их, отредактируйте этот файл %1. +Чтобы узнать о доступных настройках, ознакомьтесь с документацией по адресу https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md. + + + + QObject - Toggle between fit to width and fit to height - Переключение режима подгонки страницы по ширине/высоте + + 7z lib not found + Библиотека распаковщика 7z не найдена - Move right - Переместить вправо + + unable to load 7z lib from ./utils + не удается загрузить 7z lib из ./ utils - Zoom in magnifying glass - Увеличить + + Trace + След - Open recent - Открыть недавние + + Debug + Отлаживать - Reading - Чтение + + Info + Информация - &Previous - &Предыдущий + + Warning + Предупреждение - Autoscroll forward, horizontal first - Автопрокрутка вперед, горизонтальная + + Error + Ошибка - Go to next page - Перейти к следующей странице + + Fatal + Фатальный - Show keyboard shortcuts - Показать горячие клавиши + + Select custom cover + Выбрать индивидуальную обложку - Double page manga mode - Двухстраничный режим манги + + Images (%1) + Изображения (%1) - There is a new version available - Доступна новая версия + + The file could not be read or is not valid JSON. + Файл не может быть прочитан или имеет недопустимый формат JSON. - Autoscroll down - Автопрокрутка вниз + + This theme is for %1, not %2. + Эта тема предназначена для %1, а не для %2. - Open next comic - Открыть следующий комикс + + Libraries + Библиотеки - Remind me in 14 days - Напомнить через 14 дней + + Folders + Папки - Fit to page - Подогнать под размер страницы + + Reading Lists + Списки чтения + + + RenameLibraryDialog - Show bookmarks - Показать закладки + + New Library Name : + Новое имя библиотеки: - Open previous comic - Открыть предыдуший комикс + + Rename + Переименовать - Rotate image to the left - Повернуть изображение против часовой стрелки + + Cancel + Отмена - Fit image to height - Подогнать по высоте + + Rename current library + Переименовать эту библиотеку + + + ScraperResultsPaginator - Reset zoom - Сбросить масштаб + + Number of volumes found : %1 + Количество найденных томов : %1 - Show the bookmarks of the current comic - Показать закладки в текущем комиксе + + + page %1 of %2 + страница %1 из %2 - Show Dictionary - Переводчик YACreader + + Number of %1 found : %2 + Количество из %1 найдено : %2 + + + SearchSingleComic - Move down - Переместить вниз + + Please provide some additional information for this comic. + Пожалуйста, введите инфомарцию для поиска. - Move left - Переместить влево + + Series: + Серия: - Reverse reading order in double page mode - Двухстраничный режим манги + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Используйте поиск по точному совпадению. Отключите, если хотите найти тома, соответствующие некоторым словам в названии. + + + SearchVolume - YACReader options - Настройки + + Please provide some additional information. + Пожалуйста, введите инфомарцию для поиска. - Clear open recent list - Очистить список недавно открытых файлов + + Series: + Серия: - Help, About YACReader - Справка + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Используйте поиск по точному совпадению. Отключите, если хотите найти тома, соответствующие некоторым словам в названии. + + + SelectComic - Show go to flow - Показать поток страниц + + Please, select the right comic info. + Пожалуйста, выберите правильную информацию об комиксе. - Previous Comic - Предыдущий комикс + + comics + комиксы - Show full size - Показать в полном размере + + loading cover + загрузка обложки - Hide/show toolbar - Показать/скрыть панель инструментов + + loading description + загрузка описания - Magnifying glass - Увеличительное стекло + + comic description unavailable + Описание комикса недоступно + + + SelectVolume - Edit shortcuts - Редактировать горячие клавиши + + Please, select the right series for your comic. + Пожалуйста, выберите правильную серию для вашего комикса. - General - Общие + + Filter: + Фильтр: - Set a bookmark on the current page - Установить закладку на текущей странице + + volumes + тома - Page adjustement - Настройка страницы + + Nothing found, clear the filter if any. + Ничего не найдено, очистите фильтр, если есть. - Show zoom slider - Показать ползунок масштабирования + + loading cover + загрузка обложки - Go to the last page - Перейти к последней странице + + loading description + загрузка описания - Do you want to download the new version? - Хотите загрузить новую версию ? + + volume description unavailable + описание тома недоступно + + + SeriesQuestion - Rotate image to the right - Повернуть изображение по часовой стрелке + + You are trying to get information for various comics at once, are they part of the same series? + Вы пытаетесь получить информацию для нескольких комиксов одновременно, являются ли они все частью одной серии? - Always on top - Всегда сверху + + yes + да - Autoscroll backward, horizontal first - Автопрокрутка назад, горизонтальная + + no + нет - OptionsDialog + ServerConfigDialog - - Gamma - Гамма + + set port + указать порт - - Reset - Вернуть к первоначальным значениям + + Server connectivity information + Информация о подключении - - My comics path - Папка комиксов + + Scan it! + Сканируйте! - - Image adjustment - Настройка изображения + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader доступен для устройств iOS и Android.<br/>Найдите его для <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> или <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - - "Go to flow" size - Размер потока страниц + + Choose an IP address + Выбрать IP адрес - - Choose - Выбрать + + Port + Порт - - Image options - Настройки изображения + + enable the server + активировать сервер + + + ShortcutsDialog - - Contrast - Контраст + Close + Закрыть - - Options - Настройки + YACReader keyboard shortcuts + Клавиатурные комбинации YACReader - - Comics directory - Папка комиксов + Keyboard Shortcuts + Клавиатурные комбинации + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + Пожалуйста, отсортируйте список комиксов слева, пока он не будет соответствовать информации комикса. - - Quick Navigation Mode - Ползунок для быстрой навигации по страницам + + sort comics to match comic information + сортировать комиксы, чтобы соответствовать информации комиксов + + + + issues + выпуск + + + + remove selected comics + удалить выбранные комиксы - - Display - + + restore all removed comics + восстановить все удаленные комиксы + + + ThemeEditorDialog - - Show time in current page information label - + + Theme Editor + Редактор тем - - Background color - Фоновый цвет + + + + + - - Scroll behaviour - + + - + - - - Disable scroll animations and smooth scrolling - + + i + я - - Do not turn page using scroll - + + Expand all + Развернуть все - - Use single scroll step to turn page - + + Collapse all + Свернуть все - - Mouse mode - + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Удерживайте, чтобы выбранное значение мигало в пользовательском интерфейсе (пурпурный / переключено / 0↔10). Релизы восстанавливают оригинал. - - Only Back/Forward buttons can turn pages - + + Search… + Поиск… - - Use the Left/Right buttons to turn pages. - + + Light + Осветить - - Click left or right half of the screen to turn pages. - + + Dark + Темный - - Disable mouse over activation - Отключить активацию потока при наведении мыши + + ID: + ИДЕНТИФИКАТОР: - - Page Flow - Поток Страниц + + Display name: + Отображаемое имя: - - General - Общие + + Variant: + Вариант: - - Brightness - Яркость + + Theme info + Информация о теме - - Restart is needed - + + Parameter + Параметр - - Fit options - + + Value + Ценить - - Enlarge images to fit width/height - + + Save and apply + Сохраните и примените - - Double Page options - + + Export to file... + Экспортировать в файл... - - Show covers as single page - + + Load from file... + Загрузить из файла... - - - QObject - - 7z lib not found - Библиотека распаковщика 7z не найдена + + Close + Закрыть - - unable to load 7z lib from ./utils - не удается загрузить 7z lib из ./ utils + + Double-click to edit color + Дважды щелкните, чтобы изменить цвет - - Trace - + + + + + + + true + истинный - - Debug - + + + + + false + ЛОЖЬ - - Info - + + Double-click to toggle + Дважды щелкните, чтобы переключиться - - Warning - + + Double-click to edit value + Дважды щелкните, чтобы изменить значение - - Error - + + + + Edit: %1 + Изменить: %1 - - Fatal - + + Save theme + Сохранить тему - - Select custom cover - + + + JSON files (*.json);;All files (*) + Файлы JSON (*.json);;Все файлы (*) - - Images (%1) - + + Save failed + Сохранить не удалось - - - QsLogging::LogWindowModel - - Time - + + Could not open file for writing: +%1 + Не удалось открыть файл для записи: +%1 - - Level - + + Load theme + Загрузить тему - - Message - + + + + Load failed + Загрузка не удалась - - - QsLogging::Window - - &Pause - + + Could not open file: +%1 + Не удалось открыть файл: +%1 - - &Resume - + + Invalid JSON: +%1 + Неверный JSON: +%1 - - Save log - + + Expected a JSON object. + Ожидается объект JSON. + + + TitleHeader - - Log file (*.log) - + + SEARCH + ПОИСК - ShortcutsDialog + UpdateLibraryDialog - Close - Закрыть + + Updating.... + Обновление... - YACReader keyboard shortcuts - Клавиатурные комбинации YACReader + + Cancel + Отмена - Keyboard Shortcuts - Клавиатурные комбинации + + Update library + Обновить библиотеку Viewer - + Page not available! Страница недоступна! - - + + Press 'O' to open comic. Нажмите "O" чтобы открыть комикс. - + Error opening comic Ошибка открытия комикса - + Cover! Начало! - + CRC Error Ошибка CRC - + Comic not found Комикс не найден - + Not found Не найдено - + Last page! Конец! - + Loading...please wait! Загрузка... Пожалуйста подождите! + + VolumeComicsModel + + + title + название + + + + VolumesModel + + + year + год + + + + issues + выпуск + + + + publisher + издатель + + + + YACReader3DFlowConfigWidget + + + Presets: + Предустановки: + + + + Classic look + Классический вид + + + + Stripe look + Вид полосами + + + + Overlapped Stripe look + Вид перекрывающимися полосами + + + + Modern look + Современный вид + + + + Roulette look + Вид рулеткой + + + + Show advanced settings + Показать дополнительные настройки + + + + Custom: + Пользовательский: + + + + View angle + Угол зрения + + + + Position + Позиция + + + + Cover gap + Осветить разрыв + + + + Central gap + Сфокусировать разрыв + + + + Zoom + Масштабировать + + + + Y offset + Смещение по Y + + + + Z offset + Смещение по Z + + + + Cover Angle + Охватить угол + + + + Visibility + Прозрачность + + + + Light + Осветить + + + + Max angle + Максимальный угол + + + + Low Performance + Минимальная производительность + + + + High Performance + Максимальная производительность + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Использовать VSync (повысить формат изображения в полноэкранном режиме , хуже производительность) + + + + Performance: + Производительность: + + YACReader::MainWindowViewer - + &Open - &Открыть + &Открыть - + Open a comic - Открыть комикс + Открыть комикс - + New instance - + Новый экземпляр - + Open Folder - Открыть папку + Открыть папку - + Open image folder - Открыть папку с изображениями + Открыть папку с изображениями - + Open latest comic - Открыть последний комикс + Открыть последний комикс - + Open the latest comic opened in the previous reading session - Открыть комикс открытый в предыдущем сеансе чтения + Открыть комикс открытый в предыдущем сеансе чтения - + Clear - Очистить + Очистить - + Clear open recent list - Очистить список недавно открытых файлов + Очистить список недавно открытых файлов - + Save - Сохранить + Сохранить - + Save current page - Сохранить текущию страницу + Сохранить текущию страницу Previous Comic - Предыдущий комикс + Предыдущий комикс - - - + + + Open previous comic - Открыть предыдуший комикс + Открыть предыдуший комикс - + Next Comic - Следующий комикс + Следующий комикс - - - + + + Open next comic - Открыть следующий комикс + Открыть следующий комикс - + &Previous - &Предыдущий + &Предыдущий - - - + + + Go to previous page - Перейти к предыдущей странице + Перейти к предыдущей странице - + &Next - &Следующий + &Следующий - - - + + + Go to next page - Перейти к следующей странице + Перейти к следующей странице - + Fit Height - Подогнать по высоте + Подогнать по высоте - + Fit image to height - Подогнать по высоте + Подогнать по высоте - + Fit Width - Подогнать по ширине + Подогнать по ширине - + Fit image to width - Подогнать по ширине + Подогнать по ширине - + Show full size - Показать в полном размере + Показать в полном размере - + Fit to page - Подогнать под размер страницы + Подогнать под размер страницы + + + + Continuous scroll + Непрерывная прокрутка + + + + Switch to continuous scroll mode + Переключиться в режим непрерывной прокрутки - + Reset zoom - Сбросить масштаб + Сбросить масштаб - + Show zoom slider - Показать ползунок масштабирования + Показать ползунок масштабирования - + Zoom+ - Увеличить масштаб + Увеличить масштаб - + Zoom- - Уменьшить масштаб + Уменьшить масштаб - + Rotate image to the left - Повернуть изображение против часовой стрелки + Повернуть изображение против часовой стрелки - + Rotate image to the right - Повернуть изображение по часовой стрелке + Повернуть изображение по часовой стрелке - + Double page mode - Двухстраничный режим + Двухстраничный режим - + Switch to double page mode - Двухстраничный режим + Двухстраничный режим - + Double page manga mode - Двухстраничный режим манги + Двухстраничный режим манги - + Reverse reading order in double page mode - Двухстраничный режим манги + Двухстраничный режим манги - + Go To - Перейти к странице... + Перейти к странице... - + Go to page ... - Перейти к странице... + Перейти к странице... - + Options - Настройки + Настройки - + YACReader options - Настройки + Настройки - - + + Help - Справка + Справка - + Help, About YACReader - Справка + Справка - + Magnifying glass - Увеличительное стекло + Увеличительное стекло - + Switch Magnifying glass - Увеличительное стекло + Увеличительное стекло - + Set bookmark - Установить закладку + Установить закладку - + Set a bookmark on the current page - Установить закладку на текущей странице + Установить закладку на текущей странице - + Show bookmarks - Показать закладки + Показать закладки - + Show the bookmarks of the current comic - Показать закладки в текущем комиксе + Показать закладки в текущем комиксе - + Show keyboard shortcuts - Показать горячие клавиши + Показать горячие клавиши - + Show Info - Показать/скрыть номер страницы и текущее время + Показать/скрыть номер страницы и текущее время - + Close - Закрыть + Закрыть - + Show Dictionary - Переводчик YACreader + Переводчик YACreader - + Show go to flow - Показать поток страниц + Показать поток страниц - + Edit shortcuts - Редактировать горячие клавиши + Редактировать горячие клавиши - + &File - &Отображать панель инструментов + &Отображать панель инструментов - - + + Open recent - Открыть недавние + Открыть недавние - + File - Файл + Файл - + Edit - Редактировать + Редактировать - + View - Посмотреть + Посмотреть - + Go - Перейти + Перейти - + Window - Окно + Окно - - - + + + Open Comic - Открыть комикс + Открыть комикс - - - + + + Comic files - Файлы комикса + Файлы комикса - + Open folder - Открыть папку + Открыть папку - + page_%1.jpg - страница_%1.jpg + страница_%1.jpg - + Image files (*.jpg) - Файлы изображений (*.jpg) + Файлы изображений (*.jpg) + Comics - Комикс + Комикс Toggle fullscreen mode - Полноэкранный режим включить/выключить + Полноэкранный режим включить/выключить Hide/show toolbar - Показать/скрыть панель инструментов + Показать/скрыть панель инструментов + General - Общие + Общие Size up magnifying glass - Увеличение размера окошка увеличительного стекла + Увеличение размера окошка увеличительного стекла Size down magnifying glass - Уменьшение размера окошка увеличительного стекла + Уменьшение размера окошка увеличительного стекла Zoom in magnifying glass - Увеличить + Увеличить Zoom out magnifying glass - Уменьшить + Уменьшить Reset magnifying glass - + Сбросить увеличительное стекло + Magnifiying glass - Увеличительное стекло + Увеличительное стекло Toggle between fit to width and fit to height - Переключение режима подгонки страницы по ширине/высоте + Переключение режима подгонки страницы по ширине/высоте + Page adjustement - Настройка страницы + Настройка страницы - + Autoscroll down - Автопрокрутка вниз + Автопрокрутка вниз - + Autoscroll up - Автопрокрутка вверх + Автопрокрутка вверх - + Autoscroll forward, horizontal first - Автопрокрутка вперед, горизонтальная + Автопрокрутка вперед, горизонтальная - + Autoscroll backward, horizontal first - Автопрокрутка назад, горизонтальная + Автопрокрутка назад, горизонтальная - + Autoscroll forward, vertical first - Автопрокрутка вперед, вертикальная + Автопрокрутка вперед, вертикальная - + Autoscroll backward, vertical first - Автопрокрутка назад, вертикальная + Автопрокрутка назад, вертикальная - + Move down - Переместить вниз + Переместить вниз - + Move up - Переместить вверх + Переместить вверх - + Move left - Переместить влево + Переместить влево - + Move right - Переместить вправо + Переместить вправо - + Go to the first page - Перейти к первой странице + Перейти к первой странице - + Go to the last page - Перейти к последней странице + Перейти к последней странице - + Offset double page to the left - + Смещение разворота влево - + Offset double page to the right - + Смещение разворота вправо - + + Reading - Чтение + Чтение - + There is a new version available - Доступна новая версия + Доступна новая версия - + Do you want to download the new version? - Хотите загрузить новую версию ? + Хотите загрузить новую версию ? - + Remind me in 14 days - Напомнить через 14 дней + Напомнить через 14 дней - + Not now - Не сейчас + Не сейчас + + + + YACReader::TrayIconController + + + &Restore + &Rмагазин + + + + Systray + Систрей + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary продолжит работать в системном трее. Чтобы завершить работу программы, выберите <b>Quit</b> в контекстном меню значка на панели задач. YACReader::WhatsNewDialog - Close - Закрыть + Закрыть @@ -1407,172 +4047,152 @@ YACReaderFlowConfigWidget - CoverFlow look - Вид рулеткой + Вид рулеткой - How to show covers: - Как отображать обложки: + Как отображать обложки: - Stripe look - Вид полосами + Вид полосами - Overlapped Stripe look - Вид перекрывающимися полосами + Вид перекрывающимися полосами YACReaderGLFlowConfigWidget - Zoom - Масштабировать + Масштабировать - Light - Осветить + Осветить - Show advanced settings - Показать дополнительные настройки + Показать дополнительные настройки - Roulette look - Вид рулеткой + Вид рулеткой - Cover Angle - Охватить угол + Охватить угол - Stripe look - Вид полосами + Вид полосами - Position - Позиция + Позиция - Z offset - Смещение по Z + Смещение по Z - Y offset - Смещение по Y + Смещение по Y - Central gap - Сфокусировать разрыв + Сфокусировать разрыв - Presets: - Предустановки: + Предустановки: - Overlapped Stripe look - Вид перекрывающимися полосами + Вид перекрывающимися полосами - Modern look - Современный вид + Современный вид - View angle - Угол зрения + Угол зрения - Max angle - Максимальный угол + Максимальный угол - Custom: - Пользовательский: + Пользовательский: - Classic look - Классический вид + Классический вид - Cover gap - Осветить разрыв + Осветить разрыв - High Performance - Максимальная производительность + Максимальная производительность - Performance: - Производительность: + Производительность: - Use VSync (improve the image quality in fullscreen mode, worse performance) - Использовать VSync (повысить формат изображения в полноэкранном режиме , хуже производительность) + Использовать VSync (повысить формат изображения в полноэкранном режиме , хуже производительность) - Visibility - Прозрачность + Прозрачность - Low Performance - Минимальная производительность + Минимальная производительность YACReaderOptionsDialog - + Save Сохранить - Use hardware acceleration (restart needed) - Использовать аппаратное ускорение (Требуется перезагрузка) + Использовать аппаратное ускорение (Требуется перезагрузка) - + Cancel Отмена - + Shortcuts Горячие клавиши - + Edit shortcuts Редактировать горячие клавиши + + YACReaderSearchLineEdit + + + type to search + Начать поиск + + YACReaderSlider @@ -1584,23 +4204,23 @@ YACReaderTranslator - + clear очистить - + Service not available Сервис недоступен - - + + Translation Перевод - + YACReader translator Переводчик YACReader diff --git a/YACReader/yacreader_tr.ts b/YACReader/yacreader_tr.ts index 105ce7f30..05e874c7b 100644 --- a/YACReader/yacreader_tr.ts +++ b/YACReader/yacreader_tr.ts @@ -9,6 +9,196 @@ Hiçbiri + + AddLabelDialog + + + Label name: + Etiket adı: + + + + Choose a color: + Renk seçiniz: + + + + accept + kabul et + + + + cancel + vazgeç + + + + AddLibraryDialog + + + Comics folder : + Çizgi roman klasörü : + + + + Library name : + Kütüphane adı : + + + + Add + Ekle + + + + Cancel + Vazgeç + + + + Add an existing library + Kütüphaneye ekle + + + + ApiKeyDialog + + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Comic Vine'a bağlanmadan önce kendi API anahtarınıza ihtiyacınız var. Lütfen <a href="http://www.comicvine.com/api/">buradan</a> ücretsiz bir tane edinin + + + + Paste here your Comic Vine API key + Comic Vine API anahtarınızı buraya yapıştırın + + + + Accept + Kabul et + + + + Cancel + Vazgeç + + + + AppearanceTabWidget + + + Color scheme + Renk şeması + + + + System + Sistem + + + + Light + Işık + + + + Dark + Karanlık + + + + Custom + Gelenek + + + + Remove + Kaldırmak + + + + Remove this user-imported theme + Kullanıcı tarafından içe aktarılan bu temayı kaldır + + + + Light: + Işık: + + + + Dark: + Karanlık: + + + + Custom: + Kişisel: + + + + Import theme... + Temayı içe aktar... + + + + Theme + Tema + + + + Theme editor + Tema düzenleyici + + + + Open Theme Editor... + Tema Düzenleyiciyi Aç... + + + + Theme editor error + Tema düzenleyici hatası + + + + The current theme JSON could not be loaded. + Geçerli tema JSON yüklenemedi. + + + + Import theme + Temayı içe aktar + + + + JSON files (*.json);;All files (*) + JSON dosyaları (*.json);;Tüm dosyalar (*) + + + + Could not import theme from: +%1 + Tema şu kaynaktan içe aktarılamadı: +%1 + + + + Could not import theme from: +%1 + +%2 + Tema şu kaynaktan içe aktarılamadı: +%1 + +%2 + + + + Import failed + İçe aktarma başarısız oldu + + BookmarksDialog @@ -33,6 +223,200 @@ Son Sayfa + + ClassicComicsView + + + Hide comic flow + Çizgi roman akışını gizle + + + + ComicModel + + + yes + evet + + + + no + hayır + + + + Title + Başlık + + + + File Name + Dosya Adı + + + + Pages + Sayfalar + + + + Size + Boyut + + + + Read + Oku + + + + Current Page + Geçreli Sayfa + + + + Publication Date + Yayın Tarihi + + + + Rating + Reyting + + + + Series + Seri + + + + Volume + Hacim + + + + Story Arc + Hikaye Arkı + + + + ComicVineDialog + + + skip + geç + + + + back + geri + + + + next + sonraki + + + + search + ara + + + + close + kapat + + + + + comic %1 of %2 - %3 + çizgi roman %1 / %2 - %3 + + + + + + Looking for volume... + Sayılar aranıyor... + + + + %1 comics selected + %1 çizgi roman seçildi + + + + Error connecting to ComicVine + ComicVine sitesine bağlanılırken hata + + + + + Retrieving tags for : %1 + %1 için etiketler alınıyor + + + + Retrieving volume info... + Sayı bilgileri alınıyor... + + + + Looking for comic... + Çizgi romanlar aranıyor... + + + + ContinuousPageWidget + + + Loading page %1 + %1 sayfası yükleniyor + + + + CreateLibraryDialog + + + Comics folder : + Çizgi roman klasörü : + + + + Library Name : + Kütüphane Adı : + + + + Create + Oluştur + + + + Cancel + Vazgeç + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Yeni kütüphanenin oluşturulması birkaç dakika sürecek. + + + + Create new library + Yeni kütüphane oluştur + + + + Path not found + Dizin bulunamadı + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + Seçilen dizine yazma iznimiz yok yazma izni olduğundan emin ol + + EditShortcutsDialog @@ -51,16 +435,134 @@ Kısayol oyarları - + Shortcut in use Kısayol kullanımda - + The shortcut "%1" is already assigned to other function "%1" kısayolu bir başka işleve zaten atanmış + + EmptyFolderWidget + + + This folder doesn't contain comics yet + Bu klasör henüz çizgi roman içermiyor + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + Bu etiket henüz çizgi roman içermiyor + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + Bu okuma listesi henüz çizgi roman içermiyor + + + + EmptySpecialListWidget + + + No favorites + Favoriler boş + + + + You are not reading anything yet, come on!! + Henüz bir şey okumuyorsun, hadi ama! + + + + There are no recent comics! + Yeni çizgi roman yok! + + + + ExportComicsInfoDialog + + + Output file : + Çıkış dosyası : + + + + Create + Oluştur + + + + Cancel + Vazgeç + + + + Export comics info + Çizgi roman bilgilerini göster + + + + Destination database name + Hedef adı + + + + Problem found while writing + Yazma sırasında bir problem oldu + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Seçilen dizine yazma iznimiz yok yazma izni olduğundan emin ol + + + + ExportLibraryDialog + + + Output folder : + Çıktı klasörü : + + + + Create + Oluştur + + + + Cancel + Vazgeç + + + + Create covers package + Kapak paketi oluştur + + + + Problem found while writing + Yazma sırasında bir problem oldu + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Seçilen dizine yazma iznimiz yok yazma izni olduğundan emin ol + + + + Destination directory + Hedef dizin + + FileComic @@ -116,1266 +618,3466 @@ GoToFlowToolBar - + Page : Sayfa : + + GridComicsView + + + Show info + Bilgi göster + + HelpAboutDialog - + Help Yardım - + System info - + Sistem bilgisi - + About Hakkında - LogWindow + ImportComicsInfoDialog - - Log window - Günlük penceresi + + Import comics info + Çizgi roman bilgilerini çıkart - - &Pause - &Duraklat + + Info database location : + Bilgi veritabanı konumu : - - &Save - &Kaydet + + Import + Çıkart - - C&lear - &Temizle + + Cancel + Vazgeç - - &Copy - &Kopyala + + Comics info file (*.ydb) + Çizgi roman bilgi dosyası (*.ydb) + + + ImportLibraryDialog - - Level: - + + Library Name : + Kütüphane Adı : - - &Auto scroll - &Otomatik kaydır + + Package location : + Paket konumu : - - - MainWindowViewer - Help - Yardım + + Destination folder : + Hedef klasör : - Save - Kaydet + + Unpack + Paketten çıkar - &File - &Dosya + + Cancel + Vazgeç - &Next - &İleri + + Extract a catalog + Katalog ayıkla - &Open - &Aç + + Compresed library covers (*.clc) + Sıkıştırılmış kütüphane kapakları (*.clc) + + + ImportWidget - Close - Kapat + + stop + dur + + + + Some of the comics being added... + Bazı çizgi romanlar önceden eklenmiş... + + + + Importing comics + önemli çizgi romanlar + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderKütüphane şu anda yeni bir kütüphane oluşturuyor</p><p>Kütüphanenin oluşturulması birkaç dakika alacak.</p> + + + + Updating the library + Kütüphaneyi güncelle + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>Kütüphane güncelleniyor</p><p>Güncellemeyi daha sonra iptal edebilirsin.</p> + + + + Upgrading the library + Kütüphane güncelleniyor + + + + <p>The current library is being upgraded, please wait.</p> + <p>Mevcut kütüphane güncelleniyor, lütfen bekleyin.</p> + + + + Scanning the library + Kütüphaneyi taramak + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>Geçerli kitaplık, eski XML meta veri bilgileri için taranıyor.</p><p>Bu yalnızca bir kez gereklidir ve yalnızca kitaplığın YACReaderLibrary 9.8.2 veya daha eski bir sürümle oluşturulmuş olması durumunda gereklidir.</p> + + + + LibraryWindow + + + YACReader Library + YACReader Kütüphane + + + + + + comic + komik + + + + + + manga + manga t?r? + + + + + + western manga (left to right) + Batı mangası (soldan sağa) + + + + + + web comic + web çizgi romanı + + + + + + 4koma (top to botom) + 4koma (yukarıdan aşağıya) + + + + + + + Set type + Türü ayarla + + + + Library + Kütüphane + + + + Folder + Klasör + + + + Comic + Çizgi roman + + + + Upgrade failed + Yükseltme başarısız oldu + + + + There were errors during library upgrade in: + Kütüphane yükseltmesi sırasında hatalar oluştu: + + + + Update needed + Güncelleme gerekli + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Bu kütüphane YACReaderKütüphabenin bir önceki versiyonun oluşturulmuş, güncellemeye ihtiyacın var. Şimdi güncellemek ister misin ? + + + + Download new version + Yeni versiyonu indir + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Bu kütüphane YACRKütüphanenin üst bir versiyonunda oluşturulmu. Yeni versiyonu indirmek ister misiniz ? + + + + + Library not available + Kütüphane ulaşılabilir değil + + + + Library '%1' is no longer available. Do you want to remove it? + Kütüphane '%1'ulaşılabilir değil. Kaldırmak ister misin? + + + + Old library + Eski kütüphane + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Kütüphane '%1 YACRKütüphanenin eski bir sürümünde oluşturulmuş, Kütüphaneyi yeniden oluşturmak ister misin? + + + + + Copying comics... + Çizgi romanlar kopyalanıyor... + + + + + Moving comics... + Çizgi romanlar taşınıyor... + + + + Add new folder + Yeni klasör ekle + + + + Folder name: + Klasör adı: + + + + No folder selected + Hiçbir klasör seçilmedi + + + + Please, select a folder first + Lütfen, önce bir klasör seçiniz + + + + Error in path + Yolda hata + + + + There was an error accessing the folder's path + Klasörün yoluna erişilirken hata oluştu + + + + Delete folder + Klasörü sil + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + Seçilen klasör ve tüm içeriği diskinizden silinecek. Emin misin? + + + + + Unable to delete + Silinemedi + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Seçili klasörleri silmeye çalışırken bir sorun oluştu. Lütfen yazma izinlerini kontrol edin ve herhangi bir uygulamanın bu klasörleri veya içerdiği dosyalardan herhangi birini kullandığından emin olun. + + + + Add new reading lists + Yeni okuma listeleri ekle + + + + + List name: + Liste adı: + + + + Delete list/label + Listeyi/Etiketi sil + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + Seçilen öğe silinecek, çizgi romanlarınız veya klasörleriniz diskinizden SİLİNMEYECEKTİR. Emin misin? + + + + Rename list name + Listeyi yeniden adlandır + + + + Open folder... + Dosyayı aç... + + + + Update folder + Klasörü güncelle + + + + Rescan library for XML info + XML bilgisi için kitaplığı yeniden tarayın + + + + Set as uncompleted + Tamamlanmamış olarak ayarla + + + + Set as completed + Tamamlanmış olarak ayarla + + + + Set as read + Okundu olarak işaretle + + + + + Set as unread + Hepsini okunmadı işaretle + + + + Set custom cover + Özel kapak ayarla + + + + Delete custom cover + Özel kapağı sil + + + + Save covers + Kapakları kaydet + + + + You are adding too many libraries. + Çok fazla kütüphane ekliyorsunuz. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Çok fazla kütüphane ekliyorsunuz. + +Muhtemelen üst düzey çizgi roman klasörünüzde yalnızca bir kütüphaneye ihtiyacınız vardır, sol kenar çubuğundaki klasörler bölümünü kullanarak herhangi bir alt klasöre göz atabilirsiniz. + +YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütüphane sayısını düşük tutmalısınız. + + + + + YACReader not found + YACReader bulunamadı + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader bulunamadı. YACReader, YACReaderLibrary ile aynı klasöre kurulmalıdır. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader bulunamadı. YACReader kurulumunuzda bir sorun olabilir. + + + + Error + Hata + + + + Error opening comic with third party reader. + Çizgi roman üçüncü taraf okuyucuyla açılırken hata oluştu. + + + + Library not found + Kütüphane bulunamadı + + + + The selected folder doesn't contain any library. + Seçilen dosya kütüphanede yok. + + + + Are you sure? + Emin misin? + + + + Do you want remove + Kaldırmak ister misin + + + + library? + kütüphane? + + + + Remove and delete metadata + Metadata'yı kaldır ve sil + + + + Library info + Kütüphane bilgisi + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Seçilen çizgi romanlar silinmeye çalışılırken bir sorun oluştu. Lütfen seçilen dosyalarda veya klasörleri içeren yazma izinlerini kontrol edin. + + + + Assign comics numbers + Çizgi roman numaraları ata + + + + Assign numbers starting in: + Şunlardan başlayarak numaralar ata: + + + + Invalid image + Geçersiz resim + + + + The selected file is not a valid image. + Seçilen dosya geçerli bir resim değil. + + + + Error saving cover + Kapak kaydedilirken hata oluştu + + + + There was an error saving the cover image. + Kapak resmi kaydedilirken bir hata oluştu. + + + + Error creating the library + Kütüphane oluşturma sorunu + + + + Error updating the library + Kütüphane güncelleme sorunu + + + + Error opening the library + Haa kütüphanesini aç + + + + Delete comics + Çizgi romanları sil + + + + All the selected comics will be deleted from your disk. Are you sure? + Seçilen tüm çizgi romanlar diskten silinecek emin misin ? + + + + Remove comics + Çizgi romanları kaldır + + + + Comics will only be deleted from the current label/list. Are you sure? + Çizgi romanlar yalnızca mevcut etiketten/listeden silinecektir. Emin misin? + + + + Library name already exists + Kütüphane ismi zaten alınmış + + + + There is another library with the name '%1'. + Bu başka bir kütüphanenin adı '%1'. + + + + LibraryWindowActions + + + Create a new library + Yeni kütüphane oluştur + + + + Open an existing library + Çıkış kütüphanesini aç + + + + + Export comics info + Çizgi roman bilgilerini göster + + + + + Import comics info + Çizgi roman bilgilerini çıkart + + + + Pack covers + Paket kapakları + + + + Pack the covers of the selected library + Kütüphanede ki kapakları paketle + + + + Unpack covers + Kapakları aç + + + + Unpack a catalog + Kataloğu çkart + + + + Update library + Kütüphaneyi güncelle + + + + Update current library + Kütüphaneyi güncelle + + + + Rename library + Kütüphaneyi yeniden adlandır + + + + Rename current library + Kütüphaneyi adlandır + + + + Remove library + Kütüphaneyi sil + + + + Remove current library from your collection + Kütüphaneyi koleksiyonundan kaldır + + + + Rescan library for XML info + XML bilgisi için kitaplığı yeniden tarayın + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Komik dosyalara gömülü XML bilgilerini bulmaya çalışır. Bunu yalnızca kitaplık 9.8.2 veya önceki sürümlerle oluşturulmuşsa veya XML bilgilerini dosyalara eklemek için üçüncü taraf yazılım kullanıyorsanız yapmanız gerekir. + + + + Show library info + Kitaplık bilgilerini göster + + + + Show information about the current library + Geçerli kitaplık hakkındaki bilgileri göster + + + + Open current comic + Seçili çizgi romanı aç + + + + Open current comic on YACReader + YACReader'ı geçerli çizgi roman okuyucsu seç + + + + Save selected covers to... + Seçilen kapakları şuraya kaydet... + + + + Save covers of the selected comics as JPG files + Seçilen çizgi romanların kapaklarını JPG dosyaları olarak kaydet + + + + + Set as read + Okundu olarak işaretle + + + + Set comic as read + Çizgi romanı okundu olarak işaretle + + + + + Set as unread + Hepsini okunmadı işaretle + + + + Set comic as unread + Çizgi Romanı okunmadı olarak seç + + + + + manga + manga t?r? + + + + Set issue as manga + Sayıyı manga olarak ayarla + + + + + comic + komik + + + + Set issue as normal + Sayıyı normal olarak ayarla + + + + western manga + batı mangası + + + + Set issue as western manga + Konuyu western mangası olarak ayarla + + + + + web comic + web çizgi romanı + + + + Set issue as web comic + Sorunu web çizgi romanı olarak ayarla + + + + + yonkoma + d?rt panelli + + + + Set issue as yonkoma + Sorunu yonkoma olarak ayarla + + + + Show/Hide marks + Altçizgileri aç/kapa + + + + Show or hide read marks + Okundu işaretlerini göster yada gizle + + + + Show/Hide recent indicator + Son göstergeyi Göster/Gizle + + + + Show or hide recent indicator + Son göstergeyi göster veya gizle + + + + + Fullscreen mode on/off + Tam ekran modu açık/kapalı + + + + Help, About YACReader + YACReader hakkında yardım ve bilgi + + + + Add new folder + Yeni klasör ekle + + + + Add new folder to the current library + Geçerli kitaplığa yeni klasör ekle + + + + Delete folder + Klasörü sil + + + + Delete current folder from disk + Geçerli klasörü diskten sil + + + + Select root node + Kökü seçin + + + + Expand all nodes + Tüm düğümleri büyüt + + + + Collapse all nodes + Tüm düğümleri kapat + + + + Show options dialog + Ayarları göster + + + + Show comics server options dialog + Çizgi romanların server ayarlarını göster + + + + + Change between comics views + Çizgi roman görünümleri arasında değiştir + + + + Open folder... + Dosyayı aç... + + + + Set as uncompleted + Tamamlanmamış olarak ayarla + + + + Set as completed + Tamamlanmış olarak ayarla + + + + Set custom cover + Özel kapak ayarla + + + + Delete custom cover + Özel kapağı sil + + + + western manga (left to right) + Batı mangası (soldan sağa) + + + + Open containing folder... + Klasör açılıyor... + + + + Reset comic rating + Çizgi roman reytingini sıfırla + + + + Select all comics + Tüm çizgi romanları seç + + + + Edit + Düzen + + + + Assign current order to comics + Geçerli sırayı çizgi romanlara ata + + + + Update cover + Kapağı güncelle + + + + Delete selected comics + Seçili çizgi romanları sil + + + + Delete metadata from selected comics + Seçilen çizgi romanlardan meta verileri sil + + + + Download tags from Comic Vine + Etiketleri Comic Vine sitesinden indir + + + + Focus search line + Arama satırına odaklan + + + + Focus comics view + Çizgi roman görünümüne odaklanın + + + + Edit shortcuts + Kısayolları düzenle + + + + &Quit + &Çıkış + + + + Update folder + Klasörü güncelle + + + + Update current folder + Geçerli klasörü güncelle + + + + Scan legacy XML metadata + Eski XML meta verilerini tarayın + + + + Add new reading list + Yeni okuma listesi ekle + + + + Add a new reading list to the current library + Geçerli kitaplığa yeni bir okuma listesi ekle + + + + Remove reading list + Okuma listesini kaldır + + + + Remove current reading list from the library + Geçerli okuma listesini kütüphaneden kaldır + + + + Add new label + Yeni etiket ekle + + + + Add a new label to this library + Bu kitaplığa yeni bir etiket ekle + + + + Rename selected list + Seçilen listeyi yeniden adlandır + + + + Rename any selected labels or lists + Seçilen etiketleri ya da listeleri yeniden adlandır + + + + Add to... + Şuraya ekle... + + + + Favorites + Favoriler + + + + Add selected comics to favorites list + Seçilen çizgi romanları favoriler listesine ekle + + + + LocalComicListModel + + + file name + dosya adı + + + + LogWindow + + Log window + Günlük penceresi + + + &Pause + &Duraklat + + + &Save + &Kaydet + + + C&lear + &Temizle + + + &Copy + &Kopyala + + + &Auto scroll + &Otomatik kaydır + + + + MainWindowViewer + + Help + Yardım + + + Save + Kaydet + + + &File + &Dosya + + + &Next + &İleri + + + &Open + &Aç + + + Close + Kapat Open Comic Çizgi Romanı Aç - Go To - Git + Go To + Git + + + Open image folder + Resim dosyasınıaç + + + Set bookmark + Yer imi yap + + + page_%1.jpg + sayfa_%1.jpg + + + Switch to double page mode + Çift sayfa moduna geç + + + Save current page + Geçerli sayfayı kaydet + + + Double page mode + Çift sayfa modu + + + Switch Magnifying glass + Büyüteç + + + Open Folder + Dosyayı Aç + + + Comic files + Çizgi Roman Dosyaları + + + Go to previous page + Önceki sayfaya dön + + + Open a comic + Çizgi romanı aç + + + Image files (*.jpg) + Resim dosyaları (*.jpg) + + + Next Comic + Sırada ki çizgi roman + + + Fit Width + Uygun Genişlik + + + Options + Ayarlar + + + Show Info + Bilgiyi göster + + + Open folder + Dosyayı aç + + + Go to page ... + Sayfata git... + + + Fit image to width + Görüntüyü sığdır + + + &Previous + &Geri + + + Go to next page + Sonra ki sayfaya geç + + + Show keyboard shortcuts + Klavye kısayollarını göster + + + There is a new version available + Yeni versiyon mevcut + + + Open next comic + Sıradaki çizgi romanı aç + + + Show bookmarks + Yer imlerini göster + + + Open previous comic + Önceki çizgi romanı aç + + + Rotate image to the left + Sayfayı sola yatır + + + Fit image to height + Uygun yüksekliğe getir + + + Show the bookmarks of the current comic + Bu çizgi romanın yer imlerini göster + + + Show Dictionary + Sözlüğü göster + + + YACReader options + YACReader ayarları + + + Help, About YACReader + YACReader hakkında yardım ve bilgi + + + Show go to flow + Akışı göster + + + Previous Comic + Önce ki çizgi roman + + + Show full size + Tam erken + + + Magnifying glass + Büyüteç + + + General + Genel + + + Set a bookmark on the current page + Sayfayı yer imi olarak ayarla + + + Do you want to download the new version? + Yeni versiyonu indirmek ister misin ? + + + Rotate image to the right + Sayfayı sağa yator + + + Always on top + Her zaman üstte + + + New instance + Yeni örnek + + + Open latest comic + En son çizgi romanı aç + + + Open the latest comic opened in the previous reading session + Önceki okuma oturumunda açılan en son çizgi romanı aç + + + Clear + Temizle + + + Clear open recent list + Son açılanlar listesini temizle + + + Fit Height + Yüksekliğe Sığdır + + + Fit to page + Sayfaya sığdır + + + Reset zoom + Yakınlaştırmayı sıfırla + + + Show zoom slider + Yakınlaştırma çubuğunu göster + + + Zoom+ + Yakınlaştır + + + Zoom- + Uzaklaştır + + + Double page manga mode + Çift sayfa manga kipi + + + Reverse reading order in double page mode + Çift sayfa kipinde ters okuma sırası + + + Edit shortcuts + Kısayolları düzenle + + + Open recent + Son dosyaları aç + + + File + Dosya + + + Edit + Düzen + + + View + Görünüm + + + Go + Git + + + Window + Pencere + + + Comics + Çizgi Roman + + + Toggle fullscreen mode + Tam ekran kipini aç/kapat + + + Hide/show toolbar + Araç çubuğunu göster/gizle + + + Size up magnifying glass + Büyüteci büyüt + + + Size down magnifying glass + Büyüteci küçült + + + Zoom in magnifying glass + Büyüteci yakınlaştır + + + Zoom out magnifying glass + Büyüteci uzaklaştır + + + Magnifiying glass + Büyüteç + + + Toggle between fit to width and fit to height + Genişliğe sığdır ile yüksekliğe sığdır arasında geçiş yap + + + Page adjustement + Sayfa ayarı + + + Autoscroll down + Otomatik aşağı kaydır + + + Autoscroll up + Otomatik yukarı kaydır + + + Autoscroll forward, horizontal first + Otomatik ileri kaydır, önce yatay + + + Autoscroll backward, horizontal first + Otomatik geri kaydır, önce yatay + + + Autoscroll forward, vertical first + Otomatik ileri kaydır, önce dikey + + + Autoscroll backward, vertical first + Otomatik geri kaydır, önce dikey + + + Move down + Aşağı git + + + Move up + Yukarı git + + + Move left + Sola git + + + Move right + Sağa git + + + Go to the first page + İlk sayfaya git + + + Go to the last page + En son sayfaya git + + + Reading + Okuma + + + Remind me in 14 days + 14 gün içinde hatırlat + + + Not now + Şimdi değil + + + + NoLibrariesWidget + + + You don't have any libraries yet + Henüz bir kütüphaneye sahip değilsin + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Yeni bir kütüphane oluşturabilmeniçin kütüphane</p><p>No olvides que puedes usar YACReader como una aplicación independiente para leer los cómics en tu ordenador.</p> + + + + create your first library + İlk kütüphaneni oluştur + + + + add an existing one + Var olan bir tane ekle + + + + NoSearchResultsWidget + + + No results + Sonuç yok + + + + OptionsDialog + + + Gamma + Gama + + + + Reset + Yeniden başlat + + + + My comics path + Çizgi Romanlarım + + + + Scaling + Ölçeklendirme + + + + Scaling method + Ölçeklendirme yöntemi + + + + Nearest (fast, low quality) + En yakın (hızlı, düşük kalite) + + + + Bilinear + Çift doğrusal + + + + Lanczos (better quality) + Lanczos (daha kaliteli) + + + + Image adjustment + Resim ayarları + + + + "Go to flow" size + Akış görünümüne git + + + + Choose + Seç + + + + Image options + Sayfa ayarları - Open image folder - Resim dosyasınıaç + + Contrast + Kontrast - Set bookmark - Yer imi yap + + + Libraries + Kütüphaneler - page_%1.jpg - sayfa_%1.jpg + + Comic Flow + Çizgi Roman Akışı - Switch to double page mode - Çift sayfa moduna geç + + Grid view + Izgara görünümü - Save current page - Geçerli sayfayı kaydet + + + Appearance + Dış görünüş - Double page mode - Çift sayfa modu + + + Options + Ayarlar - Switch Magnifying glass - Büyüteç + + + Language + Dil - Open Folder - Dosyayı Aç + + + Application language + Uygulama dili - Comic files - Çizgi Roman Dosyaları + + + System default + Sistem varsayılanı - Go to previous page - Önceki sayfaya dön + + Tray icon settings (experimental) + Tepsi simgesi ayarları (deneysel) - Open a comic - Çizgi romanı aç + + Close to tray + Tepsiyi kapat - Image files (*.jpg) - Resim dosyaları (*.jpg) + + Start into the system tray + Sistem tepsisinde başlat - Next Comic - Sırada ki çizgi roman + + Edit Comic Vine API key + Comic Vine API anahtarını düzenle - Fit Width - Uygun Genişlik + + Comic Vine API key + Comic Vine API anahtarı - Options - Ayarlar + + ComicInfo.xml legacy support + ComicInfo.xml eski desteği - Show Info - Bilgiyi göster + + Import metadata from ComicInfo.xml when adding new comics + Yeni çizgi roman eklerken meta verileri ComicInfo.xml'den içe aktarın - Open folder - Dosyayı aç + + Consider 'recent' items added or updated since X days ago + X gün öncesinden bu yana eklenen veya güncellenen 'en son' öğeleri göz önünde bulundurun - Go to page ... - Sayfata git... + + Third party reader + Üçüncü taraf okuyucu - Fit image to width - Görüntüyü sığdır + + Write {comic_file_path} where the path should go in the command + Komutta yolun gitmesi gereken yere {comic_file_path} yazın + + + + + Clear + Temizle + + + + Update libraries at startup + Başlangıçta kitaplıkları güncelleyin + + + + Try to detect changes automatically + Değişiklikleri otomatik olarak algılamayı deneyin + + + + Update libraries periodically + Kitaplıkları düzenli aralıklarla güncelleyin + + + + Interval: + Aralık: + + + + 30 minutes + 30 dakika + + + + 1 hour + 1 saat + + + + 2 hours + 2 saat + + + + 4 hours + 4 saat + + + + 8 hours + 8 saat + + + + 12 hours + 12 saat + + + + daily + günlük + + + + Update libraries at certain time + Kitaplıkları belirli bir zamanda güncelle + + + + Time: + Zaman: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + UYARI! Kütüphane güncellemeleri sırasında veritabanına yazma işlemi devre dışı bırakılır! +Uygulamayı aktif olarak kullanırken güncelleme planlamayın. +Otomatik güncellemeler sırasında uygulama, güncelleme bitene kadar bazı eylemleri engelleyecektir. +Otomatik güncellemeyi durdurmak için Kitaplıklar başlığının yanındaki yükleme göstergesine dokunun. + + + + Modifications detection + Değişiklik tespiti + + + + Compare the modified date of files when updating a library (not recommended) + Kitaplığı güncellerken dosyaların değiştirilme tarihini karşılaştırın (önerilmez) + + + + Enable background image + Arka plan resmini etkinleştir + + + + Opacity level + Matlık düzeyi + + + + Blur level + Bulanıklık düzeyi + + + + Use selected comic cover as background + Seçilen çizgi roman kapanığı arka plan olarak kullan + + + + Restore defautls + Varsayılanları geri yükle + + + + Background + Arka plan + + + + Display continue reading banner + Okuma devam et bannerını göster + + + + Display current comic banner + Mevcut çizgi roman banner'ını görüntüle + + + + Continue reading + Okumaya devam et + + + + Comics directory + Çizgi roman konumu + + + + Background color + Arka plan rengi + + + + Page Flow + Sayfa akışı + + + + + General + Genel + + + + Brightness + Parlaklık + + + + + Restart is needed + Yeniden başlatılmalı + + + + Quick Navigation Mode + Hızlı Gezinti Kipi + + + + Display + Görüntülemek + + + + Show time in current page information label + Geçerli sayfa bilgisi etiketinde zamanı göster + + + + Scroll behaviour + Kaydırma davranışı + + + + Disable scroll animations and smooth scrolling + Kaydırma animasyonlarını ve düzgün kaydırmayı devre dışı bırakın + + + + Do not turn page using scroll + Kaydırmayı kullanarak sayfayı çevirmeyin + + + + Use single scroll step to turn page + Sayfayı çevirmek için tek kaydırma adımını kullanın + + + + Mouse mode + Fare modu + + + + Only Back/Forward buttons can turn pages + Yalnızca Geri/İleri düğmeleri sayfaları çevirebilir + + + + Use the Left/Right buttons to turn pages. + Sayfaları çevirmek için Sol/Sağ tuşlarını kullanın. + + + + Click left or right half of the screen to turn pages. + Sayfaları çevirmek için ekranın sol veya sağ yarısına tıklayın. + + + + Disable mouse over activation + Etkinleştirme üzerinde fareyi devre dışı bırak + + + + Fit options + Sığdırma seçenekleri + + + + Enlarge images to fit width/height + Genişliğe/yüksekliği sığmaları için resimleri genişlet + + + + Double Page options + Çift Sayfa seçenekleri + + + + Show covers as single page + Kapakları tek sayfa olarak göster + + + + PropertiesDialog + + + General info + Genel bilgi + + + + Plot + Argumento + + + + Authors + Yazarlar + + + + Publishing + Yayın + + + + Notes + Notlar + + + + Cover page + Kapak sayfası + + + + Load previous page as cover + Önceki sayfayı kapak olarak yükle + + + + Load next page as cover + Sonraki sayfayı kapak olarak yükle + + + + Reset cover to the default image + Kapağı varsayılan görüntüye sıfırla + + + + Load custom cover image + Özel kapak resmini yükle + + + + Series: + Seriler: + + + + Title: + Başlık: + + + + + + of: + ile ilgili: + + + + Issue number: + Yayın numarası: + + + + Volume: + Cilt: + + + + Arc number: + Ark numarası: + + + + Story arc: + Hiakye: + + + + alt. number: + alternatif sayı: + + + + Alternate series: + Alternatif seri: + + + + Series Group: + Seri Grubu: + + + + Genre: + Tür: + + + + Size: + Boyut: + + + + Writer(s): + Yazarlar: + + + + Penciller(s): + Çizenler: + + + + Inker(s): + Mürekkep(ler): + + + + Colorist(s): + Renklendiren: + + + + Letterer(s): + Mesaj(lar): + + + + Cover Artist(s): + Kapak artisti: + + + + Editor(s): + Editör(ler): + + + + Imprint: + Künye: + + + + Day: + Gün: + + + + Month: + Ay: + + + + Year: + Yıl: + + + + Publisher: + Yayıncı: + + + + Format: + Formato: + + + + Color/BW: + Renk/BW: + + + + Age rating: + Yaş sınırı: - &Previous - &Geri + + Type: + Tip: - Go to next page - Sonra ki sayfaya geç + + Language (ISO): + Dil (ISO): - Show keyboard shortcuts - Klavye kısayollarını göster + + Synopsis: + Özet: - There is a new version available - Yeni versiyon mevcut + + Characters: + Karakterler: - Open next comic - Sıradaki çizgi romanı aç + + Teams: + Takımlar: - Show bookmarks - Yer imlerini göster + + Locations: + Konumlar: - Open previous comic - Önceki çizgi romanı aç + + Main character or team: + Ana karakter veya takım: - Rotate image to the left - Sayfayı sola yatır + + Review: + Gözden geçirmek: - Fit image to height - Uygun yüksekliğe getir + + Notes: + Notlar: - Show the bookmarks of the current comic - Bu çizgi romanın yer imlerini göster + + Tags: + Etiketler: - Show Dictionary - Sözlüğü göster + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine bağlantısı: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> görüntüle </a> - YACReader options - YACReader ayarları + + Not found + Bulunamadı - Help, About YACReader - YACReader hakkında yardım ve bilgi + + Comic not found. You should update your library. + Çizgi roman bulunamadı. Kütüphaneyi güncellemelisin. - Show go to flow - Akışı göster + + Edit comic information + Çizgi roman bilgisini düzenle - Previous Comic - Önce ki çizgi roman + + Edit selected comics information + Seçilen çizgi roman bilgilerini düzenle - Show full size - Tam erken + + Invalid cover + Geçersiz kapak - Magnifying glass - Büyüteç + + The image is invalid. + Resim geçersiz. + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer, YACReaderLibrary'nin başsız (gui yok) sürümüdür. + +Bu uygulama kalıcı ayarları destekler, bunları ayarlamak için bu dosyayı düzenleyin %1 +Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md adresindeki belgelere bakın. + + + QObject - General - Genel + + 7z lib not found + 7z lib bulunamadı - Set a bookmark on the current page - Sayfayı yer imi olarak ayarla + + unable to load 7z lib from ./utils + ./utils içinden 7z lib yüklenemedi - Do you want to download the new version? - Yeni versiyonu indirmek ister misin ? + + Trace + İz - Rotate image to the right - Sayfayı sağa yator + + Debug + Hata ayıkla - Always on top - Her zaman üstte + + Info + Bilgi - New instance - Yeni örnek + + Warning + Uyarı - Open latest comic - En son çizgi romanı aç + + Error + Hata - Open the latest comic opened in the previous reading session - Önceki okuma oturumunda açılan en son çizgi romanı aç + + Fatal + Ölümcül - Clear - Temizle + + Select custom cover + Özel kapak seçin - Clear open recent list - Son açılanlar listesini temizle + + Images (%1) + Resimler (%1) - Fit Height - Yüksekliğe Sığdır + + The file could not be read or is not valid JSON. + Dosya okunamadı veya geçerli bir JSON değil. - Fit to page - Sayfaya sığdır + + This theme is for %1, not %2. + Bu tema %2 için değil, %1 içindir. - Reset zoom - Yakınlaştırmayı sıfırla + + Libraries + Kütüphaneler - Show zoom slider - Yakınlaştırma çubuğunu göster + + Folders + Klasör - Zoom+ - Yakınlaştır + + Reading Lists + Okuma Listeleri + + + QsLogging::LogWindowModel - Zoom- - Uzaklaştır + Time + Süre - Double page manga mode - Çift sayfa manga kipi + Level + Düzey - Reverse reading order in double page mode - Çift sayfa kipinde ters okuma sırası + Message + Mesaj + + + QsLogging::Window - Edit shortcuts - Kısayolları düzenle + &Pause + &Duraklat - Open recent - Son dosyaları aç + &Resume + &Sürdür - File - Dosya + Save log + Günlük kaydet - Edit - Düzen + Log file (*.log) + Günlük dosyası (*.log) + + + RenameLibraryDialog - View - Görünüm + + New Library Name : + Yeni Kütüphane Adı : - Go - Git + + Rename + Yeniden adlandır - Window - Pencere + + Cancel + Vazgeç - Comics - Çizgi Roman + + Rename current library + Kütüphaneyi adlandır + + + ScraperResultsPaginator - Toggle fullscreen mode - Tam ekran kipini aç/kapat + + Number of volumes found : %1 + Bulunan bölüm sayısı: %1 - Hide/show toolbar - Araç çubuğunu göster/gizle + + + page %1 of %2 + sayfa %1 / %2 - Size up magnifying glass - Büyüteci büyüt + + Number of %1 found : %2 + Sayı %1, bulunan : %2 + + + SearchSingleComic - Size down magnifying glass - Büyüteci küçült + + Please provide some additional information for this comic. + Lütfen bazı ek bilgiler sağlayın. - Zoom in magnifying glass - Büyüteci yakınlaştır + + Series: + Seriler: - Zoom out magnifying glass - Büyüteci uzaklaştır + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Tam eşleme aramasını kullanın. Addaki bazı sözcüklerle eşleşen ciltleri bulmak istiyorsanız devre dışı bırakın. + + + SearchVolume - Magnifiying glass - Büyüteç + + Please provide some additional information. + Lütfen bazı ek bilgiler sağlayın. - Toggle between fit to width and fit to height - Genişliğe sığdır ile yüksekliğe sığdır arasında geçiş yap + + Series: + Seriler: - Page adjustement - Sayfa ayarı + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Tam eşleme aramasını kullanın. Addaki bazı sözcüklerle eşleşen ciltleri bulmak istiyorsanız devre dışı bırakın. + + + SelectComic - Autoscroll down - Otomatik aşağı kaydır + + Please, select the right comic info. + Lütfen, doğru çizgi roman bilgisini seçin. - Autoscroll up - Otomatik yukarı kaydır + + comics + çizgi roman - Autoscroll forward, horizontal first - Otomatik ileri kaydır, önce yatay + + loading cover + kapak yükleniyor - Autoscroll backward, horizontal first - Otomatik geri kaydır, önce yatay + + loading description + açıklama yükleniyor - Autoscroll forward, vertical first - Otomatik ileri kaydır, önce dikey + + comic description unavailable + çizgi roman açıklaması mevcut değil + + + SelectVolume - Autoscroll backward, vertical first - Otomatik geri kaydır, önce dikey + + Please, select the right series for your comic. + Çizgi romanınız için doğru seriyi seçin. - Move down - Aşağı git + + Filter: + Filtre: - Move up - Yukarı git + + volumes + sayı - Move left - Sola git + + Nothing found, clear the filter if any. + Hiçbir şey bulunamadı, varsa filtreyi temizleyin. - Move right - Sağa git + + loading cover + kapak yükleniyor - Go to the first page - İlk sayfaya git + + loading description + açıklama yükleniyor - Go to the last page - En son sayfaya git + + volume description unavailable + cilt açıklaması kullanılamıyor + + + SeriesQuestion - Reading - Okuma + + You are trying to get information for various comics at once, are they part of the same series? + Aynı anda çeşitli çizgi romanlar için bilgi almaya çalışıyorsunuz, bunlar aynı serinin parçası mı? - Remind me in 14 days - 14 gün içinde hatırlat + + yes + evet - Not now - Şimdi değil + + no + hayır - OptionsDialog + ServerConfigDialog - - Gamma - Gama + + set port + Port Ayarla - - Reset - Yeniden başlat + + Server connectivity information + Sunucu bağlantı bilgileri - - My comics path - Çizgi Romanlarım + + Scan it! + Tara! - - Image adjustment - Resim ayarları + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader, iOS ve Android cihazlarda kullanılabilir.<br/>Bunu <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> veya <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a> için keşfedin. - - "Go to flow" size - Akış görünümüne git + + Choose an IP address + IP adresi seçin - - Choose - Seç + + Port + Liman - - Image options - Sayfa ayarları + + enable the server + erişilebilir server + + + ShortcutsDialog - - Contrast - Kontrast + Close + Kapat - - Options - Ayarlar + YACReader keyboard shortcuts + YACReader klavye kısayolları - - Comics directory - Çizgi roman konumu + Keyboard Shortcuts + Klavye Kısayolları + + + SortVolumeComics - - Background color - Arka plan rengi + + Please, sort the list of comics on the left until it matches the comics' information. + Lütfen, çizgi romanların bilgileriyle eşleşene kadar soldaki çizgi roman listesini sıralayın. - - Page Flow - Sayfa akışı + + sort comics to match comic information + çizgi roman bilgilerini eşleştirmek için çizgi romanları sıralayın - - General - Genel + + issues + sayı - - Brightness - Parlaklık + + remove selected comics + seçilen çizgi romanları kaldır - - Restart is needed - Yeniden başlatılmalı + + restore all removed comics + tüm seçilen çizgi romanları geri yükle + + + ThemeEditorDialog - - Quick Navigation Mode - Hızlı Gezinti Kipi + + Theme Editor + Tema Düzenleyici - - Display - + + + + + - - Show time in current page information label - + + - + - - - Scroll behaviour - + + i + Ben - - Disable scroll animations and smooth scrolling - + + Expand all + Tümünü genişlet - - Do not turn page using scroll - + + Collapse all + Tümünü daralt + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Kullanıcı arayüzünde seçilen değeri (macenta / geçişli / 0↔10) yanıp sönmek için basılı tutun. Sürümler orijinali geri yükler. + + + + Search… + Aramak… + + + + Light + Işık - - Use single scroll step to turn page - + + Dark + Karanlık - - Mouse mode - + + ID: + İD: - - Only Back/Forward buttons can turn pages - + + Display name: + Ekran adı: - - Use the Left/Right buttons to turn pages. - + + Variant: + Varyant: - - Click left or right half of the screen to turn pages. - + + Theme info + Tema bilgisi - - Disable mouse over activation - Etkinleştirme üzerinde fareyi devre dışı bırak + + Parameter + Parametre - - Fit options - Sığdırma seçenekleri + + Value + Değer - - Enlarge images to fit width/height - Genişliğe/yüksekliği sığmaları için resimleri genişlet + + Save and apply + Kaydet ve uygula - - Double Page options - Çift Sayfa seçenekleri + + Export to file... + Dosyaya aktar... - - Show covers as single page - Kapakları tek sayfa olarak göster + + Load from file... + Dosyadan yükle... - - - QObject - - 7z lib not found - 7z lib bulunamadı + + Close + Kapat - - unable to load 7z lib from ./utils - ./utils içinden 7z lib yüklenemedi + + Double-click to edit color + Rengi düzenlemek için çift tıklayın - - Trace - İz + + + + + + + true + doğru - - Debug - Hata ayıkla + + + + + false + YANLIŞ - - Info - Bilgi + + Double-click to toggle + Geçiş yapmak için çift tıklayın - - Warning - Uyarı + + Double-click to edit value + Değeri düzenlemek için çift tıklayın - - Error - Hata + + + + Edit: %1 + Düzenleme: %1 - - Fatal - Ölümcül + + Save theme + Temayı kaydet - - Select custom cover - + + + JSON files (*.json);;All files (*) + JSON dosyaları (*.json);;Tüm dosyalar (*) - - Images (%1) - + + Save failed + Kaydetme başarısız oldu - - - QsLogging::LogWindowModel - - Time - Süre + + Could not open file for writing: +%1 + Dosya yazmak için açılamadı: +%1 - - Level - Düzey + + Load theme + Temayı yükle - - Message - Mesaj + + + + Load failed + Yükleme başarısız oldu - - - QsLogging::Window - - &Pause - &Duraklat + + Could not open file: +%1 + Dosya açılamadı: +%1 - - &Resume - &Sürdür + + Invalid JSON: +%1 + Geçersiz JSON: +%1 - - Save log - Günlük kaydet + + Expected a JSON object. + Bir JSON nesnesi bekleniyordu. + + + TitleHeader - - Log file (*.log) - Günlük dosyası (*.log) + + SEARCH + ARA - ShortcutsDialog + UpdateLibraryDialog - Close - Kapat + + Updating.... + Güncelleniyor... - YACReader keyboard shortcuts - YACReader klavye kısayolları + + Cancel + Vazgeç - Keyboard Shortcuts - Klavye Kısayolları + + Update library + Kütüphaneyi güncelle Viewer - - + + Press 'O' to open comic. 'O'ya basarak aç. - + Cover! Kapak! - + Comic not found Çizgi roman bulunamadı - + Not found Bulunamadı - + Last page! Son sayfa! - + Loading...please wait! Yükleniyor... lütfen bekleyin! - + Error opening comic Çizgi roman açılırken hata - + CRC Error CRC Hatası - + Page not available! Sayfa bulunamadı! + + VolumeComicsModel + + + title + başlık + + + + VolumesModel + + + year + yıl + + + + issues + sayı + + + + publisher + yayıncı + + + + YACReader3DFlowConfigWidget + + + Presets: + Hazırlayan: + + + + Classic look + Klasik görünüm + + + + Stripe look + Şerit görünüm + + + + Overlapped Stripe look + Çakışan şerit görünüm + + + + Modern look + Modern görünüm + + + + Roulette look + Rulet görünüm + + + + Show advanced settings + Daha fazla ayar göster + + + + Custom: + Kişisel: + + + + View angle + Bakış açısı + + + + Position + Pozisyon + + + + Cover gap + Kapak boşluğu + + + + Central gap + Boş merkaz + + + + Zoom + Yakınlaş + + + + Y offset + Y dengesi + + + + Z offset + Z dengesi + + + + Cover Angle + Kapak Açısı + + + + Visibility + Görünülebilirlik + + + + Light + Işık + + + + Max angle + Maksimum açı + + + + Low Performance + Düşük Performans + + + + High Performance + Yüksek performans + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + VSync kullan + + + + Performance: + Performans: + + YACReader::MainWindowViewer - + &Open - &Aç + &Aç - + Open a comic - Çizgi romanı aç + Çizgi romanı aç - + New instance - Yeni örnek + Yeni örnek - + Open Folder - Dosyayı Aç + Dosyayı Aç - + Open image folder - Resim dosyasınıaç + Resim dosyasınıaç - + Open latest comic - En son çizgi romanı aç + En son çizgi romanı aç - + Open the latest comic opened in the previous reading session - Önceki okuma oturumunda açılan en son çizgi romanı aç + Önceki okuma oturumunda açılan en son çizgi romanı aç - + Clear - Temizle + Temizle - + Clear open recent list - Son açılanlar listesini temizle + Son açılanlar listesini temizle - + Save - Kaydet + Kaydet - + Save current page - Geçerli sayfayı kaydet + Geçerli sayfayı kaydet Previous Comic - Önce ki çizgi roman + Önce ki çizgi roman - - - + + + Open previous comic - Önceki çizgi romanı aç + Önceki çizgi romanı aç - + Next Comic - Sırada ki çizgi roman + Sırada ki çizgi roman - - - + + + Open next comic - Sıradaki çizgi romanı aç + Sıradaki çizgi romanı aç - + &Previous - &Geri + &Geri - - - + + + Go to previous page - Önceki sayfaya dön + Önceki sayfaya dön - + &Next - &İleri + &İleri - - - + + + Go to next page - Sonra ki sayfaya geç + Sonra ki sayfaya geç - + Fit Height - Yüksekliğe Sığdır + Yüksekliğe Sığdır - + Fit image to height - Uygun yüksekliğe getir + Uygun yüksekliğe getir - + Fit Width - Uygun Genişlik + Uygun Genişlik - + Fit image to width - Görüntüyü sığdır + Görüntüyü sığdır - + Show full size - Tam erken + Tam erken - + Fit to page - Sayfaya sığdır + Sayfaya sığdır + + + + Continuous scroll + Sürekli kaydırma + + + + Switch to continuous scroll mode + Sürekli kaydırma moduna geç - + Reset zoom - Yakınlaştırmayı sıfırla + Yakınlaştırmayı sıfırla - + Show zoom slider - Yakınlaştırma çubuğunu göster + Yakınlaştırma çubuğunu göster - + Zoom+ - Yakınlaştır + Yakınlaştır - + Zoom- - Uzaklaştır + Uzaklaştır - + Rotate image to the left - Sayfayı sola yatır + Sayfayı sola yatır - + Rotate image to the right - Sayfayı sağa yator + Sayfayı sağa yator - + Double page mode - Çift sayfa modu + Çift sayfa modu - + Switch to double page mode - Çift sayfa moduna geç + Çift sayfa moduna geç - + Double page manga mode - Çift sayfa manga kipi + Çift sayfa manga kipi - + Reverse reading order in double page mode - Çift sayfa kipinde ters okuma sırası + Çift sayfa kipinde ters okuma sırası - + Go To - Git + Git - + Go to page ... - Sayfata git... + Sayfata git... - + Options - Ayarlar + Ayarlar - + YACReader options - YACReader ayarları + YACReader ayarları - - + + Help - Yardım + Yardım - + Help, About YACReader - YACReader hakkında yardım ve bilgi + YACReader hakkında yardım ve bilgi - + Magnifying glass - Büyüteç + Büyüteç - + Switch Magnifying glass - Büyüteç + Büyüteç - + Set bookmark - Yer imi yap + Yer imi yap - + Set a bookmark on the current page - Sayfayı yer imi olarak ayarla + Sayfayı yer imi olarak ayarla - + Show bookmarks - Yer imlerini göster + Yer imlerini göster - + Show the bookmarks of the current comic - Bu çizgi romanın yer imlerini göster + Bu çizgi romanın yer imlerini göster - + Show keyboard shortcuts - Klavye kısayollarını göster + Klavye kısayollarını göster - + Show Info - Bilgiyi göster + Bilgiyi göster - + Close - Kapat + Kapat - + Show Dictionary - Sözlüğü göster + Sözlüğü göster - + Show go to flow - Akışı göster + Akışı göster - + Edit shortcuts - Kısayolları düzenle + Kısayolları düzenle - + &File - &Dosya + &Dosya - - + + Open recent - Son dosyaları aç + Son dosyaları aç - + File - Dosya + Dosya - + Edit - Düzen + Düzen - + View - Görünüm + Görünüm - + Go - Git + Git - + Window - Pencere + Pencere - - - + + + Open Comic - Çizgi Romanı Aç + Çizgi Romanı Aç - - - + + + Comic files - Çizgi Roman Dosyaları + Çizgi Roman Dosyaları - + Open folder - Dosyayı aç + Dosyayı aç - + page_%1.jpg - sayfa_%1.jpg + sayfa_%1.jpg - + Image files (*.jpg) - Resim dosyaları (*.jpg) + Resim dosyaları (*.jpg) + Comics - Çizgi Roman + Çizgi Roman Toggle fullscreen mode - Tam ekran kipini aç/kapat + Tam ekran kipini aç/kapat Hide/show toolbar - Araç çubuğunu göster/gizle + Araç çubuğunu göster/gizle + General - Genel + Genel Size up magnifying glass - Büyüteci büyüt + Büyüteci büyüt Size down magnifying glass - Büyüteci küçült + Büyüteci küçült Zoom in magnifying glass - Büyüteci yakınlaştır + Büyüteci yakınlaştır Zoom out magnifying glass - Büyüteci uzaklaştır + Büyüteci uzaklaştır Reset magnifying glass - + Büyüteci sıfırla + Magnifiying glass - Büyüteç + Büyüteç Toggle between fit to width and fit to height - Genişliğe sığdır ile yüksekliğe sığdır arasında geçiş yap + Genişliğe sığdır ile yüksekliğe sığdır arasında geçiş yap + Page adjustement - Sayfa ayarı + Sayfa ayarı - + Autoscroll down - Otomatik aşağı kaydır + Otomatik aşağı kaydır - + Autoscroll up - Otomatik yukarı kaydır + Otomatik yukarı kaydır - + Autoscroll forward, horizontal first - Otomatik ileri kaydır, önce yatay + Otomatik ileri kaydır, önce yatay - + Autoscroll backward, horizontal first - Otomatik geri kaydır, önce yatay + Otomatik geri kaydır, önce yatay - + Autoscroll forward, vertical first - Otomatik ileri kaydır, önce dikey + Otomatik ileri kaydır, önce dikey - + Autoscroll backward, vertical first - Otomatik geri kaydır, önce dikey + Otomatik geri kaydır, önce dikey - + Move down - Aşağı git + Aşağı git - + Move up - Yukarı git + Yukarı git - + Move left - Sola git + Sola git - + Move right - Sağa git + Sağa git - + Go to the first page - İlk sayfaya git + İlk sayfaya git - + Go to the last page - En son sayfaya git + En son sayfaya git - + Offset double page to the left - + Çift sayfayı sola kaydır - + Offset double page to the right - + Çift sayfayı sağa kaydır - + + Reading - Okuma + Okuma - + There is a new version available - Yeni versiyon mevcut + Yeni versiyon mevcut - + Do you want to download the new version? - Yeni versiyonu indirmek ister misin ? + Yeni versiyonu indirmek ister misin ? - + Remind me in 14 days - 14 gün içinde hatırlat + 14 gün içinde hatırlat - + Not now - Şimdi değil + Şimdi değil + + + + YACReader::TrayIconController + + + &Restore + &Geri Yükle + + + + Systray + Sistem tepsisi + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary sistem tepsisinde çalışmaya devam edecektir. Programı sonlandırmak için sistem tepsisi simgesinin bağlam menüsünden <b>Çık</b>'ı seçin. YACReader::WhatsNewDialog - Close - Kapat + Kapat @@ -1411,172 +4113,152 @@ YACReaderFlowConfigWidget - CoverFlow look - Kapak akışı görünümü + Kapak akışı görünümü - How to show covers: - Kapaklar nasıl gözüksün: + Kapaklar nasıl gözüksün: - Stripe look - Şerit görünüm + Şerit görünüm - Overlapped Stripe look - Çakışan şerit görünüm + Çakışan şerit görünüm YACReaderGLFlowConfigWidget - Zoom - Yakınlaş + Yakınlaş - Light - Işık + Işık - Show advanced settings - Daha fazla ayar göster + Daha fazla ayar göster - Roulette look - Rulet görünüm + Rulet görünüm - Cover Angle - Kapak Açısı + Kapak Açısı - Stripe look - Strip görünüm + Strip görünüm - Position - Pozisyon + Pozisyon - Z offset - Z dengesi + Z dengesi - Y offset - Y dengesi + Y dengesi - Central gap - Boş merkaz + Boş merkaz - Presets: - Hazırlayan: + Hazırlayan: - Overlapped Stripe look - Çakışan şerit görünüm + Çakışan şerit görünüm - Modern look - Modern görünüm + Modern görünüm - View angle - Bakış açısı + Bakış açısı - Max angle - Maksimum açı + Maksimum açı - Custom: - Kişisel: + Kişisel: - Classic look - Klasik görünüm + Klasik görünüm - Cover gap - Kapak boşluğu + Kapak boşluğu - High Performance - Yüksek performans + Yüksek performans - Performance: - Performans: + Performans: - Use VSync (improve the image quality in fullscreen mode, worse performance) - VSync kullan + VSync kullan - Visibility - Görünülebilirlik + Görünülebilirlik - Low Performance - Düşük Performans + Düşük Performans YACReaderOptionsDialog - + Save Kaydet - Use hardware acceleration (restart needed) - Yüksek donanımlı kullan (yeniden başlatmak gerekli) + Yüksek donanımlı kullan (yeniden başlatmak gerekli) - + Cancel Vazgeç - + Edit shortcuts Kısayolları düzenle - + Shortcuts Kısayollar + + YACReaderSearchLineEdit + + + type to search + aramak için yazınız + + YACReaderSlider @@ -1588,23 +4270,23 @@ YACReaderTranslator - + YACReader translator YACReader çevirmeni - - + + Translation Çeviri - + clear temizle - + Service not available Servis kullanılamıyor diff --git a/YACReader/yacreader_zh_CN.ts b/YACReader/yacreader_zh_CN.ts index 713495301..b76c7756c 100644 --- a/YACReader/yacreader_zh_CN.ts +++ b/YACReader/yacreader_zh_CN.ts @@ -9,6 +9,196 @@ + + AddLabelDialog + + + Label name: + 标签名称: + + + + Choose a color: + 选择标签颜色: + + + + accept + 接受 + + + + cancel + 取消 + + + + AddLibraryDialog + + + Comics folder : + 漫画文件夹: + + + + Library name : + 库名: + + + + Add + 添加 + + + + Cancel + 取消 + + + + Add an existing library + 添加一个现有库 + + + + ApiKeyDialog + + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要拥有自己的API密钥才能够连接Comic Vine. 你可以通过这个链接获得一个免费的<a href="http://www.comicvine.com/api/">API</a>密钥 + + + + Paste here your Comic Vine API key + 在此粘贴你的Comic Vine API + + + + Accept + 接受 + + + + Cancel + 取消 + + + + AppearanceTabWidget + + + Color scheme + 配色方案 + + + + System + 系统 + + + + Light + 亮度 + + + + Dark + 黑暗的 + + + + Custom + 风俗 + + + + Remove + 消除 + + + + Remove this user-imported theme + 删除此用户导入的主题 + + + + Light: + 光: + + + + Dark: + 黑暗的: + + + + Custom: + 自定义: + + + + Import theme... + 导入主题... + + + + Theme + 主题 + + + + Theme editor + 主题编辑器 + + + + Open Theme Editor... + 打开主题编辑器... + + + + Theme editor error + 主题编辑器错误 + + + + The current theme JSON could not be loaded. + 无法加载当前主题 JSON。 + + + + Import theme + 导入主题 + + + + JSON files (*.json);;All files (*) + JSON 文件 (*.json);;所有文件 (*) + + + + Could not import theme from: +%1 + 无法从以下位置导入主题: +%1 + + + + Could not import theme from: +%1 + +%2 + 无法从以下位置导入主题: +%1 + +%2 + + + + Import failed + 导入失败 + + BookmarksDialog @@ -33,10 +223,204 @@ 尾页 + + ClassicComicsView + + + Hide comic flow + 隐藏漫画流 + + + + ComicModel + + + yes + + + + + no + + + + + Title + 标题 + + + + File Name + 文件名 + + + + Pages + 页数 + + + + Size + 大小 + + + + Read + 阅读 + + + + Current Page + 当前页 + + + + Publication Date + 出版日期 + + + + Rating + 评分 + + + + Series + 系列 + + + + Volume + + + + + Story Arc + 故事线 + + + + ComicVineDialog + + + skip + 忽略 + + + + back + 返回 + + + + next + 下一步 + + + + search + 搜索 + + + + close + 关闭 + + + + + comic %1 of %2 - %3 + 第 %1 本 共 %2 本 - %3 + + + + + + Looking for volume... + 搜索卷... + + + + %1 comics selected + 已选择 %1 本漫画 + + + + Error connecting to ComicVine + ComicVine 连接时出错 + + + + + Retrieving tags for : %1 + 正在检索标签: %1 + + + + Retrieving volume info... + 正在接收卷信息... + + + + Looking for comic... + 搜索漫画中... + + + + ContinuousPageWidget + + + Loading page %1 + 正在加载页面 %1 + + + + CreateLibraryDialog + + + Comics folder : + 漫画文件夹: + + + + Library Name : + 库名: + + + + Create + 创建 + + + + Cancel + 取消 + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + 创建一个新的库可能需要几分钟时间,您可以先停止该进程,稍后可以通过更新库选项来更新数据。 + + + + Create new library + 创建新的漫画库 + + + + Path not found + 未找到路径 + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + 所选路径不存在或不是有效路径. 确保您具有此文件夹的写入权限 + + EditShortcutsDialog - + Shortcut in use 快捷键被占用 @@ -51,7 +435,7 @@ 快捷键设置 - + The shortcut "%1" is already assigned to other function 快捷键 "%1" 已被映射至其他功能 @@ -61,6 +445,124 @@ 更改快捷键: 双击按键组合并输入新的映射. + + EmptyFolderWidget + + + This folder doesn't contain comics yet + 该文件夹还没有漫画 + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + 此标签尚未包含漫画 + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + 此阅读列表尚未包含任何漫画 + + + + EmptySpecialListWidget + + + No favorites + 没有收藏 + + + + You are not reading anything yet, come on!! + 你还没有阅读任何东西,加油!! + + + + There are no recent comics! + 没有最近的漫画! + + + + ExportComicsInfoDialog + + + Output file : + 输出文件: + + + + Create + 创建 + + + + Cancel + 取消 + + + + Export comics info + 导出漫画信息 + + + + Destination database name + 目标数据库名称 + + + + Problem found while writing + 写入时出现问题 + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 选定的输出文件路径不存在或路径无效. 确保您具有此文件夹的写入权限 + + + + ExportLibraryDialog + + + Output folder : + 输出文件夹: + + + + Create + 创建 + + + + Cancel + 取消 + + + + Create covers package + 创建封面包 + + + + Problem found while writing + 写入时出现问题 + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 选定的输出文件路径不存在或路径无效. 确保您具有此文件夹的写入权限 + + + + Destination directory + 目标目录 + + FileComic @@ -116,450 +618,2621 @@ GoToFlowToolBar - + Page : 页码 : + + GridComicsView + + + Show info + 显示信息 + + HelpAboutDialog - + Help 帮助 - + About 关于 - + System info 系统信息 - LogWindow + ImportComicsInfoDialog - - &Copy - 复制(&C) + + Import comics info + 导入漫画信息 - - &Save - 保存(&S) + + Info database location : + 数据库地址: - - &Pause - 中止(&P) + + Import + 导入 - - C&lear - 清空(&l) + + Cancel + 取消 - - Level: - 等级: + + Comics info file (*.ydb) + 漫画信息文件(*.ydb) + + + ImportLibraryDialog - - &Auto scroll - 自动滚动(&A) + + Library Name : + 库名: - - Log window - 日志窗口 + + Package location : + 打包地址: - - - OptionsDialog - - Gamma - Gamma值 + + Destination folder : + 目标文件夹: - - Reset - 重置 + + Unpack + 解压 - - Enlarge images to fit width/height - 放大图片以适应宽度/高度 + + Cancel + 取消 - - Disable scroll animations and smooth scrolling - 禁用滚动动画和平滑滚动 + + Extract a catalog + 提取目录 - - Use single scroll step to turn page + + Compresed library covers (*.clc) + 已压缩的库封面 (*.clc) + + + + ImportWidget + + + stop + 停止 + + + + Some of the comics being added... + 正在添加漫画... + + + + Importing comics + 正在导入漫画 + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary现在正在创建一个新库。</p><p>这可能需要几分钟时间,您可以先停止该进程,稍后可以通过更新库选项来更新数据。</p> + + + + Updating the library + 正在更新库 + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>正在更新当前库。要获得更快的更新,请经常更新您的库。</p><p>您可以停止该进程,稍后继续更新操作。</p> + + + + Upgrading the library + 正在更新库 + + + + <p>The current library is being upgraded, please wait.</p> + <p>正在更新当前漫画库, 请稍候.</p> + + + + Scanning the library + 正在扫描库 + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>正在扫描当前库的旧版 XML metadata 信息。</p><p>这只需要执行一次,且只有当创建库的 YACReaderLibrary 版本低于 9.8.2 时。</p> + + + + LibraryWindow + + + YACReader Library + YACReader 库 + + + + + + comic + 漫画 + + + + + + manga + 日本漫画 + + + + + + western manga (left to right) + 欧美漫画(从左到右) + + + + + + web comic + 网络漫画 + + + + + + 4koma (top to botom) + 四格漫画(从上到下) + + + + + + + Set type + 设置类型 + + + + Library + + + + + Folder + 文件夹 + + + + Comic + 漫画 + + + + Upgrade failed + 更新失败 + + + + There were errors during library upgrade in: + 漫画库更新时出现错误: + + + + Update needed + 需要更新 + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + 此库是使用旧版本的YACReaderLibrary创建的. 它需要更新. 现在更新? + + + + Download new version + 下载新版本 + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + 此库是使用较新版本的YACReaderLibrary创建的。 立即下载新版本? + + + + Library not available + 库不可用 + + + + Library '%1' is no longer available. Do you want to remove it? + 库 '%1' 不再可用。 你想删除它吗? + + + + Old library + 旧的库 + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 库 '%1' 是通过旧版本的YACReaderLibrary创建的。 必须再次创建。 你想现在创建吗? + + + + + Copying comics... + 复制漫画中... + + + + + Moving comics... + 移动漫画中... + + + + Add new folder + 添加新的文件夹 + + + + Folder name: + 文件夹名称: + + + + No folder selected + 没有选中的文件夹 + + + + Please, select a folder first + 请先选择一个文件夹 + + + + Error in path + 路径错误 + + + + There was an error accessing the folder's path + 访问文件夹的路径时出错 + + + + Delete folder + 删除文件夹 + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + 所选文件夹及其所有内容将从磁盘中删除。 你确定吗? + + + + + Unable to delete + 无法删除 + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + 尝试删除所选文件夹时出现问题。 请检查写入权限,并确保没有其他应用程序在使用这些文件夹或文件。 + + + + Add new reading lists + 添加新的阅读列表 + + + + + List name: + 列表名称: + + + + Delete list/label + 删除 列表/标签 + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + 所选项目将被删除,您的漫画或文件夹将不会从您的磁盘中删除。 你确定吗? + + + + Rename list name + 重命名列表 + + + + Open folder... + 打开文件夹... + + + + Update folder + 更新文件夹 + + + + Rescan library for XML info + 重新扫描库的 XML 信息 + + + + Set as uncompleted + 设为未完成 + + + + Set as completed + 设为已完成 + + + + Set as read + 设为已读 + + + + + Set as unread + 设为未读 + + + + Set custom cover + 设置自定义封面 + + + + Delete custom cover + 删除自定义封面 + + + + Save covers + 保存封面 + + + + You are adding too many libraries. + 您添加的库太多了。 + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + 您添加的库太多了。 + +一般情况只需要一个顶级的库,您可以使用左侧边栏中的文件夹功能来进行分类管理。 + +YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低的库数量来提升性能。 + + + + + YACReader not found + YACReader 未找到 + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + 未找到YACReader. YACReader应安装在与YACReaderLibrary相同的文件夹中. + + + + YACReader not found. There might be a problem with your YACReader installation. + 未找到YACReader. YACReader的安装可能有问题. + + + + Error + 错误 + + + + Error opening comic with third party reader. + 使用第三方阅读器打开漫画时出错。 + + + + Library not found + 未找到库 + + + + The selected folder doesn't contain any library. + 所选文件夹不包含任何库。 + + + + Are you sure? + 你确定吗? + + + + Do you want remove + 你想要删除 + + + + library? + 库? + + + + Remove and delete metadata + 移除并删除元数据 + + + + Library info + 图书馆信息 + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + 尝试删除所选漫画时出现问题。 请检查所选文件或包含文件夹中的写入权限。 + + + + Assign comics numbers + 分配漫画编号 + + + + Assign numbers starting in: + 从以下位置开始分配编号: + + + + Invalid image + 图片无效 + + + + The selected file is not a valid image. + 所选文件不是有效图像。 + + + + Error saving cover + 保存封面时出错 + + + + There was an error saving the cover image. + 保存封面图像时出错。 + + + + Error creating the library + 创建库时出错 + + + + Error updating the library + 更新库时出错 + + + + Error opening the library + 打开库时出错 + + + + Delete comics + 删除漫画 + + + + All the selected comics will be deleted from your disk. Are you sure? + 所有选定的漫画都将从您的磁盘中删除。你确定吗? + + + + Remove comics + 移除漫画 + + + + Comics will only be deleted from the current label/list. Are you sure? + 漫画只会从当前标签/列表中删除。 你确定吗? + + + + Library name already exists + 库名已存在 + + + + There is another library with the name '%1'. + 已存在另一个名为'%1'的库。 + + + + LibraryWindowActions + + + Create a new library + 创建一个新的库 + + + + Open an existing library + 打开现有的库 + + + + + Export comics info + 导出漫画信息 + + + + + Import comics info + 导入漫画信息 + + + + Pack covers + 打包封面 + + + + Pack the covers of the selected library + 打包所选库的封面 + + + + Unpack covers + 解压封面 + + + + Unpack a catalog + 解压目录 + + + + Update library + 更新库 + + + + Update current library + 更新当前库 + + + + Rename library + 重命名库 + + + + Rename current library + 重命名当前库 + + + + Remove library + 移除库 + + + + Remove current library from your collection + 从您的集合中移除当前库 + + + + Rescan library for XML info + 重新扫描库的 XML 信息 + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + 尝试查找漫画文件内嵌的 XML 信息。只有当创建库的 YACReaderLibrary 版本低于 9.8.2 或者使用第三方软件嵌入 XML 信息时,才需要执行该操作。 + + + + Show library info + 显示图书馆信息 + + + + Show information about the current library + 显示当前库的信息 + + + + Open current comic + 打开当前漫画 + + + + Open current comic on YACReader + 用YACReader打开漫画 + + + + Save selected covers to... + 选中的封面保存到... + + + + Save covers of the selected comics as JPG files + 保存所选的封面为jpg + + + + + Set as read + 设为已读 + + + + Set comic as read + 漫画设为已读 + + + + + Set as unread + 设为未读 + + + + Set comic as unread + 漫画设为未读 + + + + + manga + 日本漫画 + + + + Set issue as manga + 将问题设置为漫画 + + + + + comic + 漫画 + + + + Set issue as normal + 设置漫画为 + + + + western manga + 欧美漫画 + + + + Set issue as western manga + 设置为欧美漫画 + + + + + web comic + 网络漫画 + + + + Set issue as web comic + 设置为网络漫画 + + + + + yonkoma + 四格漫画 + + + + Set issue as yonkoma + 设置为四格漫画 + + + + Show/Hide marks + 显示/隐藏标记 + + + + Show or hide read marks + 显示或隐藏阅读标记 + + + + Show/Hide recent indicator + 显示/隐藏最近的指示标志 + + + + Show or hide recent indicator + 显示或隐藏最近的指示标志 + + + + + Fullscreen mode on/off + 全屏模式 开/关 + + + + Help, About YACReader + 帮助, 关于 YACReader + + + + Add new folder + 添加新的文件夹 + + + + Add new folder to the current library + 在当前库下添加新的文件夹 + + + + Delete folder + 删除文件夹 + + + + Delete current folder from disk + 从磁盘上删除当前文件夹 + + + + Select root node + 选择根节点 + + + + Expand all nodes + 展开所有节点 + + + + Collapse all nodes + 折叠所有节点 + + + + Show options dialog + 显示选项对话框 + + + + Show comics server options dialog + 显示漫画服务器选项对话框 + + + + + Change between comics views + 漫画视图之间的变化 + + + + Open folder... + 打开文件夹... + + + + Set as uncompleted + 设为未完成 + + + + Set as completed + 设为已完成 + + + + Set custom cover + 设置自定义封面 + + + + Delete custom cover + 删除自定义封面 + + + + western manga (left to right) + 欧美漫画(从左到右) + + + + Open containing folder... + 打开包含文件夹... + + + + Reset comic rating + 重置漫画评分 + + + + Select all comics + 全选漫画 + + + + Edit + 编辑 + + + + Assign current order to comics + 将当前序号分配给漫画 + + + + Update cover + 更新封面 + + + + Delete selected comics + 删除所选的漫画 + + + + Delete metadata from selected comics + 从选定的漫画中删除元数据 + + + + Download tags from Comic Vine + 从 Comic Vine 下载标签 + + + + Focus search line + 聚焦于搜索行 + + + + Focus comics view + 聚焦于漫画视图 + + + + Edit shortcuts + 编辑快捷键 + + + + &Quit + 退出(&Q) + + + + Update folder + 更新文件夹 + + + + Update current folder + 更新当前文件夹 + + + + Scan legacy XML metadata + 扫描旧版 XML 元数据 + + + + Add new reading list + 添加新的阅读列表 + + + + Add a new reading list to the current library + 在当前库添加新的阅读列表 + + + + Remove reading list + 移除阅读列表 + + + + Remove current reading list from the library + 从当前库移除阅读列表 + + + + Add new label + 添加新标签 + + + + Add a new label to this library + 在当前库添加标签 + + + + Rename selected list + 重命名列表 + + + + Rename any selected labels or lists + 重命名任何选定的标签或列表 + + + + Add to... + 添加到... + + + + Favorites + 收藏夹 + + + + Add selected comics to favorites list + 将所选漫画添加到收藏夹列表 + + + + LocalComicListModel + + + file name + 文件名 + + + + LogWindow + + &Copy + 复制(&C) + + + &Save + 保存(&S) + + + &Pause + 中止(&P) + + + C&lear + 清空(&l) + + + Level: + 等级: + + + &Auto scroll + 自动滚动(&A) + + + Log window + 日志窗口 + + + + NoLibrariesWidget + + + You don't have any libraries yet + 你还没有库 + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>您可以在任何文件夹中创建库,YACReaderLibrary将导入此文件夹中的所有漫画和文件夹。如果已有库,则可以打开它们。</p><p>您可以把YACReader当成独立应用来阅读电脑上的漫画。</p> + + + + create your first library + 创建你的第一个库 + + + + add an existing one + 添加一个现有库 + + + + NoSearchResultsWidget + + + No results + 没有结果 + + + + OptionsDialog + + + Gamma + Gamma值 + + + + Reset + 重置 + + + + Enlarge images to fit width/height + 放大图片以适应宽度/高度 + + + + Disable scroll animations and smooth scrolling + 禁用滚动动画和平滑滚动 + + + + Use single scroll step to turn page 使用单滚动步骤翻页 - - My comics path - 我的漫画路径 + + My comics path + 我的漫画路径 + + + + Image adjustment + 图像调整 + + + + "Go to flow" size + 页面流尺寸 + + + + Choose + 选择 + + + + Show covers as single page + 显示封面为单页 + + + + Do not turn page using scroll + 滚动时不翻页 + + + + Fit options + 适应项 + + + + Image options + 图片选项 + + + + Display + 展示 + + + + Show time in current page information label + 在当前页面信息标签中显示时间 + + + + Mouse mode + 鼠标模式 + + + + Only Back/Forward buttons can turn pages + 只有后退/前进按钮可以翻页 + + + + Use the Left/Right buttons to turn pages. + 使用向左/向右按钮翻页。 + + + + Click left or right half of the screen to turn pages. + 单击屏幕的左半部分或右半部分即可翻页。 + + + + Contrast + 对比度 + + + + + Libraries + + + + + Comic Flow + 漫画流 + + + + Grid view + 网格视图 + + + + + Appearance + 外貌 + + + + + Options + 选项 + + + + + Language + 语言 + + + + + Application language + 应用程序语言 + + + + + System default + 系统默认 + + + + Tray icon settings (experimental) + 托盘图标设置 (实验特性) + + + + Close to tray + 关闭至托盘 + + + + Start into the system tray + 启动至系统托盘 + + + + Edit Comic Vine API key + 编辑Comic Vine API 密匙 + + + + Comic Vine API key + Comic Vine API 密匙 + + + + ComicInfo.xml legacy support + ComicInfo.xml 旧版支持 + + + + Import metadata from ComicInfo.xml when adding new comics + 添加新漫画时从 ComicInfo.xml 导入元数据 + + + + Consider 'recent' items added or updated since X days ago + 参考自 X 天前添加或更新的“最近”项目 + + + + Third party reader + 第三方阅读器 + + + + Write {comic_file_path} where the path should go in the command + 在命令中应将路径写入 {comic_file_path} + + + + + Clear + 清空 + + + + Update libraries at startup + 启动时更新库 + + + + Try to detect changes automatically + 尝试自动检测变化 + + + + Update libraries periodically + 定期更新库 + + + + Interval: + 间隔: + + + + 30 minutes + 30分钟 + + + + 1 hour + 1小时 + + + + 2 hours + 2小时 + + + + 4 hours + 4小时 + + + + 8 hours + 8小时 + + + + 12 hours + 12小时 + + + + daily + 每天 + + + + Update libraries at certain time + 定时更新库 + + + + Time: + 时间: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + 警告! 在库更新期间,将禁用对数据库的写入! +当您可能正在积极使用该应用程序时,请勿安排更新。 +在自动更新期间,应用程序将阻止某些操作,直到更新完成。 +要停止自动更新,请点击库标题旁边的加载指示器。 + + + + Modifications detection + 修改检测 + + + + Compare the modified date of files when updating a library (not recommended) + 更新库时比较文件的修改日期(不推荐) + + + + Enable background image + 启用背景图片 + + + + Opacity level + 透明度 + + + + Blur level + 模糊 + + + + Use selected comic cover as background + 使用选定的漫画封面做背景 + + + + Restore defautls + 恢复默认值 + + + + Background + 背景 + + + + Display continue reading banner + 显示继续阅读横幅 + + + + Display current comic banner + 显示当前漫画横幅 + + + + Continue reading + 继续阅读 + + + + Comics directory + 漫画目录 + + + + Quick Navigation Mode + 快速导航模式 + + + + Background color + 背景颜色 + + + + Double Page options + 双页选项 + + + + Scroll behaviour + 滚动效果 + + + + Disable mouse over activation + 禁用鼠标激活 + + + + Scaling + 缩放 + + + + Scaling method + 缩放方法 + + + + Nearest (fast, low quality) + 最近(快速,低质量) + + + + Bilinear + 双线性 + + + + Lanczos (better quality) + Lanczos(质量更好) + + + + Page Flow + 页面流 + + + + + General + 常规 + + + + Brightness + 亮度 + + + + + Restart is needed + 需要重启 + + + + PropertiesDialog + + + General info + 基本信息 + + + + Plot + 情节 + + + + Authors + 作者 + + + + Publishing + 出版 + + + + Notes + 笔记 + + + + Cover page + 封面 + + + + Load previous page as cover + 加载上一页作为封面 + + + + Load next page as cover + 加载下一页作为封面 + + + + Reset cover to the default image + 将封面重置为默认图像 + + + + Load custom cover image + 加载自定义封面图片 + + + + Series: + 系列: + + + + Title: + 标题: + + + + + + of: + 的: + + + + Issue number: + 发行刊号: + + + + Volume: + 卷: + + + + Arc number: + 世界线数量: + + + + Story arc: + 故事线: + + + + alt. number: + 备选编号: + + + + Alternate series: + 备用系列: + + + + Series Group: + 系列组: + + + + Genre: + 类型: + + + + Size: + 大小: + + + + Writer(s): + 作者: + + + + Penciller(s): + 线稿师: + + + + Inker(s): + 上墨师: + + + + Colorist(s): + 上色师: + + + + Letterer(s): + 嵌字师: + + + + Cover Artist(s): + 封面设计: - - Image adjustment - 图像调整 + + Editor(s): + 编辑: - - "Go to flow" size - 页面流尺寸 + + Imprint: + 印记: - - Choose - 选择 + + Day: + 日: - - Show covers as single page - 显示封面为单页 + + Month: + 月: - - Do not turn page using scroll - 滚动时不翻页 + + Year: + 年: - - Fit options - 适应项 + + Publisher: + 出版商: + + + + Format: + 格式: + + + + Color/BW: + 彩色/黑白: + + + + Age rating: + 年龄分级: + + + + Type: + 类型: + + + + Language (ISO): + 语言(ISO): + + + + Synopsis: + 简介: + + + + Characters: + 角色: + + + + Teams: + 团队: + + + + Locations: + 地点: + + + + Main character or team: + 主要角色或团队: + + + + Review: + 审查: + + + + Notes: + 笔记: + + + + Tags: + 标签: + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 连接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + + + + Not found + 未找到 + + + + Comic not found. You should update your library. + 未找到漫画,请先更新您的库. + + + + Edit comic information + 编辑漫画信息 + + + + Edit selected comics information + 编辑选中的漫画信息 + + + + Invalid cover + 封面无效 + + + + The image is invalid. + 该图像无效。 + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 + +此应用程序支持持久设置,要设置它们,请编辑此文件 %1 +要了解可用设置,请查看文档:https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject + + + Info + 信息 + + + + Debug + 除错 + + + + Fatal + 严重错误 + + + + Error + 错误 + + + + Trace + 追踪 + + + + 7z lib not found + 未找到 7z 库文件 + + + + unable to load 7z lib from ./utils + 无法从 ./utils 载入 7z 库文件 + + + + Warning + 警告 + + + + Select custom cover + 选择自定义封面 + + + + Images (%1) + 图片 (%1) + + + + The file could not be read or is not valid JSON. + 无法读取该文件或者该文件不是有效的 JSON。 + + + + This theme is for %1, not %2. + 此主题适用于 %1,而不是 %2。 + + + + Libraries + + + + + Folders + 文件夹 + + + + Reading Lists + 阅读列表 + + + + QsLogging::LogWindowModel + + Time + 时间 + + + Level + 等级 + + + Message + 信息 + + + + QsLogging::Window + + &Pause + 中止(&P) + + + Save log + 保存日志 + + + &Resume + 恢复(&R) + + + Log file (*.log) + 日志文件 (*.log) + + + + RenameLibraryDialog + + + New Library Name : + 新库名: + + + + Rename + 重命名 + + + + Cancel + 取消 + + + + Rename current library + 重命名当前库 + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + 搜索结果: %1 + + + + + page %1 of %2 + 第 %1 页 共 %2 页 + + + + Number of %1 found : %2 + 第 %1 页 共: %2 条 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + 请提供附加信息. + + + + Series: + 系列: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + 使用精确匹配搜索。如果您想要查找与名称中某些单词匹配的卷,请禁用。 + + + + SearchVolume + + + Please provide some additional information. + 请提供附加信息. + + + + Series: + 系列: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + 使用精确匹配搜索。如果您想要查找与名称中某些单词匹配的卷,请禁用。 + + + + SelectComic + + + Please, select the right comic info. + 请正确选择漫画信息. + + + + comics + 漫画 + + + + loading cover + 加载封面 + + + + loading description + 加载描述 + + + + comic description unavailable + 漫画描述不可用 + + + + SelectVolume + + + Please, select the right series for your comic. + 请选择正确的漫画系列。 + + + + Filter: + 筛选: + + + + volumes + + + + + Nothing found, clear the filter if any. + 未找到任何内容,如果有,请清除筛选器。 + + + + loading cover + 加载封面 + + + + loading description + 加载描述 + + + + volume description unavailable + 卷描述不可用 + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + 您正在尝试同时获取各种漫画的信息,它们是同一系列的吗? + + + + yes + + + + + no + + + + + ServerConfigDialog + + + set port + 设置端口 + + + + Server connectivity information + 服务器连接信息 + + + + Scan it! + 扫一扫! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 适用于 iOS 和 Android 设备。<br/>搜索 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + + + + Choose an IP address + 选择IP地址 + + + + Port + 端口 + + + + enable the server + 启用服务器 + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + 请在左侧对漫画列表进行排序,直到它与漫画的信息相符。 + + + + sort comics to match comic information + 排序漫画以匹配漫画信息 + + + + issues + 发行 + + + + remove selected comics + 移除所选漫画 + + + + restore all removed comics + 恢复所有移除的漫画 + + + + ThemeEditorDialog + + + Theme Editor + 主题编辑器 + + + + + + + + + + + - + - - - Image options - 图片选项 + + i + - - Display - + + Expand all + 全部展开 - - Show time in current page information label - + + Collapse all + 全部折叠 - - Mouse mode - + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + 按住可在 UI 中闪烁所选值(洋红色/切换/0↔10)。发布后恢复原样。 - - Only Back/Forward buttons can turn pages - + + Search… + 搜索… - - Use the Left/Right buttons to turn pages. - + + Light + 亮度 - - Click left or right half of the screen to turn pages. - + + Dark + 黑暗的 - - Contrast - 对比度 + + ID: + ID: - - Options - 选项 + + Display name: + 显示名称: - - Comics directory - 漫画目录 + + Variant: + 变体: - - Quick Navigation Mode - 快速导航模式 + + Theme info + 主题信息 - - Background color - 背景颜色 + + Parameter + 范围 - - Double Page options - 双页选项 + + Value + 价值 - - Scroll behaviour - 滚动效果 + + Save and apply + 保存并应用 - - Disable mouse over activation - 禁用鼠标激活 + + Export to file... + 导出到文件... - - Page Flow - 页面流 + + Load from file... + 从文件加载... - - General - 常规 + + Close + 关闭 - - Brightness - 亮度 + + Double-click to edit color + 双击编辑颜色 - - Restart is needed - 需要重启 + + + + + + + true + 真的 - - - QObject - - Info - 信息 + + + + + false + 错误的 - - Debug - 除错 + + Double-click to toggle + 双击切换 - - Fatal - 严重错误 + + Double-click to edit value + 双击编辑值 - - Error - 错误 + + + + Edit: %1 + 编辑:%1 - - Trace - 追踪 + + Save theme + 保存主题 - - 7z lib not found - 未找到 7z 库文件 + + + JSON files (*.json);;All files (*) + JSON 文件 (*.json);;所有文件 (*) - - unable to load 7z lib from ./utils - 无法从 ./utils 载入 7z 库文件 + + Save failed + 保存失败 - - Warning - 警告 + + Could not open file for writing: +%1 + 无法打开文件进行写入: +%1 - - Select custom cover - + + Load theme + 加载主题 - - Images (%1) - + + + + Load failed + 加载失败 - - - QsLogging::LogWindowModel - - Time - 时间 + + Could not open file: +%1 + 无法打开文件: +%1 - - Level - 等级 + + Invalid JSON: +%1 + 无效的 JSON: +%1 - - Message - 信息 + + Expected a JSON object. + 需要一个 JSON 对象。 - QsLogging::Window + TitleHeader - - &Pause - 中止(&P) + + SEARCH + 搜索 + + + UpdateLibraryDialog - - Save log - 保存日志 + + Updating.... + 更新中... - - &Resume - 恢复(&R) + + Cancel + 取消 - - Log file (*.log) - 日志文件 (*.log) + + Update library + 更新库 Viewer - + Page not available! 页面不可用! - - + + Press 'O' to open comic. 按下 'O' 以打开漫画. - + Error opening comic 打开漫画时发生错误 - + Cover! 封面! - + CRC Error CRC 校验失败 - + Comic not found 未找到漫画 - + Not found 未找到 - + Last page! 尾页! - + Loading...please wait! 载入中... 请稍候! + + VolumeComicsModel + + + title + 标题 + + + + VolumesModel + + + year + + + + + issues + 发行 + + + + publisher + 出版者 + + + + YACReader3DFlowConfigWidget + + + Presets: + 预设: + + + + Classic look + 经典 + + + + Stripe look + 条状 + + + + Overlapped Stripe look + 重叠条状 + + + + Modern look + 现代 + + + + Roulette look + 轮盘 + + + + Show advanced settings + 显示高级选项 + + + + Custom: + 自定义: + + + + View angle + 视角 + + + + Position + 位置 + + + + Cover gap + 封面间距 + + + + Central gap + 中心间距 + + + + Zoom + 缩放 + + + + Y offset + Y位移 + + + + Z offset + Z位移 + + + + Cover Angle + 封面角度 + + + + Visibility + 透明度 + + + + Light + 亮度 + + + + Max angle + 最大角度 + + + + Low Performance + 低性能 + + + + High Performance + 高性能 + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + 使用VSync (在全屏模式下提高图像质量, 性能更差) + + + + Performance: + 性能: + + YACReader::MainWindowViewer - + Go 转到 - + Edit 编辑 - + File 文件 - - + + Help 帮助 - + Save 保存 - + View 查看 - + &File 文件(&F) - + &Next 下一页(&N) - + &Open 打开(&O) - + Clear 清空 - + Close 关闭 - - - + + + Open Comic 打开漫画 - + Go To 跳转 - + Zoom+ 放大 - + Zoom- 缩小 - + Open image folder 打开图片文件夹 @@ -574,43 +3247,43 @@ 减小缩放级别 - + New instance 新建实例 - + Open latest comic 打开最近的漫画 - + Autoscroll up 向上自动滚动 - + Set bookmark 设置书签 - + page_%1.jpg - page_%1.jpg + 页_%1.jpg - + Autoscroll forward, vertical first 向前自动滚动,垂直优先 - + Switch to double page mode 切换至双页模式 - + Save current page 保存当前页面 @@ -620,126 +3293,128 @@ 增大放大镜尺寸 - + Double page mode 双页模式 - + Move up 向上移动 - + Switch Magnifying glass 切换放大镜 - + Open Folder 打开文件夹 + Comics 漫画 - + Offset double page to the right 双页向右偏移 - + Fit Height 适应高度 - + Autoscroll backward, vertical first 向后自动滚动,垂直优先 - - - + + + Comic files 漫画文件 - + Not now 现在不 - + Go to the first page 转到第一页 - - - + + + Go to previous page 转至上一页 - + Window 窗口 - + Open the latest comic opened in the previous reading session 打开最近阅读漫画 - + Open a comic 打开漫画 - + Image files (*.jpg) 图像文件 (*.jpg) - + Next Comic 下一个漫画 - + Fit Width 适合宽度 - + Options 选项 - + Show Info 显示信息 - + Open folder 打开文件夹 - + Go to page ... 跳转至页面 ... + Magnifiying glass 放大镜 - + Fit image to width 缩放图片以适应宽度 @@ -754,7 +3429,7 @@ 切换显示为"适应宽度"或"适应高度" - + Move right 向右移动 @@ -764,149 +3439,160 @@ 增大缩放级别 - - + + Open recent 最近打开的文件 - + Offset double page to the left 双页向左偏移 - + + Reading 阅读 - + &Previous 上一页(&P) - + Autoscroll forward, horizontal first 向前自动滚动,水平优先 - - - + + + Go to next page 转至下一页 - + Show keyboard shortcuts 显示键盘快捷键 - + Double page manga mode 双页漫画模式 - + There is a new version available 有新版本可用 - + Autoscroll down 向下自动滚动 - - - + + + Open next comic 打开下一个漫画 - + Remind me in 14 days 14天后提醒我 - + Fit to page 适应页面 - + Show bookmarks 显示书签 - - - + + + Open previous comic 打开上一个漫画 - + Rotate image to the left 向左旋转图片 - + Fit image to height 缩放图片以适应高度 - + + Continuous scroll + 连续滚动 + + + + Switch to continuous scroll mode + 切换到连续滚动模式 + + + Reset zoom 重置缩放 - + Show the bookmarks of the current comic 显示当前漫画的书签 - + Show Dictionary 显示字典 Reset magnifying glass - + 重置放大镜 - + Move down 向下移动 - + Move left 向左移动 - + Reverse reading order in double page mode 双页模式 (逆序阅读) - + YACReader options YACReader 选项 - + Clear open recent list 清空最近访问列表 - + Help, About YACReader 帮助, 关于 YACReader - + Show go to flow 显示页面流 @@ -916,7 +3602,7 @@ 上一个漫画 - + Show full size 显示全尺寸 @@ -926,62 +3612,81 @@ 隐藏/显示 工具栏 - + Magnifying glass 放大镜 - + Edit shortcuts 编辑快捷键 + General 常规 - + Set a bookmark on the current page 在当前页面设置书签 + Page adjustement 页面调整 - + Show zoom slider 显示缩放滑块 - + Go to the last page 转到最后一页 - + Do you want to download the new version? 你要下载新版本吗? - + Rotate image to the right 向右旋转图片 - + Autoscroll backward, horizontal first 向后自动滚动,水平优先 + + YACReader::TrayIconController + + + &Restore + 复位(&R) + + + + Systray + 系统托盘 + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary 将继续在系统托盘中运行. 想要终止程序, 请在系统托盘图标的上下文菜单中选择<b>退出</b>. + + YACReader::WhatsNewDialog - Close - 关闭 + 关闭 @@ -1017,172 +3722,152 @@ YACReaderFlowConfigWidget - CoverFlow look - 封面流 + 封面流 - How to show covers: - 封面显示方式: + 封面显示方式: - Stripe look - 条状 + 条状 - Overlapped Stripe look - 重叠条状 + 重叠条状 YACReaderGLFlowConfigWidget - Zoom - 缩放 + 缩放 - Light - 亮度 + 亮度 - Show advanced settings - 显示高级选项 + 显示高级选项 - Roulette look - 轮盘 + 轮盘 - Cover Angle - 封面角度 + 封面角度 - Stripe look - 条状 + 条状 - Position - 位置 + 位置 - Z offset - Z位移 + Z位移 - Y offset - Y位移 + Y位移 - Central gap - 中心间距 + 中心间距 - Presets: - 预设: + 预设: - Overlapped Stripe look - 重叠条状 + 重叠条状 - Modern look - 现代 + 现代 - View angle - 视角 + 视角 - Max angle - 最大角度 + 最大角度 - Custom: - 自定义: + 自定义: - Classic look - 经典 + 经典 - Cover gap - 封面间距 + 封面间距 - High Performance - 高性能 + 高性能 - Performance: - 性能: + 性能: - Use VSync (improve the image quality in fullscreen mode, worse performance) - 使用VSync (在全屏模式下提高图像质量, 性能更差) + 使用VSync (在全屏模式下提高图像质量, 性能更差) - Visibility - 透明度 + 透明度 - Low Performance - 低性能 + 低性能 YACReaderOptionsDialog - + Save 保存 - Use hardware acceleration (restart needed) - 使用硬件加速 (需要重启) + 使用硬件加速 (需要重启) - + Cancel 取消 - + Shortcuts 快捷键 - + Edit shortcuts 编辑快捷键 + + YACReaderSearchLineEdit + + + type to search + 搜索类型 + + YACReaderSlider @@ -1194,23 +3879,23 @@ YACReaderTranslator - + clear 清空 - + Service not available 服务不可用 - - + + Translation 翻译 - + YACReader translator YACReader 翻译 diff --git a/YACReader/yacreader_zh_HK.ts b/YACReader/yacreader_zh_HK.ts index fc14d3407..40017c5aa 100644 --- a/YACReader/yacreader_zh_HK.ts +++ b/YACReader/yacreader_zh_HK.ts @@ -9,6 +9,196 @@ + + AddLabelDialog + + + Label name: + 標籤名稱: + + + + Choose a color: + 選擇標籤顏色: + + + + accept + 接受 + + + + cancel + 取消 + + + + AddLibraryDialog + + + Comics folder : + 漫畫檔夾: + + + + Library name : + 庫名: + + + + Add + 添加 + + + + Cancel + 取消 + + + + Add an existing library + 添加一個現有庫 + + + + ApiKeyDialog + + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 + + + + Paste here your Comic Vine API key + 在此粘貼你的Comic Vine API + + + + Accept + 接受 + + + + Cancel + 取消 + + + + AppearanceTabWidget + + + Color scheme + 配色方案 + + + + System + 系統 + + + + Light + 亮度 + + + + Dark + 黑暗的 + + + + Custom + 風俗 + + + + Remove + 消除 + + + + Remove this user-imported theme + 刪除此使用者匯入的主題 + + + + Light: + 光: + + + + Dark: + 黑暗的: + + + + Custom: + 自定義: + + + + Import theme... + 導入主題... + + + + Theme + 主題 + + + + Theme editor + 主題編輯器 + + + + Open Theme Editor... + 開啟主題編輯器... + + + + Theme editor error + 主題編輯器錯誤 + + + + The current theme JSON could not be loaded. + 無法載入目前主題 JSON。 + + + + Import theme + 導入主題 + + + + JSON files (*.json);;All files (*) + JSON 檔案 (*.json);;所有檔案 (*) + + + + Could not import theme from: +%1 + 無法從以下位置匯入主題: +%1 + + + + Could not import theme from: +%1 + +%2 + 無法從以下位置匯入主題: +%1 + +%2 + + + + Import failed + 導入失敗 + + BookmarksDialog @@ -33,6 +223,200 @@ 載入中... + + ClassicComicsView + + + Hide comic flow + 隱藏漫畫流 + + + + ComicModel + + + yes + + + + + no + + + + + Title + 標題 + + + + File Name + 檔案名 + + + + Pages + 頁數 + + + + Size + 大小 + + + + Read + 閱讀 + + + + Current Page + 當前頁 + + + + Publication Date + 發行日期 + + + + Rating + 評分 + + + + Series + 系列 + + + + Volume + 體積 + + + + Story Arc + 故事線 + + + + ComicVineDialog + + + skip + 忽略 + + + + back + 返回 + + + + next + 下一步 + + + + search + 搜索 + + + + close + 關閉 + + + + + comic %1 of %2 - %3 + 第 %1 本 共 %2 本 - %3 + + + + + + Looking for volume... + 搜索卷... + + + + %1 comics selected + 已選擇 %1 本漫畫 + + + + Error connecting to ComicVine + ComicVine 連接時出錯 + + + + + Retrieving tags for : %1 + 正在檢索標籤: %1 + + + + Retrieving volume info... + 正在接收卷資訊... + + + + Looking for comic... + 搜索漫畫中... + + + + ContinuousPageWidget + + + Loading page %1 + 正在載入頁面 %1 + + + + CreateLibraryDialog + + + Comics folder : + 漫畫檔夾: + + + + Library Name : + 庫名: + + + + Create + 創建 + + + + Cancel + 取消 + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + 創建一個新的庫可能需要幾分鐘時間,您可以先停止該進程,稍後可以通過更新庫選項來更新數據。 + + + + Create new library + 創建新的漫畫庫 + + + + Path not found + 未找到路徑 + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + 所選路徑不存在或不是有效路徑. 確保您具有此檔夾的寫入許可權 + + EditShortcutsDialog @@ -51,16 +435,134 @@ 快捷鍵設置 - + Shortcut in use 快捷鍵被佔用 - + The shortcut "%1" is already assigned to other function 快捷鍵 "%1" 已被映射至其他功能 + + EmptyFolderWidget + + + This folder doesn't contain comics yet + 該資料夾還沒有漫畫 + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + 此標籤尚未包含漫畫 + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + 此閱讀列表尚未包含任何漫畫 + + + + EmptySpecialListWidget + + + No favorites + 沒有收藏 + + + + You are not reading anything yet, come on!! + 你還沒有閱讀任何東西,加油!! + + + + There are no recent comics! + 沒有最近的漫畫! + + + + ExportComicsInfoDialog + + + Output file : + 輸出檔: + + + + Create + 創建 + + + + Cancel + 取消 + + + + Export comics info + 導出漫畫資訊 + + + + Destination database name + 目標資料庫名稱 + + + + Problem found while writing + 寫入時出現問題 + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 選定的輸出檔路徑不存在或路徑無效. 確保您具有此檔夾的寫入許可權 + + + + ExportLibraryDialog + + + Output folder : + 輸出檔夾: + + + + Create + 創建 + + + + Cancel + 取消 + + + + Create covers package + 創建封面包 + + + + Problem found while writing + 寫入時出現問題 + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 選定的輸出檔路徑不存在或路徑無效. 確保您具有此檔夾的寫入許可權 + + + + Destination directory + 目標目錄 + + FileComic @@ -116,438 +618,2609 @@ GoToFlowToolBar - + Page : 頁碼 : + + GridComicsView + + + Show info + 顯示資訊 + + HelpAboutDialog - + About 關於 - + Help 幫助 - + System info 系統資訊 - LogWindow + ImportComicsInfoDialog - - Log window - 日誌窗口 + + Import comics info + 導入漫畫資訊 - - &Pause - 中止(&P) + + Info database location : + 資料庫地址: - - &Save - 保存(&S) + + Import + 導入 - - C&lear - 清空(&l) + + Cancel + 取消 - - &Copy - 複製(&C) + + Comics info file (*.ydb) + 漫畫資訊檔(*.ydb) + + + ImportLibraryDialog - - Level: - 等級: + + Library Name : + 庫名: - - &Auto scroll - 自動滾動(&A) + + Package location : + 打包地址: - - - OptionsDialog - - "Go to flow" size - 頁面流尺寸 + + Destination folder : + 目標檔夾: - - My comics path - 我的漫畫路徑 + + Unpack + 解壓 - - Background color - 背景顏色 + + Cancel + 取消 - - Choose - 選擇 + + Extract a catalog + 提取目錄 - - Quick Navigation Mode + + Compresed library covers (*.clc) + 已壓縮的庫封面 (*.clc) + + + + ImportWidget + + + stop + 停止 + + + + Some of the comics being added... + 正在添加漫畫... + + + + Importing comics + 正在導入漫畫 + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary現在正在創建一個新庫。</p><p>這可能需要幾分鐘時間,您可以先停止該進程,稍後可以通過更新庫選項來更新數據。</p> + + + + Updating the library + 正在更新庫 + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>正在更新當前庫。要獲得更快的更新,請經常更新您的庫。</p><p>您可以停止該進程,稍後繼續更新操作。</p> + + + + Upgrading the library + 正在更新庫 + + + + <p>The current library is being upgraded, please wait.</p> + <p>正在更新當前漫畫庫, 請稍候.</p> + + + + Scanning the library + 正在掃描庫 + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>正在掃描當前庫的舊版 XML metadata 資訊。</p><p>這只需要執行一次,且只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 時。</p> + + + + LibraryWindow + + + YACReader Library + YACReader 庫 + + + + + + comic + 漫畫 + + + + + + manga + 漫畫 + + + + + + western manga (left to right) + 西方漫畫(從左到右) + + + + + + web comic + 網路漫畫 + + + + + + 4koma (top to botom) + 4koma(由上至下) + + + + + + + Set type + 套裝類型 + + + + Library + + + + + Folder + 檔夾 + + + + Comic + 漫畫 + + + + Upgrade failed + 更新失敗 + + + + There were errors during library upgrade in: + 漫畫庫更新時出現錯誤: + + + + Update needed + 需要更新 + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + 此庫是使用舊版本的YACReaderLibrary創建的. 它需要更新. 現在更新? + + + + Download new version + 下載新版本 + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + 此庫是使用較新版本的YACReaderLibrary創建的。 立即下載新版本? + + + + Library not available + 庫不可用 + + + + Library '%1' is no longer available. Do you want to remove it? + 庫 '%1' 不再可用。 你想刪除它嗎? + + + + Old library + 舊的庫 + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? + + + + + Copying comics... + 複製漫畫中... + + + + + Moving comics... + 移動漫畫中... + + + + Add new folder + 添加新的檔夾 + + + + Folder name: + 檔夾名稱: + + + + No folder selected + 沒有選中的檔夾 + + + + Please, select a folder first + 請先選擇一個檔夾 + + + + Error in path + 路徑錯誤 + + + + There was an error accessing the folder's path + 訪問檔夾的路徑時出錯 + + + + Delete folder + 刪除檔夾 + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + 所選檔夾及其所有內容將從磁片中刪除。 你確定嗎? + + + + + Unable to delete + 無法刪除 + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + 嘗試刪除所選檔夾時出現問題。 請檢查寫入許可權,並確保沒有其他應用程式在使用這些檔夾或檔。 + + + + Add new reading lists + 添加新的閱讀列表 + + + + + List name: + 列表名稱: + + + + Delete list/label + 刪除 列表/標籤 + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + 所選項目將被刪除,您的漫畫或檔夾將不會從您的磁片中刪除。 你確定嗎? + + + + Rename list name + 重命名列表 + + + + Open folder... + 打開檔夾... + + + + Update folder + 更新檔夾 + + + + Rescan library for XML info + 重新掃描庫的 XML 資訊 + + + + Set as uncompleted + 設為未完成 + + + + Set as completed + 設為已完成 + + + + Set as read + 設為已讀 + + + + + Set as unread + 設為未讀 + + + + Set custom cover + 設定自訂封面 + + + + Delete custom cover + 刪除自訂封面 + + + + Save covers + 保存封面 + + + + You are adding too many libraries. + 您添加的庫太多了。 + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + 您添加的庫太多了。 + +一般情況只需要一個頂級的庫,您可以使用左側邊欄中的檔夾功能來進行分類管理。 + +YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低的庫數量來提升性能。 + + + + + YACReader not found + YACReader 未找到 + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + 未找到YACReader. YACReader應安裝在與YACReaderLibrary相同的檔夾中. + + + + YACReader not found. There might be a problem with your YACReader installation. + 未找到YACReader. YACReader的安裝可能有問題. + + + + Error + 錯誤 + + + + Error opening comic with third party reader. + 使用第三方閱讀器開啟漫畫時出錯。 + + + + Library not found + 未找到庫 + + + + The selected folder doesn't contain any library. + 所選檔夾不包含任何庫。 + + + + Are you sure? + 你確定嗎? + + + + Do you want remove + 你想要刪除 + + + + library? + 庫? + + + + Remove and delete metadata + 移除並刪除元數據 + + + + Library info + 圖書館資訊 + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + 嘗試刪除所選漫畫時出現問題。 請檢查所選檔或包含檔夾中的寫入許可權。 + + + + Assign comics numbers + 分配漫畫編號 + + + + Assign numbers starting in: + 從以下位置開始分配編號: + + + + Invalid image + 圖片無效 + + + + The selected file is not a valid image. + 所選檔案不是有效影像。 + + + + Error saving cover + 儲存封面時發生錯誤 + + + + There was an error saving the cover image. + 儲存封面圖片時發生錯誤。 + + + + Error creating the library + 創建庫時出錯 + + + + Error updating the library + 更新庫時出錯 + + + + Error opening the library + 打開庫時出錯 + + + + Delete comics + 刪除漫畫 + + + + All the selected comics will be deleted from your disk. Are you sure? + 所有選定的漫畫都將從您的磁片中刪除。你確定嗎? + + + + Remove comics + 移除漫畫 + + + + Comics will only be deleted from the current label/list. Are you sure? + 漫畫只會從當前標籤/列表中刪除。 你確定嗎? + + + + Library name already exists + 庫名已存在 + + + + There is another library with the name '%1'. + 已存在另一個名為'%1'的庫。 + + + + LibraryWindowActions + + + Create a new library + 創建一個新的庫 + + + + Open an existing library + 打開現有的庫 + + + + + Export comics info + 導出漫畫資訊 + + + + + Import comics info + 導入漫畫資訊 + + + + Pack covers + 打包封面 + + + + Pack the covers of the selected library + 打包所選庫的封面 + + + + Unpack covers + 解壓封面 + + + + Unpack a catalog + 解壓目錄 + + + + Update library + 更新庫 + + + + Update current library + 更新當前庫 + + + + Rename library + 重命名庫 + + + + Rename current library + 重命名當前庫 + + + + Remove library + 移除庫 + + + + Remove current library from your collection + 從您的集合中移除當前庫 + + + + Rescan library for XML info + 重新掃描庫的 XML 資訊 + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + 嘗試查找漫畫檔內嵌的 XML 資訊。只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 或者使用第三方軟體嵌入 XML 資訊時,才需要執行該操作。 + + + + Show library info + 顯示圖書館資訊 + + + + Show information about the current library + 顯示當前庫的信息 + + + + Open current comic + 打開當前漫畫 + + + + Open current comic on YACReader + 用YACReader打開漫畫 + + + + Save selected covers to... + 選中的封面保存到... + + + + Save covers of the selected comics as JPG files + 保存所選的封面為jpg + + + + + Set as read + 設為已讀 + + + + Set comic as read + 漫畫設為已讀 + + + + + Set as unread + 設為未讀 + + + + Set comic as unread + 漫畫設為未讀 + + + + + manga + 漫畫 + + + + Set issue as manga + 將問題設定為漫畫 + + + + + comic + 漫畫 + + + + Set issue as normal + 設置發行狀態為正常發行 + + + + western manga + 西方漫畫 + + + + Set issue as western manga + 將問題設定為西方漫畫 + + + + + web comic + 網路漫畫 + + + + Set issue as web comic + 將問題設定為網路漫畫 + + + + + yonkoma + 四科馬 + + + + Set issue as yonkoma + 將問題設定為 yonkoma + + + + Show/Hide marks + 顯示/隱藏標記 + + + + Show or hide read marks + 顯示或隱藏閱讀標記 + + + + Show/Hide recent indicator + 顯示/隱藏最近的指標 + + + + Show or hide recent indicator + 顯示或隱藏最近的指示器 + + + + + Fullscreen mode on/off + 全屏模式 開/關 + + + + Help, About YACReader + 幫助, 關於 YACReader + + + + Add new folder + 添加新的檔夾 + + + + Add new folder to the current library + 在當前庫下添加新的檔夾 + + + + Delete folder + 刪除檔夾 + + + + Delete current folder from disk + 從磁片上刪除當前檔夾 + + + + Select root node + 選擇根節點 + + + + Expand all nodes + 展開所有節點 + + + + Collapse all nodes + 折疊所有節點 + + + + Show options dialog + 顯示選項對話框 + + + + Show comics server options dialog + 顯示漫畫伺服器選項對話框 + + + + + Change between comics views + 漫畫視圖之間的變化 + + + + Open folder... + 打開檔夾... + + + + Set as uncompleted + 設為未完成 + + + + Set as completed + 設為已完成 + + + + Set custom cover + 設定自訂封面 + + + + Delete custom cover + 刪除自訂封面 + + + + western manga (left to right) + 西方漫畫(從左到右) + + + + Open containing folder... + 打開包含檔夾... + + + + Reset comic rating + 重置漫畫評分 + + + + Select all comics + 全選漫畫 + + + + Edit + 編輯 + + + + Assign current order to comics + 將當前序號分配給漫畫 + + + + Update cover + 更新封面 + + + + Delete selected comics + 刪除所選的漫畫 + + + + Delete metadata from selected comics + 從選定的漫畫中刪除元數據 + + + + Download tags from Comic Vine + 從 Comic Vine 下載標籤 + + + + Focus search line + 聚焦於搜索行 + + + + Focus comics view + 聚焦於漫畫視圖 + + + + Edit shortcuts + 編輯快捷鍵 + + + + &Quit + 退出(&Q) + + + + Update folder + 更新檔夾 + + + + Update current folder + 更新當前檔夾 + + + + Scan legacy XML metadata + 掃描舊版 XML 元數據 + + + + Add new reading list + 添加新的閱讀列表 + + + + Add a new reading list to the current library + 在當前庫添加新的閱讀列表 + + + + Remove reading list + 移除閱讀列表 + + + + Remove current reading list from the library + 從當前庫移除閱讀列表 + + + + Add new label + 添加新標籤 + + + + Add a new label to this library + 在當前庫添加標籤 + + + + Rename selected list + 重命名列表 + + + + Rename any selected labels or lists + 重命名任何選定的標籤或列表 + + + + Add to... + 添加到... + + + + Favorites + 收藏夾 + + + + Add selected comics to favorites list + 將所選漫畫添加到收藏夾列表 + + + + LocalComicListModel + + + file name + 檔案名 + + + + LogWindow + + Log window + 日誌窗口 + + + &Pause + 中止(&P) + + + &Save + 保存(&S) + + + C&lear + 清空(&l) + + + &Copy + 複製(&C) + + + Level: + 等級: + + + &Auto scroll + 自動滾動(&A) + + + + NoLibrariesWidget + + + You don't have any libraries yet + 你還沒有庫 + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>您可以在任何檔夾中創建庫,YACReaderLibrary將導入此檔夾中的所有漫畫和文件夾。如果已有庫,則可以打開它們。</p><p>您可以把YACReader當成獨立應用來閱讀電腦上的漫畫。</p> + + + + create your first library + 創建你的第一個庫 + + + + add an existing one + 添加一個現有庫 + + + + NoSearchResultsWidget + + + No results + 沒有結果 + + + + OptionsDialog + + + "Go to flow" size + 頁面流尺寸 + + + + My comics path + 我的漫畫路徑 + + + + Background color + 背景顏色 + + + + Choose + 選擇 + + + + Quick Navigation Mode 快速導航模式 - - Disable mouse over activation - 禁用滑鼠啟動 + + Disable mouse over activation + 禁用滑鼠啟動 + + + + Scaling + 縮放 + + + + Scaling method + 縮放方法 + + + + Nearest (fast, low quality) + 最近(快速,低品質) + + + + Bilinear + 雙線性 + + + + Lanczos (better quality) + Lanczos(品質更好) + + + + + Restart is needed + 需要重啟 + + + + Brightness + 亮度 + + + + Display + 展示 + + + + Show time in current page information label + 在目前頁面資訊標籤中顯示時間 + + + + Scroll behaviour + 滾動效果 + + + + Disable scroll animations and smooth scrolling + 停用滾動動畫和平滑滾動 + + + + Do not turn page using scroll + 滾動時不翻頁 + + + + Use single scroll step to turn page + 使用單滾動步驟翻頁 + + + + Mouse mode + 滑鼠模式 + + + + Only Back/Forward buttons can turn pages + 只有後退/前進按鈕可以翻頁 + + + + Use the Left/Right buttons to turn pages. + 使用向左/向右按鈕翻頁。 + + + + Click left or right half of the screen to turn pages. + 點擊螢幕的左半部或右半部即可翻頁。 + + + + Contrast + 對比度 + + + + Gamma + Gamma值 + + + + Reset + 重置 + + + + Image options + 圖片選項 + + + + Fit options + 適應項 + + + + Enlarge images to fit width/height + 放大圖片以適應寬度/高度 + + + + Double Page options + 雙頁選項 + + + + Show covers as single page + 顯示封面為單頁 + + + + + General + 常規 + + + + + Libraries + + + + + Comic Flow + 漫畫流 + + + + Grid view + 網格視圖 + + + + + Appearance + 外貌 + + + + + Language + 語言 + + + + + Application language + 應用程式語言 + + + + + System default + 系統預設 + + + + Tray icon settings (experimental) + 託盤圖示設置 (實驗特性) + + + + Close to tray + 關閉至託盤 + + + + Start into the system tray + 啟動至系統託盤 + + + + Edit Comic Vine API key + 編輯Comic Vine API 密匙 + + + + Comic Vine API key + Comic Vine API 密匙 + + + + ComicInfo.xml legacy support + ComicInfo.xml 遺留支持 + + + + Import metadata from ComicInfo.xml when adding new comics + 新增漫畫時從 ComicInfo.xml 匯入元數據 + + + + Consider 'recent' items added or updated since X days ago + 考慮自 X 天前新增或更新的「最近」項目 + + + + Third party reader + 第三方閱讀器 + + + + Write {comic_file_path} where the path should go in the command + 在命令中應將路徑寫入 {comic_file_path} + + + + + Clear + 清空 + + + + Update libraries at startup + 啟動時更新庫 + + + + Try to detect changes automatically + 嘗試自動偵測變化 + + + + Update libraries periodically + 定期更新庫 + + + + Interval: + 間隔: + + + + 30 minutes + 30分鐘 + + + + 1 hour + 1小時 + + + + 2 hours + 2小時 + + + + 4 hours + 4小時 + + + + 8 hours + 8小時 + + + + 12 hours + 12小時 + + + + daily + 日常的 + + + + Update libraries at certain time + 定時更新庫 + + + + Time: + 時間: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + 警告!在庫更新期間,將停用對資料庫的寫入! +當您可能正在積極使用應用程式時,請勿安排更新。 +在自動更新期間,應用程式將阻止某些操作,直到更新完成。 +若要停止自動更新,請點選庫標題旁的載入指示器。 + + + + Modifications detection + 修改檢測 + + + + Compare the modified date of files when updating a library (not recommended) + 更新庫時比較文件的修改日期(不建議) + + + + Enable background image + 啟用背景圖片 + + + + Opacity level + 透明度 + + + + Blur level + 模糊 + + + + Use selected comic cover as background + 使用選定的漫畫封面做背景 + + + + Restore defautls + 恢復默認值 + + + + Background + 背景 + + + + Display continue reading banner + 顯示繼續閱讀橫幅 + + + + Display current comic banner + 顯示目前漫畫橫幅 + + + + Continue reading + 繼續閱讀 + + + + Page Flow + 頁面流 + + + + Image adjustment + 圖像調整 + + + + + Options + 選項 + + + + Comics directory + 漫畫目錄 + + + + PropertiesDialog + + + General info + 基本資訊 + + + + Plot + 情節 + + + + Authors + 作者 + + + + Publishing + 出版 + + + + Notes + 筆記 + + + + Cover page + 封面 + + + + Load previous page as cover + 載入上一頁作為封面 + + + + Load next page as cover + 載入下一頁作為封面 + + + + Reset cover to the default image + 將封面重設為預設圖片 + + + + Load custom cover image + 載入自訂封面圖片 + + + + Series: + 系列: + + + + Title: + 標題: + + + + + + of: + 的: + + + + Issue number: + 發行數量: + + + + Volume: + 卷: + + + + Arc number: + 世界線數量: + + + + Story arc: + 故事線: + + + + alt. number: + 替代。數字: + + + + Alternate series: + 替代系列: + + + + Series Group: + 系列組: + + + + Genre: + 類型: + + + + Size: + 大小: + + + + Writer(s): + 作者: + + + + Penciller(s): + 線稿: + + + + Inker(s): + 墨稿: + + + + Colorist(s): + 上色: + + + + Letterer(s): + 文本: + + + + Cover Artist(s): + 封面設計: + + + + Editor(s): + 編輯: + + + + Imprint: + 印記: + + + + Day: + 日: + + + + Month: + 月: + + + + Year: + 年: + + + + Publisher: + 出版者: + + + + Format: + 格式: + + + + Color/BW: + 彩色/黑白: + + + + Age rating: + 年齡等級: - - Restart is needed - 需要重啟 + + Type: + 類型: - - Brightness - 亮度 + + Language (ISO): + 語言(ISO): - - Display - + + Synopsis: + 概要: - - Show time in current page information label - + + Characters: + 角色: - - Scroll behaviour - 滾動效果 + + Teams: + 團隊: - - Disable scroll animations and smooth scrolling - + + Locations: + 地點: - - Do not turn page using scroll - 滾動時不翻頁 + + Main character or team: + 主要角色或團隊: - - Use single scroll step to turn page - 使用單滾動步驟翻頁 + + Review: + 審查: - - Mouse mode - + + Notes: + 筆記: - - Only Back/Forward buttons can turn pages - + + Tags: + 標籤: - - Use the Left/Right buttons to turn pages. - + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> - - Click left or right half of the screen to turn pages. - + + Not found + 未找到 - - Contrast - 對比度 + + Comic not found. You should update your library. + 未找到漫畫,請先更新您的庫. - - Gamma - Gamma值 + + Edit comic information + 編輯漫畫資訊 + + + + Edit selected comics information + 編輯選中的漫畫資訊 + + + + Invalid cover + 封面無效 + + + + The image is invalid. + 該圖像無效。 + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 + +此應用程式支援持久性設置,要設定它們,請編輯此文件 %1 +若要了解可用設置,請查看文件:https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject + + + 7z lib not found + 未找到 7z 庫檔 + + + + unable to load 7z lib from ./utils + 無法從 ./utils 載入 7z 庫檔 + + + + Trace + 追蹤 + + + + Debug + 除錯 + + + + Info + 資訊 + + + + Warning + 警告 + + + + Error + 錯誤 + + + + Fatal + 嚴重錯誤 + + + + Select custom cover + 選擇自訂封面 + + + + Images (%1) + 圖片 (%1) + + + + The file could not be read or is not valid JSON. + 無法讀取該檔案或該檔案不是有效的 JSON。 + + + + This theme is for %1, not %2. + 此主題適用於 %1,而不是 %2。 + + + + Libraries + + + + + Folders + 檔夾 + + + + Reading Lists + 閱讀列表 + + + + QsLogging::LogWindowModel + + Time + 時間 + + + Level + 等級 + + + Message + 資訊 + + + + QsLogging::Window + + &Pause + 中止(&P) + + + &Resume + 恢復(&R) + + + Save log + 保存日誌 + + + Log file (*.log) + 日誌檔 (*.log) + + + + RenameLibraryDialog + + + New Library Name : + 新庫名: + + + + Rename + 重命名 + + + + Cancel + 取消 + + + + Rename current library + 重命名當前庫 + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + 搜索結果: %1 + + + + + page %1 of %2 + 第 %1 頁 共 %2 頁 + + + + Number of %1 found : %2 + 第 %1 頁 共: %2 條 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + 請提供附加資訊. + + + + Series: + 系列: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + 使用精確匹配搜尋。如果您想要尋找與名稱中某些單字相符的捲,請停用。 + + + + SearchVolume + + + Please provide some additional information. + 請提供附加資訊. + + + + Series: + 系列: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + 使用精確匹配搜尋。如果您想要尋找與名稱中某些單字相符的捲,請停用。 + + + + SelectComic + + + Please, select the right comic info. + 請正確選擇漫畫資訊. + + + + comics + 漫畫 + + + + loading cover + 加載封面 + + + + loading description + 加載描述 + + + + comic description unavailable + 漫畫描述不可用 + + + + SelectVolume + + + Please, select the right series for your comic. + 請選擇正確的漫畫系列。 + + + + Filter: + 篩選: + + + + volumes + + + + + Nothing found, clear the filter if any. + 未找到任何內容,如果有,請清除過濾器。 + + + + loading cover + 加載封面 + + + + loading description + 加載描述 + + + + volume description unavailable + 卷描述不可用 + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + 您正在嘗試同時獲取各種漫畫的資訊,它們是同一系列的嗎? + + + + yes + + + + + no + + + + + ServerConfigDialog + + + set port + 設置端口 + + + + Server connectivity information + 伺服器連接資訊 + + + + Scan it! + 掃一掃! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 + + + + Choose an IP address + 選擇IP地址 + + + + Port + 端口 + + + + enable the server + 啟用伺服器 + + + + ShortcutsDialog + + YACReader keyboard shortcuts + YACReader 鍵盤快捷鍵 + + + Close + 關閉 + + + Keyboard Shortcuts + 鍵盤快捷鍵 + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + 請在左側對漫畫列表進行排序,直到它與漫畫的資訊相符。 + + + + sort comics to match comic information + 排序漫畫以匹配漫畫資訊 + + + + issues + 發行 + + + + remove selected comics + 移除所選漫畫 + + + + restore all removed comics + 恢復所有移除的漫畫 + + + + ThemeEditorDialog + + + Theme Editor + 主題編輯器 + + + + + + + + + + + - + - + + + + i + + + + + Expand all + 全部展開 + + + + Collapse all + 全部折疊 + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + 按住可在 UI 中閃爍所選值(洋紅色/切換/0↔10)。發布後恢復原樣。 + + + + Search… + 搜尋… - - Reset - 重置 + + Light + 亮度 - - Image options - 圖片選項 + + Dark + 黑暗的 - - Fit options - 適應項 + + ID: + ID: - - Enlarge images to fit width/height - 放大圖片以適應寬度/高度 + + Display name: + 顯示名稱: - - Double Page options - 雙頁選項 + + Variant: + 變體: - - Show covers as single page - 顯示封面為單頁 + + Theme info + 主題訊息 - - General - 常規 + + Parameter + 範圍 - - Page Flow - 頁面流 + + Value + 價值 - - Image adjustment - 圖像調整 + + Save and apply + 儲存並應用 - - Options - 選項 + + Export to file... + 匯出到文件... - - Comics directory - 漫畫目錄 + + Load from file... + 從檔案載入... - - - QObject - - 7z lib not found - 未找到 7z 庫檔 + + Close + 關閉 - - unable to load 7z lib from ./utils - 無法從 ./utils 載入 7z 庫檔 + + Double-click to edit color + 雙擊編輯顏色 - - Trace - 追蹤 + + + + + + + true + 真的 - - Debug - 除錯 + + + + + false + 錯誤的 - - Info - 資訊 + + Double-click to toggle + 按兩下切換 - - Warning - 警告 + + Double-click to edit value + 雙擊編輯值 - - Error - 錯誤 + + + + Edit: %1 + 編輯:%1 - - Fatal - 嚴重錯誤 + + Save theme + 儲存主題 - - Select custom cover - + + + JSON files (*.json);;All files (*) + JSON 檔案 (*.json);;所有檔案 (*) - - Images (%1) - + + Save failed + 保存失敗 - - - QsLogging::LogWindowModel - - Time - 時間 + + Could not open file for writing: +%1 + 無法開啟文件進行寫入: +%1 - - Level - 等級 + + Load theme + 載入主題 - - Message - 資訊 + + + + Load failed + 載入失敗 - - - QsLogging::Window - - &Pause - 中止(&P) + + Could not open file: +%1 + 無法開啟檔案: +%1 - - &Resume - 恢復(&R) + + Invalid JSON: +%1 + 無效的 JSON: +%1 - - Save log - 保存日誌 + + Expected a JSON object. + 需要一個 JSON 物件。 + + + TitleHeader - - Log file (*.log) - 日誌檔 (*.log) + + SEARCH + 搜索 - ShortcutsDialog + UpdateLibraryDialog - YACReader keyboard shortcuts - YACReader 鍵盤快捷鍵 + + Updating.... + 更新中... - Close - 關閉 + + Cancel + 取消 - Keyboard Shortcuts - 鍵盤快捷鍵 + + Update library + 更新庫 Viewer - - + + Press 'O' to open comic. 按下 'O' 以打開漫畫. - + Not found 未找到 - + Comic not found 未找到漫畫 - + Error opening comic 打開漫畫時發生錯誤 - + CRC Error CRC 校驗失敗 - + Loading...please wait! 載入中... 請稍候! - + Page not available! 頁面不可用! - + Cover! 封面! - + Last page! 尾頁! + + VolumeComicsModel + + + title + 標題 + + + + VolumesModel + + + year + + + + + issues + 發行 + + + + publisher + 出版者 + + + + YACReader3DFlowConfigWidget + + + Presets: + 預設: + + + + Classic look + 經典 + + + + Stripe look + 條狀 + + + + Overlapped Stripe look + 重疊條狀 + + + + Modern look + 現代 + + + + Roulette look + 輪盤 + + + + Show advanced settings + 顯示高級選項 + + + + Custom: + 自定義: + + + + View angle + 視角 + + + + Position + 位置 + + + + Cover gap + 封面間距 + + + + Central gap + 中心間距 + + + + Zoom + 縮放 + + + + Y offset + Y位移 + + + + Z offset + Z位移 + + + + Cover Angle + 封面角度 + + + + Visibility + 透明度 + + + + Light + 亮度 + + + + Max angle + 最大角度 + + + + Low Performance + 低性能 + + + + High Performance + 高性能 + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + 使用VSync (在全屏模式下提高圖像品質, 性能更差) + + + + Performance: + 性能: + + YACReader::MainWindowViewer - + &Open 打開(&O) - + Open a comic 打開漫畫 - + New instance 新建實例 - + Open Folder 打開檔夾 - + Open image folder 打開圖片檔夾 - + Open latest comic 打開最近的漫畫 - + Open the latest comic opened in the previous reading session 打開最近閱讀漫畫 - + Clear 清空 - + Clear open recent list 清空最近訪問列表 - + Save 保存 - + Save current page 保存當前頁面 @@ -557,285 +3230,296 @@ 上一個漫畫 - - - + + + Open previous comic 打開上一個漫畫 - + Next Comic 下一個漫畫 - - - + + + Open next comic 打開下一個漫畫 - + &Previous 上一頁(&P) - - - + + + Go to previous page 轉至上一頁 - + &Next 下一頁(&N) - - - + + + Go to next page 轉至下一頁 - + Fit Height 適應高度 - + Fit image to height 縮放圖片以適應高度 - + Fit Width 適合寬度 - + Fit image to width 縮放圖片以適應寬度 - + Show full size 顯示全尺寸 - + Fit to page 適應頁面 - + + Continuous scroll + 連續滾動 + + + + Switch to continuous scroll mode + 切換到連續滾動模式 + + + Reset zoom 重置縮放 - + Show zoom slider 顯示縮放滑塊 - + Zoom+ 放大 - + Zoom- 縮小 - + Rotate image to the left 向左旋轉圖片 - + Rotate image to the right 向右旋轉圖片 - + Double page mode 雙頁模式 - + Switch to double page mode 切換至雙頁模式 - + Double page manga mode 雙頁漫畫模式 - + Reverse reading order in double page mode 雙頁模式 (逆序閱讀) - + Go To 跳轉 - + Go to page ... 跳轉至頁面 ... - + Options 選項 - + YACReader options YACReader 選項 - - + + Help 幫助 - + Help, About YACReader 幫助, 關於 YACReader - + Magnifying glass 放大鏡 - + Switch Magnifying glass 切換放大鏡 - + Set bookmark 設置書簽 - + Set a bookmark on the current page 在當前頁面設置書簽 - + Show bookmarks 顯示書簽 - + Show the bookmarks of the current comic 顯示當前漫畫的書簽 - + Show keyboard shortcuts 顯示鍵盤快捷鍵 - + Show Info 顯示資訊 - + Close 關閉 - + Show Dictionary 顯示字典 - + Show go to flow 顯示頁面流 - + Edit shortcuts 編輯快捷鍵 - + &File 檔(&F) - - + + Open recent 最近打開的檔 - + File - + Edit 編輯 - + View 查看 - + Go 轉到 - + Window 窗口 - - - + + + Open Comic 打開漫畫 - - - + + + Comic files 漫畫檔 - + Open folder 打開檔夾 - + page_%1.jpg - page_%1.jpg + 頁_%1.jpg - + Image files (*.jpg) 圖像檔 (*.jpg) + Comics 漫畫 @@ -851,6 +3535,7 @@ 隱藏/顯示 工具欄 + General 常規 @@ -878,9 +3563,10 @@ Reset magnifying glass - + 重置放大鏡 + Magnifiying glass 放大鏡 @@ -891,112 +3577,131 @@ 切換顯示為"適應寬度"或"適應高度" + Page adjustement 頁面調整 - + Autoscroll down 向下自動滾動 - + Autoscroll up 向上自動滾動 - + Autoscroll forward, horizontal first 向前自動滾動,水準優先 - + Autoscroll backward, horizontal first 向後自動滾動,水準優先 - + Autoscroll forward, vertical first 向前自動滾動,垂直優先 - + Autoscroll backward, vertical first 向後自動滾動,垂直優先 - + Move down 向下移動 - + Move up 向上移動 - + Move left 向左移動 - + Move right 向右移動 - + Go to the first page 轉到第一頁 - + Go to the last page 轉到最後一頁 - + Offset double page to the left - + 雙頁向左偏移 - + Offset double page to the right - + 雙頁向右偏移 - + + Reading 閱讀 - + There is a new version available 有新版本可用 - + Do you want to download the new version? 你要下載新版本嗎? - + Remind me in 14 days 14天後提醒我 - + Not now 現在不 + + YACReader::TrayIconController + + + &Restore + 複位(&R) + + + + Systray + 系統託盤 + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary 將繼續在系統託盤中運行. 想要終止程式, 請在系統託盤圖示的上下文菜單中選擇<b>退出</b>. + + YACReader::WhatsNewDialog - Close - 關閉 + 關閉 @@ -1032,170 +3737,150 @@ YACReaderFlowConfigWidget - How to show covers: - 封面顯示方式: + 封面顯示方式: - CoverFlow look - 封面流 + 封面流 - Stripe look - 條狀 + 條狀 - Overlapped Stripe look - 重疊條狀 + 重疊條狀 YACReaderGLFlowConfigWidget - Presets: - 預設: + 預設: - Classic look - 經典 + 經典 - Stripe look - 條狀 + 條狀 - Overlapped Stripe look - 重疊條狀 + 重疊條狀 - Modern look - 現代 + 現代 - Roulette look - 輪盤 + 輪盤 - Show advanced settings - 顯示高級選項 + 顯示高級選項 - Custom: - 自定義: + 自定義: - View angle - 視角 + 視角 - Position - 位置 + 位置 - Cover gap - 封面間距 + 封面間距 - Central gap - 中心間距 + 中心間距 - Zoom - 縮放 + 縮放 - Y offset - Y位移 + Y位移 - Z offset - Z位移 + Z位移 - Cover Angle - 封面角度 + 封面角度 - Visibility - 透明度 + 透明度 - Light - 亮度 + 亮度 - Max angle - 最大角度 + 最大角度 - Low Performance - 低性能 + 低性能 - High Performance - 高性能 + 高性能 - Use VSync (improve the image quality in fullscreen mode, worse performance) - 使用VSync (在全屏模式下提高圖像品質, 性能更差) + 使用VSync (在全屏模式下提高圖像品質, 性能更差) - Performance: - 性能: + 性能: YACReaderOptionsDialog - + Save 保存 - + Cancel 取消 - + Edit shortcuts 編輯快捷鍵 - + Shortcuts 快捷鍵 - Use hardware acceleration (restart needed) - 使用硬體加速 (需要重啟) + 使用硬體加速 (需要重啟) + + + + YACReaderSearchLineEdit + + + type to search + 搜索類型 @@ -1209,23 +3894,23 @@ YACReaderTranslator - + YACReader translator YACReader 翻譯 - - + + Translation 翻譯 - + clear 清空 - + Service not available 服務不可用 diff --git a/YACReader/yacreader_zh_TW.ts b/YACReader/yacreader_zh_TW.ts index 4745cbaff..07e46820a 100644 --- a/YACReader/yacreader_zh_TW.ts +++ b/YACReader/yacreader_zh_TW.ts @@ -9,6 +9,196 @@ + + AddLabelDialog + + + Label name: + 標籤名稱: + + + + Choose a color: + 選擇標籤顏色: + + + + accept + 接受 + + + + cancel + 取消 + + + + AddLibraryDialog + + + Comics folder : + 漫畫檔夾: + + + + Library name : + 庫名: + + + + Add + 添加 + + + + Cancel + 取消 + + + + Add an existing library + 添加一個現有庫 + + + + ApiKeyDialog + + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 + + + + Paste here your Comic Vine API key + 在此粘貼你的Comic Vine API + + + + Accept + 接受 + + + + Cancel + 取消 + + + + AppearanceTabWidget + + + Color scheme + 配色方案 + + + + System + 系統 + + + + Light + 亮度 + + + + Dark + 黑暗的 + + + + Custom + 風俗 + + + + Remove + 消除 + + + + Remove this user-imported theme + 刪除此使用者匯入的主題 + + + + Light: + 光: + + + + Dark: + 黑暗的: + + + + Custom: + 自定義: + + + + Import theme... + 導入主題... + + + + Theme + 主題 + + + + Theme editor + 主題編輯器 + + + + Open Theme Editor... + 開啟主題編輯器... + + + + Theme editor error + 主題編輯器錯誤 + + + + The current theme JSON could not be loaded. + 無法載入目前主題 JSON。 + + + + Import theme + 導入主題 + + + + JSON files (*.json);;All files (*) + JSON 檔案 (*.json);;所有檔案 (*) + + + + Could not import theme from: +%1 + 無法從以下位置匯入主題: +%1 + + + + Could not import theme from: +%1 + +%2 + 無法從以下位置匯入主題: +%1 + +%2 + + + + Import failed + 導入失敗 + + BookmarksDialog @@ -33,6 +223,200 @@ 載入中... + + ClassicComicsView + + + Hide comic flow + 隱藏漫畫流 + + + + ComicModel + + + yes + + + + + no + + + + + Title + 標題 + + + + File Name + 檔案名 + + + + Pages + 頁數 + + + + Size + 大小 + + + + Read + 閱讀 + + + + Current Page + 當前頁 + + + + Publication Date + 發行日期 + + + + Rating + 評分 + + + + Series + 系列 + + + + Volume + 體積 + + + + Story Arc + 故事線 + + + + ComicVineDialog + + + skip + 忽略 + + + + back + 返回 + + + + next + 下一步 + + + + search + 搜索 + + + + close + 關閉 + + + + + comic %1 of %2 - %3 + 第 %1 本 共 %2 本 - %3 + + + + + + Looking for volume... + 搜索卷... + + + + %1 comics selected + 已選擇 %1 本漫畫 + + + + Error connecting to ComicVine + ComicVine 連接時出錯 + + + + + Retrieving tags for : %1 + 正在檢索標籤: %1 + + + + Retrieving volume info... + 正在接收卷資訊... + + + + Looking for comic... + 搜索漫畫中... + + + + ContinuousPageWidget + + + Loading page %1 + 正在載入頁面 %1 + + + + CreateLibraryDialog + + + Comics folder : + 漫畫檔夾: + + + + Library Name : + 庫名: + + + + Create + 創建 + + + + Cancel + 取消 + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + 創建一個新的庫可能需要幾分鐘時間,您可以先停止該進程,稍後可以通過更新庫選項來更新數據。 + + + + Create new library + 創建新的漫畫庫 + + + + Path not found + 未找到路徑 + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + 所選路徑不存在或不是有效路徑. 確保您具有此檔夾的寫入許可權 + + EditShortcutsDialog @@ -51,16 +435,134 @@ 快捷鍵設置 - + Shortcut in use 快捷鍵被佔用 - + The shortcut "%1" is already assigned to other function 快捷鍵 "%1" 已被映射至其他功能 + + EmptyFolderWidget + + + This folder doesn't contain comics yet + 該資料夾還沒有漫畫 + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + 此標籤尚未包含漫畫 + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + 此閱讀列表尚未包含任何漫畫 + + + + EmptySpecialListWidget + + + No favorites + 沒有收藏 + + + + You are not reading anything yet, come on!! + 你還沒有閱讀任何東西,加油!! + + + + There are no recent comics! + 沒有最近的漫畫! + + + + ExportComicsInfoDialog + + + Output file : + 輸出檔: + + + + Create + 創建 + + + + Cancel + 取消 + + + + Export comics info + 導出漫畫資訊 + + + + Destination database name + 目標資料庫名稱 + + + + Problem found while writing + 寫入時出現問題 + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 選定的輸出檔路徑不存在或路徑無效. 確保您具有此檔夾的寫入許可權 + + + + ExportLibraryDialog + + + Output folder : + 輸出檔夾: + + + + Create + 創建 + + + + Cancel + 取消 + + + + Create covers package + 創建封面包 + + + + Problem found while writing + 寫入時出現問題 + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 選定的輸出檔路徑不存在或路徑無效. 確保您具有此檔夾的寫入許可權 + + + + Destination directory + 目標目錄 + + FileComic @@ -116,438 +618,2609 @@ GoToFlowToolBar - + Page : 頁碼 : + + GridComicsView + + + Show info + 顯示資訊 + + HelpAboutDialog - + About 關於 - + Help 幫助 - + System info 系統資訊 - LogWindow + ImportComicsInfoDialog - - Log window - 日誌窗口 + + Import comics info + 導入漫畫資訊 - - &Pause - 中止(&P) + + Info database location : + 資料庫地址: - - &Save - 保存(&S) + + Import + 導入 - - C&lear - 清空(&l) + + Cancel + 取消 - - &Copy - 複製(&C) + + Comics info file (*.ydb) + 漫畫資訊檔(*.ydb) + + + ImportLibraryDialog - - Level: - 等級: + + Library Name : + 庫名: - - &Auto scroll - 自動滾動(&A) + + Package location : + 打包地址: - - - OptionsDialog - - "Go to flow" size - 頁面流尺寸 + + Destination folder : + 目標檔夾: - - My comics path - 我的漫畫路徑 + + Unpack + 解壓 - - Background color - 背景顏色 + + Cancel + 取消 - - Choose - 選擇 + + Extract a catalog + 提取目錄 - - Quick Navigation Mode + + Compresed library covers (*.clc) + 已壓縮的庫封面 (*.clc) + + + + ImportWidget + + + stop + 停止 + + + + Some of the comics being added... + 正在添加漫畫... + + + + Importing comics + 正在導入漫畫 + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary現在正在創建一個新庫。</p><p>這可能需要幾分鐘時間,您可以先停止該進程,稍後可以通過更新庫選項來更新數據。</p> + + + + Updating the library + 正在更新庫 + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>正在更新當前庫。要獲得更快的更新,請經常更新您的庫。</p><p>您可以停止該進程,稍後繼續更新操作。</p> + + + + Upgrading the library + 正在更新庫 + + + + <p>The current library is being upgraded, please wait.</p> + <p>正在更新當前漫畫庫, 請稍候.</p> + + + + Scanning the library + 正在掃描庫 + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>正在掃描當前庫的舊版 XML metadata 資訊。</p><p>這只需要執行一次,且只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 時。</p> + + + + LibraryWindow + + + YACReader Library + YACReader 庫 + + + + + + comic + 漫畫 + + + + + + manga + 漫畫 + + + + + + western manga (left to right) + 西方漫畫(從左到右) + + + + + + web comic + 網路漫畫 + + + + + + 4koma (top to botom) + 4koma(由上至下) + + + + + + + Set type + 套裝類型 + + + + Library + + + + + Folder + 檔夾 + + + + Comic + 漫畫 + + + + Upgrade failed + 更新失敗 + + + + There were errors during library upgrade in: + 漫畫庫更新時出現錯誤: + + + + Update needed + 需要更新 + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + 此庫是使用舊版本的YACReaderLibrary創建的. 它需要更新. 現在更新? + + + + Download new version + 下載新版本 + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + 此庫是使用較新版本的YACReaderLibrary創建的。 立即下載新版本? + + + + Library not available + 庫不可用 + + + + Library '%1' is no longer available. Do you want to remove it? + 庫 '%1' 不再可用。 你想刪除它嗎? + + + + Old library + 舊的庫 + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? + + + + + Copying comics... + 複製漫畫中... + + + + + Moving comics... + 移動漫畫中... + + + + Add new folder + 添加新的檔夾 + + + + Folder name: + 檔夾名稱: + + + + No folder selected + 沒有選中的檔夾 + + + + Please, select a folder first + 請先選擇一個檔夾 + + + + Error in path + 路徑錯誤 + + + + There was an error accessing the folder's path + 訪問檔夾的路徑時出錯 + + + + Delete folder + 刪除檔夾 + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + 所選檔夾及其所有內容將從磁片中刪除。 你確定嗎? + + + + + Unable to delete + 無法刪除 + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + 嘗試刪除所選檔夾時出現問題。 請檢查寫入許可權,並確保沒有其他應用程式在使用這些檔夾或檔。 + + + + Add new reading lists + 添加新的閱讀列表 + + + + + List name: + 列表名稱: + + + + Delete list/label + 刪除 列表/標籤 + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + 所選項目將被刪除,您的漫畫或檔夾將不會從您的磁片中刪除。 你確定嗎? + + + + Rename list name + 重命名列表 + + + + Open folder... + 打開檔夾... + + + + Update folder + 更新檔夾 + + + + Rescan library for XML info + 重新掃描庫的 XML 資訊 + + + + Set as uncompleted + 設為未完成 + + + + Set as completed + 設為已完成 + + + + Set as read + 設為已讀 + + + + + Set as unread + 設為未讀 + + + + Set custom cover + 設定自訂封面 + + + + Delete custom cover + 刪除自訂封面 + + + + Save covers + 保存封面 + + + + You are adding too many libraries. + 您添加的庫太多了。 + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + 您添加的庫太多了。 + +一般情況只需要一個頂級的庫,您可以使用左側邊欄中的檔夾功能來進行分類管理。 + +YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低的庫數量來提升性能。 + + + + + YACReader not found + YACReader 未找到 + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + 未找到YACReader. YACReader應安裝在與YACReaderLibrary相同的檔夾中. + + + + YACReader not found. There might be a problem with your YACReader installation. + 未找到YACReader. YACReader的安裝可能有問題. + + + + Error + 錯誤 + + + + Error opening comic with third party reader. + 使用第三方閱讀器開啟漫畫時出錯。 + + + + Library not found + 未找到庫 + + + + The selected folder doesn't contain any library. + 所選檔夾不包含任何庫。 + + + + Are you sure? + 你確定嗎? + + + + Do you want remove + 你想要刪除 + + + + library? + 庫? + + + + Remove and delete metadata + 移除並刪除元數據 + + + + Library info + 圖書館資訊 + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + 嘗試刪除所選漫畫時出現問題。 請檢查所選檔或包含檔夾中的寫入許可權。 + + + + Assign comics numbers + 分配漫畫編號 + + + + Assign numbers starting in: + 從以下位置開始分配編號: + + + + Invalid image + 圖片無效 + + + + The selected file is not a valid image. + 所選檔案不是有效影像。 + + + + Error saving cover + 儲存封面時發生錯誤 + + + + There was an error saving the cover image. + 儲存封面圖片時發生錯誤。 + + + + Error creating the library + 創建庫時出錯 + + + + Error updating the library + 更新庫時出錯 + + + + Error opening the library + 打開庫時出錯 + + + + Delete comics + 刪除漫畫 + + + + All the selected comics will be deleted from your disk. Are you sure? + 所有選定的漫畫都將從您的磁片中刪除。你確定嗎? + + + + Remove comics + 移除漫畫 + + + + Comics will only be deleted from the current label/list. Are you sure? + 漫畫只會從當前標籤/列表中刪除。 你確定嗎? + + + + Library name already exists + 庫名已存在 + + + + There is another library with the name '%1'. + 已存在另一個名為'%1'的庫。 + + + + LibraryWindowActions + + + Create a new library + 創建一個新的庫 + + + + Open an existing library + 打開現有的庫 + + + + + Export comics info + 導出漫畫資訊 + + + + + Import comics info + 導入漫畫資訊 + + + + Pack covers + 打包封面 + + + + Pack the covers of the selected library + 打包所選庫的封面 + + + + Unpack covers + 解壓封面 + + + + Unpack a catalog + 解壓目錄 + + + + Update library + 更新庫 + + + + Update current library + 更新當前庫 + + + + Rename library + 重命名庫 + + + + Rename current library + 重命名當前庫 + + + + Remove library + 移除庫 + + + + Remove current library from your collection + 從您的集合中移除當前庫 + + + + Rescan library for XML info + 重新掃描庫的 XML 資訊 + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + 嘗試查找漫畫檔內嵌的 XML 資訊。只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 或者使用第三方軟體嵌入 XML 資訊時,才需要執行該操作。 + + + + Show library info + 顯示圖書館資訊 + + + + Show information about the current library + 顯示當前庫的信息 + + + + Open current comic + 打開當前漫畫 + + + + Open current comic on YACReader + 用YACReader打開漫畫 + + + + Save selected covers to... + 選中的封面保存到... + + + + Save covers of the selected comics as JPG files + 保存所選的封面為jpg + + + + + Set as read + 設為已讀 + + + + Set comic as read + 漫畫設為已讀 + + + + + Set as unread + 設為未讀 + + + + Set comic as unread + 漫畫設為未讀 + + + + + manga + 漫畫 + + + + Set issue as manga + 將問題設定為漫畫 + + + + + comic + 漫畫 + + + + Set issue as normal + 設置發行狀態為正常發行 + + + + western manga + 西方漫畫 + + + + Set issue as western manga + 將問題設定為西方漫畫 + + + + + web comic + 網路漫畫 + + + + Set issue as web comic + 將問題設定為網路漫畫 + + + + + yonkoma + 四科馬 + + + + Set issue as yonkoma + 將問題設定為 yonkoma + + + + Show/Hide marks + 顯示/隱藏標記 + + + + Show or hide read marks + 顯示或隱藏閱讀標記 + + + + Show/Hide recent indicator + 顯示/隱藏最近的指標 + + + + Show or hide recent indicator + 顯示或隱藏最近的指示器 + + + + + Fullscreen mode on/off + 全屏模式 開/關 + + + + Help, About YACReader + 幫助, 關於 YACReader + + + + Add new folder + 添加新的檔夾 + + + + Add new folder to the current library + 在當前庫下添加新的檔夾 + + + + Delete folder + 刪除檔夾 + + + + Delete current folder from disk + 從磁片上刪除當前檔夾 + + + + Select root node + 選擇根節點 + + + + Expand all nodes + 展開所有節點 + + + + Collapse all nodes + 折疊所有節點 + + + + Show options dialog + 顯示選項對話框 + + + + Show comics server options dialog + 顯示漫畫伺服器選項對話框 + + + + + Change between comics views + 漫畫視圖之間的變化 + + + + Open folder... + 打開檔夾... + + + + Set as uncompleted + 設為未完成 + + + + Set as completed + 設為已完成 + + + + Set custom cover + 設定自訂封面 + + + + Delete custom cover + 刪除自訂封面 + + + + western manga (left to right) + 西方漫畫(從左到右) + + + + Open containing folder... + 打開包含檔夾... + + + + Reset comic rating + 重置漫畫評分 + + + + Select all comics + 全選漫畫 + + + + Edit + 編輯 + + + + Assign current order to comics + 將當前序號分配給漫畫 + + + + Update cover + 更新封面 + + + + Delete selected comics + 刪除所選的漫畫 + + + + Delete metadata from selected comics + 從選定的漫畫中刪除元數據 + + + + Download tags from Comic Vine + 從 Comic Vine 下載標籤 + + + + Focus search line + 聚焦於搜索行 + + + + Focus comics view + 聚焦於漫畫視圖 + + + + Edit shortcuts + 編輯快捷鍵 + + + + &Quit + 退出(&Q) + + + + Update folder + 更新檔夾 + + + + Update current folder + 更新當前檔夾 + + + + Scan legacy XML metadata + 掃描舊版 XML 元數據 + + + + Add new reading list + 添加新的閱讀列表 + + + + Add a new reading list to the current library + 在當前庫添加新的閱讀列表 + + + + Remove reading list + 移除閱讀列表 + + + + Remove current reading list from the library + 從當前庫移除閱讀列表 + + + + Add new label + 添加新標籤 + + + + Add a new label to this library + 在當前庫添加標籤 + + + + Rename selected list + 重命名列表 + + + + Rename any selected labels or lists + 重命名任何選定的標籤或列表 + + + + Add to... + 添加到... + + + + Favorites + 收藏夾 + + + + Add selected comics to favorites list + 將所選漫畫添加到收藏夾列表 + + + + LocalComicListModel + + + file name + 檔案名 + + + + LogWindow + + Log window + 日誌窗口 + + + &Pause + 中止(&P) + + + &Save + 保存(&S) + + + C&lear + 清空(&l) + + + &Copy + 複製(&C) + + + Level: + 等級: + + + &Auto scroll + 自動滾動(&A) + + + + NoLibrariesWidget + + + You don't have any libraries yet + 你還沒有庫 + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>您可以在任何檔夾中創建庫,YACReaderLibrary將導入此檔夾中的所有漫畫和文件夾。如果已有庫,則可以打開它們。</p><p>您可以把YACReader當成獨立應用來閱讀電腦上的漫畫。</p> + + + + create your first library + 創建你的第一個庫 + + + + add an existing one + 添加一個現有庫 + + + + NoSearchResultsWidget + + + No results + 沒有結果 + + + + OptionsDialog + + + "Go to flow" size + 頁面流尺寸 + + + + My comics path + 我的漫畫路徑 + + + + Background color + 背景顏色 + + + + Choose + 選擇 + + + + Quick Navigation Mode 快速導航模式 - - Disable mouse over activation - 禁用滑鼠啟動 + + Disable mouse over activation + 禁用滑鼠啟動 + + + + Scaling + 縮放 + + + + Scaling method + 縮放方法 + + + + Nearest (fast, low quality) + 最近(快速,低品質) + + + + Bilinear + 雙線性 + + + + Lanczos (better quality) + Lanczos(品質更好) + + + + + Restart is needed + 需要重啟 + + + + Brightness + 亮度 + + + + Display + 展示 + + + + Show time in current page information label + 在目前頁面資訊標籤中顯示時間 + + + + Scroll behaviour + 滾動效果 + + + + Disable scroll animations and smooth scrolling + 停用滾動動畫和平滑滾動 + + + + Do not turn page using scroll + 滾動時不翻頁 + + + + Use single scroll step to turn page + 使用單滾動步驟翻頁 + + + + Mouse mode + 滑鼠模式 + + + + Only Back/Forward buttons can turn pages + 只有後退/前進按鈕可以翻頁 + + + + Use the Left/Right buttons to turn pages. + 使用向左/向右按鈕翻頁。 + + + + Click left or right half of the screen to turn pages. + 點擊螢幕的左半部或右半部即可翻頁。 + + + + Contrast + 對比度 + + + + Gamma + Gamma值 + + + + Reset + 重置 + + + + Image options + 圖片選項 + + + + Fit options + 適應項 + + + + Enlarge images to fit width/height + 放大圖片以適應寬度/高度 + + + + Double Page options + 雙頁選項 + + + + Show covers as single page + 顯示封面為單頁 + + + + + General + 常規 + + + + + Libraries + + + + + Comic Flow + 漫畫流 + + + + Grid view + 網格視圖 + + + + + Appearance + 外貌 + + + + + Language + 語言 + + + + + Application language + 應用程式語言 + + + + + System default + 系統預設 + + + + Tray icon settings (experimental) + 託盤圖示設置 (實驗特性) + + + + Close to tray + 關閉至託盤 + + + + Start into the system tray + 啟動至系統託盤 + + + + Edit Comic Vine API key + 編輯Comic Vine API 密匙 + + + + Comic Vine API key + Comic Vine API 密匙 + + + + ComicInfo.xml legacy support + ComicInfo.xml 遺留支持 + + + + Import metadata from ComicInfo.xml when adding new comics + 新增漫畫時從 ComicInfo.xml 匯入元數據 + + + + Consider 'recent' items added or updated since X days ago + 考慮自 X 天前新增或更新的「最近」項目 + + + + Third party reader + 第三方閱讀器 + + + + Write {comic_file_path} where the path should go in the command + 在命令中應將路徑寫入 {comic_file_path} + + + + + Clear + 清空 + + + + Update libraries at startup + 啟動時更新庫 + + + + Try to detect changes automatically + 嘗試自動偵測變化 + + + + Update libraries periodically + 定期更新庫 + + + + Interval: + 間隔: + + + + 30 minutes + 30分鐘 + + + + 1 hour + 1小時 + + + + 2 hours + 2小時 + + + + 4 hours + 4小時 + + + + 8 hours + 8小時 + + + + 12 hours + 12小時 + + + + daily + 日常的 + + + + Update libraries at certain time + 定時更新庫 + + + + Time: + 時間: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + 警告!在庫更新期間,將停用對資料庫的寫入! +當您可能正在積極使用應用程式時,請勿安排更新。 +在自動更新期間,應用程式將阻止某些操作,直到更新完成。 +若要停止自動更新,請點選庫標題旁的載入指示器。 + + + + Modifications detection + 修改檢測 + + + + Compare the modified date of files when updating a library (not recommended) + 更新庫時比較文件的修改日期(不建議) + + + + Enable background image + 啟用背景圖片 + + + + Opacity level + 透明度 + + + + Blur level + 模糊 + + + + Use selected comic cover as background + 使用選定的漫畫封面做背景 + + + + Restore defautls + 恢復默認值 + + + + Background + 背景 + + + + Display continue reading banner + 顯示繼續閱讀橫幅 + + + + Display current comic banner + 顯示目前漫畫橫幅 + + + + Continue reading + 繼續閱讀 + + + + Page Flow + 頁面流 + + + + Image adjustment + 圖像調整 + + + + + Options + 選項 + + + + Comics directory + 漫畫目錄 + + + + PropertiesDialog + + + General info + 基本資訊 + + + + Plot + 情節 + + + + Authors + 作者 + + + + Publishing + 出版 + + + + Notes + 筆記 + + + + Cover page + 封面 + + + + Load previous page as cover + 載入上一頁作為封面 + + + + Load next page as cover + 載入下一頁作為封面 + + + + Reset cover to the default image + 將封面重設為預設圖片 + + + + Load custom cover image + 載入自訂封面圖片 + + + + Series: + 系列: + + + + Title: + 標題: + + + + + + of: + 的: + + + + Issue number: + 發行數量: + + + + Volume: + 卷: + + + + Arc number: + 世界線數量: + + + + Story arc: + 故事線: + + + + alt. number: + 替代。數字: + + + + Alternate series: + 替代系列: + + + + Series Group: + 系列組: + + + + Genre: + 類型: + + + + Size: + 大小: + + + + Writer(s): + 作者: + + + + Penciller(s): + 線稿: + + + + Inker(s): + 墨稿: + + + + Colorist(s): + 上色: + + + + Letterer(s): + 文本: + + + + Cover Artist(s): + 封面設計: + + + + Editor(s): + 編輯: + + + + Imprint: + 印記: + + + + Day: + 日: + + + + Month: + 月: + + + + Year: + 年: + + + + Publisher: + 出版者: + + + + Format: + 格式: + + + + Color/BW: + 彩色/黑白: + + + + Age rating: + 年齡等級: - - Restart is needed - 需要重啟 + + Type: + 類型: - - Brightness - 亮度 + + Language (ISO): + 語言(ISO): - - Display - + + Synopsis: + 概要: - - Show time in current page information label - + + Characters: + 角色: - - Scroll behaviour - 滾動效果 + + Teams: + 團隊: - - Disable scroll animations and smooth scrolling - + + Locations: + 地點: - - Do not turn page using scroll - 滾動時不翻頁 + + Main character or team: + 主要角色或團隊: - - Use single scroll step to turn page - 使用單滾動步驟翻頁 + + Review: + 審查: - - Mouse mode - + + Notes: + 筆記: - - Only Back/Forward buttons can turn pages - + + Tags: + 標籤: - - Use the Left/Right buttons to turn pages. - + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> - - Click left or right half of the screen to turn pages. - + + Not found + 未找到 - - Contrast - 對比度 + + Comic not found. You should update your library. + 未找到漫畫,請先更新您的庫. - - Gamma - Gamma值 + + Edit comic information + 編輯漫畫資訊 + + + + Edit selected comics information + 編輯選中的漫畫資訊 + + + + Invalid cover + 封面無效 + + + + The image is invalid. + 該圖像無效。 + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 + +此應用程式支援持久性設置,要設定它們,請編輯此文件 %1 +若要了解可用設置,請查看文件:https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject + + + 7z lib not found + 未找到 7z 庫檔 + + + + unable to load 7z lib from ./utils + 無法從 ./utils 載入 7z 庫檔 + + + + Trace + 追蹤 + + + + Debug + 除錯 + + + + Info + 資訊 + + + + Warning + 警告 + + + + Error + 錯誤 + + + + Fatal + 嚴重錯誤 + + + + Select custom cover + 選擇自訂封面 + + + + Images (%1) + 圖片 (%1) + + + + The file could not be read or is not valid JSON. + 無法讀取該檔案或該檔案不是有效的 JSON。 + + + + This theme is for %1, not %2. + 此主題適用於 %1,而不是 %2。 + + + + Libraries + + + + + Folders + 檔夾 + + + + Reading Lists + 閱讀列表 + + + + QsLogging::LogWindowModel + + Time + 時間 + + + Level + 等級 + + + Message + 資訊 + + + + QsLogging::Window + + &Pause + 中止(&P) + + + &Resume + 恢復(&R) + + + Save log + 保存日誌 + + + Log file (*.log) + 日誌檔 (*.log) + + + + RenameLibraryDialog + + + New Library Name : + 新庫名: + + + + Rename + 重命名 + + + + Cancel + 取消 + + + + Rename current library + 重命名當前庫 + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + 搜索結果: %1 + + + + + page %1 of %2 + 第 %1 頁 共 %2 頁 + + + + Number of %1 found : %2 + 第 %1 頁 共: %2 條 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + 請提供附加資訊. + + + + Series: + 系列: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + 使用精確匹配搜尋。如果您想要尋找與名稱中某些單字相符的捲,請停用。 + + + + SearchVolume + + + Please provide some additional information. + 請提供附加資訊. + + + + Series: + 系列: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + 使用精確匹配搜尋。如果您想要尋找與名稱中某些單字相符的捲,請停用。 + + + + SelectComic + + + Please, select the right comic info. + 請正確選擇漫畫資訊. + + + + comics + 漫畫 + + + + loading cover + 加載封面 + + + + loading description + 加載描述 + + + + comic description unavailable + 漫畫描述不可用 + + + + SelectVolume + + + Please, select the right series for your comic. + 請選擇正確的漫畫系列。 + + + + Filter: + 篩選: + + + + volumes + + + + + Nothing found, clear the filter if any. + 未找到任何內容,如果有,請清除過濾器。 + + + + loading cover + 加載封面 + + + + loading description + 加載描述 + + + + volume description unavailable + 卷描述不可用 + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + 您正在嘗試同時獲取各種漫畫的資訊,它們是同一系列的嗎? + + + + yes + + + + + no + + + + + ServerConfigDialog + + + set port + 設置端口 + + + + Server connectivity information + 伺服器連接資訊 + + + + Scan it! + 掃一掃! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 + + + + Choose an IP address + 選擇IP地址 + + + + Port + 端口 + + + + enable the server + 啟用伺服器 + + + + ShortcutsDialog + + YACReader keyboard shortcuts + YACReader 鍵盤快捷鍵 + + + Close + 關閉 + + + Keyboard Shortcuts + 鍵盤快捷鍵 + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + 請在左側對漫畫列表進行排序,直到它與漫畫的資訊相符。 + + + + sort comics to match comic information + 排序漫畫以匹配漫畫資訊 + + + + issues + 發行 + + + + remove selected comics + 移除所選漫畫 + + + + restore all removed comics + 恢復所有移除的漫畫 + + + + ThemeEditorDialog + + + Theme Editor + 主題編輯器 + + + + + + + + + + + - + - + + + + i + + + + + Expand all + 全部展開 + + + + Collapse all + 全部折疊 + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + 按住可在 UI 中閃爍所選值(洋紅色/切換/0↔10)。發布後恢復原樣。 + + + + Search… + 搜尋… - - Reset - 重置 + + Light + 亮度 - - Image options - 圖片選項 + + Dark + 黑暗的 - - Fit options - 適應項 + + ID: + ID: - - Enlarge images to fit width/height - 放大圖片以適應寬度/高度 + + Display name: + 顯示名稱: - - Double Page options - 雙頁選項 + + Variant: + 變體: - - Show covers as single page - 顯示封面為單頁 + + Theme info + 主題訊息 - - General - 常規 + + Parameter + 範圍 - - Page Flow - 頁面流 + + Value + 價值 - - Image adjustment - 圖像調整 + + Save and apply + 儲存並應用 - - Options - 選項 + + Export to file... + 匯出到文件... - - Comics directory - 漫畫目錄 + + Load from file... + 從檔案載入... - - - QObject - - 7z lib not found - 未找到 7z 庫檔 + + Close + 關閉 - - unable to load 7z lib from ./utils - 無法從 ./utils 載入 7z 庫檔 + + Double-click to edit color + 雙擊編輯顏色 - - Trace - 追蹤 + + + + + + + true + 真的 - - Debug - 除錯 + + + + + false + 錯誤的 - - Info - 資訊 + + Double-click to toggle + 按兩下切換 - - Warning - 警告 + + Double-click to edit value + 雙擊編輯值 - - Error - 錯誤 + + + + Edit: %1 + 編輯:%1 - - Fatal - 嚴重錯誤 + + Save theme + 儲存主題 - - Select custom cover - + + + JSON files (*.json);;All files (*) + JSON 檔案 (*.json);;所有檔案 (*) - - Images (%1) - + + Save failed + 保存失敗 - - - QsLogging::LogWindowModel - - Time - 時間 + + Could not open file for writing: +%1 + 無法開啟文件進行寫入: +%1 - - Level - 等級 + + Load theme + 載入主題 - - Message - 資訊 + + + + Load failed + 載入失敗 - - - QsLogging::Window - - &Pause - 中止(&P) + + Could not open file: +%1 + 無法開啟檔案: +%1 - - &Resume - 恢復(&R) + + Invalid JSON: +%1 + 無效的 JSON: +%1 - - Save log - 保存日誌 + + Expected a JSON object. + 需要一個 JSON 物件。 + + + TitleHeader - - Log file (*.log) - 日誌檔 (*.log) + + SEARCH + 搜索 - ShortcutsDialog + UpdateLibraryDialog - YACReader keyboard shortcuts - YACReader 鍵盤快捷鍵 + + Updating.... + 更新中... - Close - 關閉 + + Cancel + 取消 - Keyboard Shortcuts - 鍵盤快捷鍵 + + Update library + 更新庫 Viewer - - + + Press 'O' to open comic. 按下 'O' 以打開漫畫. - + Not found 未找到 - + Comic not found 未找到漫畫 - + Error opening comic 打開漫畫時發生錯誤 - + CRC Error CRC 校驗失敗 - + Loading...please wait! 載入中... 請稍候! - + Page not available! 頁面不可用! - + Cover! 封面! - + Last page! 尾頁! + + VolumeComicsModel + + + title + 標題 + + + + VolumesModel + + + year + + + + + issues + 發行 + + + + publisher + 出版者 + + + + YACReader3DFlowConfigWidget + + + Presets: + 預設: + + + + Classic look + 經典 + + + + Stripe look + 條狀 + + + + Overlapped Stripe look + 重疊條狀 + + + + Modern look + 現代 + + + + Roulette look + 輪盤 + + + + Show advanced settings + 顯示高級選項 + + + + Custom: + 自定義: + + + + View angle + 視角 + + + + Position + 位置 + + + + Cover gap + 封面間距 + + + + Central gap + 中心間距 + + + + Zoom + 縮放 + + + + Y offset + Y位移 + + + + Z offset + Z位移 + + + + Cover Angle + 封面角度 + + + + Visibility + 透明度 + + + + Light + 亮度 + + + + Max angle + 最大角度 + + + + Low Performance + 低性能 + + + + High Performance + 高性能 + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + 使用VSync (在全屏模式下提高圖像品質, 性能更差) + + + + Performance: + 性能: + + YACReader::MainWindowViewer - + &Open 打開(&O) - + Open a comic 打開漫畫 - + New instance 新建實例 - + Open Folder 打開檔夾 - + Open image folder 打開圖片檔夾 - + Open latest comic 打開最近的漫畫 - + Open the latest comic opened in the previous reading session 打開最近閱讀漫畫 - + Clear 清空 - + Clear open recent list 清空最近訪問列表 - + Save 保存 - + Save current page 保存當前頁面 @@ -557,285 +3230,296 @@ 上一個漫畫 - - - + + + Open previous comic 打開上一個漫畫 - + Next Comic 下一個漫畫 - - - + + + Open next comic 打開下一個漫畫 - + &Previous 上一頁(&P) - - - + + + Go to previous page 轉至上一頁 - + &Next 下一頁(&N) - - - + + + Go to next page 轉至下一頁 - + Fit Height 適應高度 - + Fit image to height 縮放圖片以適應高度 - + Fit Width 適合寬度 - + Fit image to width 縮放圖片以適應寬度 - + Show full size 顯示全尺寸 - + Fit to page 適應頁面 - + + Continuous scroll + 連續滾動 + + + + Switch to continuous scroll mode + 切換到連續滾動模式 + + + Reset zoom 重置縮放 - + Show zoom slider 顯示縮放滑塊 - + Zoom+ 放大 - + Zoom- 縮小 - + Rotate image to the left 向左旋轉圖片 - + Rotate image to the right 向右旋轉圖片 - + Double page mode 雙頁模式 - + Switch to double page mode 切換至雙頁模式 - + Double page manga mode 雙頁漫畫模式 - + Reverse reading order in double page mode 雙頁模式 (逆序閱讀) - + Go To 跳轉 - + Go to page ... 跳轉至頁面 ... - + Options 選項 - + YACReader options YACReader 選項 - - + + Help 幫助 - + Help, About YACReader 幫助, 關於 YACReader - + Magnifying glass 放大鏡 - + Switch Magnifying glass 切換放大鏡 - + Set bookmark 設置書簽 - + Set a bookmark on the current page 在當前頁面設置書簽 - + Show bookmarks 顯示書簽 - + Show the bookmarks of the current comic 顯示當前漫畫的書簽 - + Show keyboard shortcuts 顯示鍵盤快捷鍵 - + Show Info 顯示資訊 - + Close 關閉 - + Show Dictionary 顯示字典 - + Show go to flow 顯示頁面流 - + Edit shortcuts 編輯快捷鍵 - + &File 檔(&F) - - + + Open recent 最近打開的檔 - + File - + Edit 編輯 - + View 查看 - + Go 轉到 - + Window 窗口 - - - + + + Open Comic 打開漫畫 - - - + + + Comic files 漫畫檔 - + Open folder 打開檔夾 - + page_%1.jpg - page_%1.jpg + 頁_%1.jpg - + Image files (*.jpg) 圖像檔 (*.jpg) + Comics 漫畫 @@ -851,6 +3535,7 @@ 隱藏/顯示 工具欄 + General 常規 @@ -878,9 +3563,10 @@ Reset magnifying glass - + 重置放大鏡 + Magnifiying glass 放大鏡 @@ -891,112 +3577,131 @@ 切換顯示為"適應寬度"或"適應高度" + Page adjustement 頁面調整 - + Autoscroll down 向下自動滾動 - + Autoscroll up 向上自動滾動 - + Autoscroll forward, horizontal first 向前自動滾動,水準優先 - + Autoscroll backward, horizontal first 向後自動滾動,水準優先 - + Autoscroll forward, vertical first 向前自動滾動,垂直優先 - + Autoscroll backward, vertical first 向後自動滾動,垂直優先 - + Move down 向下移動 - + Move up 向上移動 - + Move left 向左移動 - + Move right 向右移動 - + Go to the first page 轉到第一頁 - + Go to the last page 轉到最後一頁 - + Offset double page to the left - + 雙頁向左偏移 - + Offset double page to the right - + 雙頁向右偏移 - + + Reading 閱讀 - + There is a new version available 有新版本可用 - + Do you want to download the new version? 你要下載新版本嗎? - + Remind me in 14 days 14天後提醒我 - + Not now 現在不 + + YACReader::TrayIconController + + + &Restore + 複位(&R) + + + + Systray + 系統託盤 + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary 將繼續在系統託盤中運行. 想要終止程式, 請在系統託盤圖示的上下文菜單中選擇<b>退出</b>. + + YACReader::WhatsNewDialog - Close - 關閉 + 關閉 @@ -1032,170 +3737,150 @@ YACReaderFlowConfigWidget - How to show covers: - 封面顯示方式: + 封面顯示方式: - CoverFlow look - 封面流 + 封面流 - Stripe look - 條狀 + 條狀 - Overlapped Stripe look - 重疊條狀 + 重疊條狀 YACReaderGLFlowConfigWidget - Presets: - 預設: + 預設: - Classic look - 經典 + 經典 - Stripe look - 條狀 + 條狀 - Overlapped Stripe look - 重疊條狀 + 重疊條狀 - Modern look - 現代 + 現代 - Roulette look - 輪盤 + 輪盤 - Show advanced settings - 顯示高級選項 + 顯示高級選項 - Custom: - 自定義: + 自定義: - View angle - 視角 + 視角 - Position - 位置 + 位置 - Cover gap - 封面間距 + 封面間距 - Central gap - 中心間距 + 中心間距 - Zoom - 縮放 + 縮放 - Y offset - Y位移 + Y位移 - Z offset - Z位移 + Z位移 - Cover Angle - 封面角度 + 封面角度 - Visibility - 透明度 + 透明度 - Light - 亮度 + 亮度 - Max angle - 最大角度 + 最大角度 - Low Performance - 低性能 + 低性能 - High Performance - 高性能 + 高性能 - Use VSync (improve the image quality in fullscreen mode, worse performance) - 使用VSync (在全屏模式下提高圖像品質, 性能更差) + 使用VSync (在全屏模式下提高圖像品質, 性能更差) - Performance: - 性能: + 性能: YACReaderOptionsDialog - + Save 保存 - + Cancel 取消 - + Edit shortcuts 編輯快捷鍵 - + Shortcuts 快捷鍵 - Use hardware acceleration (restart needed) - 使用硬體加速 (需要重啟) + 使用硬體加速 (需要重啟) + + + + YACReaderSearchLineEdit + + + type to search + 搜索類型 @@ -1209,23 +3894,23 @@ YACReaderTranslator - + YACReader translator YACReader 翻譯 - - + + Translation 翻譯 - + clear 清空 - + Service not available 服務不可用 diff --git a/YACReaderLibrary/CMakeLists.txt b/YACReaderLibrary/CMakeLists.txt index 485c11916..5fff54c74 100644 --- a/YACReaderLibrary/CMakeLists.txt +++ b/YACReaderLibrary/CMakeLists.txt @@ -223,6 +223,10 @@ endif() # Translations qt_add_translations(YACReaderLibrary + SOURCE_TARGETS + YACReaderLibrary + # Keep full C++ extraction via SOURCE_TARGETS and add qml.qrc as extra input + # so qsTr() strings in QML are collected too. TS_FILES yacreaderlibrary_es.ts yacreaderlibrary_ru.ts @@ -235,7 +239,10 @@ qt_add_translations(YACReaderLibrary yacreaderlibrary_zh_TW.ts yacreaderlibrary_zh_HK.ts yacreaderlibrary_it.ts + yacreaderlibrary_source.ts yacreaderlibrary_en.ts + SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/qml.qrc ) target_link_libraries(YACReaderLibrary PRIVATE diff --git a/YACReaderLibrary/library_window_actions.cpp b/YACReaderLibrary/library_window_actions.cpp index cebf7b51f..ce6e9f0fe 100644 --- a/YACReaderLibrary/library_window_actions.cpp +++ b/YACReaderLibrary/library_window_actions.cpp @@ -23,7 +23,7 @@ LibraryWindowActions::LibraryWindowActions() void LibraryWindowActions::createActions(LibraryWindow *window, QSettings *settings) { - auto tr = [](const char *text) { return QObject::tr(text); }; + auto tr = [](const char *text) { return QCoreApplication::translate("LibraryWindowActions", text); }; backAction = new QAction(window); backAction->setData(BACK_ACTION_YL); diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index 9c339e8f5..141b6561c 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -1,7 +1,6 @@ #include "library_window.h" #include -#include #include #include #include @@ -24,6 +23,7 @@ #include "appearance_configuration.h" #include "theme_manager.h" #include "theme_repository.h" +#include "app_language_utils.h" #ifdef Q_OS_MACOS #include "trayhandler.h" #endif @@ -171,13 +171,11 @@ int main(int argc, char **argv) logger.addDestination(std::move(debugDestination)); logger.addDestination(std::move(fileDestination)); - QTranslator translator; -#if defined Q_OS_UNIX && !defined Q_OS_MACOS - translator.load(QLocale(), "yacreaderlibrary", "_", QString(DATADIR) + "/yacreader/languages"); -#else - translator.load(QLocale(), "yacreaderlibrary", "_", "languages"); -#endif - app.installTranslator(&translator); + QSettings uiSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); + uiSettings.beginGroup("libraryConfig"); + QString selectedLanguage = uiSettings.value(UI_LANGUAGE).toString(); + uiSettings.endGroup(); + YACReader::UiLanguage::applyLanguage("yacreaderlibrary", selectedLanguage); /*QTranslator viewerTranslator; #if defined Q_OS_UNIX && !defined Q_OS_MACOS diff --git a/YACReaderLibrary/options_dialog.cpp b/YACReaderLibrary/options_dialog.cpp index f2cdb4bf8..aa00080cc 100644 --- a/YACReaderLibrary/options_dialog.cpp +++ b/YACReaderLibrary/options_dialog.cpp @@ -7,6 +7,7 @@ #include "theme_manager.h" #include "theme_factory.h" #include "appearance_tab_widget.h" +#include "app_language_utils.h" #include @@ -31,6 +32,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) auto buttons = new QHBoxLayout(); buttons->addStretch(); + buttons->addWidget(new QLabel(tr("Restart is needed"))); buttons->addWidget(accept); buttons->addWidget(cancel); @@ -54,6 +56,12 @@ void OptionsDialog::restoreOptions(QSettings *settings) { YACReaderOptionsDialog::restoreOptions(settings); + const auto selectedLanguage = settings->value(UI_LANGUAGE).toString().trimmed(); + int languageIndex = languageCombo->findData(selectedLanguage); + if (languageIndex < 0) + languageIndex = 0; + languageCombo->setCurrentIndex(languageIndex); + trayIconCheckbox->setChecked(settings->value(CLOSE_TO_TRAY, false).toBool()); startToTrayCheckbox->setChecked(settings->value(START_TO_TRAY, false).toBool()); startToTrayCheckbox->setEnabled(trayIconCheckbox->isChecked()); @@ -92,6 +100,12 @@ void OptionsDialog::restoreOptions(QSettings *settings) void OptionsDialog::saveOptions() { + const auto selectedLanguage = languageCombo->currentData().toString().trimmed(); + if (selectedLanguage.isEmpty()) + settings->remove(UI_LANGUAGE); + else + settings->setValue(UI_LANGUAGE, selectedLanguage); + settings->setValue(THIRD_PARTY_READER_COMMAND, thirdPartyReaderEdit->text()); YACReaderOptionsDialog::saveOptions(); } @@ -152,6 +166,19 @@ void OptionsDialog::resetToDefaults() QWidget *OptionsDialog::createGeneralTab() { + auto *languageBox = new QGroupBox(tr("Language")); + auto *languageLayout = new QHBoxLayout(); + languageLayout->addWidget(new QLabel(tr("Application language"))); + languageCombo = new QComboBox(this); + languageCombo->addItem(tr("System default"), QString()); + const auto availableLanguages = YACReader::UiLanguage::availableLanguages("yacreaderlibrary"); + for (const auto &language : availableLanguages) { + languageCombo->addItem( + QString("%1 (%2)").arg(language.displayName, language.code), language.code); + } + languageLayout->addWidget(languageCombo); + languageBox->setLayout(languageLayout); + // Tray icon settings QGroupBox *trayIconBox = new QGroupBox(tr("Tray icon settings (experimental)")); QVBoxLayout *trayLayout = new QVBoxLayout(); @@ -218,6 +245,7 @@ QWidget *OptionsDialog::createGeneralTab() connect(clearButton, &QPushButton::clicked, thirdPartyReaderEdit, &QLineEdit::clear); auto generalLayout = new QVBoxLayout(); + generalLayout->addWidget(languageBox); generalLayout->addWidget(trayIconBox); generalLayout->addWidget(shortcutsBox); generalLayout->addWidget(apiKeyBox); diff --git a/YACReaderLibrary/options_dialog.h b/YACReaderLibrary/options_dialog.h index 84caae53c..68faa16bd 100644 --- a/YACReaderLibrary/options_dialog.h +++ b/YACReaderLibrary/options_dialog.h @@ -34,6 +34,7 @@ private slots: QCheckBox *displayContinueReadingBannerCheck; QCheckBox *trayIconCheckbox; QCheckBox *startToTrayCheckbox; + QComboBox *languageCombo; QCheckBox *comicInfoXMLCheckbox; QSlider *recentIntervalSlider; QLabel *numDaysLabel; diff --git a/YACReaderLibrary/yacreaderlibrary_de.ts b/YACReaderLibrary/yacreaderlibrary_de.ts index abc2bc5a0..a4aaacf32 100644 --- a/YACReaderLibrary/yacreaderlibrary_de.ts +++ b/YACReaderLibrary/yacreaderlibrary_de.ts @@ -12,82 +12,70 @@ AddLabelDialog - + cancel Abbrechen - + Label name: Label-Name: - + Choose a color: Wähle eine Farbe: - red - Rot + Rot - orange - Orange + Orange - yellow - Gelb + Gelb - green - Grün + Grün - cyan - Kobalt + Kobalt - blue - Blau + Blau - violet - Violett + Violett - purple - Lila + Lila - pink - Pink + Pink - white - Weiß + Weiß - light - Hell + Hell - dark - Dunkel + Dunkel - + accept Akzeptieren @@ -100,7 +88,7 @@ Hinzufügen - + Add an existing library Eine vorhandene Bibliothek hinzufügen @@ -143,10 +131,150 @@ Abbrechen + + AppearanceTabWidget + + + Color scheme + Farbschema + + + + System + Systemumgebung + + + + Light + Helligkeit + + + + Dark + Dunkel + + + + Custom + Brauch + + + + Remove + Entfernen + + + + Remove this user-imported theme + Entfernen Sie dieses vom Benutzer importierte Design + + + + Light: + Licht: + + + + Dark: + Dunkel: + + + + Custom: + Benutzerdefiniert: + + + + Import theme... + Theme importieren... + + + + Theme + Thema + + + + Theme editor + Theme-Editor + + + + Open Theme Editor... + Theme-Editor öffnen... + + + + Theme editor error + Fehler im Theme-Editor + + + + The current theme JSON could not be loaded. + Der aktuelle Theme-JSON konnte nicht geladen werden. + + + + Import theme + Thema importieren + + + + JSON files (*.json);;All files (*) + JSON-Dateien (*.json);;Alle Dateien (*) + + + + Could not import theme from: +%1 + Theme konnte nicht importiert werden von: +%1 + + + + Could not import theme from: +%1 + +%2 + Theme konnte nicht importiert werden von: +%1 + +%2 + + + + Import failed + Der Import ist fehlgeschlagen + + + + BookmarksDialog + + + Lastest Page + Neueste Seite + + + + Close + Schließen + + + + Click on any image to go to the bookmark + Klicke auf ein beliebiges Bild, um zum Lesezeichen zu gehen + + + + + Loading... + Laden... + + ClassicComicsView - + Hide comic flow Comic "Flow" verstecken @@ -154,82 +282,82 @@ ComicInfoView - + Main character or team - + Hauptfigur oder Team - + Teams - + Mannschaften - + Locations - + Standorte - + Authors Autoren - + writer Schriftsteller - + penciller Künstler (Bleistift) - + inker Künstler (Tinte) - + colorist Künstler (Farbe) - + letterer Künstler (Lettering) - + cover artist Künstler (Cover) - + editor - + Redakteur - + imprint - + Imprint - + Publisher Herausgeber - + color Farbe - + b/w Schwarzweiß - + Characters Charaktere @@ -254,17 +382,17 @@ Series - + Serie Volume - + Volumen Story Arc - + Handlungsbogen @@ -294,7 +422,7 @@ Publication Date - + Veröffentlichungsdatum @@ -305,74 +433,82 @@ ComicVineDialog - + back zurück - + next nächste - + skip überspringen - + close schließen - - + + Retrieving tags for : %1 Herunterladen von Tags für : %1 - + Looking for comic... Suche nach Comic... - + search suche - - - + + + Looking for volume... Suche nach Band.... - - + + comic %1 of %2 - %3 Comic %1 von %2 - %3 - + %1 comics selected %1 Comic ausgewählt - + Error connecting to ComicVine Fehler bei Verbindung zu ComicVine - + Retrieving volume info... Herunterladen von Info zu Ausgabe... + + ContinuousPageWidget + + + Loading page %1 + Seite wird geladen %1 + + CreateLibraryDialog - + Create new library Erstelle eine neue Bibliothek @@ -392,7 +528,7 @@ Es kann einige Minuten dauern, eine neue Bibliothek zu erstellen. Sie können den Prozess abbrechen und die Bibliothek später aktualisieren, um den Vorgang abzuschließen. - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben @@ -407,7 +543,7 @@ Bibliothek-Name : - + Path not found Pfad nicht gefunden @@ -430,12 +566,12 @@ Kürzel-Einstellungen - + Shortcut in use Verwendete Kürzel - + The shortcut "%1" is already assigned to other function Das Kürzel "%1" ist bereits für eine andere Funktion in Verwendung @@ -443,26 +579,27 @@ EmptyFolderWidget - - Subfolders in this folder - Unterordner in diesem Ordner + Unterordner in diesem Ordner - Empty folder - Leerer Ordner + Leerer Ordner - Drag and drop folders and comics here - Ziehen Sie Ordner und Comics hierher, um sie abzulegen + Ziehen Sie Ordner und Comics hierher, um sie abzulegen + + + + This folder doesn't contain comics yet + Dieser Ordner enthält noch keine Comics EmptyLabelWidget - + This label doesn't contain comics yet Dieses Label enthält noch keine Comics @@ -475,6 +612,24 @@ Diese Leseliste enthält noch keine Comics + + EmptySpecialListWidget + + + No favorites + Keine Favoriten + + + + You are not reading anything yet, come on!! + Sie lesen noch nichts, starten Sie!! + + + + There are no recent comics! + Es gibt keine aktuellen Comics! + + ExportComicsInfoDialog @@ -483,7 +638,7 @@ Zieldatei : - + Destination database name Ziel-Datenbank Name @@ -498,17 +653,17 @@ Erstellen - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben - + Export comics info Comicinfo exportieren - + Problem found while writing Problem beim Schreiben @@ -526,7 +681,7 @@ Erstellen - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben @@ -536,17 +691,17 @@ Ziel-Ordner : - + Problem found while writing Problem beim Schreiben - + Create covers package Erzeuge Titelbild-Paket - + Destination directory Ziel-Verzeichnis @@ -577,23 +732,52 @@ FolderContentView - + Continue Reading... - + Weiterlesen... - FolderContentView6 + GoToDialog - - Continue Reading... - + + Page : + Seite : + + + + Go To + Gehe zu + + + + Cancel + Abbrechen + + + + + Total pages : + Seiten gesamt : + + + + Go to... + Gehe zu... + + + + GoToFlowToolBar + + + Page : + Seite : GridComicsView - + Show info Info anzeigen @@ -601,17 +785,17 @@ HelpAboutDialog - + Help Hilfe - + System info - + Systeminformationen - + About Über @@ -639,9 +823,9 @@ Importiere Comic-Info - + Comics info file (*.ydb) - Comics Info File (*.ydb) + Comics-Info-Datei (*.ydb) @@ -662,7 +846,7 @@ Entpacken - + Compresed library covers (*.clc) Komprimierte Bibliothek Cover (*.clc) @@ -677,7 +861,7 @@ Bibliothek-Name : - + Extract a catalog Einen Katalog extrahieren @@ -685,54 +869,54 @@ ImportWidget - + stop - Stop + Stopp - + Importing comics Comics werden importiert - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> <p>YACReaderLibrary erstellt nun eine neue Bibliothek. </p><p>Es kann einige Minuten dauern, eine neue Bibliothek zu erstellen. Sie können den Prozess abbrechen und die Bibliothek später aktualisieren, um den Vorgang abzuschließen.</p> - + Some of the comics being added... Einige der Comics werden hinzugefügt... - + Updating the library Aktualisierung der Bibliothek - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> <p>Die aktuelle Bibliothek wird gerade aktualisiert. Für eine schnellere Aktualisierung, aktualisieren Sie die Bibliothek bitte regelmäßig.</p><p>Sie können den Prozess abbrechen und mit der Aktualisierung später fortfahren.<p> - + Upgrading the library Upgrade der Bibliothek - + <p>The current library is being upgraded, please wait.</p> Die aktuelle Bibliothek wird gerade upgegradet, bitte warten. - + Scanning the library - + Durchsuchen der Bibliothek - + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> - + <p>Die aktuelle Bibliothek wird nach alten XML-Metadateninformationen durchsucht.</p><p>Dies ist nur einmal erforderlich und nur, wenn die Bibliothek mit YACReaderLibrary 9.8.2 oder früher erstellt wurde.</p> @@ -742,22 +926,22 @@ Bearbeiten - + The selected folder doesn't contain any library. Der ausgewählte Ordner enthält keine Bibliothek. - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? Diese Bibliothek wurde mit einer älteren Version von YACReader erzeugt. Sie muss geupdated werden. Jetzt updaten? - + Comic - Comic + Komisch - + Error opening the library Fehler beim Öffnen der Bibliothek @@ -766,8 +950,8 @@ Zeige/Verberge Markierungen - - + + YACReader not found YACReader nicht gefunden @@ -784,12 +968,12 @@ Comic als gelesen markieren - + Remove and delete metadata Entferne und lösche Metadaten - + Old library Alte Bibliothek @@ -798,12 +982,12 @@ Titelbild updaten - + Set as completed Als gelesen markieren - + Library Bibliothek @@ -816,7 +1000,7 @@ Vollbildmodus an/aus - + This library was created with a newer version of YACReaderLibrary. Download the new version now? Die Bibliothek wurde mit einer neueren Version von YACReader erstellt. Die neue Version jetzt herunterladen? @@ -829,7 +1013,7 @@ Aktuelle Bibliothek updaten - + Library '%1' is no longer available. Do you want to remove it? Bibliothek '%1' ist nicht mehr verfügbar. Wollen Sie sie entfernen? @@ -838,17 +1022,17 @@ Bibliothek updaten - + Open folder... Öffne Ordner... - + Do you want remove Möchten Sie entfernen - + Set as uncompleted Als nicht gelesen markieren @@ -857,12 +1041,12 @@ Comic-Bewertung zurücksetzen - + Error updating the library Fehler beim Updaten der Bibliothek - + Folder Ordner @@ -871,7 +1055,7 @@ Alle Unterordner anzeigen - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? Bibliothek '%1' wurde mit einer älteren Version von YACReader erstellt. Sie muss neu erzeugt werden. Wollen Sie die Bibliothek jetzt erzeugen? @@ -880,7 +1064,7 @@ Titelbild-Paket erzeugen - + Set as read Als gelesen markieren @@ -901,7 +1085,7 @@ Neue Bibliothek erstellen - + Library not available Bibliothek nicht verfügbar @@ -910,7 +1094,7 @@ Importiere Comics-Info - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. Es gab ein Problem beim Löschen der ausgewählten Comics. Überprüfen Sie bitte die Schreibberechtigung für die ausgewählten Dateien oder Ordner. @@ -919,12 +1103,12 @@ Aktuellen Comic öffnen - + YACReader Library YACReader Bibliothek - + Error creating the library Fehler beim Erstellen der Bibliothek @@ -933,7 +1117,7 @@ Titelbilder entpacken - + Update needed Update benötigt @@ -942,22 +1126,22 @@ Eine vorhandede Bibliothek öffnen - + Library name already exists Bibliothek-Name bereits vorhanden - + There is another library with the name '%1'. Es gibt bereits eine Bibliothek mit dem Namen '%1'. - + Download new version Neue Version herunterladen - + Delete comics Comics löschen @@ -986,7 +1170,7 @@ Katalog entpacken - + All the selected comics will be deleted from your disk. Are you sure? Alle ausgewählten Comics werden von Ihrer Festplatte gelöscht. Sind Sie sicher? @@ -995,13 +1179,13 @@ Tags von Comic Vine herunterladen - - + + Set as unread Als ungelesen markieren - + Library not found Bibliothek nicht gefunden @@ -1014,58 +1198,58 @@ Bibliothek entfernen - - - + + + manga - + Manga - - - + + + comic - + komisch - - - + + + web comic - + Webcomic - - - + + + western manga (left to right) - + Western-Manga (von links nach rechts) Open containing folder... Öffne aktuellen Ordner... - - + + Unable to delete Löschen nicht möglich - - - + + + 4koma (top to botom) 4koma (top to botom - + 4koma (von oben nach unten) - + library? Bibliothek? - + Are you sure? Sind Sie sicher? @@ -1074,9 +1258,9 @@ Ausgewählte Titelbilder speichern in... - + Rescan library for XML info - + Durchsuchen Sie die Bibliothek erneut nach XML-Informationen Save covers of the selected comics as JPG files @@ -1103,7 +1287,7 @@ Gelesen-Markierungen anzeigen oder verbergen - + Add new folder Neuen Ordner erstellen @@ -1112,7 +1296,7 @@ Neuen Ordner in der aktuellen Bibliothek erstellen - + Delete folder Ordner löschen @@ -1145,7 +1329,7 @@ &Schließen - + Update folder Ordner aktualisieren @@ -1198,118 +1382,118 @@ Ausgewählte Comics zu Favoriten hinzufügen - + Upgrade failed Update gescheitert - + There were errors during library upgrade in: Beim Upgrade der Bibliothek kam es zu Fehlern in: - - + + Copying comics... Kopieren von Comics... - - + + Moving comics... Verschieben von Comics... - + Folder name: Ordnername - + No folder selected Kein Ordner ausgewählt - + Please, select a folder first Bitte wählen Sie zuerst einen Ordner aus - + Error in path Fehler im Pfad - + There was an error accessing the folder's path Beim Aufrufen des Ordnerpfades kam es zu einem Fehler - + The selected folder and all its contents will be deleted from your disk. Are you sure? Der ausgewählte Ordner und sein gesamter Inhalt wird von Ihrer Festplatte gelöscht. Sind Sie sicher? - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. Beim Löschen des ausgewählten Ordners ist ein Problem aufgetreten. Bitte überprüfen Sie die Schreibrechte und stellen Sie sicher, dass keine Anwendung diese Ordner oder die darin enthaltenen Dateien verwendet. - + Add new reading lists Neue Leseliste hinzufügen - - + + List name: Name der Liste - + Delete list/label Ausgewählte/s Liste/Label löschen - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? Das ausgewählte Element wird gelöscht; Ihre Comics oder Ordner werden NICHT von Ihrer Festplatte gelöscht. Sind Sie sicher? - + Rename list name Listenname ändern - - - - + + + + Set type - + Typ festlegen - + Set custom cover - + Legen Sie ein benutzerdefiniertes Cover fest - + Delete custom cover - + Benutzerdefiniertes Cover löschen - + Save covers Titelbilder speichern - + You are adding too many libraries. Sie fügen zu viele Bibliotheken hinzu. - + You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. @@ -1321,67 +1505,67 @@ YACReaderLibrary will not stop you from creating more libraries but you should k YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen, aber Sie sollten die Anzahl der Bibliotheken gering halten. - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. YACReader nicht gefunden. YACReader muss im gleichen Ordner installiert sein wie YACReaderLibrary. - + YACReader not found. There might be a problem with your YACReader installation. YACReader nicht gefunden. Eventuell besteht ein Problem mit Ihrer YACReader-Installation. - + Error - Error + Fehler - + Error opening comic with third party reader. - + Beim Öffnen des Comics mit dem Drittanbieter-Reader ist ein Fehler aufgetreten. - + Library info - + Informationen zur Bibliothek - + Assign comics numbers Comics Nummern zuweisen - + Assign numbers starting in: Nummern zuweisen, beginnend mit: - + Invalid image - + Ungültiges Bild - + The selected file is not a valid image. - + Die ausgewählte Datei ist kein gültiges Bild. - + Error saving cover - + Fehler beim Speichern des Covers - + There was an error saving the cover image. - + Beim Speichern des Titelbildes ist ein Fehler aufgetreten. - + Remove comics Comics löschen - + Comics will only be deleted from the current label/list. Are you sure? Comics werden nur vom aktuellen Label/der aktuellen Liste gelöscht. Sind Sie sicher? @@ -1389,439 +1573,439 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen LibraryWindowActions - + Create a new library - Neue Bibliothek erstellen + Neue Bibliothek erstellen - + Open an existing library - Eine vorhandede Bibliothek öffnen + Eine vorhandede Bibliothek öffnen - - + + Export comics info - + Comicinfo exportieren - - + + Import comics info - + Importiere Comic-Info - + Pack covers - Titelbild-Paket erzeugen + Titelbild-Paket erzeugen - + Pack the covers of the selected library - Packe die Titelbilder der ausgewählten Bibliothek in ein Paket + Packe die Titelbilder der ausgewählten Bibliothek in ein Paket - + Unpack covers - Titelbilder entpacken + Titelbilder entpacken - + Unpack a catalog - Katalog entpacken + Katalog entpacken - + Update library - + Bibliothek updaten - + Update current library - Aktuelle Bibliothek updaten + Aktuelle Bibliothek updaten - + Rename library - Bibliothek umbenennen + Bibliothek umbenennen - + Rename current library - Aktuelle Bibliothek umbenennen + Aktuelle Bibliothek umbenennen - + Remove library - Bibliothek entfernen + Bibliothek entfernen - + Remove current library from your collection - Aktuelle Bibliothek aus der Sammlung entfernen + Aktuelle Bibliothek aus der Sammlung entfernen - + Rescan library for XML info - + Durchsuchen Sie die Bibliothek erneut nach XML-Informationen - + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. - + Versucht, in Comic-Dateien eingebettete XML-Informationen zu finden. Sie müssen dies nur tun, wenn die Bibliothek mit 9.8.2 oder früheren Versionen erstellt wurde oder wenn Sie Software von Drittanbietern verwenden, um XML-Informationen in die Dateien einzubetten. - + Show library info - + Bibliotheksinformationen anzeigen - + Show information about the current library - + Informationen zur aktuellen Bibliothek anzeigen - + Open current comic - Aktuellen Comic öffnen + Aktuellen Comic öffnen - + Open current comic on YACReader - Aktuellen Comic mit YACReader öffnen + Aktuellen Comic mit YACReader öffnen - + Save selected covers to... - Ausgewählte Titelbilder speichern in... + Ausgewählte Titelbilder speichern in... - + Save covers of the selected comics as JPG files - Titelbilder der ausgewählten Comics als JPG-Datei speichern + Titelbilder der ausgewählten Comics als JPG-Datei speichern - - + + Set as read - Als gelesen markieren + Als gelesen markieren - + Set comic as read - Comic als gelesen markieren + Comic als gelesen markieren - - + + Set as unread - Als ungelesen markieren + Als ungelesen markieren - + Set comic as unread - Comic als ungelesen markieren + Comic als ungelesen markieren - - + + manga - + Manga - + Set issue as manga - Ausgabe als Manga festlegen + Ausgabe als Manga festlegen - - + + comic - + komisch - + Set issue as normal - Ausgabe als normal festlegen + Ausgabe als normal festlegen - + western manga - + Western-Manga - + Set issue as western manga - + Ausgabe als Western-Manga festlegen - - + + web comic - + Webcomic - + Set issue as web comic - + Ausgabe als Webcomic festlegen - - + + yonkoma - + Yonkoma - + Set issue as yonkoma - + Stellen Sie das Problem als Yonkoma ein - + Show/Hide marks - Zeige/Verberge Markierungen + Zeige/Verberge Markierungen - + Show or hide read marks - Gelesen-Markierungen anzeigen oder verbergen + Gelesen-Markierungen anzeigen oder verbergen - + Show/Hide recent indicator - + Aktuelle Anzeige ein-/ausblenden - + Show or hide recent indicator - + Aktuelle Anzeige anzeigen oder ausblenden - - + + Fullscreen mode on/off - Vollbildmodus an/aus + Vollbildmodus an/aus - + Help, About YACReader - Hilfe, Über YACReader + Hilfe, Über YACReader - + Add new folder - Neuen Ordner erstellen + Neuen Ordner erstellen - + Add new folder to the current library - Neuen Ordner in der aktuellen Bibliothek erstellen + Neuen Ordner in der aktuellen Bibliothek erstellen - + Delete folder - Ordner löschen + Ordner löschen - + Delete current folder from disk - Aktuellen Ordner von der Festplatte löschen + Aktuellen Ordner von der Festplatte löschen - + Select root node - Ursprungsordner auswählen + Ursprungsordner auswählen - + Expand all nodes - Alle Unterordner anzeigen + Alle Unterordner anzeigen - + Collapse all nodes - Alle Unterordner einklappen + Alle Unterordner einklappen - + Show options dialog - Zeige den Optionen-Dialog + Zeige den Optionen-Dialog - + Show comics server options dialog - Zeige Comic-Server-Optionen-Dialog + Zeige Comic-Server-Optionen-Dialog - - + + Change between comics views - Zwischen Comic-Anzeigemodi wechseln + Zwischen Comic-Anzeigemodi wechseln - + Open folder... - Öffne Ordner... + Öffne Ordner... - + Set as uncompleted - Als nicht gelesen markieren + Als nicht gelesen markieren - + Set as completed - Als gelesen markieren + Als gelesen markieren - + Set custom cover - + Legen Sie ein benutzerdefiniertes Cover fest - + Delete custom cover - + Benutzerdefiniertes Cover löschen - + western manga (left to right) - + Western-Manga (von links nach rechts) - + Open containing folder... - Öffne aktuellen Ordner... + Öffne aktuellen Ordner... - + Reset comic rating - Comic-Bewertung zurücksetzen + Comic-Bewertung zurücksetzen - + Select all comics - Alle Comics auswählen + Alle Comics auswählen - + Edit - Bearbeiten + Bearbeiten - + Assign current order to comics - Aktuele Sortierung auf Comics anwenden + Aktuele Sortierung auf Comics anwenden - + Update cover - Titelbild updaten + Titelbild updaten - + Delete selected comics - Ausgewählte Comics löschen + Ausgewählte Comics löschen - + Delete metadata from selected comics - + Metadaten aus ausgewählten Comics löschen - + Download tags from Comic Vine - Tags von Comic Vine herunterladen + Tags von Comic Vine herunterladen - + Focus search line - + Suchzeile fokussieren - + Focus comics view - + Fokus-Comic-Ansicht - + Edit shortcuts - Kürzel bearbeiten + Kürzel bearbeiten - + &Quit - &Schließen + &Schließen - + Update folder - Ordner aktualisieren + Ordner aktualisieren - + Update current folder - Aktuellen Ordner aktualisieren + Aktuellen Ordner aktualisieren - + Scan legacy XML metadata - + Scannen Sie ältere XML-Metadaten - + Add new reading list - Neue Leseliste hinzufügen + Neue Leseliste hinzufügen - + Add a new reading list to the current library - Neue Leseliste zur aktuellen Bibliothek hinzufügen + Neue Leseliste zur aktuellen Bibliothek hinzufügen - + Remove reading list - Leseliste entfernen + Leseliste entfernen - + Remove current reading list from the library - Aktuelle Leseliste von der Bibliothek entfernen + Aktuelle Leseliste von der Bibliothek entfernen - + Add new label - Neues Label hinzufügen + Neues Label hinzufügen - + Add a new label to this library - Neues Label zu dieser Bibliothek hinzufügen + Neues Label zu dieser Bibliothek hinzufügen - + Rename selected list - Ausgewählte Liste umbenennen + Ausgewählte Liste umbenennen - + Rename any selected labels or lists - Ausgewählte Labels oder Listen umbenennen + Ausgewählte Labels oder Listen umbenennen - + Add to... - Hinzufügen zu... + Hinzufügen zu... - + Favorites - Favoriten + Favoriten - + Add selected comics to favorites list - Ausgewählte Comics zu Favoriten hinzufügen + Ausgewählte Comics zu Favoriten hinzufügen @@ -1835,194 +2019,221 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen LogWindow - Log window - Protokollfenster + Protokollfenster - &Pause - &Pause + Pause - &Save - &Speichern + &Speichern - C&lear - L&öschen + L&öschen - &Copy - &Kopieren + &Kopieren - Level: - Level: + Level - &Auto scroll - Automatisches Scrollen + Automatisches Scrollen NoLibrariesWidget - + create your first library Erstellen Sie Ihre erste Bibliothek - + You don't have any libraries yet Sie haben aktuell noch keine Bibliothek - + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Sie können eine Bibliothek in jedem beliebigen Ordner erstellen, YACReaderLibrary wird alle Comics und Unterordner von diesem Ordner importieren. Wenn Sie bereits eine Bibliothek erstellt haben, können Sie sie öffnen.</p><p>Vergessen Sie nicht, dass Sie YACReader als eigentsändige Anwendung nutzen können, um Comics auf Ihrem Computer zu lesen.</p> - + add an existing one Existierende hinzufügen + + NoSearchResultsWidget + + + No results + Keine Ergebnisse + + OptionsDialog - + + + Appearance + Aussehen + + + + Options Optionen - + + + Language + Sprache + + + + + Application language + Anwendungssprache + + + + + System default + Systemstandard + + + Tray icon settings (experimental) Taskleisten-Einstellungen (experimentell) - + Close to tray In Taskleiste schließen - + Start into the system tray In die Taskleiste starten - + Edit Comic Vine API key Comic Vine API-Schlüssel ändern - + Comic Vine API key Comic Vine API Schlüssel - + ComicInfo.xml legacy support - + ComicInfo.xml-Legacy-Unterstützung - + Import metadata from ComicInfo.xml when adding new comics Import metada from ComicInfo.xml when adding new comics - + Importieren Sie Metadaten aus ComicInfo.xml, wenn Sie neue Comics hinzufügen - + Consider 'recent' items added or updated since X days ago - + Berücksichtigen Sie „neue“ Elemente, die seit X Tagen hinzugefügt oder aktualisiert wurden - + Third party reader - + Drittanbieter-Reader - + Write {comic_file_path} where the path should go in the command - + Schreiben Sie {comic_file_path}, wohin der Pfad im Befehl gehen soll - + + Clear - + Löschen - + Update libraries at startup - + Aktualisieren Sie die Bibliotheken beim Start - + Try to detect changes automatically - + Versuchen Sie, Änderungen automatisch zu erkennen - + Update libraries periodically - + Aktualisieren Sie die Bibliotheken regelmäßig - + Interval: - + Intervall: - + 30 minutes - + 30 Minuten - + 1 hour - + 1 Stunde - + 2 hours - + 2 Stunden - + 4 hours - + 4 Stunden - + 8 hours - + 8 Stunden - + 12 hours - + 12 Stunden - + daily - + täglich - + Update libraries at certain time - + Aktualisieren Sie Bibliotheken zu einem bestimmten Zeitpunkt - + Time: - + Zeit: - + WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. @@ -2030,181 +2241,356 @@ To stop an automatic update tap on the loading indicator next to the Libraries t WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. - + WARNUNG! Während Bibliotheksaktualisierungen sind Schreibvorgänge in die Datenbank deaktiviert! +Planen Sie keine Updates, während Sie die App möglicherweise aktiv nutzen. +Bei automatischen Updates blockiert die App einige Aktionen, bis das Update abgeschlossen ist. +Um eine automatische Aktualisierung zu stoppen, tippen Sie auf die Ladeanzeige neben dem Titel „Bibliotheken“. - + Modifications detection - + Erkennung von Änderungen - + Compare the modified date of files when updating a library (not recommended) - + Vergleichen Sie das Änderungsdatum von Dateien beim Aktualisieren einer Bibliothek (nicht empfohlen) - + Enable background image Hintergrundbild aktivieren - + Opacity level Deckkraft-Stufe - + Blur level Unschärfe-Stufe - + Use selected comic cover as background Den ausgewählten Comic als Hintergrund verwenden - + Restore defautls Standardwerte wiederherstellen - + Background Hintergrund - + Display continue reading banner Weiterlesen-Banner anzeigen - + Display current comic banner - + Aktuelles Comic-Banner anzeigen - + Continue reading Weiterlesen - + Comic Flow - Comic Flow + Comic-Flow - - + + Libraries - Bibliotheken + Bibliotheken - + Grid view Rasteransicht - + + General Allgemein - - - PropertiesDialog - - Day: - Tag: + + My comics path + Meine Comics-Pfad - - Plot - Inhalt + + Display + Anzeige - - Size: - Größe: + + Show time in current page information label + Zeit im Informationsetikett der aktuellen Seite anzeigen - - Year: - Jahr: + + "Go to flow" size + "Go to flow" Größe - - Inker(s): - Künstler(Tinte): + + Background color + Hintergrundfarbe - - Publishing - Veröffentlichung + + Choose + Auswählen - - Publisher: - Verlag: + + Scroll behaviour + Scrollverhalten - - General info - Allgemeine Info + + Disable scroll animations and smooth scrolling + Scroll-Animationen und sanftes Scrollen deaktivieren - - Color/BW: - Farbe/Schwarz-Weiß: + + Do not turn page using scroll + Blättern Sie nicht mit dem Scrollen um - - Edit selected comics information - Ausgewählte Comic-Informationen bearbeiten + + Use single scroll step to turn page + Verwenden Sie einen einzelnen Bildlaufschritt, um die Seite umzublättern - - Penciller(s): - Künstler(Bleistift): + + Mouse mode + Mausmodus - - Colorist(s): - Künstler(Farbe): + + Only Back/Forward buttons can turn pages + Nur mit den Zurück-/Vorwärts-Tasten können Seiten umgeblättert werden - - Genre: - Genre: + + Use the Left/Right buttons to turn pages. + Verwenden Sie die Links-/Rechts-Tasten, um Seiten umzublättern. - - Notes - + + Click left or right half of the screen to turn pages. + Klicken Sie auf die linke oder rechte Hälfte des Bildschirms, um die Seiten umzublättern. - - Load previous page as cover - + + Quick Navigation Mode + Schnellnavigations-Modus - - Load next page as cover - + + Disable mouse over activation + Aktivierung durch Maus deaktivieren - - Reset cover to the default image - + + Brightness + Helligkeit - - Load custom cover image - + + Contrast + Kontrast + + + + Gamma + Gammawert + + + + Reset + Zurücksetzen + + + + Image options + Bilderoptionen + + + + Fit options + Anpassungsoptionen + + + + Enlarge images to fit width/height + Bilder vergrößern, um sie Breite/Höhe anzupassen + + + + Double Page options + Doppelseiten-Einstellungen + + + + Show covers as single page + Cover als eine Seite darstellen + + + + Scaling + Skalierung + + + + Scaling method + Skalierungsmethode + + + + Nearest (fast, low quality) + Am nächsten (schnell, niedrige Qualität) + + + + Bilinear + Bilinear-Filter + + + + Lanczos (better quality) + Lanczos (bessere Qualität) + + + + Page Flow + Seitenfluss + + + + Image adjustment + Bildanpassung + + + + + Restart is needed + Neustart erforderlich + + + + Comics directory + Comics-Verzeichnis + + + + PropertiesDialog + + + Day: + Tag: + + + + Plot + Inhalt + + + + Size: + Größe: + + + + Year: + Jahr: + + + + Inker(s): + Künstler(Tinte): + + + + Publishing + Veröffentlichung + + + + Publisher: + Verlag: + + + + General info + Allgemeine Info + + + + Color/BW: + Farbe/Schwarz-Weiß: + + + + Edit selected comics information + Ausgewählte Comic-Informationen bearbeiten + + + + Penciller(s): + Künstler(Bleistift): + + + + Colorist(s): + Künstler(Farbe): + + + + Genre: + Gattung: + + + + Notes + Notizen + + + + Load previous page as cover + Vorherige Seite als Cover laden + + + + Load next page as cover + Nächste Seite als Cover laden + + + + Reset cover to the default image + Cover auf das Standardbild zurücksetzen + + + + Load custom cover image + Laden Sie ein benutzerdefiniertes Titelbild Series: - Serie: + Serie: @@ -2214,27 +2600,27 @@ To stop an automatic update tap on the loading indicator next to the Libraries t alt. number: - + alt. Nummer: Alternate series: - + Alternative Serie: Series Group: - + Seriengruppe: Editor(s): - + Herausgeber(n): Imprint: - + Impressum: @@ -2244,32 +2630,32 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Type: - + Typ: Language (ISO): - + Sprache (ISO): Teams: - + Mannschaften: Locations: - + Standorte: Main character or team: - + Hauptfigur oder Team: Review: - + Rezension: @@ -2279,12 +2665,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Invalid cover - + Ungültiger Versicherungsschutz The image is invalid. - + Das Bild ist ungültig. @@ -2329,7 +2715,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Tags: - + Schlagworte: @@ -2354,7 +2740,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine Link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine-Link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ansehen </a> @@ -2364,7 +2750,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Format: - Format: + Formatangabe: @@ -2385,7 +2771,23 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Manga: - Manga: + Manga-Typ: + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer ist die Headless-Version (keine GUI) von YACReaderLibrary. + +Diese Anwendung unterstützt dauerhafte Einstellungen. Um sie einzurichten, bearbeiten Sie diese Datei %1 +Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Dokumentation unter https://raw.githubusercontent.com/YACReader/yareader/develop/YACReaderLibraryServer/SETTINGS_README.md @@ -2413,7 +2815,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Info - Info + Information @@ -2423,69 +2825,87 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Error - Error + Fehler Fatal - Fatal + Tödlich - + Select custom cover - + Wählen Sie ein benutzerdefiniertes Cover - + Images (%1) - + Bilder (%1) + + + + The file could not be read or is not valid JSON. + Die Datei konnte nicht gelesen werden oder ist kein gültiges JSON. + + + + This theme is for %1, not %2. + Dieses Thema ist für %1, nicht für %2. + + + + Libraries + Bibliotheken + + + + Folders + Ordner + + + + Reading Lists + Leselisten QsLogging::LogWindowModel - Time - Zeit + Zeit - Level - Level + Stufe - Message - Nachricht + Nachricht QsLogging::Window - &Pause - &Pause + Pause - &Resume - &Weiter + &Weiter - Save log - Protokoll speichern + Protokoll speichern - Log file (*.log) - Protokolldatei (*.log) + Protokolldatei (*.log) RenameLibraryDialog - + Rename current library Aktuelle Bibliothek umbenennen @@ -2508,18 +2928,18 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ScraperResultsPaginator - + Number of %1 found : %2 Anzahl von %1 gefunden : %2 - - + + page %1 of %2 Seite %1 von %2 - + Number of volumes found : %1 Anzahl der gefundenen Bände: %1 @@ -2530,17 +2950,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information for this comic. Please provide some additional information. - Bitte stellen Sie weitere Informationen zur Verfügung. + Bitte stellen Sie weitere Informationen zur Verfügung. - + Series: Serie: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Verwenden Sie die Suche nach exakten Übereinstimmungen. Deaktivieren Sie diese Option, wenn Sie Bände finden möchten, die mit einigen Wörtern im Namen übereinstimmen. @@ -2551,40 +2971,40 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Bitte stellen Sie weitere Informationen zur Verfügung. - + Series: Serie: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Verwenden Sie die Suche nach exakten Übereinstimmungen. Deaktivieren Sie diese Option, wenn Sie Bände finden möchten, die mit einigen Wörtern im Namen übereinstimmen. SelectComic - + loading description Beschreibung wird laden - + comics Comics - + loading cover Titelbild wird geladen - + comic description unavailable - + Comic-Beschreibung nicht verfügbar - + Please, select the right comic info. Bitte wählen Sie die korrekte Comic-Information aus. @@ -2596,37 +3016,37 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SelectVolume - + loading description Beschreibung wird geladen - + Please, select the right series for your comic. Bitte wählen Sie die korrekte Serie für Ihre Comics aus. - + Filter: - + Filteroption: - + Nothing found, clear the filter if any. - + Nichts gefunden. Löschen Sie ggf. den Filter. - + loading cover Titelbild wird geladen - + volume description unavailable - + Bandbeschreibung nicht verfügbar - + volumes Bände @@ -2638,12 +3058,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SeriesQuestion - + no Nein - + yes Ja @@ -2656,41 +3076,41 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ServerConfigDialog - + Port Anschluss - + enable the server Server aktivieren - + set port Anschluss wählen - + Server connectivity information Serveranschluss-Information - + Scan it! Durchsuchen! - + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + YACReader ist für iOS- und Android-Geräte verfügbar.<br/>Entdecken Sie es für <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> oder <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> YACReader ist für iOS-Geräte verfügbar. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Jetzt entdecken! </a> - + Choose an IP address IP-Adresse auswählen @@ -2708,326 +3128,1167 @@ um die Leistung zu verbessern SortVolumeComics - + remove selected comics Ausgewählte Comics entfernen - + sort comics to match comic information Comics laut Comic-Information sortieren - + restore all removed comics Alle entfernten Comics wiederherstellen - + issues Ausgaben - + Please, sort the list of comics on the left until it matches the comics' information. Sortieren Sie bitte die Comic-Informationen links, bis die Informationen mit den Comics übereinstimmen. - TitleHeader + ThemeEditorDialog - - SEARCH - Suchen + + Theme Editor + Theme-Editor - - - UpdateLibraryDialog - - Update library - Bibliothek aktualisieren + + + + + - - Cancel - Abbrechen + + - + - - - Updating.... - Aktualisierung.... + + i + ich - - - VolumeComicsModel - - title - Titel + + Expand all + Alles erweitern - - - VolumesModel - - year - Jahr + + Collapse all + Alles einklappen - - issues - Ausgaben + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Halten Sie gedrückt, um den ausgewählten Wert in der Benutzeroberfläche zu blinken (Magenta / umgeschaltet / 0↔10). Releases stellen das Original wieder her. - - publisher - Herausgeber + + Search… + Suchen… - - - YACReader::TrayIconController - - &Restore - &Wiederherstellen + + Light + Helligkeit - &Quit - &Schließen + + Dark + Dunkel - - Systray - Taskleiste + + ID: + AUSWEIS: - - YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary wird im Hintergrund weiterlaufen. Um das Programm zu schließen, wählen Sie <b>Schließen</b> im Kontextmenü des Taskleisten-Symbols. + + Display name: + Anzeigename: - - - YACReader::WhatsNewDialog - - Close - Schließen + + Variant: + Variante: - - - YACReaderFieldEdit - - Restore to default - Standardeinstellungen wiederherstellen + + Theme info + Themeninfo - - - Click to overwrite - Zum Überschreiben anklicken + + Parameter + Parameterwert - - - YACReaderFieldPlainTextEdit - - Restore to default - Standardeinstellungen wiederherstellen + + Value + Wert - - - - - Click to overwrite - Zum Überschreiben anklicken + + Save and apply + Speichern und bewerben - - - YACReaderFlowConfigWidget - - CoverFlow look - CoverFlow-Ansicht + + Export to file... + In Datei exportieren... - - How to show covers: - Wie Titelseiten angezeigt werden sollen: + + Load from file... + Aus Datei laden... - - Stripe look - Streifen-Ansicht + + Close + Schließen - - Overlapped Stripe look - Überlappende Streifen-Ansicht + + Double-click to edit color + Doppelklicken Sie, um die Farbe zu bearbeiten - - - YACReaderGLFlowConfigWidget - - Zoom - Vergößern + + + + + + + true + WAHR - - Light - Helligkeit + + + + + false + FALSCH - - Show advanced settings - Zeige erweiterte Einstellungen + + Double-click to toggle + Zum Umschalten doppelklicken - - Roulette look - Zufällige Darstellung + + Double-click to edit value + Doppelklicken Sie, um den Wert zu bearbeiten - - Cover Angle - Titelbild-Winkel + + + + Edit: %1 + Bearbeiten: %1 - - Stripe look - Streifen-Ansicht + + Save theme + Thema speichern - - Position - Position + + + JSON files (*.json);;All files (*) + JSON-Dateien (*.json);;Alle Dateien (*) - - Z offset - Z Abstand + + Save failed + Speichern fehlgeschlagen - - Y offset - Y Abstand + + Could not open file for writing: +%1 + Die Datei konnte nicht zum Schreiben geöffnet werden: +%1 - - Central gap - Mittiger Abstand + + Load theme + Theme laden - - Presets: + + + + Load failed + Das Laden ist fehlgeschlagen + + + + Could not open file: +%1 + Datei konnte nicht geöffnet werden: +%1 + + + + Invalid JSON: +%1 + Ungültiger JSON: +%1 + + + + Expected a JSON object. + Es wurde ein JSON-Objekt erwartet. + + + + TitleHeader + + + SEARCH + Suchen + + + + UpdateLibraryDialog + + + Update library + Bibliothek aktualisieren + + + + Cancel + Abbrechen + + + + Updating.... + Aktualisierung.... + + + + Viewer + + + + Press 'O' to open comic. + 'O' drücken, um Comic zu öffnen. + + + + Not found + Nicht gefunden + + + + Comic not found + Comic nicht gefunden + + + + Error opening comic + Fehler beim Öffnen des Comics + + + + CRC Error + CRC Fehler + + + + Loading...please wait! + Ladevorgang... Bitte warten! + + + + Page not available! + Seite nicht verfügbar! + + + + Cover! + Titelseite! + + + + Last page! + Letzte Seite! + + + + VolumeComicsModel + + + title + Titel + + + + VolumesModel + + + year + Jahr + + + + issues + Ausgaben + + + + publisher + Herausgeber + + + + YACReader3DFlowConfigWidget + + + Presets: Voreinstellungen: - + + Classic look + Klassische Ansicht + + + + Stripe look + Streifen-Ansicht + + + + Overlapped Stripe look + Überlappende Streifen-Ansicht + + + + Modern look + Moderne Ansicht + + + + Roulette look + Zufällige Darstellung + + + + Show advanced settings + Zeige erweiterte Einstellungen + + + + Custom: + Benutzerdefiniert: + + + + View angle + Zeige Winkel + + + + Position + Lage + + + + Cover gap + Titelbild Abstand + + + + Central gap + Mittiger Abstand + + + + Zoom + Vergößern + + + + Y offset + Y Abstand + + + + Z offset + Z Abstand + + + + Cover Angle + Titelbild-Winkel + + + + Visibility + Sichtbarkeit + + + + Light + Helligkeit + + + + Max angle + Maximaler Winkel + + + + Low Performance + Niedrige Leistung + + + + High Performance + Hohe Leistung + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + VSync nutzen (verbessert die Bilddarstellung im Vollbild, schlechtere Leistung) + + + + Performance: + Leistung: + + + + YACReader::MainWindowViewer + + + &Open + &Öffnen + + + + Open a comic + Comic öffnen + + + + New instance + Neuer Fall + + + + Open Folder + Ordner öffnen + + + + Open image folder + Bilder-Ordner öffnen + + + + Open latest comic + Neuesten Comic öffnen + + + + Open the latest comic opened in the previous reading session + Öffne den neuesten Comic deiner letzten Sitzung + + + + Clear + Löschen + + + + Clear open recent list + Lösche Liste zuletzt geöffneter Elemente + + + + Save + Speichern + + + + + Save current page + Aktuelle Seite speichern + + + + Previous Comic + Voheriger Comic + + + + + + Open previous comic + Vorherigen Comic öffnen + + + + Next Comic + Nächster Comic + + + + + + Open next comic + Nächsten Comic öffnen + + + + &Previous + &Vorherige + + + + + + Go to previous page + Zur vorherigen Seite gehen + + + + &Next + &Nächstes + + + + + + Go to next page + Zur nächsten Seite gehen + + + + Fit Height + Höhe anpassen + + + + Fit image to height + Bild an Höhe anpassen + + + + Fit Width + Breite anpassen + + + + Fit image to width + Bildbreite anpassen + + + + Show full size + Vollansicht anzeigen + + + + Fit to page + An Seite anpassen + + + + Continuous scroll + Kontinuierliches Scrollen + + + + Switch to continuous scroll mode + Wechseln Sie in den kontinuierlichen Bildlaufmodus + + + + Reset zoom + Zoom zurücksetzen + + + + Show zoom slider + Zoomleiste anzeigen + + + + Zoom+ + Vergr??ern+ + + + + Zoom- + Verkleinern- + + + + Rotate image to the left + Bild nach links drehen + + + + Rotate image to the right + Bild nach rechts drehen + + + + Double page mode + Doppelseiten-Modus + + + + Switch to double page mode + Zum Doppelseiten-Modus wechseln + + + + Double page manga mode + Doppelseiten-Manga-Modus + + + + Reverse reading order in double page mode + Umgekehrte Lesereihenfolge im Doppelseiten-Modus + + + + Go To + Gehe zu + + + + Go to page ... + Gehe zu Seite ... + + + + Options + Optionen + + + + YACReader options + YACReader Optionen + + + + + Help + Hilfe + + + + Help, About YACReader + Hilfe, Über YACReader + + + + Magnifying glass + Vergößerungsglas + + + + Switch Magnifying glass + Vergrößerungsglas wechseln + + + + Set bookmark + Lesezeichen setzen + + + + Set a bookmark on the current page + Lesezeichen auf dieser Seite setzen + + + + Show bookmarks + Lesezeichen anzeigen + + + + Show the bookmarks of the current comic + Lesezeichen für diesen Comic anzeigen + + + + Show keyboard shortcuts + Tastenkürzel anzeigen + + + + Show Info + Info anzeigen + + + + Close + Schließen + + + + Show Dictionary + Wörterbuch anzeigen + + + + Show go to flow + "Go to Flow" anzeigen + + + + Edit shortcuts + Kürzel bearbeiten + + + + &File + &Datei + + + + + Open recent + Kürzlich geöffnet + + + + File + Datei + + + + Edit + Bearbeiten + + + + View + Anzeigen + + + + Go + Los + + + + Window + Fenster + + + + + + Open Comic + Comic öffnen + + + + + + Comic files + Comic-Dateien + + + + Open folder + Ordner öffnen + + + + page_%1.jpg + Seite_%1.jpg + + + + Image files (*.jpg) + Bildateien (*.jpg) + + + + + Comics + Comichefte + + + + + General + Allgemein + + + + + Magnifiying glass + Vergrößerungsglas + + + + + Page adjustement + Seitenanpassung + + + + + Reading + Lesend + + + + Toggle fullscreen mode + Vollbild-Modus umschalten + + + + Hide/show toolbar + Symbolleiste anzeigen/verstecken + + + + Size up magnifying glass + Vergrößerungsglas vergrößern + + + + Size down magnifying glass + Vergrößerungsglas verkleinern + + + + Zoom in magnifying glass + Vergrößerungsglas reinzoomen + + + + Zoom out magnifying glass + Vergrößerungsglas rauszoomen + + + + Reset magnifying glass + Lupe zurücksetzen + + + + Toggle between fit to width and fit to height + Zwischen Anpassung an Seite und Höhe wechseln + + + + Autoscroll down + Automatisches Runterscrollen + + + + Autoscroll up + Automatisches Raufscrollen + + + + Autoscroll forward, horizontal first + Automatisches Vorwärtsscrollen, horizontal zuerst + + + + Autoscroll backward, horizontal first + Automatisches Zurückscrollen, horizontal zuerst + + + + Autoscroll forward, vertical first + Automatisches Vorwärtsscrollen, vertikal zuerst + + + + Autoscroll backward, vertical first + Automatisches Zurückscrollen, vertikal zuerst + + + + Move down + Nach unten + + + + Move up + Nach oben + + + + Move left + Nach links + + + + Move right + Nach rechts + + + + Go to the first page + Zur ersten Seite gehen + + + + Go to the last page + Zur letzten Seite gehen + + + + Offset double page to the left + Doppelseite nach links versetzt + + + + Offset double page to the right + Doppelseite nach rechts versetzt + + + + There is a new version available + Neue Version verfügbar + + + + Do you want to download the new version? + Möchten Sie die neue Version herunterladen? + + + + Remind me in 14 days + In 14 Tagen erneut erinnern + + + + Not now + Nicht jetzt + + + + YACReader::TrayIconController + + + &Restore + &Wiederherstellen + + + &Quit + &Schließen + + + + Systray + Taskleiste + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary wird im Hintergrund weiterlaufen. Um das Programm zu schließen, wählen Sie <b>Schließen</b> im Kontextmenü des Taskleisten-Symbols. + + + + YACReader::WhatsNewDialog + + Close + Schließen + + + + YACReaderFieldEdit + + + Restore to default + Standardeinstellungen wiederherstellen + + + + + Click to overwrite + Zum Überschreiben anklicken + + + + YACReaderFieldPlainTextEdit + + + Restore to default + Standardeinstellungen wiederherstellen + + + + + + + Click to overwrite + Zum Überschreiben anklicken + + + + YACReaderFlowConfigWidget + + CoverFlow look + CoverFlow-Ansicht + + + How to show covers: + Wie Titelseiten angezeigt werden sollen: + + + Stripe look + Streifen-Ansicht + + Overlapped Stripe look - Überlappende Streifen-Ansicht + Überlappende Streifen-Ansicht + + + + YACReaderGLFlowConfigWidget + + Zoom + Vergößern + + + Light + Helligkeit + + + Show advanced settings + Zeige erweiterte Einstellungen + + + Roulette look + Zufällige Darstellung + + + Cover Angle + Titelbild-Winkel + + + Stripe look + Streifen-Ansicht + + + Position + Lage + + + Z offset + Z Abstand + + + Y offset + Y Abstand + + + Central gap + Mittiger Abstand + + + Presets: + Voreinstellungen: + + + Overlapped Stripe look + Überlappende Streifen-Ansicht - Modern look - Moderne Ansicht + Moderne Ansicht - View angle - Zeige Winkel + Zeige Winkel - Max angle - Maximaler Winkel + Maximaler Winkel - Custom: - Benutzerdefiniert: + Benutzerdefiniert: - Classic look - Klassische Ansicht + Klassische Ansicht - Cover gap - Titelbild Abstand + Titelbild Abstand - High Performance - Hohe Leistung + Hohe Leistung - Performance: - Leistung: + Leistung: - Use VSync (improve the image quality in fullscreen mode, worse performance) - VSync nutzen (verbessert die Bilddarstellung im Vollbild, schlechtere Leistung) + VSync nutzen (verbessert die Bilddarstellung im Vollbild, schlechtere Leistung) - Visibility - Sichtbarkeit + Sichtbarkeit - Low Performance - Niedrige Leistung + Niedrige Leistung YACReaderNavigationController - No favorites - Keine Favoriten + Keine Favoriten - You are not reading anything yet, come on!! - Sie lesen noch nichts, starten Sie!! - - - - There are no recent comics! - + Sie lesen noch nichts, starten Sie!! YACReaderOptionsDialog - + Save Speichern - Use hardware acceleration (restart needed) - Hardwarebeschleunigung nutzen (Neustart erforderlich) + Hardwarebeschleunigung nutzen (Neustart erforderlich) - + Cancel Abbrechen - + Edit shortcuts Kürzel bearbeiten - + Shortcuts Kürzel @@ -3035,7 +4296,7 @@ um die Leistung zu verbessern YACReaderSearchLineEdit - + type to search tippen, um zu suchen @@ -3043,34 +4304,60 @@ um die Leistung zu verbessern YACReaderSideBar - LIBRARIES - BIBLIOTHEKEN + BIBLIOTHEKEN - FOLDERS - ORDNER + ORDNER - Libraries - Bibliotheken + Bibliotheken - Folders - Ordner + Ordner - Reading Lists - Leselisten + Leselisten - READING LISTS - LESELISTEN + LESELISTEN + + + + YACReaderSlider + + + Reset + Zurücksetzen + + + + YACReaderTranslator + + + YACReader translator + YACReader Übersetzer + + + + + Translation + Übersetzung + + + + clear + Löschen + + + + Service not available + Service nicht verfügbar diff --git a/YACReaderLibrary/yacreaderlibrary_en.ts b/YACReaderLibrary/yacreaderlibrary_en.ts index 0d9528dc1..68b815eac 100644 --- a/YACReaderLibrary/yacreaderlibrary_en.ts +++ b/YACReaderLibrary/yacreaderlibrary_en.ts @@ -6,90 +6,30 @@ None - + None AddLabelDialog - + Label name: - + Label name: - + Choose a color: - - - - - red - - - - - orange - - - - - yellow - - - - - green - - - - - cyan - - - - - blue - - - - - violet - - - - - purple - - - - - pink - - - - - white - - - - - light - - - - - dark - + Choose a color: - + accept - + accept - + cancel - + cancel @@ -97,28 +37,28 @@ Comics folder : - + Comics folder : Library name : Library Name : - + Library name : Add - + Add Cancel - + Cancel - + Add an existing library - + Add an existing library @@ -126,113 +66,170 @@ Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> Paste here your Comic Vine API key - + Paste here your Comic Vine API key Accept - + Accept Cancel - + Cancel - ClassicComicsView + AppearanceTabWidget - - Hide comic flow - + + Color scheme + Color scheme - - - ComicInfoView - - Main character or team - + + System + System - - Teams - + + Light + Light - - Locations - + + Dark + Dark - - Authors - + + Custom + Custom - - writer - + + Remove + Remove - - penciller - + + Remove this user-imported theme + Remove this user-imported theme - - inker - + + Light: + Light: - - colorist - + + Dark: + Dark: - - letterer - + + Custom: + Custom: + + + + Import theme... + Import theme... + + + + Theme + Theme + + + + Theme editor + Theme editor + + + + Open Theme Editor... + Open Theme Editor... + + + + Theme editor error + Theme editor error + + + + The current theme JSON could not be loaded. + The current theme JSON could not be loaded. + + + + Import theme + Import theme + + + + JSON files (*.json);;All files (*) + JSON files (*.json);;All files (*) + + + + Could not import theme from: +%1 + Could not import theme from: +%1 - - cover artist - + + Could not import theme from: +%1 + +%2 + Could not import theme from: +%1 + +%2 - - editor - + + Import failed + Import failed + + + BookmarksDialog - - imprint - + + Lastest Page + Lastest Page - - Publisher - + + Close + Close - - color - + + Click on any image to go to the bookmark + Click on any image to go to the bookmark - - b/w - + + + Loading... + Loading... + + + ClassicComicsView - - Characters - + + Hide comic flow + Hide comic flow @@ -240,134 +237,142 @@ yes - + yes no - + no Title - + Title File Name - + File Name Pages - + Pages Size - + Size Read - + Read Current Page - + Current Page Publication Date - + Publication Date Rating - + Rating Series - + Series Volume - + Volume Story Arc - + Story Arc ComicVineDialog - + skip - + skip - + back - + back - + next - + next - + search - + search - + close - + close - - - + + + Looking for volume... - + Looking for volume... - - + + comic %1 of %2 - %3 - + comic %1 of %2 - %3 - + %1 comics selected - + %1 comics selected - + Error connecting to ComicVine - + Error connecting to ComicVine - - + + Retrieving tags for : %1 - + Retrieving tags for : %1 - + Retrieving volume info... - + Retrieving volume info... - + Looking for comic... - + Looking for comic... + + + + ContinuousPageWidget + + + Loading page %1 + Loading page %1 @@ -375,42 +380,42 @@ Comics folder : - + Comics folder : Library Name : - + Library Name : Create - + Create Cancel - + Cancel Create a library could take several minutes. You can stop the process and update the library later for completing the task. - + Create a library could take several minutes. You can stop the process and update the library later for completing the task. - + Create new library - + Create new library - + Path not found - + Path not found - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder @@ -418,54 +423,43 @@ Restore defaults - + Restore defaults To change a shortcut, double click in the key combination and type the new keys. - + To change a shortcut, double click in the key combination and type the new keys. Shortcuts settings - + Shortcuts settings - + Shortcut in use - + Shortcut in use - + The shortcut "%1" is already assigned to other function - + The shortcut "%1" is already assigned to other function EmptyFolderWidget - - - Subfolders in this folder - - - - - Empty folder - - - - - Drag and drop folders and comics here - + + This folder doesn't contain comics yet + This folder doesn't contain comics yet EmptyLabelWidget - + This label doesn't contain comics yet - + This label doesn't contain comics yet @@ -474,7 +468,25 @@ This reading list does not contain any comics yet This reading list doesn't contain any comics yet - + This reading list does not contain any comics yet + + + + EmptySpecialListWidget + + + No favorites + No favorites + + + + You are not reading anything yet, come on!! + You are not reading anything yet, come on!! + + + + There are no recent comics! + There are no recent comics! @@ -482,37 +494,37 @@ Output file : - + Output file : Create - + Create Cancel - + Cancel - + Export comics info - + Export comics info - + Destination database name - + Destination database name - + Problem found while writing - + Problem found while writing - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder @@ -520,37 +532,37 @@ Output folder : - + Output folder : Create - + Create Cancel - + Cancel - + Create covers package - + Create covers package - + Problem found while writing - + Problem found while writing - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - + Destination directory - + Destination directory @@ -558,64 +570,85 @@ CRC error on page (%1): some of the pages will not be displayed correctly - + CRC error on page (%1): some of the pages will not be displayed correctly Unknown error opening the file - + Unknown error opening the file 7z not found - + 7z not found Format not supported - + Format not supported - FolderContentView + GoToDialog + + + Page : + Page : + + + + Go To + Go To + + + + Cancel + Cancel + + + + + Total pages : + Total pages : + - - Continue Reading... - + + Go to... + Go to... - FolderContentView6 + GoToFlowToolBar - - Continue Reading... - + + Page : + Page : GridComicsView - + Show info - + Show info HelpAboutDialog - + About - + About - + Help - + Help - + System info - + System info @@ -623,27 +656,27 @@ Import comics info - + Import comics info Info database location : - + Info database location : Import - + Import Cancel - + Cancel - + Comics info file (*.ydb) - + Comics info file (*.ydb) @@ -651,940 +684,944 @@ Library Name : - + Library Name : Package location : - + Package location : Destination folder : - + Destination folder : Unpack - + Unpack Cancel - + Cancel - + Extract a catalog - + Extract a catalog - + Compresed library covers (*.clc) - + Compresed library covers (*.clc) ImportWidget - + stop - + stop - + Some of the comics being added... - + Some of the comics being added... - + Importing comics - + Importing comics - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - + Updating the library - + Updating the library - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> - + Upgrading the library - + Upgrading the library - + <p>The current library is being upgraded, please wait.</p> - + <p>The current library is being upgraded, please wait.</p> - + Scanning the library - + Scanning the library - + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> - + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> LibraryWindow - + YACReader Library - + YACReader Library - + Library - + Library - + Set as read - + Set as read - - + + Set as unread - + Set as unread - - - + + + manga - + manga - - - + + + comic - + comic - - - + + + web comic - + web comic - - - + + + western manga (left to right) - + western manga (left to right) - + Library not available Library ' - + Library not available - + Rescan library for XML info - + Rescan library for XML info - + Delete folder - + Delete folder - + Open folder... - + Open folder... - + Set as uncompleted - + Set as uncompleted - + Set as completed - + Set as completed - + Update folder - + Update folder - + Folder - + Folder - + Comic - + Comic - + Upgrade failed - + Upgrade failed - + There were errors during library upgrade in: - + There were errors during library upgrade in: - + Update needed - + Update needed - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? - + Download new version - + Download new version - + This library was created with a newer version of YACReaderLibrary. Download the new version now? - + This library was created with a newer version of YACReaderLibrary. Download the new version now? - + Library '%1' is no longer available. Do you want to remove it? - + Library '%1' is no longer available. Do you want to remove it? - + Old library - + Old library - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - - + + Copying comics... - + Copying comics... - - + + Moving comics... - + Moving comics... - + Folder name: - + Folder name: - + No folder selected - + No folder selected - + Please, select a folder first - + Please, select a folder first - + Error in path - + Error in path - + There was an error accessing the folder's path - + There was an error accessing the folder's path - + The selected folder and all its contents will be deleted from your disk. Are you sure? - + The selected folder and all its contents will be deleted from your disk. Are you sure? - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - + Add new reading lists - + Add new reading lists - - + + List name: - + List name: - + Delete list/label - + Delete list/label - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - + Rename list name - + Rename list name - - - + + + 4koma (top to botom) - + 4koma (top to botom) - - - - + + + + Set type - + Set type - + Set custom cover - + Set custom cover - + Delete custom cover - + Delete custom cover - + Save covers - + Save covers - + You are adding too many libraries. - + You are adding too many libraries. - + You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - - + + YACReader not found - + YACReader not found - + Error - + Error - + Error opening comic with third party reader. - + Error opening comic with third party reader. - + Library not found - + Library not found - + The selected folder doesn't contain any library. - + The selected folder doesn't contain any library. - + Are you sure? - + Are you sure? - + Do you want remove - + Do you want remove - + library? - + library? - + Remove and delete metadata - + Remove and delete metadata - + Library info - + Library info - + Assign comics numbers - + Assign comics numbers - + Assign numbers starting in: - + Assign numbers starting in: - - + + Unable to delete - + Unable to delete - + Add new folder - + Add new folder - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - + YACReader not found. There might be a problem with your YACReader installation. - + YACReader not found. There might be a problem with your YACReader installation. - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - + Invalid image - + Invalid image - + The selected file is not a valid image. - + The selected file is not a valid image. - + Error saving cover - + Error saving cover - + There was an error saving the cover image. - + There was an error saving the cover image. - + Error creating the library - + Error creating the library - + Error updating the library - + Error updating the library - + Error opening the library - + Error opening the library - + Delete comics - + Delete comics - + All the selected comics will be deleted from your disk. Are you sure? - + All the selected comics will be deleted from your disk. Are you sure? - + Remove comics - + Remove comics - + Comics will only be deleted from the current label/list. Are you sure? - + Comics will only be deleted from the current label/list. Are you sure? - + Library name already exists - + Library name already exists - + There is another library with the name '%1'. - + There is another library with the name '%1'. LibraryWindowActions - + Create a new library - + Create a new library - + Open an existing library - + Open an existing library - - + + Export comics info - + Export comics info - - + + Import comics info - + Import comics info - + Pack covers - + Pack covers - + Pack the covers of the selected library - + Pack the covers of the selected library - + Unpack covers - + Unpack covers - + Unpack a catalog - + Unpack a catalog - + Update library - + Update library - + Update current library - + Update current library - + Rename library - + Rename library - + Rename current library - + Rename current library - + Remove library - + Remove library - + Remove current library from your collection - + Remove current library from your collection - + Rescan library for XML info - + Rescan library for XML info - + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. - + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. - + Show library info - + Show library info - + Show information about the current library - + Show information about the current library - + Open current comic - + Open current comic - + Open current comic on YACReader - + Open current comic on YACReader - + Save selected covers to... - + Save selected covers to... - + Save covers of the selected comics as JPG files - + Save covers of the selected comics as JPG files - - + + Set as read - + Set as read - + Set comic as read - + Set comic as read - - + + Set as unread - + Set as unread - + Set comic as unread - + Set comic as unread - - + + manga - + manga - + Set issue as manga - + Set issue as manga - - + + comic - + comic - + Set issue as normal - + Set issue as normal - + western manga - + western manga - + Set issue as western manga - + Set issue as western manga - - + + web comic - + web comic - + Set issue as web comic - + Set issue as web comic - - + + yonkoma - + yonkoma - + Set issue as yonkoma - + Set issue as yonkoma - + Show/Hide marks - + Show/Hide marks - + Show or hide read marks - + Show or hide read marks - + Show/Hide recent indicator - + Show/Hide recent indicator - + Show or hide recent indicator - + Show or hide recent indicator - - + + Fullscreen mode on/off - + Fullscreen mode on/off - + Help, About YACReader - + Help, About YACReader - + Add new folder - + Add new folder - + Add new folder to the current library - + Add new folder to the current library - + Delete folder - + Delete folder - + Delete current folder from disk - + Delete current folder from disk - + Select root node - + Select root node - + Expand all nodes - + Expand all nodes - + Collapse all nodes - + Collapse all nodes - + Show options dialog - + Show options dialog - + Show comics server options dialog - + Show comics server options dialog - - + + Change between comics views - + Change between comics views - + Open folder... - + Open folder... - + Set as uncompleted - + Set as uncompleted - + Set as completed - + Set as completed - + Set custom cover - + Set custom cover - + Delete custom cover - + Delete custom cover - + western manga (left to right) - + western manga (left to right) - + Open containing folder... - + Open containing folder... - + Reset comic rating - + Reset comic rating - + Select all comics - + Select all comics - + Edit - + Edit - + Assign current order to comics - + Assign current order to comics - + Update cover - + Update cover - + Delete selected comics - + Delete selected comics - + Delete metadata from selected comics - + Delete metadata from selected comics - + Download tags from Comic Vine - + Download tags from Comic Vine - + Focus search line - + Focus search line - + Focus comics view - + Focus comics view - + Edit shortcuts - + Edit shortcuts - + &Quit - + &Quit - + Update folder - + Update folder - + Update current folder - + Update current folder - + Scan legacy XML metadata - + Scan legacy XML metadata - + Add new reading list - + Add new reading list - + Add a new reading list to the current library - + Add a new reading list to the current library - + Remove reading list - + Remove reading list - + Remove current reading list from the library - + Remove current reading list from the library - + Add new label - + Add new label - + Add a new label to this library - + Add a new label to this library - + Rename selected list - + Rename selected list - + Rename any selected labels or lists - + Rename any selected labels or lists - + Add to... - + Add to... - + Favorites - + Favorites - + Add selected comics to favorites list - + Add selected comics to favorites list @@ -1592,68 +1629,38 @@ YACReaderLibrary will not stop you from creating more libraries but you should k file name - - - - - LogWindow - - - Log window - - - - - &Pause - - - - - &Save - - - - - C&lear - - - - - &Copy - - - - - Level: - - - - - &Auto scroll - + file name NoLibrariesWidget - + You don't have any libraries yet - + You don't have any libraries yet - + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> - + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> - + create your first library - + create your first library - + add an existing one - + add an existing one + + + + NoSearchResultsWidget + + + No results + No results @@ -1661,123 +1668,124 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Tray icon settings (experimental) - + Tray icon settings (experimental) Close to tray - + Close to tray Start into the system tray - + Start into the system tray Edit Comic Vine API key - + Edit Comic Vine API key Comic Vine API key - + Comic Vine API key ComicInfo.xml legacy support - + ComicInfo.xml legacy support Import metadata from ComicInfo.xml when adding new comics Import metada from ComicInfo.xml when adding new comics - + Import metadata from ComicInfo.xml when adding new comics Consider 'recent' items added or updated since X days ago - + Consider 'recent' items added or updated since X days ago Third party reader - + Third party reader Write {comic_file_path} where the path should go in the command - + Write {comic_file_path} where the path should go in the command + Clear - + Clear Update libraries at startup - + Update libraries at startup Try to detect changes automatically - + Try to detect changes automatically Update libraries periodically - + Update libraries periodically Interval: - + Interval: 30 minutes - + 30 minutes 1 hour - + 1 hour 2 hours - + 2 hours 4 hours - + 4 hours 8 hours - + 8 hours 12 hours - + 12 hours daily - + daily Update libraries at certain time - + Update libraries at certain time Time: - + Time: @@ -1788,364 +1796,561 @@ To stop an automatic update tap on the loading indicator next to the Libraries t WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. - + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. Modifications detection - + Modifications detection Compare the modified date of files when updating a library (not recommended) - + Compare the modified date of files when updating a library (not recommended) - + Enable background image - + Enable background image - + Opacity level - + Opacity level - + Blur level - + Blur level - + Use selected comic cover as background - + Use selected comic cover as background - + Restore defautls - + Restore defautls - + Background - + Background - + Display continue reading banner - + Display continue reading banner - + Display current comic banner - + Display current comic banner - + Continue reading - + Continue reading - + Comic Flow - + Comic Flow - + Libraries - + Libraries Grid view - + Grid view - + + General - + General + + + + + Appearance + Appearance + Options - + Options - - - PropertiesDialog - - General info - + + My comics path + My comics path - - Authors - + + Display + Display - - Publishing - + + Show time in current page information label + Show time in current page information label - - Plot - + + "Go to flow" size + "Go to flow" size - - Notes - + + Background color + Background color - - Cover page - + + Choose + Choose - - Load previous page as cover - + + Scroll behaviour + Scroll behaviour - - Load next page as cover - + + Disable scroll animations and smooth scrolling + Disable scroll animations and smooth scrolling - - Reset cover to the default image - + + Do not turn page using scroll + Do not turn page using scroll - - Load custom cover image - + + Use single scroll step to turn page + Use single scroll step to turn page - - Series: - + + Mouse mode + Mouse mode - - Title: - + + Only Back/Forward buttons can turn pages + Only Back/Forward buttons can turn pages - - - - of: - + + Use the Left/Right buttons to turn pages. + Use the Left/Right buttons to turn pages. - - Issue number: - + + Click left or right half of the screen to turn pages. + Click left or right half of the screen to turn pages. - - Volume: - + + Quick Navigation Mode + Quick Navigation Mode - - Arc number: - + + Disable mouse over activation + Disable mouse over activation - - Story arc: - + + Brightness + Brightness - - alt. number: - + + Contrast + Contrast - - Alternate series: - + + Gamma + Gamma - - Series Group: - + + Reset + Reset - - Genre: - Genere: - + + Image options + Image options - - Size: - + + Fit options + Fit options - - Writer(s): - + + Enlarge images to fit width/height + Enlarge images to fit width/height - - Penciller(s): - + + Double Page options + Double Page options - - Inker(s): - + + Show covers as single page + Show covers as single page - - Colorist(s): - + + Scaling + Scaling - - Letterer(s): - + + Scaling method + Scaling method - - Cover Artist(s): - + + Nearest (fast, low quality) + Nearest (fast, low quality) - - Editor(s): - + + Bilinear + Bilinear - - Imprint: - + + Lanczos (better quality) + Lanczos (better quality) - + + Page Flow + Page Flow + + + + Image adjustment + Image adjustment + + + + Restart is needed + Restart is needed + + + + Comics directory + Comics directory + + + + PropertiesDialog + + + General info + General info + + + + Authors + Authors + + + + Publishing + Publishing + + + + Plot + Plot + + + + Notes + Notes + + + + Cover page + Cover page + + + + Load previous page as cover + Load previous page as cover + + + + Load next page as cover + Load next page as cover + + + + Reset cover to the default image + Reset cover to the default image + + + + Load custom cover image + Load custom cover image + + + + Series: + Series: + + + + Title: + Title: + + + + + + of: + of: + + + + Issue number: + Issue number: + + + + Volume: + Volume: + + + + Arc number: + Arc number: + + + + Story arc: + Story arc: + + + + alt. number: + alt. number: + + + + Alternate series: + Alternate series: + + + + Series Group: + Series Group: + + + + Genre: + Genere: + Genre: + + + + Size: + Size: + + + + Writer(s): + Writer(s): + + + + Penciller(s): + Penciller(s): + + + + Inker(s): + Inker(s): + + + + Colorist(s): + Colorist(s): + + + + Letterer(s): + Letterer(s): + + + + Cover Artist(s): + Cover Artist(s): + + + + Editor(s): + Editor(s): + + + + Imprint: + Imprint: + + + Day: - + Day: Month: - + Month: Year: - + Year: Publisher: - + Publisher: Format: - + Format: Color/BW: - + Color/BW: Age rating: - + Age rating: Type: - + Type: Language (ISO): - + Language (ISO): Synopsis: - + Synopsis: Characters: - + Characters: Teams: - + Teams: Locations: - + Locations: Main character or team: - + Main character or team: Review: - + Review: Notes: - + Notes: Tags: - + Tags: Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> Not found - + Not found Comic not found. You should update your library. - + Comic not found. You should update your library. Edit selected comics information - + Edit selected comics information Invalid cover - + Invalid cover The image is invalid. - + The image is invalid. Edit comic information - + Edit comic information + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md @@ -2153,93 +2358,77 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 7z lib not found - + 7z lib not found unable to load 7z lib from ./utils - + unable to load 7z lib from ./utils Trace - + Trace Debug - + Debug Info - + Info Warning - + Warning Error - + Error Fatal - + Fatal - + Select custom cover - + Select custom cover - + Images (%1) - - - - - QsLogging::LogWindowModel - - - Time - - - - - Level - + Images (%1) - - Message - + + The file could not be read or is not valid JSON. + The file could not be read or is not valid JSON. - - - QsLogging::Window - - &Pause - + + This theme is for %1, not %2. + This theme is for %1, not %2. - - &Resume - + + Libraries + Libraries - - Save log - + + Folders + Folders - - Log file (*.log) - + + Reading Lists + Reading Lists @@ -2247,41 +2436,41 @@ To stop an automatic update tap on the loading indicator next to the Libraries t New Library Name : - + New Library Name : Rename - + Rename Cancel - + Cancel - + Rename current library - + Rename current library ScraperResultsPaginator - + Number of volumes found : %1 - + Number of volumes found : %1 - - + + page %1 of %2 - + page %1 of %2 - + Number of %1 found : %2 - + Number of %1 found : %2 @@ -2290,17 +2479,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information for this comic. Please provide some additional information. - + Please provide some additional information for this comic. - + Series: - + Series: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. @@ -2308,83 +2497,83 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information. - + Please provide some additional information. - + Series: - + Series: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. SelectComic - + Please, select the right comic info. - + Please, select the right comic info. - + comics - + comics - + loading cover - + loading cover - + loading description - + loading description - + comic description unavailable - + comic description unavailable SelectVolume - + Please, select the right series for your comic. - + Please, select the right series for your comic. - + Filter: - + Filter: - + volumes - + volumes - + Nothing found, clear the filter if any. - + Nothing found, clear the filter if any. - + loading cover - + loading cover - + loading description - + loading description - + volume description unavailable - + volume description unavailable @@ -2392,419 +2581,1123 @@ To stop an automatic update tap on the loading indicator next to the Libraries t You are trying to get information for various comics at once, are they part of the same series? - + You are trying to get information for various comics at once, are they part of the same series? - + yes - + yes - + no - + no ServerConfigDialog - + set port - + set port - + Server connectivity information - + Server connectivity information - + Scan it! - + Scan it! - + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + Choose an IP address - + Choose an IP address - + Port - + Port - + enable the server - + enable the server SortVolumeComics - + Please, sort the list of comics on the left until it matches the comics' information. - + Please, sort the list of comics on the left until it matches the comics' information. - + sort comics to match comic information - + sort comics to match comic information - + issues - + issues - + remove selected comics - + remove selected comics - + restore all removed comics - + restore all removed comics - TitleHeader + ThemeEditorDialog - - SEARCH - + + Theme Editor + Theme Editor - - - UpdateLibraryDialog - - Updating.... - + + + + + - - Cancel - + + - + - - - Update library - + + i + i - - - VolumeComicsModel - - title - + + Expand all + Expand all - - - VolumesModel - - year - + + Collapse all + Collapse all - - issues - + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - - publisher - + + Search… + Search… - - - YACReader::TrayIconController - - &Restore - + + Light + Light - - Systray - + + Dark + Dark - - YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - + + ID: + ID: - - - YACReader::WhatsNewDialog - - Close - + + Display name: + Display name: - - - YACReaderFieldEdit - - - Click to overwrite - + + Variant: + Variant: - - Restore to default - + + Theme info + Theme info - - - YACReaderFieldPlainTextEdit - - - - - Click to overwrite - + + Parameter + Parameter - - Restore to default - + + Value + Value - - - YACReaderFlowConfigWidget - - How to show covers: - + + Save and apply + Save and apply - - CoverFlow look - + + Export to file... + Export to file... - - Stripe look - + + Load from file... + Load from file... - - Overlapped Stripe look - + + Close + Close - - - YACReaderGLFlowConfigWidget - - Presets: - + + Double-click to edit color + Double-click to edit color - - Classic look - + + + + + + + true + true - - Stripe look - + + + + + false + false - - Overlapped Stripe look - + + Double-click to toggle + Double-click to toggle - - Modern look - + + Double-click to edit value + Double-click to edit value - - Roulette look - + + + + Edit: %1 + Edit: %1 - - Show advanced settings - + + Save theme + Save theme - - Custom: - + + + JSON files (*.json);;All files (*) + JSON files (*.json);;All files (*) - - View angle - + + Save failed + Save failed - - Position - + + Could not open file for writing: +%1 + Could not open file for writing: +%1 - - Cover gap - + + Load theme + Load theme - - Central gap - + + + + Load failed + Load failed - - Zoom - + + Could not open file: +%1 + Could not open file: +%1 - - Y offset - + + Invalid JSON: +%1 + Invalid JSON: +%1 - - Z offset - + + Expected a JSON object. + Expected a JSON object. + + + TitleHeader - - Cover Angle - + + SEARCH + SEARCH + + + UpdateLibraryDialog - - Visibility - + + Updating.... + Updating.... - - Light - + + Cancel + Cancel - - Max angle - + + Update library + Update library + + + Viewer - - Low Performance - + + + Press 'O' to open comic. + Press 'O' to open comic. - - High Performance - + + Not found + Not found - - Use VSync (improve the image quality in fullscreen mode, worse performance) - + + Comic not found + Comic not found - - Performance: - + + Error opening comic + Error opening comic - - - YACReaderNavigationController - - No favorites - + + CRC Error + CRC Error - - You are not reading anything yet, come on!! - + + Loading...please wait! + Loading...please wait! - - There are no recent comics! - + + Page not available! + Page not available! + + + + Cover! + Cover! + + + + Last page! + Last page! + + + + VolumeComicsModel + + + title + title + + + + VolumesModel + + + year + year + + + + issues + issues + + + + publisher + publisher + + + + YACReader3DFlowConfigWidget + + + Presets: + Presets: + + + + Classic look + Classic look + + + + Stripe look + Stripe look + + + + Overlapped Stripe look + Overlapped Stripe look + + + + Modern look + Modern look + + + + Roulette look + Roulette look + + + + Show advanced settings + Show advanced settings + + + + Custom: + Custom: + + + + View angle + View angle + + + + Position + Position + + + + Cover gap + Cover gap + + + + Central gap + Central gap + + + + Zoom + Zoom + + + + Y offset + Y offset + + + + Z offset + Z offset + + + + Cover Angle + Cover Angle + + + + Visibility + Visibility + + + + Light + Light + + + + Max angle + Max angle + + + + Low Performance + Low Performance + + + + High Performance + High Performance + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Use VSync (improve the image quality in fullscreen mode, worse performance) + + + + Performance: + Performance: + + + + YACReader::MainWindowViewer + + + &Open + &Open + + + + Open a comic + Open a comic + + + + New instance + New instance + + + + Open Folder + Open Folder + + + + Open image folder + Open image folder + + + + Open latest comic + Open latest comic + + + + Open the latest comic opened in the previous reading session + Open the latest comic opened in the previous reading session + + + + Clear + Clear + + + + Clear open recent list + Clear open recent list + + + + Save + Save + + + + + Save current page + Save current page + + + + Previous Comic + Previous Comic + + + + + + Open previous comic + Open previous comic + + + + Next Comic + Next Comic + + + + + + Open next comic + Open next comic + + + + &Previous + &Previous + + + + + + Go to previous page + Go to previous page + + + + &Next + &Next + + + + + + Go to next page + Go to next page + + + + Fit Height + Fit Height + + + + Fit image to height + Fit image to height + + + + Fit Width + Fit Width + + + + Fit image to width + Fit image to width + + + + Show full size + Show full size + + + + Fit to page + Fit to page + + + + Continuous scroll + Continuous scroll + + + + Switch to continuous scroll mode + Switch to continuous scroll mode + + + + Reset zoom + Reset zoom + + + + Show zoom slider + Show zoom slider + + + + Zoom+ + Zoom+ + + + + Zoom- + Zoom- + + + + Rotate image to the left + Rotate image to the left + + + + Rotate image to the right + Rotate image to the right + + + + Double page mode + Double page mode + + + + Switch to double page mode + Switch to double page mode + + + + Double page manga mode + Double page manga mode + + + + Reverse reading order in double page mode + Reverse reading order in double page mode + + + + Go To + Go To + + + + Go to page ... + Go to page ... + + + + Options + Options + + + + YACReader options + YACReader options + + + + + Help + Help + + + + Help, About YACReader + Help, About YACReader + + + + Magnifying glass + Magnifying glass + + + + Switch Magnifying glass + Switch Magnifying glass + + + + Set bookmark + Set bookmark + + + + Set a bookmark on the current page + Set a bookmark on the current page + + + + Show bookmarks + Show bookmarks + + + + Show the bookmarks of the current comic + Show the bookmarks of the current comic + + + + Show keyboard shortcuts + Show keyboard shortcuts + + + + Show Info + Show Info + + + + Close + Close + + + + Show Dictionary + Show Dictionary + + + + Show go to flow + Show go to flow + + + + Edit shortcuts + Edit shortcuts + + + + &File + &File + + + + + Open recent + Open recent + + + + File + File + + + + Edit + Edit + + + + View + View + + + + Go + Go + + + + Window + Window + + + + + + Open Comic + Open Comic + + + + + + Comic files + Comic files + + + + Open folder + Open folder + + + + page_%1.jpg + page_%1.jpg + + + + Image files (*.jpg) + Image files (*.jpg) + + + + + Comics + Comics + + + + + General + General + + + + + Magnifiying glass + Magnifiying glass + + + + + Page adjustement + Page adjustement + + + + + Reading + Reading + + + + Toggle fullscreen mode + Toggle fullscreen mode + + + + Hide/show toolbar + Hide/show toolbar + + + + Size up magnifying glass + Size up magnifying glass + + + + Size down magnifying glass + Size down magnifying glass + + + + Zoom in magnifying glass + Zoom in magnifying glass + + + + Zoom out magnifying glass + Zoom out magnifying glass + + + + Reset magnifying glass + Reset magnifying glass + + + + Toggle between fit to width and fit to height + Toggle between fit to width and fit to height + + + + Autoscroll down + Autoscroll down + + + + Autoscroll up + Autoscroll up + + + + Autoscroll forward, horizontal first + Autoscroll forward, horizontal first + + + + Autoscroll backward, horizontal first + Autoscroll backward, horizontal first + + + + Autoscroll forward, vertical first + Autoscroll forward, vertical first + + + + Autoscroll backward, vertical first + Autoscroll backward, vertical first + + + + Move down + Move down + + + + Move up + Move up + + + + Move left + Move left + + + + Move right + Move right + + + + Go to the first page + Go to the first page + + + + Go to the last page + Go to the last page + + + + Offset double page to the left + Offset double page to the left + + + + Offset double page to the right + Offset double page to the right + + + + There is a new version available + There is a new version available + + + + Do you want to download the new version? + Do you want to download the new version? + + + + Remind me in 14 days + Remind me in 14 days + + + + Not now + Not now + + + + YACReader::TrayIconController + + + &Restore + &Restore + + + + Systray + Systray + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + + + + YACReaderFieldEdit + + + + Click to overwrite + Click to overwrite + + + + Restore to default + Restore to default + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + Click to overwrite + + + + Restore to default + Restore to default YACReaderOptionsDialog - + Save - + Save - + Cancel - + Cancel - + Edit shortcuts - + Edit shortcuts - + Shortcuts - - - - - Use hardware acceleration (restart needed) - + Shortcuts YACReaderSearchLineEdit - + type to search - + type to search - YACReaderSideBar + YACReaderSlider - - Libraries - - - - - Folders - + + Reset + Reset + + + YACReaderTranslator - - Reading Lists - + + YACReader translator + YACReader translator - - LIBRARIES - + + + Translation + Translation - - FOLDERS - + + clear + clear - - READING LISTS - + + Service not available + Service not available diff --git a/YACReaderLibrary/yacreaderlibrary_es.ts b/YACReaderLibrary/yacreaderlibrary_es.ts index 643c55b0d..c3db24d0a 100644 --- a/YACReaderLibrary/yacreaderlibrary_es.ts +++ b/YACReaderLibrary/yacreaderlibrary_es.ts @@ -12,82 +12,70 @@ AddLabelDialog - + cancel cancelar - + Label name: Nombre de la etiqueta: - + Choose a color: Elige un color: - red - rojo + rojo - orange - naranja + naranja - yellow - amarillo + amarillo - green - verde + verde - cyan - cian + cian - blue - azul + azul - violet - violeta + violeta - purple - morado + morado - pink - rosa + rosa - white - blanco + blanco - light - claro + claro - dark - oscuro + oscuro - + accept aceptar @@ -100,7 +88,7 @@ Añadir - + Add an existing library Añadir una biblioteca existente @@ -130,12 +118,12 @@ Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Antes de que te puedas conectar a Comic Vine necesitas tu ropia clave API. Por favor, obtén una gratis <a href=\"http://www.comicvine.com/api/\">aquí</a> + Antes de que te puedas conectar a Comic Vine necesitas tu propia clave API. Por favor, obtén una gratis <a href="http://www.comicvine.com/api/">aquí</a> Paste here your Comic Vine API key - Pega aquí tu clave API de Comic Vina + Pega aquí tu clave API de Comic Vine @@ -143,10 +131,146 @@ Aceptar + + AppearanceTabWidget + + + Color scheme + Esquema de color + + + + System + Sistema + + + + Light + Luz + + + + Dark + Oscuro + + + + Custom + Personalizado + + + + Remove + Eliminar + + + + Remove this user-imported theme + Eliminar este tema importado por el usuario + + + + Light: + Claro: + + + + Dark: + Oscuro: + + + + Custom: + Personalizado: + + + + Import theme... + Importar tema... + + + + Theme + Tema + + + + Theme editor + Editor de temas + + + + Open Theme Editor... + Abrir editor de temas... + + + + Theme editor error + Error del editor de temas + + + + The current theme JSON could not be loaded. + No se ha podido cargar el JSON del tema actual. + + + + Import theme + Importar tema + + + + JSON files (*.json);;All files (*) + Archivos JSON (*.json);;Todos los archivos (*) + + + + Could not import theme from: +%1 + No se pudo importar el tema desde:\n%1 + + + + Could not import theme from: +%1 + +%2 + No se pudo importar el tema desde:\n%1\n\n%2 + + + + Import failed + Error al importar + + + + BookmarksDialog + + + Lastest Page + Última página + + + + Close + Cerrar + + + + Click on any image to go to the bookmark + Pulsa en cualquier imagen para ir al marcador + + + + + Loading... + Cargando... + + ClassicComicsView - + Hide comic flow Ocultar cómic flow @@ -154,82 +278,82 @@ ComicInfoView - + Main character or team Personaje principal o equipo - + Teams Equipos - + Locations Lugares - + Authors Autores - + writer escritor - + penciller dibujante - + inker entintador - + colorist colorista - + letterer rotulista - + cover artist artista de portada - + editor editor - + imprint sello editorial - + Publisher Editorial - + color color - + b/w b/n - + Characters Personajes @@ -239,7 +363,7 @@ no - no + No @@ -259,7 +383,7 @@ Volume - Volúmen + Volumen @@ -305,74 +429,82 @@ ComicVineDialog - + back atrás - + next siguiente - + skip omitir - + close cerrar - - + + Retrieving tags for : %1 Recuperando etiquetas para : %1 - + Looking for comic... Buscando cómic... - + search buscar - - - + + + Looking for volume... Buscando volumen... - - + + comic %1 of %2 - %3 cómic %1 de %2 - %3 - + %1 comics selected - %1 comics seleccionados + %1 cómics seleccionados - + Error connecting to ComicVine Error conectando a ComicVine - + Retrieving volume info... - Recuperando imformación del volumen... + Recuperando información del volumen... + + + + ContinuousPageWidget + + + Loading page %1 + Cargando página %1 CreateLibraryDialog - + Create new library Crear la nueva biblioteca @@ -392,7 +524,7 @@ Crear una biblioteca puede llevar varios minutos. Puedes parar el proceso en cualquier momento y completar la tarea más tarde. - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder La ruta seleccionada no existe o no es válida. Asegúrate de que tienes privilegios de escritura en esta carpeta @@ -407,7 +539,7 @@ Nombre de la biblioteca : - + Path not found Ruta no encontrada @@ -430,12 +562,12 @@ Configuración de atajos - + Shortcut in use Atajo en uso - + The shortcut "%1" is already assigned to other function El atajo "%1" ya está asignado a otra función @@ -443,26 +575,27 @@ EmptyFolderWidget - - Subfolders in this folder - Subcarpetas en esta carpeta + Subcarpetas en esta carpeta - Empty folder - Carpeta vacía + Carpeta vacía - Drag and drop folders and comics here - Arrastra y suelta carpetas y cómics aquí + Arrastra y suelta carpetas y cómics aquí + + + + This folder doesn't contain comics yet + Esta carpeta aún no contiene cómics EmptyLabelWidget - + This label doesn't contain comics yet Esta etiqueta aún no contiene ningún cómic @@ -475,6 +608,24 @@ Esta lista de tectura aún no contiene ningún cómic + + EmptySpecialListWidget + + + No favorites + Ningún favorito + + + + You are not reading anything yet, come on!! + No estás leyendo nada aún, ¡vamos! + + + + There are no recent comics! + ¡No hay comics recientes! + + ExportComicsInfoDialog @@ -483,7 +634,7 @@ Archivo de salida : - + Destination database name Nombre de la base de datos de destino @@ -498,17 +649,17 @@ Crear - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder La ruta seleccionada para el archivo de salida no existe o no es una ruta válida. Asegúrate de que tienes permisos de escritura en esta carpeta - + Export comics info Exportar información de los cómics - + Problem found while writing Problema encontrado mientras se escribía @@ -526,7 +677,7 @@ Crear - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder La ruta seleccionada para el archivo de salida no existe o no es una ruta válida. Asegúrate de que tienes permisos de escritura en esta carpeta @@ -536,17 +687,17 @@ Carpeta de destino : - + Problem found while writing Problema encontrado mientras se escribía - + Create covers package Crear paquete de portadas - + Destination directory Carpeta de destino @@ -577,7 +728,7 @@ FolderContentView - + Continue Reading... Continúa leyendo... @@ -585,15 +736,51 @@ FolderContentView6 - Continue Reading... - Continúa leyendo... + Continúa leyendo... + + + + GoToDialog + + + Page : + Página : + + + + Go To + Ir a + + + + Cancel + Cancelar + + + + + Total pages : + Páginas totales : + + + + Go to... + Ir a... + + + + GoToFlowToolBar + + + Page : + Página : GridComicsView - + Show info Mostrar información @@ -601,17 +788,17 @@ HelpAboutDialog - + Help Ayuda - + System info Información de systema - + About Acerca de @@ -639,7 +826,7 @@ Importar información de cómics - + Comics info file (*.ydb) Archivo de información de cómics (*.ydb) @@ -662,9 +849,9 @@ Desempaquetar - + Compresed library covers (*.clc) - Compresed library covers (*.clc) + Portadas de biblioteca comprimidas (*.clc) @@ -677,7 +864,7 @@ Nombre de la biblioteca : - + Extract a catalog Extraer un catálogo @@ -685,52 +872,52 @@ ImportWidget - + stop parar - + Importing comics Importando cómics - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> <p>YACReaderLibrary está creando una nueva biblioteca.</p><p>Crear una biblioteca puede llevar varios minutos. Puedes parar el proceso en cualquier momento y actualizar la biblioteca más tarde para completar el proceso.</p> - + Some of the comics being added... Algunos de los cómics que estan siendo añadidos.... - + Updating the library Actualizando la biblioteca - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> <p>La biblioteca actual está siendo actualizada. Para actualizaciones más rápidas, por favor, actualiza tus bibliotecas frecuentemente.</p><p>Puedes parar el proceso y continunar la actualización más tarde.</p> - + Upgrading the library Actualizando la biblioteca - + <p>The current library is being upgraded, please wait.</p> <p>La biblioteca actual está siendo actualizadad, espera por favor.</p> - + Scanning the library Escaneando la biblioteca - + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> <p>La biblioteca está siendo escaneada para encontrar metadatos en formato XML.</p><p>Sólo necesitas hacer esto una vez, y sólo si la biblioteca fue creada con YACReaderLibrary 9.8.2 o antes.</p> @@ -742,22 +929,22 @@ Editar - + The selected folder doesn't contain any library. La carpeta seleccionada no contiene ninguna biblioteca. - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? Esta biblioteca fue creada con una versión anterior de YACReaderLibrary. Es necesario que se actualice. ¿Deseas hacerlo ahora? - + Comic Cómic - + Error opening the library Error abriendo la biblioteca @@ -766,8 +953,8 @@ Mostrar/Ocultar marcas - - + + YACReader not found YACReader no encontrado @@ -780,12 +967,12 @@ Marcar cómic como leído - + Remove and delete metadata Eliminar y borrar metadatos - + Old library Biblioteca antigua @@ -794,12 +981,12 @@ Actualizar portada - + Set as completed Marcar como completo - + Library Librería @@ -812,7 +999,7 @@ Modo a pantalla completa on/off - + This library was created with a newer version of YACReaderLibrary. Download the new version now? Esta biblioteca fue creada con una versión más nueva de YACReaderLibrary. ¿Deseas descargar la nueva versión ahora? @@ -825,7 +1012,7 @@ Actualizar la biblioteca seleccionada - + Library '%1' is no longer available. Do you want to remove it? La biblioteca '%1' no está disponible. ¿Deseas eliminarla? @@ -834,17 +1021,17 @@ Actualizar biblioteca - + Open folder... Abrir carpeta... - + Do you want remove ¿Deseas eliminar la biblioteca - + Set as uncompleted Marcar como incompleto @@ -853,12 +1040,12 @@ Reseteal cómic rating - + Error updating the library Error actualizando la biblioteca - + Folder Carpeta @@ -867,7 +1054,7 @@ Expandir todos los nodos - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? La biblioteca '%1' ha sido creada con una versión más antigua de YACReaderLibrary y debe ser creada de nuevo. ¿Deseas crear la biblioteca ahora? @@ -876,7 +1063,7 @@ Empaquetar portadas - + Set as read Marcar como leído @@ -897,7 +1084,7 @@ Crear una nueva biblioteca - + Library not available Biblioteca no disponible @@ -906,7 +1093,7 @@ Importar información de cómics - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. Ha habido algún problema intentando borrar los cómics selecionados. Por favor, verifica los permisos de escritura en los arhicovs seleccionados o los directorios que los conienen. @@ -915,12 +1102,12 @@ Abrir cómic actual - + YACReader Library - YACReader Library + Biblioteca YACReader - + Error creating the library Errar creando la biblioteca @@ -929,7 +1116,7 @@ Desempaquetar portadas - + Update needed Se necesita actualizar @@ -938,22 +1125,22 @@ Abrir una biblioteca existente - + Library name already exists Ya existe el nombre de la biblioteca - + There is another library with the name '%1'. Hay otra biblioteca con el nombre '%1'. - + Download new version Descargar la nueva versión - + Delete comics Borrar cómics @@ -982,7 +1169,7 @@ Desempaquetar un catálogo - + All the selected comics will be deleted from your disk. Are you sure? Todos los cómics seleccionados serán borrados de tu disco. ¿Estás seguro? @@ -991,13 +1178,13 @@ Descargar etiquetas de Comic Vine - - + + Set as unread Marcar como no leído - + Library not found Biblioteca no encontrada @@ -1010,16 +1197,16 @@ Eliminar biblioteca - - - + + + manga - manga + historieta manga - - - + + + comic cómic @@ -1032,9 +1219,9 @@ Marcar número como manga occidental - - - + + + web comic cómic web @@ -1044,7 +1231,7 @@ yonkoma - yonkoma + tira yonkoma Set issue as yonkoma @@ -1059,9 +1246,9 @@ Mostrar o ocultar el indicador reciente - - - + + + western manga (left to right) manga occidental (izquierda a derecha) @@ -1070,26 +1257,26 @@ Abrir carpeta contenedora... - - + + Unable to delete No se ha podido borrar - - - + + + 4koma (top to botom) 4koma (top to botom 4koma (de arriba a abajo) - + library? ? - + Are you sure? ¿Estás seguro? @@ -1098,7 +1285,7 @@ Guardar las portadas seleccionadas en... - + Rescan library for XML info Volver a escanear la biblioteca en busca de información XML @@ -1123,7 +1310,7 @@ Mostrar u ocultar marcas - + Add new folder Añadir carpeta @@ -1132,7 +1319,7 @@ Añadir carpeta a la biblioteca actual - + Delete folder Borrar carpeta @@ -1173,7 +1360,7 @@ Salir - + Update folder Actualizar carpeta @@ -1230,118 +1417,118 @@ Añadir cómics seleccionados a la lista de favoritos - + Upgrade failed La actualización falló - + There were errors during library upgrade in: Hubo errores durante la actualización de la biblioteca en: - - + + Copying comics... Copiando cómics... - - + + Moving comics... Moviendo cómics... - + Folder name: Nombre de la carpeta: - + No folder selected No has selecionado ninguna carpeta - + Please, select a folder first Por favor, selecciona una carpeta primero - + Error in path Error en la ruta - + There was an error accessing the folder's path Hubo un error al acceder a la ruta de la carpeta - + The selected folder and all its contents will be deleted from your disk. Are you sure? ¿Estás seguro de que deseas eliminar la carpeta seleccionada y todo su contenido de tu disco? - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. Se produjo un problema al intentar eliminar las carpetas seleccionadas. Por favor, verifica los permisos de escritura y asegúrate de que no haya aplicaciones usando estas carpetas o alguno de los archivos contenidos en ellas. - + Add new reading lists Añadir nuevas listas de lectura - - + + List name: Nombre de la lista: - + Delete list/label Eliminar lista/etiqueta - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? El elemento seleccionado se eliminará, tus cómics o carpetas NO se eliminarán de tu disco. ¿Estás seguro? - + Rename list name Renombrar lista - - - - + + + + Set type Establecer tipo - + Set custom cover Establecer portada personalizada - + Delete custom cover Eliminar portada personalizada - + Save covers Guardar portadas - + You are adding too many libraries. Estás añadiendo demasiadas bibliotecas. - + You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. @@ -1350,67 +1537,67 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Estás añadiendo demasiadas bibliotecas.\n\nProbablemente solo necesites una biblioteca en la carpeta principal de tus cómics, puedes explorar cualquier subcarpeta utilizando la sección de carpetas en la barra lateral izquierda.\n\nYACReaderLibrary no te detendrá de crear más bibliotecas, pero deberías mantener el número de bibliotecas bajo control. - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. YACReader no encontrado. YACReader debería estar instalado en la misma carpeta que YACReaderLibrary. - + YACReader not found. There might be a problem with your YACReader installation. YACReader no encontrado. Podría haber un problema con tu instalación de YACReader. - + Error - Error + Fallo - + Error opening comic with third party reader. Error al abrir el cómic con una aplicación de terceros. - + Library info Información de la biblioteca - + Assign comics numbers Asignar números a los cómics - + Assign numbers starting in: Asignar números comenzando en: - + Invalid image Imagen inválida - + The selected file is not a valid image. El archivo seleccionado no es una imagen válida. - + Error saving cover Error guardando portada - + There was an error saving the cover image. Hubo un error guardando la image de portada. - + Remove comics Eliminar cómics - + Comics will only be deleted from the current label/list. Are you sure? Los cómics sólo se eliminarán de la etiqueta/lista actual. ¿Estás seguro? @@ -1418,437 +1605,437 @@ YACReaderLibrary will not stop you from creating more libraries but you should k LibraryWindowActions - + Create a new library Crear una nueva biblioteca - + Open an existing library Abrir una biblioteca existente - - + + Export comics info Exportar información de los cómics - - + + Import comics info Importar información de cómics - + Pack covers Empaquetar portadas - + Pack the covers of the selected library Empaquetar las portadas de la biblioteca seleccionada - + Unpack covers Desempaquetar portadas - + Unpack a catalog Desempaquetar un catálogo - + Update library Actualizar biblioteca - + Update current library Actualizar la biblioteca seleccionada - + Rename library Renombrar biblioteca - + Rename current library Renombrar la biblioteca seleccionada - + Remove library Eliminar biblioteca - + Remove current library from your collection Eliminar biblioteca de la colección - + Rescan library for XML info Volver a escanear la biblioteca en busca de información XML - + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. Intenta encontrar información XML incrustada en los archivos de cómic. Solo necesitas hacer esto si la biblioteca fue creada con la versión 9.8.2 o versiones anteriores o si estás utilizando software de terceros para incrustar información XML en los archivos. - + Show library info Mostrar información de la biblioteca - + Show information about the current library Mostrar información de la biblioteca actual - + Open current comic Abrir cómic actual - + Open current comic on YACReader Abrir el cómic actual en YACReader - + Save selected covers to... Guardar las portadas seleccionadas en... - + Save covers of the selected comics as JPG files Guardar las portadas de los cómics seleccionados como archivos JPG - - + + Set as read Marcar como leído - + Set comic as read Marcar cómic como leído - - + + Set as unread Marcar como no leído - + Set comic as unread Marcar cómic como no leído - - + + manga - manga + historieta manga - + Set issue as manga Marcar número como manga - - + + comic cómic - + Set issue as normal Marcar número como cómic - + western manga manga occidental - + Set issue as western manga Marcar número como manga occidental - - + + web comic cómic web - + Set issue as web comic Marcar número como cómic web - - + + yonkoma - yonkoma + tira yonkoma - + Set issue as yonkoma Marcar número como yonkoma - + Show/Hide marks Mostrar/Ocultar marcas - + Show or hide read marks Mostrar u ocultar marcas - + Show/Hide recent indicator Mostrar/Ocultar el indicador reciente - + Show or hide recent indicator Mostrar o ocultar el indicador reciente - - + + Fullscreen mode on/off Modo a pantalla completa on/off - + Help, About YACReader Ayuda, A cerca de... YACReader - + Add new folder Añadir carpeta - + Add new folder to the current library Añadir carpeta a la biblioteca actual - + Delete folder Borrar carpeta - + Delete current folder from disk Borrar carpeta actual del disco - + Select root node Seleccionar el nodo raíz - + Expand all nodes Expandir todos los nodos - + Collapse all nodes Contraer todos los nodos - + Show options dialog Mostrar opciones - + Show comics server options dialog - + Mostrar el diálogo de opciones del servidor de cómics - - + + Change between comics views Cambiar entre vistas de cómics - + Open folder... Abrir carpeta... - + Set as uncompleted Marcar como incompleto - + Set as completed Marcar como completo - + Set custom cover Establecer portada personalizada - + Delete custom cover Eliminar portada personalizada - + western manga (left to right) manga occidental (izquierda a derecha) - + Open containing folder... Abrir carpeta contenedora... - + Reset comic rating Reseteal cómic rating - + Select all comics Seleccionar todos los cómics - + Edit Editar - + Assign current order to comics Asignar el orden actual a los cómics - + Update cover Actualizar portada - + Delete selected comics Borrar los cómics seleccionados - + Delete metadata from selected comics Borrar metadatos de los cómics seleccionados - + Download tags from Comic Vine Descargar etiquetas de Comic Vine - + Focus search line Selecionar el campo de búsqueda - + Focus comics view Selecionar la vista de cómics - + Edit shortcuts Editar atajos - + &Quit - Salir + &Salir - + Update folder Actualizar carpeta - + Update current folder Actualizar carpeta actual - + Scan legacy XML metadata Escaneal metadatos XML - + Add new reading list Añadir lista de lectura - + Add a new reading list to the current library Añadir una nueva lista de lectura a la biblioteca actual - + Remove reading list Eliminar lista de lectura - + Remove current reading list from the library Eliminar la lista de lectura actual de la biblioteca - + Add new label Añadir etiqueta - + Add a new label to this library Añadir etiqueta a esta biblioteca - + Rename selected list Renombrar la lista seleccionada - + Rename any selected labels or lists Renombrar las etiquetas o listas seleccionadas - + Add to... Añadir a... - + Favorites Favoritos - + Add selected comics to favorites list Añadir cómics seleccionados a la lista de favoritos @@ -1864,194 +2051,197 @@ YACReaderLibrary will not stop you from creating more libraries but you should k LogWindow - - Log window - - - - &Pause - &Pausar - - - - &Save - - - - - C&lear - - - - - &Copy - - - - - Level: - - - - - &Auto scroll - + &Pausar NoLibrariesWidget - + create your first library crea tu primera biblioteca - + You don't have any libraries yet Aún no tienes ninguna biblioteca - + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Puedes crear una biblioteca en cualquier carpeta, YACReaderLibrary importará todos las carpetas y cómics de esa carpeta. Si has creado alguna biblioteca anteriormente, puedes abrirla sin volver a crearla.</p><p>No olvides que puedes usar YACReader como una aplicación independiente para leer los cómics en tu ordenador.</p> - + add an existing one añade una existente + + NoSearchResultsWidget + + + No results + Sin resultados + + OptionsDialog - + + + Appearance + Apariencia + + + + Options Opciones - + + + Language + Idioma + + + + + Application language + Idioma de la aplicación + + + + + System default + Predeterminado del sistema + + + Tray icon settings (experimental) Opciones de bandeja de sistema (experimental) - + Close to tray Cerrar a la bandeja - + Start into the system tray Comenzar en la bandeja de sistema - + Edit Comic Vine API key Editar la clave API de Comic Vine - + Comic Vine API key Clave API de Comic Vine - + ComicInfo.xml legacy support Soporte para ComicInfo.xml - + Import metadata from ComicInfo.xml when adding new comics Import metada from ComicInfo.xml when adding new comics Importar metadatos desde ComicInfo.xml al añadir nuevos cómics - + Consider 'recent' items added or updated since X days ago Considerar elementos 'recientes' añadidos o actualizados desde hace X días - + Third party reader Lector externo - + Write {comic_file_path} where the path should go in the command Escribe {comic_file_path} donde la ruta al cómic debería ir en el comando - + + Clear Borrar - + Update libraries at startup Actualizar bibliotecas al inicio - + Try to detect changes automatically Intentar detectar cambios automáticamente - + Update libraries periodically Actualizar bibliotecas periódicamente - + Interval: Intervalo: - + 30 minutes 30 minutos - + 1 hour 1 hora - + 2 hours 2 horas - + 4 hours 4 horas - + 8 hours 8 horas - + 12 hours 12 horas - + daily dirariamente - + Update libraries at certain time Actualizar bibliotecas en un momento determinado - + Time: Hora: - + WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. @@ -2062,166 +2252,338 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ¡ADVERTENCIA! Durante las actualizaciones de la biblioteca se desactivan las escrituras en la base de datos. No programes actualizaciones mientras puedas estar usando la aplicación activamente. Durante las actualizaciones automáticas, la aplicación bloqueará algunas de las acciones hasta que la actualización esté terminada. Para detener una actualización automática, toca en el indicador de carga junto al título de Bibliotecas. - + Modifications detection Detección de modificaciones - + Compare the modified date of files when updating a library (not recommended) Comparar la fecha de modificación de los archivos al actualizar una biblioteca (no recomendado) - + Enable background image Activar imagen de fondo - + Opacity level Nivel de opacidad - + Blur level Nivel de desenfoque - + Use selected comic cover as background Usar la portada del cómic seleccionado como fondo - + Restore defautls Restaurar valores predeterminados - + Background Fondo - + Display continue reading banner Mostrar banner de "Continuar leyendo" - + Display current comic banner Mostar el báner del cómic actual - + Continue reading Continuar leyendo - + Comic Flow - Comic Flow + Flujo cómico - - + + Libraries Bibliotecas - + Grid view Vista en cuadrícula - + + General - General + Opciones generales - - - PropertiesDialog - - Day: - Día: + + My comics path + Ruta a mis cómics - - Plot - Argumento + + Display + Visualización - - Size: - Tamaño: + + Show time in current page information label + Mostrar la hora en la etiqueta de información de la página actual - - Year: - Año: + + "Go to flow" size + Tamaño de "Go to flow" - - Inker(s): - Entintador(es): + + Background color + Color de fondo - - Publishing - Publicación + + Choose + Elegir - - Publisher: - Editorial: + + Scroll behaviour + Comportamiento del scroll - - General info - Información general + + Disable scroll animations and smooth scrolling + Desactivar animaciones de desplazamiento y desplazamiento suave - - Color/BW: - Color/BN: + + Do not turn page using scroll + No cambiar de página usando el scroll - - Edit selected comics information - Editar la información de los cómics seleccionados + + Use single scroll step to turn page + Usar un solo paso de desplazamiento para cambiar de página - - Penciller(s): - Dibujant(es): + + Mouse mode + Modo del ratón - - Colorist(s): - Color: + + Only Back/Forward buttons can turn pages + Solo los botones Atrás/Adelante pueden cambiar de página - - Genre: - Género: + + Use the Left/Right buttons to turn pages. + Usar los botones Izquierda/Derecha para cambiar de página. - - Notes - Notas + + Click left or right half of the screen to turn pages. + Hacer clic en la mitad izquierda o derecha de la pantalla para cambiar de página. - - Load previous page as cover - Cargar página anterior como portada + + Quick Navigation Mode + Modo de navegación rápida - - Load next page as cover - Cargar página siguiente como portada + + Disable mouse over activation + Desactivar activación al pasar el ratón - + + Brightness + Brillo + + + + Contrast + Contraste + + + + Gamma + Gama + + + + Reset + Restablecer + + + + Image options + Opciones de imagen + + + + Fit options + Opciones de ajuste + + + + Enlarge images to fit width/height + Ampliar imágenes para ajustarse al ancho/alto + + + + Double Page options + Opciones de doble página + + + + Show covers as single page + Mostrar portadas como página única + + + + Scaling + Escalado + + + + Scaling method + Método de escalado + + + + Nearest (fast, low quality) + Vecino más cercano (rápido, baja calidad) + + + + Bilinear + Bilineal + + + + Lanczos (better quality) + Lanczos (mejor calidad) + + + + Page Flow + Flujo de página + + + + Image adjustment + Ajustes de imagen + + + + + Restart is needed + Es necesario reiniciar + + + + Comics directory + Directorio de cómics + + + + PropertiesDialog + + + Day: + Día: + + + + Plot + Argumento + + + + Size: + Tamaño: + + + + Year: + Año: + + + + Inker(s): + Entintador(es): + + + + Publishing + Publicación + + + + Publisher: + Editorial: + + + + General info + Información general + + + + Color/BW: + Color/BN: + + + + Edit selected comics information + Editar la información de los cómics seleccionados + + + + Penciller(s): + Dibujant(es): + + + + Colorist(s): + Color: + + + + Genre: + Género: + + + + Notes + Notas + + + + Load previous page as cover + Cargar página anterior como portada + + + + Load next page as cover + Cargar página siguiente como portada + + + Reset cover to the default image Restaurar la portada por defecto @@ -2233,7 +2595,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Series: - Series: + Serie: @@ -2413,6 +2775,18 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Número de arco: + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + \nYACReaderLibraryServer es la versión sin interfaz gráfica (headless) de YACReaderLibrary.\n\nEsta aplicación admite ajustes persistentes; para configurarlos, edita este archivo %1\nPara conocer los ajustes disponibles, consulta la documentación en https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + QObject @@ -2428,89 +2802,107 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Trace - + Traza Debug - + Depuración Info - + Información Warning - + Advertencia Error - + Fallo Fatal - + Cr?tico - + Select custom cover - + Seleccionar portada personalizada - + Images (%1) - + Imágenes (%1) + + + + The file could not be read or is not valid JSON. + No se pudo leer el archivo o no es un JSON válido. + + + + This theme is for %1, not %2. + Este tema es para %1, no para %2. + + + + Libraries + Bibliotecas + + + + Folders + Carpetas + + + + Reading Lists + Listas de lectura QsLogging::LogWindowModel - Time - Hora + Hora - Level - Nivel + Nivel - Message - Mensaje + Mensaje QsLogging::Window - &Pause - &Pausar + &Pausar - &Resume - &Restaurar + &Restaurar - Save log - Guardar log + Guardar log - Log file (*.log) - Archivo de log (*.log) + Archivo de log (*.log) RenameLibraryDialog - + Rename current library Renombrar la biblioteca seleccionada @@ -2533,18 +2925,18 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ScraperResultsPaginator - + Number of %1 found : %2 Número de %1 encontrados : %2 - - + + page %1 of %2 página %1 de %2 - + Number of volumes found : %1 Número de volúmenes encontrados : %1 @@ -2558,12 +2950,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Por favor, proporciona alguna información adicional para éste cómic. - + Series: - Series: + Serie: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. Usar búsqueda exacta. Desactívala si quieres encontrar volúmenes que coincidan con algunas palabras del nombre. @@ -2576,12 +2968,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Por favor, proporciona alguna informacion adicional. - + Series: - Series: + Serie: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. Usar búsqueda exacta. Desactívala si queires buscar volúmenes que coincidan con algunas de las palabras del nombre. @@ -2589,27 +2981,27 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SelectComic - + loading description cargando descripción - + comics cómics - + loading cover cargando portada - + comic description unavailable Descripción del cómic no disponible - + Please, select the right comic info. Por favor, selecciona la información correcta. @@ -2621,37 +3013,37 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SelectVolume - + loading description cargando descripción - + Please, select the right series for your comic. Por favor, seleciona la serie correcta para tu cómic. - + Filter: Filtro: - + Nothing found, clear the filter if any. No se encontró nada, limpia el filtro si lo hubiera. - + loading cover cargando portada - + volume description unavailable Descripción del volumen no disponible - + volumes volúmenes @@ -2663,12 +3055,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SeriesQuestion - + no - no + No - + yes @@ -2681,37 +3073,37 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ServerConfigDialog - + Port Puerto - + enable the server activar el servidor - + set port fijar puerto - + Server connectivity information Infomación de conexión del servidor - + Scan it! ¡Escaneálo! - + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. YACReader está disponible para iOS y Android.<br/> Descúbrela para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a>o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + Choose an IP address Elige una dirección IP @@ -2719,322 +3111,1164 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SortVolumeComics - + remove selected comics eliminar cómics seleccionados - + sort comics to match comic information ordena los cómics para coincidir con la información - + restore all removed comics restaurar todos los cómics eliminados - + issues números - + Please, sort the list of comics on the left until it matches the comics' information. Por favor, ordena la lista de cómics en la izquiera hasta que coincida con la información adecuada. - TitleHeader + ThemeEditorDialog - - SEARCH - BUSCAR + + Theme Editor + Editor de temas - - - UpdateLibraryDialog - - Update library - Actualizar biblioteca + + + + + - - Cancel - Cancelar + + - + - - - Updating.... - Actualizado... + + i + ? - - - VolumeComicsModel - - title - título + + Expand all + Expandir todo - - - VolumesModel - - year - año + + Collapse all + Contraer todo - - issues - números + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Mantén pulsado para resaltar temporalmente el valor seleccionado en la interfaz (magenta / alternado / 0↔10). Al soltar se restaura el original. - - publisher - editor + + Search… + Buscar… - - - YACReader::TrayIconController - - &Restore - &Restaurar + + Light + Luz - - Systray - Bandeja del sistema + + Dark + Oscuro - - YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary se continuará ejecutando en la bandeja del sistema. Para cerrar el programa elige <b>Cerrar</b> en el menú contextual del icono de la applicación en la bandeja del sistema. + + ID: + IDENTIFICACIÓN: - - - YACReader::WhatsNewDialog - - Close - Cerrar + + Display name: + Nombre para mostrar: - - - YACReaderFieldEdit - - Restore to default - Restaurar valor por defecto + + Variant: + Variante: - - - Click to overwrite - Click para sobreescribir + + Theme info + Información del tema - - - YACReaderFieldPlainTextEdit - - Restore to default - Restaurar valor por defecto + + Parameter + Parámetro - - - - - Click to overwrite - Click para sobreescribir + + Value + Valor - - - YACReaderFlowConfigWidget - - CoverFlow look - Tipo CoverFlow + + Save and apply + Guardar y aplicar - - How to show covers: - Cómo mostrar las portadas: + + Export to file... + Exportar a archivo... - - Stripe look - Tipo tira + + Load from file... + Cargar desde archivo... - - Overlapped Stripe look - Tipo tira solapada + + Close + Cerrar - - - YACReaderGLFlowConfigWidget - - Zoom - Zoom + + Double-click to edit color + Doble clic para editar el color - - Light - Luz + + + + + + + true + verdadero - - Show advanced settings - Opciones avanzadas + + + + + false + falso - - Roulette look - Tipo ruleta + + Double-click to toggle + Doble clic para alternar - - Cover Angle - Ángulo de las portadas + + Double-click to edit value + Doble clic para editar el valor - - Stripe look - Tipo tira + + + + Edit: %1 + Editar: %1 - - Position - Posición + + Save theme + Guardar tema - - Z offset - Desplazamiento en Z + + + JSON files (*.json);;All files (*) + Archivos JSON (*.json);;Todos los archivos (*) - - Y offset - Desplazamiento en Y + + Save failed + Error al guardar - - Central gap - Hueco central + + Could not open file for writing: +%1 + No se pudo abrir el archivo para escribir:\n%1 - - Presets: - Predeterminados: + + Load theme + Cargar tema - - Overlapped Stripe look - Tipo tira solapada + + + + Load failed + Error al cargar - - Modern look - Tipo moderno + + Could not open file: +%1 + No se pudo abrir el archivo:\n%1 - - View angle + + Invalid JSON: +%1 + JSON no válido:\n%1 + + + + Expected a JSON object. + Se esperaba un objeto JSON. + + + + TitleHeader + + + SEARCH + BUSCAR + + + + UpdateLibraryDialog + + + Update library + Actualizar biblioteca + + + + Cancel + Cancelar + + + + Updating.... + Actualizado... + + + + Viewer + + + + Press 'O' to open comic. + Pulsa 'O' para abrir un fichero. + + + + Not found + No encontrado + + + + Comic not found + Cómic no encontrado + + + + Error opening comic + Error abriendo cómic + + + + CRC Error + Error CRC + + + + Loading...please wait! + Cargando...espere, por favor! + + + + Page not available! + ¡Página no disponible! + + + + Cover! + ¡Portada! + + + + Last page! + ¡Última página! + + + + VolumeComicsModel + + + title + título + + + + VolumesModel + + + year + año + + + + issues + números + + + + publisher + editor + + + + YACReader3DFlowConfigWidget + + + Presets: + Predeterminados: + + + + Classic look + Tipo clásico + + + + Stripe look + Tipo tira + + + + Overlapped Stripe look + Tipo tira solapada + + + + Modern look + Tipo moderno + + + + Roulette look + Tipo ruleta + + + + Show advanced settings + Opciones avanzadas + + + + Custom: + Personalizado: + + + + View angle Ángulo de vista - + + Position + Posición + + + + Cover gap + Hueco entre portadas + + + + Central gap + Hueco central + + + + Zoom + Ampliaci?n + + + + Y offset + Desplazamiento en Y + + + + Z offset + Desplazamiento en Z + + + + Cover Angle + Ángulo de las portadas + + + + Visibility + Visibilidad + + + + Light + Luz + + + + Max angle + Ángulo máximo + + + + Low Performance + Rendimiento bajo + + + + High Performance + Alto rendimiento + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Usar VSync (mejora la calidad de imagen en pantalla completa, peor rendimiento) + + + + Performance: + Rendimiento: + + + + YACReader::MainWindowViewer + + + &Open + &Abrir + + + + Open a comic + Abrir cómic + + + + New instance + Nueva instancia + + + + Open Folder + Abrir carpeta + + + + Open image folder + Abrir carpeta de imágenes + + + + Open latest comic + Abrir el cómic más reciente + + + + Open the latest comic opened in the previous reading session + Abrir el cómic más reciente abierto en la sesión de lectura anterior + + + + Clear + Borrar + + + + Clear open recent list + Limpiar lista de abiertos recientemente + + + + Save + Guardar + + + + + Save current page + Guardar la página actual + + + + Previous Comic + Cómic anterior + + + + + + Open previous comic + Abrir cómic anterior + + + + Next Comic + Siguiente Cómic + + + + + + Open next comic + Abrir siguiente cómic + + + + &Previous + A&nterior + + + + + + Go to previous page + Ir a la página anterior + + + + &Next + Siguie&nte + + + + + + Go to next page + Ir a la página siguiente + + + + Fit Height + Ajustar altura + + + + Fit image to height + Ajustar página a lo alto + + + + Fit Width + Ajustar anchura + + + + Fit image to width + Ajustar página a lo ancho + + + + Show full size + Mostrar a tamaño original + + + + Fit to page + Ajustar a página + + + + Continuous scroll + Desplazamiento continuo + + + + Switch to continuous scroll mode + Cambiar al modo de desplazamiento continuo + + + + Reset zoom + Restablecer zoom + + + + Show zoom slider + Mostrar control deslizante de zoom + + + + Zoom+ + Ampliar+ + + + + Zoom- + Reducir + + + + Rotate image to the left + Rotar imagen a la izquierda + + + + Rotate image to the right + Rotar imagen a la derecha + + + + Double page mode + Modo a doble página + + + + Switch to double page mode + Cambiar a modo de doble página + + + + Double page manga mode + Modo de manga de página doble + + + + Reverse reading order in double page mode + Invertir el orden de lectura en modo de página doble + + + + Go To + Ir a + + + + Go to page ... + Ir a página... + + + + Options + Opciones + + + + YACReader options + Opciones de YACReader + + + + + Help + Ayuda + + + + Help, About YACReader + Ayuda, A cerca de... YACReader + + + + Magnifying glass + Lupa + + + + Switch Magnifying glass + Lupa On/Off + + + + Set bookmark + Añadir marcador + + + + Set a bookmark on the current page + Añadir un marcador en la página actual + + + + Show bookmarks + Mostrar marcadores + + + + Show the bookmarks of the current comic + Mostrar los marcadores del cómic actual + + + + Show keyboard shortcuts + Mostrar atajos de teclado + + + + Show Info + Mostrar información + + + + Close + Cerrar + + + + Show Dictionary + Mostrar diccionario + + + + Show go to flow + Mostrar flow ir a + + + + Edit shortcuts + Editar atajos + + + + &File + &Archivo + + + + + Open recent + Abrir reciente + + + + File + Archivo + + + + Edit + Editar + + + + View + Ver + + + + Go + Ir + + + + Window + Ventana + + + + + + Open Comic + Abrir cómic + + + + + + Comic files + Archivos de cómic + + + + Open folder + Abrir carpeta + + + + page_%1.jpg + página_%1.jpg + + + + Image files (*.jpg) + Archivos de imagen (*.jpg) + + + + + Comics + Cómics + + + + + General + Opciones generales + + + + + Magnifiying glass + Lupa + + + + + Page adjustement + Ajuste de página + + + + + Reading + Leyendo + + + + Toggle fullscreen mode + Alternar modo de pantalla completa + + + + Hide/show toolbar + Ocultar/mostrar barra de herramientas + + + + Size up magnifying glass + Aumentar tamaño de la lupa + + + + Size down magnifying glass + Disminuir tamaño de lupa + + + + Zoom in magnifying glass + Incrementar el aumento de la lupa + + + + Zoom out magnifying glass + Reducir el aumento de la lupa + + + + Reset magnifying glass + Resetear lupa + + + + Toggle between fit to width and fit to height + Alternar entre ajuste al ancho y ajuste al alto + + + + Autoscroll down + Desplazamiento automático hacia abajo + + + + Autoscroll up + Desplazamiento automático hacia arriba + + + + Autoscroll forward, horizontal first + Desplazamiento automático hacia adelante, primero horizontal + + + + Autoscroll backward, horizontal first + Desplazamiento automático hacia atrás, primero horizontal + + + + Autoscroll forward, vertical first + Desplazamiento automático hacia adelante, primero vertical + + + + Autoscroll backward, vertical first + Desplazamiento automático hacia atrás, primero vertical + + + + Move down + Mover abajo + + + + Move up + Mover arriba + + + + Move left + Mover a la izquierda + + + + Move right + Mover a la derecha + + + + Go to the first page + Ir a la primera página + + + + Go to the last page + Ir a la última página + + + + Offset double page to the left + Mover una página a la izquierda + + + + Offset double page to the right + Mover una página a la derecha + + + + There is a new version available + Hay una nueva versión disponible + + + + Do you want to download the new version? + ¿Desea descargar la nueva versión? + + + + Remind me in 14 days + Recordar en 14 días + + + + Not now + Ahora no + + + + YACReader::TrayIconController + + + &Restore + &Restaurar + + + + Systray + Bandeja del sistema + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary se continuará ejecutando en la bandeja del sistema. Para cerrar el programa elige <b>Cerrar</b> en el menú contextual del icono de la aplicación en la bandeja del sistema. + + + + YACReader::WhatsNewDialog + + Close + Cerrar + + + + YACReaderFieldEdit + + + Restore to default + Restaurar valor por defecto + + + + + Click to overwrite + Clic para sobrescribir + + + + YACReaderFieldPlainTextEdit + + + Restore to default + Restaurar valor por defecto + + + + + + + Click to overwrite + Clic para sobrescribir + + + + YACReaderFlowConfigWidget + + CoverFlow look + Tipo CoverFlow + + + How to show covers: + Cómo mostrar las portadas: + + + Stripe look + Tipo tira + + + Overlapped Stripe look + Tipo tira solapada + + + + YACReaderGLFlowConfigWidget + + Zoom + Ampliaci?n + + + Light + Luz + + + Show advanced settings + Opciones avanzadas + + + Roulette look + Tipo ruleta + + + Cover Angle + Ángulo de las portadas + + + Stripe look + Tipo tira + + + Position + Posición + + + Z offset + Desplazamiento en Z + + + Y offset + Desplazamiento en Y + + + Central gap + Hueco central + + + Presets: + Predeterminados: + + + Overlapped Stripe look + Tipo tira solapada + + + Modern look + Tipo moderno + + + View angle + Ángulo de vista + + Max angle - Ángulo máximo + Ángulo máximo - Custom: - Personalizado: + Personalizado: - Classic look - Tipo clásico + Tipo clásico - Cover gap - Hueco entre portadas + Hueco entre portadas - High Performance - Alto rendimiento + Alto rendimiento - Performance: - Rendimiento: + Rendimiento: - Use VSync (improve the image quality in fullscreen mode, worse performance) - Usar VSync (mejora la calidad de imagen en pantalla completa, peor rendimiento) + Usar VSync (mejora la calidad de imagen en pantalla completa, peor rendimiento) - Visibility - Visibilidad + Visibilidad - Low Performance - Rendimiento bajo + Rendimiento bajo YACReaderNavigationController - No favorites - Ningún favorito + Ningún favorito - You are not reading anything yet, come on!! - No estás leyendo nada aún, ¡vamos! + No estás leyendo nada aún, ¡vamos! - There are no recent comics! - ¡No hay comics recientes! + ¡No hay comics recientes! YACReaderOptionsDialog - + Save Guardar - Use hardware acceleration (restart needed) - Usar aceleración por hardware (necesario reiniciar) + Usar aceleración por hardware (necesario reiniciar) - + Cancel Cancelar - + Edit shortcuts Editar atajos - + Shortcuts Atajos @@ -3042,7 +4276,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t YACReaderSearchLineEdit - + type to search escribe para buscar @@ -3050,34 +4284,60 @@ To stop an automatic update tap on the loading indicator next to the Libraries t YACReaderSideBar - LIBRARIES - BIBLIOTECAS + BIBLIOTECAS - FOLDERS - CARPETAS + CARPETAS - Libraries - Bibliotecas + Bibliotecas - Folders - Carpetas + Carpetas - Reading Lists - Listas de lectura + Listas de lectura - READING LISTS - LISTAS DE LECTURA + LISTAS DE LECTURA + + + + YACReaderSlider + + + Reset + Restablecer + + + + YACReaderTranslator + + + YACReader translator + Traductor YACReader + + + + + Translation + Traducción + + + + clear + Limpiar + + + + Service not available + Servicio no disponible diff --git a/YACReaderLibrary/yacreaderlibrary_fr.ts b/YACReaderLibrary/yacreaderlibrary_fr.ts index 5212a1457..54b978cbc 100644 --- a/YACReaderLibrary/yacreaderlibrary_fr.ts +++ b/YACReaderLibrary/yacreaderlibrary_fr.ts @@ -12,84 +12,72 @@ AddLabelDialog - red - rouge + rouge - blue - bleu + bleu - dark - foncé + foncé - cyan - cyan + bleu cyan - pink - rose + rose - green - vert + vert - light - clair + clair - white - blanc + blanc - + Choose a color: Choisissez une couleur: - + accept accepter - + cancel Annuler - orange - orange + orang? - purple - violet + violet - violet - violet + pourpre - yellow - jaune + jaune - + Label name: - + Nom de l'étiquette : @@ -100,7 +88,7 @@ Ajouter - + Add an existing library Ajouter une librairie existante @@ -143,10 +131,150 @@ Collez ici votre clé API Comic Vine + + AppearanceTabWidget + + + Color scheme + Jeu de couleurs + + + + System + Système + + + + Light + Lumière + + + + Dark + Sombre + + + + Custom + Coutume + + + + Remove + Retirer + + + + Remove this user-imported theme + Supprimer ce thème importé par l'utilisateur + + + + Light: + Lumière: + + + + Dark: + Sombre: + + + + Custom: + Personnalisation: + + + + Import theme... + Importer le thème... + + + + Theme + Thème + + + + Theme editor + Éditeur de thème + + + + Open Theme Editor... + Ouvrir l'éditeur de thème... + + + + Theme editor error + Erreur de l'éditeur de thème + + + + The current theme JSON could not be loaded. + Le thème actuel JSON n'a pas pu être chargé. + + + + Import theme + Importer un thème + + + + JSON files (*.json);;All files (*) + Fichiers JSON (*.json);;Tous les fichiers (*) + + + + Could not import theme from: +%1 + Impossible d'importer le thème depuis : +%1 + + + + Could not import theme from: +%1 + +%2 + Impossible d'importer le thème depuis : +%1 + +%2 + + + + Import failed + Échec de l'importation + + + + BookmarksDialog + + + Lastest Page + Aller à la dernière page + + + + Close + Fermer + + + + Click on any image to go to the bookmark + Cliquez sur une image pour aller au marque-page + + + + + Loading... + Chargement... + + ClassicComicsView - + Hide comic flow Cacher le flux de bande dessinée @@ -154,82 +282,82 @@ ComicInfoView - + b/w - noir et blanc + n/b - + cover artist - couverture + dessinateur de couverture - + color couleur - + inker - encre + encreur - + penciller - dessin + dessinateur - + colorist - couleur + coloriste - + writer - scénario + scénariste - + Characters Personnages - + Main character or team - + Personnage principal ou équipe - + Teams - + Équipes - + Locations - + Emplacements - + Authors Auteurs - + editor - + éditeur - + imprint - + label éditorial - + Publisher - Editeur + Éditeur - + letterer lettreur @@ -254,17 +382,17 @@ Series - + Série Volume - + Tome Story Arc - + Arc d'histoire @@ -274,7 +402,7 @@ Pages - Pages + Feuilles @@ -294,7 +422,7 @@ Publication Date - + Date de publication @@ -305,74 +433,82 @@ ComicVineDialog - + back retour - + next suivant - + skip passer - + close fermer - - + + Retrieving tags for : %1 Retrouver les infomartions de: %1 - + Looking for comic... Vous cherchez une bande dessinée ... - + search chercher - - + + comic %1 of %2 - %3 bande dessinée %1 sur %2 - %3 - + %1 comics selected %1 bande(s) dessinnée(s) sélectionnée(s) - + Error connecting to ComicVine Erreur de connexion à Comic Vine - - - + + + Looking for volume... - + Vous cherchez du volume... - + Retrieving volume info... - + Récupération des informations sur le volume... + + + + ContinuousPageWidget + + + Loading page %1 + Chargement de la page %1 CreateLibraryDialog - + Create new library Créer une nouvelle librairie @@ -392,7 +528,7 @@ La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et continuer plus tard. - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder Le chemin sélectionné n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier @@ -407,7 +543,7 @@ Nom de la librairie : - + Path not found Chemin introuvable @@ -417,52 +553,49 @@ Restore defaults - + Réinitialiser To change a shortcut, double click in the key combination and type the new keys. - + Pour modifier un raccourci, double-cliquez sur la combinaison de touches et tapez les nouvelles clés. Shortcuts settings - + Paramètres de raccourcis - + Shortcut in use - + Raccourci en cours d'utilisation - + The shortcut "%1" is already assigned to other function - + Le raccourci "%1" est déjà affecté à une autre fonction EmptyFolderWidget - - Subfolders in this folder - Sous-dossiers dans ce dossier + Sous-dossiers dans ce dossier - Drag and drop folders and comics here - Glissez et déposez les dossiers et les bandes dessinées ici + Glissez et déposez les dossiers et les bandes dessinées ici - - Empty folder - + + This folder doesn't contain comics yet + Ce dossier ne contient pas encore de bandes dessinées EmptyLabelWidget - + This label doesn't contain comics yet Ce dossier ne contient pas encore de bandes dessinées @@ -475,6 +608,24 @@ Cette liste de lecture ne contient aucune bande dessinée + + EmptySpecialListWidget + + + No favorites + Pas de favoris + + + + You are not reading anything yet, come on!! + Vous ne lisez rien encore, allez !! + + + + There are no recent comics! + Il n'y a pas de BD récente ! + + ExportComicsInfoDialog @@ -483,7 +634,7 @@ Fichier de sortie : - + Destination database name Nom de la base de données de destination @@ -498,17 +649,17 @@ Créer - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier - + Export comics info Exporter les infos des bandes dessinées - + Problem found while writing Problème durant l'écriture @@ -526,7 +677,7 @@ Créer - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier @@ -536,17 +687,17 @@ Dossier de sortie : - + Problem found while writing Problème durant l'écriture - + Create covers package Créer un pack de couvertures - + Destination directory Répertoire de destination @@ -561,57 +712,86 @@ CRC error on page (%1): some of the pages will not be displayed correctly - + Erreur CRC sur la page (%1): certaines pages ne s'afficheront pas correctement Unknown error opening the file - + Erreur inconnue lors de l'ouverture du fichier Format not supported - + Format non supporté FolderContentView - + Continue Reading... - + Continuer la lecture... - FolderContentView6 + GoToDialog - - Continue Reading... - + + Page : + Feuille : + + + + Go To + Aller à + + + + Cancel + Annuler + + + + + Total pages : + Nombre de pages : + + + + Go to... + Aller à... + + + + GoToFlowToolBar + + + Page : + Feuille : GridComicsView - + Show info - + Afficher les informations HelpAboutDialog - + Help Aide - + System info - + Informations système - + About A propos @@ -639,7 +819,7 @@ Importer les infos des bandes dessinées - + Comics info file (*.ydb) Fichier infos BD (*.ydb) @@ -662,9 +842,9 @@ Désarchiver - + Compresed library covers (*.clc) - Compresed library covers (*.clc) + Couvertures de bibliothèque compressées (*.clc) @@ -677,7 +857,7 @@ Nom de la librairie : - + Extract a catalog Extraire un catalogue @@ -685,54 +865,54 @@ ImportWidget - + stop - Stop + Arrêter - + Importing comics Importation de bande dessinée - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> <p>YACReaderLibrary est en train de créer une nouvelle librairie.</p><p>La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et poursuivre plus tard.</p> - + Some of the comics being added... Ajout de bande dessinée... - + Updating the library Mise à jour de la librairie - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> <p>Mise à jour de la librairie. Pour plus de rapidité lors de la mise à jour, veuillez effectuer cette dernière régulièrement.</p><p>Vous pouvez arrêter le processus et poursuivre plus tard.</p> - + Upgrading the library - + Mise à niveau de la bibliothèque - + <p>The current library is being upgraded, please wait.</p> - + <p>La bibliothèque actuelle est en cours de mise à niveau, veuillez patienter.</p> - + Scanning the library - + Scanner la bibliothèque - + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> - + <p>La bibliothèque actuelle est en cours d'analyse pour rechercher des informations sur les métadonnées XML héritées.</p><p>Ceci n'est nécessaire qu'une seule fois, et uniquement si la bibliothèque a été créée avec YACReaderLibrary 9.8.2 ou une version antérieure.</p> @@ -742,17 +922,17 @@ Editer - + The selected folder doesn't contain any library. Le dossier sélectionné ne contient aucune librairie. - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? Cette librairie a été créée avec une ancienne version de YACReaderLibrary. Mise à jour necessaire. Mettre à jour? - + Comic Bande dessinée @@ -761,7 +941,7 @@ Mettre à jour ce dossier - + Error opening the library Erreur lors de l'ouverture de la librairie @@ -782,45 +962,45 @@ Marquer cette bande dessinée comme lu - - - + + + manga - + mangas - - - + + + comic - + comique - - - + + + western manga (left to right) - + manga occidental (de gauche à droite) Add selected comics to favorites list Ajouter la bande dessinée sélectionnée à la liste des favoris - - - + + + 4koma (top to botom) 4koma (top to botom - + 4koma (de haut en bas) - + Remove and delete metadata Supprimer les métadata - + Old library Ancienne librairie @@ -829,12 +1009,12 @@ Mise à jour des couvertures - + Set as completed Marquer comme complet - + Library Librairie @@ -847,13 +1027,13 @@ Mode plein écran activé/désactivé - + This library was created with a newer version of YACReaderLibrary. Download the new version now? Cette librairie a été créée avec une version plus récente de YACReaderLibrary. Télécharger la nouvelle version? - - + + Moving comics... Déplacer la bande dessinée... @@ -866,13 +1046,13 @@ Mettre à jour la librairie actuelle - - + + Copying comics... Copier la bande dessinée... - + Library '%1' is no longer available. Do you want to remove it? La librarie '%1' n'est plus disponible. Voulez-vous la supprimer? @@ -881,17 +1061,17 @@ Mettre la librairie à jour - + Open folder... Ouvrir le dossier... - + Do you want remove Voulez-vous supprimer - + Set as uncompleted Marquer comme incomplet @@ -900,17 +1080,17 @@ Supprimer la note d'évaluation - + Error updating the library Erreur lors de la mise à jour de la librairie - + Folder Dossier - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? L'élément sélectionné sera supprimé, vos bandes dessinées ou dossiers ne seront pas supprimés de votre disque. Êtes-vous sûr? @@ -923,7 +1103,7 @@ Ajouter à... - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? La librarie '%1' a été créée avec une ancienne version de YACReaderLibrary. Elle doit être re-créée. Voulez-vous créer la librairie? @@ -936,12 +1116,12 @@ Supprimer la liste de lecture actuelle de la bibliothèque - + Add new reading lists Ajouter de nouvelles listes de lecture - + You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. @@ -954,7 +1134,7 @@ Vous n'avez probablement besoin que d'une bibliothèque dans votre dos YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais vous devriez garder le nombre de bibliothèques bas. - + Set as read Marquer comme lu @@ -975,7 +1155,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Créer une nouvelle librairie - + Library not available Librairie non disponible @@ -996,7 +1176,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Ouvrir cette bande dessinée - + YACReader Library Librairie de YACReader @@ -1005,12 +1185,12 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Ajouter une nouvelle liste de lecture à la bibliothèque actuelle - + Error creating the library Erreur lors de la création de la librairie - + Update folder Mettre à jour le dossier @@ -1019,7 +1199,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Désarchiver les couvertures - + Update needed Mise à jour requise @@ -1032,12 +1212,12 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Afficher ou masquer les marques de lecture - + Library name already exists Le nom de la librairie existe déjà - + There is another library with the name '%1'. Une autre librairie a le nom '%1'. @@ -1046,12 +1226,12 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Supprimer la liste de lecture - + Download new version Téléchrger la nouvelle version - + Delete comics Supprimer les comics @@ -1088,7 +1268,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Désarchiver un catalogue - + All the selected comics will be deleted from your disk. Are you sure? Tous les comics sélectionnés vont être supprimés de votre disque. Êtes-vous sûr? @@ -1097,13 +1277,13 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Télécharger les informations de Comic Vine - - + + Set as unread Marquer comme non-lu - + Library not found Librairie introuvable @@ -1120,7 +1300,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Ouvrir le dossier... - + library? la librairie? @@ -1129,640 +1309,640 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Enregistrer les couvertures des bandes dessinées sélectionnées en tant que fichiers JPG - + Are you sure? Êtes-vous sûr? - + Rescan library for XML info - + Réanalyser la bibliothèque pour les informations XML - - - + + + web comic - + bande dessinée Web - + Add new folder - + Ajouter un nouveau dossier - + Delete folder - + Supprimer le dossier - + Upgrade failed - + La mise à niveau a échoué - + There were errors during library upgrade in: - + Des erreurs se sont produites lors de la mise à niveau de la bibliothèque dans : - + Folder name: - + Nom du dossier : - + No folder selected - + Aucun dossier sélectionné - + Please, select a folder first - + Veuillez d'abord sélectionner un dossier - + Error in path - + Erreur dans le chemin - + There was an error accessing the folder's path - + Une erreur s'est produite lors de l'accès au chemin du dossier - + The selected folder and all its contents will be deleted from your disk. Are you sure? - + Le dossier sélectionné et tout son contenu seront supprimés de votre disque. Es-tu sûr? - - + + Unable to delete - + Impossible de supprimer - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - + Un problème est survenu lors de la tentative de suppression des dossiers sélectionnés. Veuillez vérifier les autorisations d'écriture et assurez-vous que toutes les applications utilisent ces dossiers ou l'un des fichiers contenus. - - + + List name: - + Nom de la liste : - + Delete list/label - + Supprimer la liste/l'étiquette - + Rename list name - + Renommer le nom de la liste - - - - + + + + Set type - + Définir le type - + Set custom cover - + Définir une couverture personnalisée - + Delete custom cover - + Supprimer la couverture personnalisée - + Save covers - + Enregistrer les couvertures - + You are adding too many libraries. - + Vous ajoutez trop de bibliothèques. - - + + YACReader not found - + YACReader introuvable - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - + YACReader introuvable. YACReader doit être installé dans le même dossier que YACReaderLibrary. - + YACReader not found. There might be a problem with your YACReader installation. - + YACReader introuvable. Il se peut qu'il y ait un problème avec votre installation de YACReader. - + Error - + Erreur - + Error opening comic with third party reader. - + Erreur lors de l'ouverture de la bande dessinée avec un lecteur tiers. - + Library info - + Informations sur la bibliothèque - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - + Un problème est survenu lors de la tentative de suppression des bandes dessinées sélectionnées. Veuillez vérifier les autorisations d'écriture dans les fichiers sélectionnés ou le dossier contenant. - + Assign comics numbers - + Attribuer des numéros de bandes dessinées - + Assign numbers starting in: - + Attribuez des numéros commençant par : - + Invalid image - + Image invalide - + The selected file is not a valid image. - + Le fichier sélectionné n'est pas une image valide. - + Error saving cover - + Erreur lors de l'enregistrement de la couverture - + There was an error saving the cover image. - + Une erreur s'est produite lors de l'enregistrement de l'image de couverture. - + Remove comics - + Supprimer les bandes dessinées - + Comics will only be deleted from the current label/list. Are you sure? - + Les bandes dessinées seront uniquement supprimées du label/liste actuelle. Es-tu sûr? LibraryWindowActions - + Create a new library - Créer une nouvelle librairie + Créer une nouvelle librairie - + Open an existing library - Ouvrir une librairie existante + Ouvrir une librairie existante - - + + Export comics info - Exporter les infos des bandes dessinées + Exporter les infos des bandes dessinées - - + + Import comics info - Importer les infos des bandes dessinées + Importer les infos des bandes dessinées - + Pack covers - Archiver les couvertures + Archiver les couvertures - + Pack the covers of the selected library - Archiver les couvertures de la librairie sélectionnée + Archiver les couvertures de la librairie sélectionnée - + Unpack covers - Désarchiver les couvertures + Désarchiver les couvertures - + Unpack a catalog - Désarchiver un catalogue + Désarchiver un catalogue - + Update library - Mettre la librairie à jour + Mettre la librairie à jour - + Update current library - Mettre à jour la librairie actuelle + Mettre à jour la librairie actuelle - + Rename library - Renommer la librairie + Renommer la librairie - + Rename current library - Renommer la librairie actuelle + Renommer la librairie actuelle - + Remove library - Supprimer la librairie + Supprimer la librairie - + Remove current library from your collection - Enlever cette librairie de votre collection + Enlever cette librairie de votre collection - + Rescan library for XML info - + Réanalyser la bibliothèque pour les informations XML - + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. - + Essaie de trouver des informations XML intégrées dans des fichiers de bandes dessinées. Vous ne devez le faire que si la bibliothèque a été créée avec la version 9.8.2 ou des versions antérieures ou si vous utilisez un logiciel tiers pour intégrer des informations XML dans les fichiers. - + Show library info - + Afficher les informations sur la bibliothèque - + Show information about the current library - + Afficher des informations sur la bibliothèque actuelle - + Open current comic - Ouvrir cette bande dessinée + Ouvrir cette bande dessinée - + Open current comic on YACReader - Ouvrir cette bande dessinée dans YACReader + Ouvrir cette bande dessinée dans YACReader - + Save selected covers to... - Exporter la couverture vers... + Exporter la couverture vers... - + Save covers of the selected comics as JPG files - Enregistrer les couvertures des bandes dessinées sélectionnées en tant que fichiers JPG + Enregistrer les couvertures des bandes dessinées sélectionnées en tant que fichiers JPG - - + + Set as read - Marquer comme lu + Marquer comme lu - + Set comic as read - Marquer cette bande dessinée comme lu + Marquer cette bande dessinée comme lu - - + + Set as unread - Marquer comme non-lu + Marquer comme non-lu - + Set comic as unread - Marquer cette bande dessinée comme non-lu + Marquer cette bande dessinée comme non-lu - - + + manga - + mangas - + Set issue as manga - + Définir le problème comme manga - - + + comic - + comique - + Set issue as normal - + Définir le problème comme d'habitude - + western manga - + manga occidental - + Set issue as western manga - + Définir le problème comme un manga occidental - - + + web comic - + bande dessinée Web - + Set issue as web comic - + Définir le problème comme bande dessinée Web - - + + yonkoma - + Yonkoma - + Set issue as yonkoma - + Définir le problème comme Yonkoma - + Show/Hide marks - Afficher/Cacher les marqueurs + Afficher/Cacher les marqueurs - + Show or hide read marks - Afficher ou masquer les marques de lecture + Afficher ou masquer les marques de lecture - + Show/Hide recent indicator - + Afficher/Masquer l'indicateur récent - + Show or hide recent indicator - + Afficher ou masquer l'indicateur récent - - + + Fullscreen mode on/off - Mode plein écran activé/désactivé + Mode plein écran activé/désactivé - + Help, About YACReader - Aide, à propos de YACReader + Aide, à propos de YACReader - + Add new folder - + Ajouter un nouveau dossier - + Add new folder to the current library - + Ajouter un nouveau dossier à la bibliothèque actuelle - + Delete folder - + Supprimer le dossier - + Delete current folder from disk - + Supprimer le dossier actuel du disque - + Select root node - Allerà la racine + Allerà la racine - + Expand all nodes - Afficher tous les noeuds + Afficher tous les noeuds - + Collapse all nodes - + Réduire tous les nœuds - + Show options dialog - Ouvrir la boite de dialogue + Ouvrir la boite de dialogue - + Show comics server options dialog - Ouvrir la boite de dialogue du serveur + Ouvrir la boite de dialogue du serveur - - + + Change between comics views - + Changement entre les vues de bandes dessinées - + Open folder... - Ouvrir le dossier... + Ouvrir le dossier... - + Set as uncompleted - Marquer comme incomplet + Marquer comme incomplet - + Set as completed - Marquer comme complet + Marquer comme complet - + Set custom cover - + Définir une couverture personnalisée - + Delete custom cover - + Supprimer la couverture personnalisée - + western manga (left to right) - + manga occidental (de gauche à droite) - + Open containing folder... - Ouvrir le dossier... + Ouvrir le dossier... - + Reset comic rating - Supprimer la note d'évaluation + Supprimer la note d'évaluation - + Select all comics - Sélectionner toutes les bandes dessinées + Sélectionner toutes les bandes dessinées - + Edit - Editer + Editer - + Assign current order to comics - Assigner l'ordre actuel aux bandes dessinées + Assigner l'ordre actuel aux bandes dessinées - + Update cover - Mise à jour des couvertures + Mise à jour des couvertures - + Delete selected comics - Supprimer la bande dessinée sélectionnée + Supprimer la bande dessinée sélectionnée - + Delete metadata from selected comics - + Supprimer les métadonnées des bandes dessinées sélectionnées - + Download tags from Comic Vine - Télécharger les informations de Comic Vine + Télécharger les informations de Comic Vine - + Focus search line - + Ligne de recherche ciblée - + Focus comics view - + Focus sur la vue des bandes dessinées - + Edit shortcuts - + Modifier les raccourcis - + &Quit - + &Quitter - + Update folder - Mettre à jour le dossier + Mettre à jour le dossier - + Update current folder - Mettre à jour ce dossier + Mettre à jour ce dossier - + Scan legacy XML metadata - + Analyser les métadonnées XML héritées - + Add new reading list - Ajouter une nouvelle liste de lecture + Ajouter une nouvelle liste de lecture - + Add a new reading list to the current library - Ajouter une nouvelle liste de lecture à la bibliothèque actuelle + Ajouter une nouvelle liste de lecture à la bibliothèque actuelle - + Remove reading list - Supprimer la liste de lecture + Supprimer la liste de lecture - + Remove current reading list from the library - Supprimer la liste de lecture actuelle de la bibliothèque + Supprimer la liste de lecture actuelle de la bibliothèque - + Add new label - + Ajouter une nouvelle étiquette - + Add a new label to this library - + Ajouter une nouvelle étiquette à cette bibliothèque - + Rename selected list - + Renommer la liste sélectionnée - + Rename any selected labels or lists - + Renommer toutes les étiquettes ou listes sélectionnées - + Add to... - Ajouter à... + Ajouter à... - + Favorites - Favoris + Favoris - + Add selected comics to favorites list - Ajouter la bande dessinée sélectionnée à la liste des favoris + Ajouter la bande dessinée sélectionnée à la liste des favoris @@ -1770,200 +1950,196 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v file name - - - - - LogWindow - - - Log window - - - - - &Pause - - - - - &Save - - - - - C&lear - - - - - &Copy - - - - - Level: - - - - - &Auto scroll - + nom de fichier NoLibrariesWidget - + create your first library Créez votre première librairie - + You don't have any libraries yet Vous n'avez pas encore de librairie - + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Vous pouvez creer une librairie dans n'importe quel dossierr, YACReaderLibrary importera les dossiers et les bandes dessinées contenus dans ce dossier. Si vous avez déjà crer des librairies, vous pouvez les ouvrir.</p><p>N'oubliez pas que vous pouvez utiliser YACReader en tant que stand alone pour lire vos bandes dessinées sur votre ordinateur.</p> - + add an existing one Ajouter une librairie existante + + NoSearchResultsWidget + + + No results + Aucun résultat + + OptionsDialog - + + + Appearance + Apparence + + + + Options - Options + Possibilités + + + + + Language + Langue - + + + Application language + Langue de l'application + + + + + System default + Par défaut du système + + + Tray icon settings (experimental) - + Paramètres de l'icône de la barre d'état (expérimental) - + Close to tray - + Près du plateau - + Start into the system tray - + Commencez dans la barre d'état système - + Edit Comic Vine API key - + Modifier la clé API Comic Vine - + Comic Vine API key - + Clé API Comic Vine - + ComicInfo.xml legacy support - + Prise en charge héritée de ComicInfo.xml - + Import metadata from ComicInfo.xml when adding new comics Import metada from ComicInfo.xml when adding new comics - + Importer des métadonnées depuis ComicInfo.xml lors de l'ajout de nouvelles bandes dessinées - + Consider 'recent' items added or updated since X days ago - + Considérez les éléments « récents » ajoutés ou mis à jour depuis X jours - + Third party reader - + Lecteur tiers - + Write {comic_file_path} where the path should go in the command - + Écrivez {comic_file_path} où le chemin doit aller dans la commande - + + Clear - + Clair - + Update libraries at startup - + Mettre à jour les bibliothèques au démarrage - + Try to detect changes automatically - + Essayez de détecter automatiquement les changements - + Update libraries periodically - + Mettre à jour les bibliothèques périodiquement - + Interval: - + Intervalle: - + 30 minutes - + 30 min - + 1 hour - + 1 heure - + 2 hours - + 2 heures - + 4 hours - + 4 heures - + 8 hours - + 8 heures - + 12 hours - + 12 heures - + daily - + tous les jours - + Update libraries at certain time - + Mettre à jour les bibliothèques à un certain moment - + Time: - + Temps: - + WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. @@ -1971,147 +2147,322 @@ To stop an automatic update tap on the loading indicator next to the Libraries t WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. - + AVERTISSEMENT! Lors des mises à jour de la bibliothèque, les écritures dans la base de données sont désactivées ! +Ne planifiez pas de mises à jour pendant que vous utilisez activement l'application. +Lors des mises à jour automatiques, l'application bloquera certaines actions jusqu'à ce que la mise à jour soit terminée. +Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de chargement à côté du titre Bibliothèques. - + Modifications detection - + Détection des modifications - + Compare the modified date of files when updating a library (not recommended) - + Comparer la date de modification des fichiers lors de la mise à jour d'une bibliothèque (déconseillé) - + Enable background image - + Activer l'image d'arrière-plan - + Opacity level - + Niveau d'opacité - + Blur level - + Niveau de flou - + Use selected comic cover as background - + Utiliser la couverture de bande dessinée sélectionnée comme arrière-plan - + Restore defautls - + Restaurer les valeurs par défaut - + Background - + Arrière-plan - + Display continue reading banner - + Afficher la bannière de lecture continue - + Display current comic banner - + Afficher la bannière de bande dessinée actuelle - + Continue reading - + Continuer la lecture - + Comic Flow - + Flux comique - - + + Libraries - + Bibliothèques - + Grid view - + Vue grille - + + General - + Général - - - PropertiesDialog - - - - of: - sur: + + My comics path + Chemin de mes bandes dessinées - - Day: - Jour: + + Display + Afficher - - Plot - Intrigue + + Show time in current page information label + Afficher l'heure dans l'étiquette d'information de la page actuelle - - Size: - Taille: + + "Go to flow" size + Taille du flux - - Year: - Année: + + Background color + Couleur d'arrière plan - - Inker(s): - Encreur(s): + + Choose + Choisir - - Publishing - Publication + + Scroll behaviour + Comportement de défilement - - Publisher: - Editeur: + + Disable scroll animations and smooth scrolling + Désactiver les animations de défilement et le défilement fluide - - General info - Infos générales + + Do not turn page using scroll + Ne tournez pas la page en utilisant le défilement - - Color/BW: - Couleur/Noir et blanc: + + Use single scroll step to turn page + Utilisez une seule étape de défilement pour tourner la page - - Edit selected comics information - Editer les informations du comic sélectionné + + Mouse mode + Mode souris - - Penciller(s): + + Only Back/Forward buttons can turn pages + Seuls les boutons Précédent/Avant peuvent tourner les pages + + + + Use the Left/Right buttons to turn pages. + Utilisez les boutons Gauche/Droite pour tourner les pages. + + + + Click left or right half of the screen to turn pages. + Cliquez sur la moitié gauche ou droite de l'écran pour tourner les pages. + + + + Quick Navigation Mode + Mode navigation rapide + + + + Disable mouse over activation + Désactiver la souris sur l'activation + + + + Brightness + Luminosité + + + + Contrast + Contraste + + + + Gamma + Valeur gamma + + + + Reset + Remise à zéro + + + + Image options + Option de l'image + + + + Fit options + Options d'ajustement + + + + Enlarge images to fit width/height + Agrandir les images pour les adapter à la largeur/hauteur + + + + Double Page options + Options de double page + + + + Show covers as single page + Afficher les couvertures sur une seule page + + + + Scaling + Mise à l'échelle + + + + Scaling method + Méthode de mise à l'échelle + + + + Nearest (fast, low quality) + Le plus proche (rapide, mauvaise qualité) + + + + Bilinear + Bilinéaire + + + + Lanczos (better quality) + Lanczos (meilleure qualité) + + + + Page Flow + Flux des pages + + + + Image adjustment + Ajustement de l'image + + + + + Restart is needed + Redémarrage nécessaire + + + + Comics directory + Répertoire des bandes dessinées + + + + PropertiesDialog + + + + + of: + sur: + + + + Day: + Jour: + + + + Plot + Intrigue + + + + Size: + Taille: + + + + Year: + Année: + + + + Inker(s): + Encreur(s): + + + + Publishing + Publication + + + + Publisher: + Editeur: + + + + General info + Infos générales + + + + Color/BW: + Couleur/Noir et blanc: + + + + Edit selected comics information + Editer les informations du comic sélectionné + + + + Penciller(s): Dessinateur(s): @@ -2122,37 +2473,37 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Genre: - Genre: + Genre : Notes - + Remarques Load previous page as cover - + Charger la page précédente comme couverture Load next page as cover - + Charger la page suivante comme couverture Reset cover to the default image - + Réinitialiser la couverture à l'image par défaut Load custom cover image - + Charger une image de couverture personnalisée Series: - + Série: @@ -2162,27 +2513,27 @@ To stop an automatic update tap on the loading indicator next to the Libraries t alt. number: - + alt. nombre: Alternate series: - + Série alternative : Series Group: - + Groupe de séries : Editor(s): - + Editeur(s) : Imprint: - + Imprimer: @@ -2192,52 +2543,52 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Type: - + Taper: Language (ISO): - + Langue (ISO) : Teams: - + Équipes : Locations: - + Emplacements : Main character or team: - + Personnage principal ou équipe : Review: - + Revoir: Notes: - Notes: + Remarques : Invalid cover - + Couverture invalide The image is invalid. - + L'image n'est pas valide. Synopsis: - Synopsis: + Synopsis : @@ -2252,7 +2603,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Tags: - + Balises : @@ -2307,12 +2658,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Volume: - Volume: + Tome : Format: - Format: + Format : @@ -2322,7 +2673,23 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - + Lien Comic Vine : <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> vue </a> + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer est la version sans tête (sans interface graphique) de YACReaderLibrary. + +Cette application prend en charge les paramètres persistants, pour les configurer, modifiez ce fichier %1 +Pour en savoir plus sur les paramètres disponibles, veuillez consulter la documentation sur https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md @@ -2330,99 +2697,83 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 7z lib not found - + lib 7z introuvable unable to load 7z lib from ./utils - + impossible de charger 7z depuis ./utils Trace - + Tracer Debug - + Déboguer Info - + Informations Warning - + Avertissement Error - + Erreur Fatal - + Critique - + Select custom cover - + Sélectionnez une couverture personnalisée - + Images (%1) - - - - - QsLogging::LogWindowModel - - - Time - - - - - Level - + Illustrations (%1) - - Message - + + The file could not be read or is not valid JSON. + Le fichier n'a pas pu être lu ou n'est pas un JSON valide. - - - QsLogging::Window - - &Pause - + + This theme is for %1, not %2. + Ce thème est pour %1, pas pour %2. - - &Resume - + + Libraries + Bibliothèques - - Save log - + + Folders + Dossiers - - Log file (*.log) - + + Reading Lists + Listes de lecture RenameLibraryDialog - + Rename current library Renommer la librairie actuelle @@ -2445,20 +2796,20 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ScraperResultsPaginator - + Number of volumes found : %1 - + Nombre de volumes trouvés : %1 - - + + page %1 of %2 - + page %1 de %2 - + Number of %1 found : %2 - + Nombre de %1 trouvés : %2 @@ -2467,17 +2818,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information for this comic. Please provide some additional information. - + Veuillez fournir des informations supplémentaires pour cette bande dessinée. - + Series: - + Série: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Utilisez la recherche de correspondance exacte. Désactivez-la si vous souhaitez rechercher des volumes correspondant à certains mots du nom. @@ -2485,503 +2836,1355 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information. - + Veuillez fournir quelques informations supplémentaires. - + Series: - + Série: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Utilisez la recherche de correspondance exacte. Désactivez-la si vous souhaitez rechercher des volumes correspondant à certains mots du nom. SelectComic - + Please, select the right comic info. - + Veuillez sélectionner les bonnes informations sur la bande dessinée. - + comics - + bandes dessinées - + loading cover - + couvercle de chargement - + loading description - + description du chargement - + comic description unavailable - + description de la bande dessinée indisponible SelectVolume - + Please, select the right series for your comic. - + Veuillez sélectionner la bonne série pour votre bande dessinée. - + Filter: - + Filtre: - + volumes - + tomes - + Nothing found, clear the filter if any. - + Rien trouvé, effacez le filtre le cas échéant. - + loading cover - + couvercle de chargement - + loading description - + description du chargement - + volume description unavailable - + description du volume indisponible SeriesQuestion - + no non - + yes oui You are trying to get information for various comics at once, are they part of the same series? - + Vous essayez d’obtenir des informations sur plusieurs bandes dessinées à la fois, font-elles partie de la même série ? ServerConfigDialog - + Port - Port + Port r?seau - + enable the server Autoriser le serveur - + set port Configurer le port - + Server connectivity information - + Informations sur la connectivité du serveur - + Scan it! - + Scannez-le ! - + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + YACReader est disponible pour les appareils iOS et Android.<br/>Découvrez-le pour <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + Choose an IP address - + Choisissez une adresse IP SortVolumeComics - + Please, sort the list of comics on the left until it matches the comics' information. - + Veuillez trier la liste des bandes dessinées sur la gauche jusqu'à ce qu'elle corresponde aux informations des bandes dessinées. - + sort comics to match comic information - + trier les bandes dessinées pour qu'elles correspondent aux informations sur les bandes dessinées - + issues - + problèmes - + remove selected comics - + supprimer les bandes dessinées sélectionnées - + restore all removed comics - + restaurer toutes les bandes dessinées supprimées - TitleHeader + ThemeEditorDialog - - SEARCH - + + Theme Editor + Éditeur de thème - - - UpdateLibraryDialog - - Update library - Mettre la librairie à jour + + + + + - - Cancel - Annuler + + - + - - - Updating.... - Mise à jour... + + i + je - - - VolumeComicsModel - - title - + + Expand all + Tout développer - - - VolumesModel - - publisher - éditeur + + Collapse all + Tout réduire - - year - + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Maintenez enfoncé pour faire clignoter la valeur sélectionnée dans l'interface utilisateur (magenta / basculé / 0↔10). Les versions restaurent l'original. - - issues - + + Search… + Rechercher… - - - YACReader::TrayIconController - - &Restore - + + Light + Lumière - - Systray - + + Dark + Sombre - - YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - + + ID: + IDENTIFIANT: - - - YACReader::WhatsNewDialog - - Close - + + Display name: + Nom d'affichage : - - - YACReaderFieldEdit - - Restore to default - Restaurer les paramètres par défaut + + Variant: + Variante: - - - Click to overwrite - Cliquer pour modifier + + Theme info + Informations sur le thème - - - YACReaderFieldPlainTextEdit - - Restore to default - Restaurer les paramètres par défaut + + Parameter + Paramètre - - - - - Click to overwrite - Cliquer pour modifier + + Value + Valeur - - - YACReaderFlowConfigWidget - - CoverFlow look - Vue CoverFlow + + Save and apply + Enregistrer et postuler - - How to show covers: - Comment voir les couvertures: + + Export to file... + Exporter vers un fichier... - - Stripe look - Vue alignée + + Load from file... + Charger à partir du fichier... - - Overlapped Stripe look - Vue superposée + + Close + Fermer - - - YACReaderGLFlowConfigWidget - - Zoom - Zoom + + Double-click to edit color + Double-cliquez pour modifier la couleur - - Light - Lumière + + + + + + + true + vrai - - Show advanced settings - Réglages avancés + + + + + false + FAUX - - Roulette look - Vue roulette + + Double-click to toggle + Double-cliquez pour basculer - - Cover Angle - Angle des couvertures + + Double-click to edit value + Double-cliquez pour modifier la valeur - - Stripe look - Vue alignée + + + + Edit: %1 + Modifier : %1 - - Position - Position + + Save theme + Enregistrer le thème - - Z offset - Axe Z + + + JSON files (*.json);;All files (*) + Fichiers JSON (*.json);;Tous les fichiers (*) - - Y offset - Axe Y + + Save failed + Échec de l'enregistrement - - Central gap - Espace central + + Could not open file for writing: +%1 + Impossible d'ouvrir le fichier en écriture : +%1 - - Presets: - Réglages: + + Load theme + Charger le thème - - Overlapped Stripe look - Vue superposée + + + + Load failed + Échec du chargement - - Modern look - Vue moderne + + Could not open file: +%1 + Impossible d'ouvrir le fichier : +%1 - - View angle - Angle de vue + + Invalid JSON: +%1 + JSON invalide : +%1 - - Max angle - Angle maximum + + Expected a JSON object. + Attendu un objet JSON. + + + TitleHeader - - Custom: - Personnalisation: + + SEARCH + RECHERCHE + + + UpdateLibraryDialog - - Classic look - Vue classique + + Update library + Mettre la librairie à jour - - Cover gap - Espace entre les couvertures + + Cancel + Annuler - - High Performance - Haute performance + + Updating.... + Mise à jour... + + + Viewer - - Performance: - Performance: + + + Press 'O' to open comic. + Appuyez sur "O" pour ouvrir une bande dessinée. - - Use VSync (improve the image quality in fullscreen mode, worse performance) - Utiliser VSync (améliore la qualité de l'image en plein écran, diminue la performance) + + Not found + Introuvable + + + + Comic not found + Bande dessinée introuvable + + + + Error opening comic + Erreur d'ouverture de la bande dessinée + + + + CRC Error + Erreur CRC + + + + Loading...please wait! + Chargement... Patientez + + + + Page not available! + Page non disponible ! + + + + Cover! + Couverture! + + + + Last page! + Dernière page! + + + + VolumeComicsModel + + + title + titre + + + + VolumesModel + + + publisher + éditeur + + + + year + année + + + + issues + problèmes + + + + YACReader3DFlowConfigWidget + + + Presets: + Réglages: + + + + Classic look + Vue classique + + + + Stripe look + Vue alignée + + + + Overlapped Stripe look + Vue superposée - + + Modern look + Vue moderne + + + + Roulette look + Vue roulette + + + + Show advanced settings + Réglages avancés + + + + Custom: + Personnalisation: + + + + View angle + Angle de vue + + + + Position + Positionnement + + + + Cover gap + Espace entre les couvertures + + + + Central gap + Espace central + + + + Zoom + Agrandissement + + + + Y offset + Axe Y + + + + Z offset + Axe Z + + + + Cover Angle + Angle des couvertures + + + Visibility Visibilité - + + Light + Lumière + + + + Max angle + Angle maximum + + + Low Performance Basse performance + + + High Performance + Haute performance + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Utiliser VSync (améliore la qualité de l'image en plein écran, diminue la performance) + + + + Performance: + Performance : + - YACReaderNavigationController + YACReader::MainWindowViewer - - You are not reading anything yet, come on!! - Vous ne lisez rien encore, allez !! + + &Open + &Ouvrir - - There are no recent comics! - + + Open a comic + Ouvrir une bande dessinée + + + + New instance + Nouvelle instance + + + + Open Folder + Ouvrir un dossier + + + + Open image folder + Ouvrir un dossier d'images + + + + Open latest comic + Ouvrir la dernière bande dessinée + + + + Open the latest comic opened in the previous reading session + Ouvrir la dernière bande dessinée ouverte lors de la session de lecture précédente + + + + Clear + Clair + + + + Clear open recent list + Vider la liste d'ouverture récente + + + + Save + Sauvegarder + + + + + Save current page + Sauvegarder la page actuelle + + + + Previous Comic + Bande dessinée précédente + + + + + + Open previous comic + Ouvrir la bande dessiné précédente + + + + Next Comic + Bande dessinée suivante + + + + + + Open next comic + Ouvrir la bande dessinée suivante + + + + &Previous + &Précédent + + + + + + Go to previous page + Aller à la page précédente + + + + &Next + &Suivant + + + + + + Go to next page + Aller à la page suivante + + + + Fit Height + Ajuster la hauteur + + + + Fit image to height + Ajuster l'image à la hauteur + + + + Fit Width + Ajuster la largeur + + + + Fit image to width + Ajuster l'image à la largeur + + + + Show full size + Plein écran + + + + Fit to page + Ajuster à la page + + + + Continuous scroll + Défilement continu + + + + Switch to continuous scroll mode + Passer en mode défilement continu + + + + Reset zoom + Réinitialiser le zoom + + + + Show zoom slider + Afficher le curseur de zoom + + + + Zoom+ + Agrandir + + + + Zoom- + R?duire + + + + Rotate image to the left + Rotation à gauche + + + + Rotate image to the right + Rotation à droite + + + + Double page mode + Mode double page + + + + Switch to double page mode + Passer en mode double page + + + + Double page manga mode + Mode manga en double page + + + + Reverse reading order in double page mode + Ordre de lecture inversée en mode double page + + + + Go To + Aller à + + + + Go to page ... + Aller à la page ... + + + + Options + Possibilités + + + + YACReader options + Options de YACReader + + + + + Help + Aide + + + + Help, About YACReader + Aide, à propos de YACReader + + + + Magnifying glass + Loupe + + + + Switch Magnifying glass + Utiliser la loupe + + + + Set bookmark + Placer un marque-page + + + + Set a bookmark on the current page + Placer un marque-page sur la page actuelle + + + + Show bookmarks + Voir les marque-pages + + + + Show the bookmarks of the current comic + Voir les marque-pages de cette bande dessinée + + + + Show keyboard shortcuts + Voir les raccourcis + + + + Show Info + Voir les infos + + + + Close + Fermer + + + + Show Dictionary + Dictionnaire + + + + Show go to flow + Afficher le flux + + + + Edit shortcuts + Modifier les raccourcis + + + + &File + &Fichier + + + + + Open recent + Ouvrir récent + + + + File + Fichier + + + + Edit + Editer + + + + View + Vue + + + + Go + Aller + + + + Window + Fenêtre + + + + + + Open Comic + Ouvrir la bande dessinée + + + + + + Comic files + Bande dessinée + + + + Open folder + Ouvirir le dossier + + + + page_%1.jpg + feuille_%1.jpg + + + + Image files (*.jpg) + Image(*.jpg) + + + + + Comics + Bandes dessinées + + + + + General + Général + + + + + Magnifiying glass + Loupe + + + + + Page adjustement + Ajustement de la page + + + + + Reading + Lecture + + + + Toggle fullscreen mode + Basculer en mode plein écran + + + + Hide/show toolbar + Masquer / afficher la barre d'outils + + + + Size up magnifying glass + Augmenter la taille de la loupe + + + + Size down magnifying glass + Réduire la taille de la loupe + + + + Zoom in magnifying glass + Zoomer + + + + Zoom out magnifying glass + Dézoomer + + + + Reset magnifying glass + Réinitialiser la loupe + + + + Toggle between fit to width and fit to height + Basculer entre adapter à la largeur et adapter à la hauteur + + + + Autoscroll down + Défilement automatique vers le bas + + + + Autoscroll up + Défilement automatique vers le haut + + + + Autoscroll forward, horizontal first + Défilement automatique en avant, horizontal + + + + Autoscroll backward, horizontal first + Défilement automatique en arrière horizontal + + + + Autoscroll forward, vertical first + Défilement automatique en avant, vertical + + + + Autoscroll backward, vertical first + Défilement automatique en arrière, verticak + + + + Move down + Descendre + + + + Move up + Monter + + + + Move left + Déplacer à gauche + + + + Move right + Déplacer à droite + + + + Go to the first page + Aller à la première page + + + + Go to the last page + Aller à la dernière page + + + + Offset double page to the left + Double page décalée vers la gauche + + + + Offset double page to the right + Double page décalée à droite + + + + There is a new version available + Une nouvelle version est disponible + + + + Do you want to download the new version? + Voulez-vous télécharger la nouvelle version? + + + + Remind me in 14 days + Rappelez-moi dans 14 jours + + + + Not now + Pas maintenant + + + + YACReader::TrayIconController + + + &Restore + &Restaurer + + + + Systray + Zone de notification + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quit</b> dans le menu contextuel de l'icône de la barre d'état système. + + + + YACReaderFieldEdit + + + Restore to default + Restaurer les paramètres par défaut + + + + + Click to overwrite + Cliquer pour modifier + + + + YACReaderFieldPlainTextEdit + + + Restore to default + Restaurer les paramètres par défaut + + + + + + + Click to overwrite + Cliquer pour modifier + + + + YACReaderFlowConfigWidget + + CoverFlow look + Vue CoverFlow + + + How to show covers: + Comment voir les couvertures: + + + Stripe look + Vue alignée + + + Overlapped Stripe look + Vue superposée + + + + YACReaderGLFlowConfigWidget + + Zoom + Agrandissement + + + Light + Lumière + + + Show advanced settings + Réglages avancés + + + Roulette look + Vue roulette + + + Cover Angle + Angle des couvertures + + + Stripe look + Vue alignée + + + Position + Positionnement + + + Z offset + Axe Z + + + Y offset + Axe Y + + + Central gap + Espace central + + + Presets: + Réglages: + + + Overlapped Stripe look + Vue superposée + + + Modern look + Vue moderne + + + View angle + Angle de vue + + + Max angle + Angle maximum + + + Custom: + Personnalisation: + + + Classic look + Vue classique + + + Cover gap + Espace entre les couvertures + + + High Performance + Haute performance + + + Performance: + Performance : + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Utiliser VSync (améliore la qualité de l'image en plein écran, diminue la performance) + + + Visibility + Visibilité + + + Low Performance + Basse performance + + + + YACReaderNavigationController + + You are not reading anything yet, come on!! + Vous ne lisez rien encore, allez !! - No favorites - Pas de favoris + Pas de favoris YACReaderOptionsDialog - + Save Sauvegarder - Use hardware acceleration (restart needed) - Utiliser l'accélération hardware (redémarrage nécessaire) + Utiliser l'accélération hardware (redémarrage nécessaire) - + Cancel Annuler - + Edit shortcuts - + Modifier les raccourcis - + Shortcuts - + Raccourcis YACReaderSearchLineEdit - + type to search - + tapez pour rechercher YACReaderSideBar - Reading Lists - Listes de lecture + Listes de lecture - LIBRARIES - LIBRAIRIES + LIBRAIRIES - FOLDERS - DOSSIERS + DOSSIERS - READING LISTS - Listes de lecture + Listes de lecture + + + YACReaderSlider - - Libraries - + + Reset + Remise à zéro + + + YACReaderTranslator - - Folders - + + YACReader translator + Traducteur YACReader + + + + + Translation + Traduction + + + + clear + effacer + + + + Service not available + Service non disponible diff --git a/YACReaderLibrary/yacreaderlibrary_it.ts b/YACReaderLibrary/yacreaderlibrary_it.ts index 8f32caea7..1a561cb11 100644 --- a/YACReaderLibrary/yacreaderlibrary_it.ts +++ b/YACReaderLibrary/yacreaderlibrary_it.ts @@ -12,82 +12,70 @@ AddLabelDialog - red - Rosso + Rosso - blue - Blu + Blu - dark - Scuro + Scuro - cyan - Azzurro + Azzurro - pink - Rosa + Rosa - green - Verde + Verde - light - Luminoso + Luminoso - white - Bianco + Bianco - + Choose a color: Seleziona un colore: - + accept Accetta - + cancel Cancella - orange - Arancione + Arancione - purple - Porpora + Porpora - violet - Viola + Viola - yellow - Giallo + Giallo - + Label name: Nome etichetta: @@ -100,7 +88,7 @@ Aggiungi - + Add an existing library Aggiungi ad una libreria esistente @@ -121,7 +109,7 @@ Library name : - + Nome della biblioteca: @@ -147,10 +135,150 @@ Incolla qui la tua chiave API di "Comic Vine" + + AppearanceTabWidget + + + Color scheme + Combinazione di colori + + + + System + Sistema + + + + Light + Luminoso + + + + Dark + Buio + + + + Custom + Costume + + + + Remove + Rimuovere + + + + Remove this user-imported theme + Rimuovi questo tema importato dall'utente + + + + Light: + Leggero: + + + + Dark: + Buio: + + + + Custom: + Personalizza: + + + + Import theme... + Importa tema... + + + + Theme + Tema + + + + Theme editor + Redattore del tema + + + + Open Theme Editor... + Apri l'editor del tema... + + + + Theme editor error + Errore nell'editor del tema + + + + The current theme JSON could not be loaded. + Impossibile caricare il tema corrente JSON. + + + + Import theme + Importa tema + + + + JSON files (*.json);;All files (*) + File JSON (*.json);;Tutti i file (*) + + + + Could not import theme from: +%1 + Impossibile importare il tema da: +%1 + + + + Could not import theme from: +%1 + +%2 + Impossibile importare il tema da: +%1 + +%2 + + + + Import failed + Importazione non riuscita + + + + BookmarksDialog + + + Lastest Page + Ultima Pagina + + + + Close + Chiudi + + + + Click on any image to go to the bookmark + Click su qualsiasi immagine per andare al bookmark + + + + + Loading... + Caricamento... + + ClassicComicsView - + Hide comic flow Nascondi il flusso dei fumetti @@ -158,84 +286,84 @@ ComicInfoView - + + Characters + Personaggi + + + Main character or team - + Personaggio principale o squadra - + Teams - + Squadre - + Locations - + Posizioni - + Authors - Autori + Autori - + writer - + sceneggiatore - + penciller - + disegnatore - + inker - + inchiostratore - + colorist - + colorista - + letterer - + letterista - + cover artist - + disegnatore di copertina - + editor - + editor - + imprint - + marchio editoriale - + Publisher - + Editore - + color - + colore - + b/w - - - - - Characters - + b/n @@ -258,17 +386,17 @@ Series - + Serie Volume - + Tomo Story Arc - + Arco narrativo @@ -298,7 +426,7 @@ Publication Date - + Data di pubblicazione @@ -309,74 +437,82 @@ ComicVineDialog - + back Indietro - + next Prossimo - + skip Salta - + close Chiudi - - + + Retrieving tags for : %1 Ricezione tag per: %1 - + Looking for comic... Sto cercando il fumetto... - + search Cerca - - - + + + Looking for volume... Sto cercando il fumetto... - - + + comic %1 of %2 - %3 Fumetto %1 di %2 - %3 - + %1 comics selected Fumetto %1 selezionato - + Error connecting to ComicVine Errore durante la connessione a ComicVine - + Retrieving volume info... Sto ricevendo le informazioni per l'abum... + + ContinuousPageWidget + + + Loading page %1 + Caricamento pagina %1 + + CreateLibraryDialog - + Create new library Crea una nuova libreria @@ -396,7 +532,7 @@ Creare una Libreria può aver bisogno di alcuni minuti. Puoi fermare il processo ed aggiornare la libreria più tardi. - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder Il percorso selezionato non esiste oppure non è valido. Controlla di avere i permessi di scrittura per questa cartella @@ -411,7 +547,7 @@ Nome libreria: - + Path not found Percorso non trovato @@ -419,7 +555,7 @@ EditShortcutsDialog - + Shortcut in use Scorciatoia in uso @@ -434,7 +570,7 @@ Impostazioni scorciatoie - + The shortcut "%1" is already assigned to other function La scorciatoia "%1" è già assegnata ad un' altra funzione @@ -447,26 +583,27 @@ EmptyFolderWidget - Empty folder - Cartella vuota + Cartella vuota - - Subfolders in this folder - Sottocartelle in questa cartella + Sottocartelle in questa cartella - Drag and drop folders and comics here - Prendi e sposta le cartelle qui + Prendi e sposta le cartelle qui + + + + This folder doesn't contain comics yet + Questa cartella non contiene ancora fumetti EmptyLabelWidget - + This label doesn't contain comics yet Per ora questa etichetta non contiene fumetti @@ -479,6 +616,24 @@ Per ora questa lista non contiene fumetti + + EmptySpecialListWidget + + + No favorites + Nessun Favorito + + + + You are not reading anything yet, come on!! + Non stai ancora leggendo nulla, Forza!! + + + + There are no recent comics! + Non ci sono fumetti recenti! + + ExportComicsInfoDialog @@ -487,7 +642,7 @@ File di Output: - + Destination database name Nome database di destinazione @@ -502,17 +657,17 @@ Crea - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder Il percorso selezionato per il file di Output non esiste oppure non è valido. Controlla di avere i permessi di scrittura per questa cartella - + Export comics info Esporta informazioni fumetto - + Problem found while writing Trovato problema durante la scrittura @@ -530,7 +685,7 @@ Crea - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder Il percorso selezionato per il file di Output non esiste oppure non è valido. Controlla di avere i permessi di scrittura per questa cartella @@ -540,17 +695,17 @@ Cartella di Output: - + Problem found while writing Trovato problema durante la scrittura - + Create covers package Crea pacchetto delle copertine - + Destination directory Cartella di destinazione @@ -581,23 +736,52 @@ FolderContentView - + Continue Reading... - + Continua a leggere... - FolderContentView6 + GoToDialog - - Continue Reading... - + + Page : + Pagina: + + + + Go To + Vai a + + + + Cancel + Cancella + + + + + Total pages : + Pagine totali: + + + + Go to... + Vai a... + + + + GoToFlowToolBar + + + Page : + Pagina: GridComicsView - + Show info Mostra informazioni @@ -605,17 +789,17 @@ HelpAboutDialog - + Help Aiuto - + System info - + Informazioni di sistema - + About Informazioni @@ -643,7 +827,7 @@ Importa informazioni fumetto - + Comics info file (*.ydb) File informazioni fumetto (*.ydb) @@ -666,7 +850,7 @@ Decomprimi - + Compresed library covers (*.clc) Libreria di copertine compresse (*.clc) @@ -681,7 +865,7 @@ Nome libreria: - + Extract a catalog Estrai un catalogo @@ -689,54 +873,54 @@ ImportWidget - + stop Ferma - + Importing comics Sto importando i fumetti - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> <p>YacReader sta creando una nuova libreria.</p><p>La creazione di una libreria può durare diversi minuti. Puoi fermare l'attività ed aggiornare la libreria più tardi, completando l'attività</p> - + Some of the comics being added... Alcuni fumetti che sto aggiungendo... - + Updating the library Sto aggiornando la Libreria - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> <p>Quest alibreria si sta aggiornando. Per aggiornamenti più veloci aggiorna la tua libreria di frequente.</p><p>Puoi fermare il processo ed aggiornare la libreria più tardi.</p> - + Upgrading the library - + Aggiornamento della biblioteca - + <p>The current library is being upgraded, please wait.</p> - + <p>È in corso l'aggiornamento della libreria corrente, attendi.</p> - + Scanning the library - + Scansione della libreria - + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> - + <p>Scansione della libreria corrente per informazioni sui metadati XML legacy.</p><p>Questa operazione è necessaria solo una volta e solo se la libreria è stata creata con YACReaderLibrary 9.8.2 o versioni precedenti.</p> @@ -746,27 +930,27 @@ Edita - + The selected folder doesn't contain any library. La cartella selezionata non contiene nessuna Libreria. - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? Questa libreria è stata creata con una versione precedente di YACREaderLibrary. Deve essere aggiornata. Aggiorno ora? - + Comic Fumetto - + Folder name: Nome della cartella: - + The selected folder and all its contents will be deleted from your disk. Are you sure? La cartella seleziona e tutto il suo contenuto verranno cancellati dal tuo disco. Sei sicuro? @@ -775,7 +959,7 @@ Aggiorna la cartella corrente - + Error opening the library Errore nell'apertura della libreria @@ -784,8 +968,8 @@ Mostra/Nascondi - - + + YACReader not found YACReader non trovato @@ -794,7 +978,7 @@ Mostra le opzioni per il server dei fumetti - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. C'è stato un problema cancellando le cartelle selezionate. Per favore controlla i tuoi permessi di scrittura e sii sicuro che non ci siano altre applicazioni che usano le stesse cartelle. @@ -807,7 +991,7 @@ Setta il fumetto come letto - + Rename list name Rinomina la lista @@ -816,7 +1000,7 @@ Aggiungi i fumetti selezionati alla lista dei favoriti - + Remove and delete metadata Rimuovi e cancella i Metadati @@ -825,7 +1009,7 @@ YACReader non trovato, YACReader deve esere installato nella stessa cartella di YACReaderLibrary. - + Old library Vecchia libreria @@ -838,17 +1022,17 @@ Rinomina qualsiasi etichetta o lista selezionata - + Set as completed Segna come completo - + There was an error accessing the folder's path C'è stato un errore nell'accesso al percorso della cartella - + Library Libreria @@ -857,7 +1041,7 @@ Aggiungi una nuova cartella alla libreria corrente - + Comics will only be deleted from the current label/list. Are you sure? I fumetti verranno cancellati dall'etichetta/lista corrente. Sei sicuro? @@ -870,13 +1054,13 @@ Modalità a schermo interno on/off - + This library was created with a newer version of YACReaderLibrary. Download the new version now? Questa libreria è stata creata con una verisone più recente di YACReaderLibrary. Scarico la versione aggiornata ora? - - + + Moving comics... Sto muovendo i fumetti... @@ -889,13 +1073,13 @@ Aggiorna la Libreria corrente - - + + Copying comics... Sto copiando i fumetti... - + Library '%1' is no longer available. Do you want to remove it? La libreria '%1' non è più disponibile, la vuoi cancellare? @@ -904,22 +1088,22 @@ Aggiorna Libreria - + Open folder... Apri Cartella... - + Do you want remove Vuoi rimuovere - + Set as uncompleted Segna come non completo - + Error in path Errore nel percorso @@ -928,17 +1112,17 @@ Resetta la valutazione dei fumetti - + Error updating the library Errore aggiornando la libreria - + Folder Cartella - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? Gli elementi selezionati verranno cancellati, i tuoi fumetti o cartella NON verranno cancellati dal tuo disco. Sei sicuro? @@ -951,8 +1135,8 @@ Cancella la cartella corrente dal disco - - + + List name: Nome lista: @@ -961,7 +1145,7 @@ Aggiungi a... - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? La libreria '%1' è stata creata con una versione precedente di YACREaderLibrary. Deve essere ricreata. Lo vuoi fare ora? @@ -970,7 +1154,7 @@ Compatta Copertine - + Save covers Salva Copertine @@ -983,12 +1167,12 @@ Rimuovi la lista di lettura dalla libreria - + Add new reading lists Aggiungi una lista di lettura - + You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. @@ -1001,17 +1185,17 @@ Hai probabilemnte bisogno di una sola Libreria al livello superiore, puoi poi na YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il numero di librerie basso. - + Set as read Setta come letto - + Library info - + Informazioni sulla biblioteca - + Assign comics numbers Assegna un numero ai fumetti @@ -1028,7 +1212,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Mostra le opzioni - + Please, select a folder first Per cortesia prima seleziona una cartella @@ -1037,7 +1221,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Crea una nuova libreria - + Library not available Libreria non disponibile @@ -1050,7 +1234,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu La libreria corrente non può essere aggiornata. Controlla i tuoi permessi di scrittura su: - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. C'è un problema nel cancellare i fumetti selezionati. Per favore controlla i tuoi permessi di scrittura sui file o sulla cartella. @@ -1067,7 +1251,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Apri il fumetto corrente - + YACReader Library Libreria YACReader @@ -1076,7 +1260,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Aggiungi una lista di lettura alla libreria corrente - + Error creating the library Errore creando la libreria @@ -1085,12 +1269,12 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Aggiornamento fallito - + You are adding too many libraries. Stai aggiungendto troppe librerie. - + Update folder Aggiorna Cartella @@ -1099,7 +1283,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Scompatta le Copertine - + Update needed Devi aggiornarmi @@ -1112,12 +1296,12 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Mostra o nascondi lo stato di lettura - + Library name already exists Esiste già una libreria con lo stesso nome - + There is another library with the name '%1'. Esiste già una libreria con il nome '%1'. @@ -1126,47 +1310,47 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Rimuovi la lista di lettura - + Delete folder Cancella Cartella - + Assign numbers starting in: Assegna numeri partendo da: - + Download new version Scarica la nuova versione - + Invalid image - + Immagine non valida - + The selected file is not a valid image. - + Il file selezionato non è un'immagine valida. - + Error saving cover - + Errore durante il salvataggio della copertina - + There was an error saving the cover image. - + Si è verificato un errore durante il salvataggio dell'immagine di copertina. - + Delete comics Cancella i fumetti - + Add new folder Aggiungi una nuova cartella @@ -1199,7 +1383,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Rinomina la lista selezionata - + Delete list/label Cancella Lista/Etichetta @@ -1216,7 +1400,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Seleziona il nodo principale - + No folder selected Nessuna cartella selezionata @@ -1225,7 +1409,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Scompatta un catalogo - + All the selected comics will be deleted from your disk. Are you sure? Tutti i fumetti selezionati saranno cancellati dal tuo disco. Sei sicuro? @@ -1234,7 +1418,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Scarica i Tag da Comic Vine - + Remove comics Rimuovi i fumetti @@ -1243,13 +1427,13 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Aggiungi una nuova etichetta a questa libreria - - + + Set as unread Setta come non letto - + Library not found Libreria non trovata @@ -1262,32 +1446,32 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Rimuovi la libreria - - - + + + manga - + Manga - - - + + + comic - + comico - - - + + + web comic - + fumetto web - - - + + + western manga (left to right) - + manga occidentale (da sinistra a destra) Open containing folder... @@ -1298,48 +1482,48 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Aggiungi una nuova etichetta - - + + Unable to delete Non posso cancellare - - - + + + 4koma (top to botom) - + 4koma (dall'alto verso il basso) - - - - + + + + Set type - + Imposta il tipo - + Set custom cover - + Imposta la copertina personalizzata - + Delete custom cover - + Elimina la copertina personalizzata - + Error - + Errore - + Error opening comic with third party reader. - + Errore nell'apertura del fumetto con un lettore di terze parti. - + library? Libreria? @@ -1348,472 +1532,472 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Salva le copertine dei fumetti selezionati come file JPG - + Are you sure? Sei sicuro? - + Rescan library for XML info - + Eseguire nuovamente la scansione della libreria per informazioni XML - + Upgrade failed - + Aggiornamento non riuscito - + There were errors during library upgrade in: - + Si sono verificati errori durante l'aggiornamento della libreria in: - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - + YACReader non trovato. YACReader deve essere installato nella stessa cartella di YACReaderLibrary. - + YACReader not found. There might be a problem with your YACReader installation. - + YACReader non trovato. Potrebbe esserci un problema con l'installazione di YACReader. LibraryWindowActions - + Create a new library - Crea una nuova libreria + Crea una nuova libreria - + Open an existing library - Apri una libreria esistente + Apri una libreria esistente - - + + Export comics info - Esporta informazioni fumetto + Esporta informazioni fumetto - - + + Import comics info - Importa informazioni fumetto + Importa informazioni fumetto - + Pack covers - Compatta Copertine + Compatta Copertine - + Pack the covers of the selected library - Compatta le copertine della libreria selezionata + Compatta le copertine della libreria selezionata - + Unpack covers - Scompatta le Copertine + Scompatta le Copertine - + Unpack a catalog - Scompatta un catalogo + Scompatta un catalogo - + Update library - Aggiorna Libreria + Aggiorna Libreria - + Update current library - Aggiorna la Libreria corrente + Aggiorna la Libreria corrente - + Rename library - Rinomina la libreria + Rinomina la libreria - + Rename current library - Rinomina la libreria corrente + Rinomina la libreria corrente - + Remove library - Rimuovi la libreria + Rimuovi la libreria - + Remove current library from your collection - Rimuovi la libreria corrente dalla tua collezione + Rimuovi la libreria corrente dalla tua collezione - + Rescan library for XML info - + Eseguire nuovamente la scansione della libreria per informazioni XML - + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. - + Cerca di trovare informazioni XML incorporate nei file dei fumetti. Devi farlo solo se la libreria è stata creata con la versione 9.8.2 o precedente o se utilizzi software di terze parti per incorporare informazioni XML nei file. - + Show library info - + Mostra informazioni sulla biblioteca - + Show information about the current library - + Mostra informazioni sulla libreria corrente - + Open current comic - Apri il fumetto corrente + Apri il fumetto corrente - + Open current comic on YACReader - Apri il fumetto corrente con YACReader + Apri il fumetto corrente con YACReader - + Save selected covers to... - Salva le copertine selezionate in... + Salva le copertine selezionate in... - + Save covers of the selected comics as JPG files - Salva le copertine dei fumetti selezionati come file JPG + Salva le copertine dei fumetti selezionati come file JPG - - + + Set as read - Setta come letto + Setta come letto - + Set comic as read - Setta il fumetto come letto + Setta il fumetto come letto - - + + Set as unread - Setta come non letto + Setta come non letto - + Set comic as unread - Setta il fumetto come non letto + Setta il fumetto come non letto - - + + manga - + Manga - + Set issue as manga - + Imposta il problema come manga - - + + comic - + comico - + Set issue as normal - + Imposta il problema come normale - + western manga - + manga occidentali - + Set issue as western manga - + Imposta il problema come manga occidentale - - + + web comic - + fumetto web - + Set issue as web comic - + Imposta il problema come fumetto web - - + + yonkoma - + Yonkoma - + Set issue as yonkoma - + Imposta il problema come Yonkoma - + Show/Hide marks - Mostra/Nascondi + Mostra/Nascondi - + Show or hide read marks - Mostra o nascondi lo stato di lettura + Mostra o nascondi lo stato di lettura - + Show/Hide recent indicator - + Mostra/Nascondi l'indicatore recente - + Show or hide recent indicator - + Mostra o nascondi l'indicatore recente - - + + Fullscreen mode on/off - Modalità a schermo interno on/off + Modalità a schermo interno on/off - + Help, About YACReader - Aiuto, Crediti YACReader + Aiuto, Crediti YACReader - + Add new folder - Aggiungi una nuova cartella + Aggiungi una nuova cartella - + Add new folder to the current library - Aggiungi una nuova cartella alla libreria corrente + Aggiungi una nuova cartella alla libreria corrente - + Delete folder - Cancella Cartella + Cancella Cartella - + Delete current folder from disk - Cancella la cartella corrente dal disco + Cancella la cartella corrente dal disco - + Select root node - Seleziona il nodo principale + Seleziona il nodo principale - + Expand all nodes - Espandi tutti i nodi + Espandi tutti i nodi - + Collapse all nodes - Compatta tutti i nodi + Compatta tutti i nodi - + Show options dialog - Mostra le opzioni + Mostra le opzioni - + Show comics server options dialog - Mostra le opzioni per il server dei fumetti + Mostra le opzioni per il server dei fumetti - - + + Change between comics views - Cambia tra i modi di visualizzazione dei fumetti + Cambia tra i modi di visualizzazione dei fumetti - + Open folder... - Apri Cartella... + Apri Cartella... - + Set as uncompleted - Segna come non completo + Segna come non completo - + Set as completed - Segna come completo + Segna come completo - + Set custom cover - + Imposta la copertina personalizzata - + Delete custom cover - + Elimina la copertina personalizzata - + western manga (left to right) - + manga occidentale (da sinistra a destra) - + Open containing folder... - Apri la cartella dei contenuti... + Apri la cartella dei contenuti... - + Reset comic rating - Resetta la valutazione dei fumetti + Resetta la valutazione dei fumetti - + Select all comics - Seleziona tutti i fumetti + Seleziona tutti i fumetti - + Edit - Edita + Edita - + Assign current order to comics - Assegna l'ordinamento corrente ai fumetti + Assegna l'ordinamento corrente ai fumetti - + Update cover - Aggiorna copertina + Aggiorna copertina - + Delete selected comics - Cancella i fumetti selezionati + Cancella i fumetti selezionati - + Delete metadata from selected comics - + Elimina i metadati dai fumetti selezionati - + Download tags from Comic Vine - Scarica i Tag da Comic Vine + Scarica i Tag da Comic Vine - + Focus search line - + Mettere a fuoco la linea di ricerca - + Focus comics view - + Focus sulla visualizzazione dei fumetti - + Edit shortcuts - + Edita scorciatoie - + &Quit - + &Esci - + Update folder - Aggiorna Cartella + Aggiorna Cartella - + Update current folder - Aggiorna la cartella corrente + Aggiorna la cartella corrente - + Scan legacy XML metadata - + Scansione dei metadati XML legacy - + Add new reading list - Aggiorna la lista di lettura + Aggiorna la lista di lettura - + Add a new reading list to the current library - Aggiungi una lista di lettura alla libreria corrente + Aggiungi una lista di lettura alla libreria corrente - + Remove reading list - Rimuovi la lista di lettura + Rimuovi la lista di lettura - + Remove current reading list from the library - Rimuovi la lista di lettura dalla libreria + Rimuovi la lista di lettura dalla libreria - + Add new label - Aggiungi una nuova etichetta + Aggiungi una nuova etichetta - + Add a new label to this library - Aggiungi una nuova etichetta a questa libreria + Aggiungi una nuova etichetta a questa libreria - + Rename selected list - Rinomina la lista selezionata + Rinomina la lista selezionata - + Rename any selected labels or lists - Rinomina qualsiasi etichetta o lista selezionata + Rinomina qualsiasi etichetta o lista selezionata - + Add to... - Aggiungi a... + Aggiungi a... - + Favorites - Favoriti + Favoriti - + Add selected comics to favorites list - Aggiungi i fumetti selezionati alla lista dei favoriti + Aggiungi i fumetti selezionati alla lista dei favoriti @@ -1824,248 +2008,245 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Nome file - - LogWindow - - - Log window - - - - - &Pause - - - - - &Save - - - - - C&lear - - - - - &Copy - - - - - Level: - - - - - &Auto scroll - - - NoLibrariesWidget - + create your first library Crea la tua prima libreria - + You don't have any libraries yet Per ora non hai ancora nessuna libreria - + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Puoi creare una libreria in qualsiasi cartella, YACReader importerà tutti i fumetti e struttura da questa certella. Se hai creato una qualsiasia libreria nel passato la puoi aprire. </p><p>Non dimenticare che puoi usare YACReader come applicazione stand alone per leggere i fumetti sul tuo PC.</p> - + add an existing one Aggiungine una esistente + + NoSearchResultsWidget + + + No results + Nessun risultato + + OptionsDialog - + Restore defautls Resetta al Default - + Background Sfondo - + Blur level Livello di sfumatura - + Enable background image Abilita l'immagine di sfondo - + + Options Opzioni - + Comic Vine API key API di ComicVine - + Edit Comic Vine API key Edita l'API di ComicVine - + Opacity level Livello di opacità - + + General Generale - + Use selected comic cover as background Usa la cover del fumetto selezionato come sfondo - + Comic Flow Flusso dei fumetti - - + + Libraries - Librerie + Librerie - + Grid view Vista a Griglia - + + + Appearance + Aspetto + + + + + Language + Lingua + + + + + Application language + Lingua dell'applicazione + + + + + System default + Predefinita del sistema + + + Tray icon settings (experimental) - + Impostazioni dell'icona nella barra delle applicazioni (sperimentale) - + Close to tray - + Vicino al vassoio - + Start into the system tray - + Inizia nella barra delle applicazioni - + ComicInfo.xml legacy support - + Supporto legacy ComicInfo.xml - + Import metadata from ComicInfo.xml when adding new comics Import metada from ComicInfo.xml when adding new comics - + Importa metadati da ComicInfo.xml quando aggiungi nuovi fumetti - + Consider 'recent' items added or updated since X days ago - + Considera gli elementi "recenti" aggiunti o aggiornati da X giorni fa - + Third party reader - + Lettore di terze parti - + Write {comic_file_path} where the path should go in the command - + Scrivi {comic_file_path} dove dovrebbe andare il percorso nel comando - + + Clear - + Cancella - + Update libraries at startup - + Aggiorna le librerie all'avvio - + Try to detect changes automatically - + Prova a rilevare automaticamente le modifiche - + Update libraries periodically - + Aggiorna periodicamente le librerie - + Interval: - + Intervallo: - + 30 minutes - + 30 minuti - + 1 hour - + 1 ora - + 2 hours - + 2 ore - + 4 hours - + 4 ore - + 8 hours - + 8 ore - + 12 hours - + 12 ore - + daily - + quotidiano - + Update libraries at certain time - + Aggiorna le librerie in determinati orari - + Time: - + Tempo: - + WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. @@ -2073,79 +2254,253 @@ To stop an automatic update tap on the loading indicator next to the Libraries t WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. - + AVVERTIMENTO! Durante gli aggiornamenti della libreria le scritture sul database sono disabilitate! +Non pianificare gli aggiornamenti mentre potresti utilizzare l'app attivamente. +Durante gli aggiornamenti automatici l'app bloccherà alcune azioni fino al termine dell'aggiornamento. +Per interrompere un aggiornamento automatico, tocca l'indicatore di caricamento accanto al titolo Librerie. - + Modifications detection - + Rilevamento delle modifiche - + Compare the modified date of files when updating a library (not recommended) - + Confronta la data di modifica dei file durante l'aggiornamento di una libreria (non consigliato) - + Display continue reading banner - + Visualizza il banner continua a leggere - + Display current comic banner - + Visualizza il banner del fumetto corrente - + Continue reading - + Continua a leggere - - - PropertiesDialog - - Day: - Giorno: + + My comics path + Percorso dei miei fumetti - - Plot - Trama + + Display + Visualizzazione - - Size: - Dimesioni: + + Show time in current page information label + Mostra l'ora nell'etichetta delle informazioni della pagina corrente - - Year: - Anno: + + "Go to flow" size + Dimensione "Vai all'elenco" - - Inker(s): - Inchiostratore(i): + + Background color + Colore di sfondo - - Publishing - Pubblicazione + + Choose + Scegli - - Publisher: - Editore: + + Scroll behaviour + Comportamento di scorrimento - - General info - Informazioni generali + + Disable scroll animations and smooth scrolling + Disabilita le animazioni di scorrimento e lo scorrimento fluido - - Color/BW: + + Do not turn page using scroll + Non voltare pagina utilizzando lo scorrimento + + + + Use single scroll step to turn page + Utilizzare un singolo passaggio di scorrimento per voltare pagina + + + + Mouse mode + Modalità mouse + + + + Only Back/Forward buttons can turn pages + Solo i pulsanti Indietro/Avanti possono girare le pagine + + + + Use the Left/Right buttons to turn pages. + Utilizzare i pulsanti Sinistra/Destra per girare le pagine. + + + + Click left or right half of the screen to turn pages. + Fare clic sulla metà sinistra o destra dello schermo per girare le pagine. + + + + Quick Navigation Mode + Modo navigazione rapida + + + + Disable mouse over activation + Disabilita il mouse all'attivazione + + + + Brightness + Luminosità + + + + Contrast + Contrasto + + + + Gamma + Valore gamma + + + + Reset + Resetta + + + + Image options + Opzione immagine + + + + Fit options + Opzioni di adattamento + + + + Enlarge images to fit width/height + Ingrandisci le immagini per adattarle alla larghezza/altezza + + + + Double Page options + Opzioni doppia pagina + + + + Show covers as single page + Mostra le copertine come pagina singola + + + + Scaling + Ridimensionamento + + + + Scaling method + Metodo di scala + + + + Nearest (fast, low quality) + Più vicino (veloce, bassa qualità) + + + + Bilinear + Bilineare + + + + Lanczos (better quality) + Lanczos (qualità migliore) + + + + Page Flow + Flusso pagine + + + + Image adjustment + Correzioni immagine + + + + + Restart is needed + Riavvio Necessario + + + + Comics directory + Cartella Fumetti + + + + PropertiesDialog + + + Day: + Giorno: + + + + Plot + Trama + + + + Size: + Dimesioni: + + + + Year: + Anno: + + + + Inker(s): + Inchiostratore(i): + + + + Publishing + Pubblicazione + + + + Publisher: + Editore: + + + + General info + Informazioni generali + + + + Color/BW: Colore o B/N: @@ -2171,32 +2526,32 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Notes - + Note Load previous page as cover - + Carica la pagina precedente come copertina Load next page as cover - + Carica la pagina successiva come copertina Reset cover to the default image - + Ripristina la copertina sull'immagine predefinita Load custom cover image - + Carica l'immagine di copertina personalizzata Series: - Serie: + Serie: @@ -2206,27 +2561,27 @@ To stop an automatic update tap on the loading indicator next to the Libraries t alt. number: - + alt. numero: Alternate series: - + Serie alternative: Series Group: - + Gruppo di serie: Editor(s): - + Redattore(i): Imprint: - + Impronta: @@ -2236,32 +2591,32 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Type: - + Tipo: Language (ISO): - + Lingua (ISO): Teams: - + Squadre: Locations: - + Posizioni: Main character or team: - + Personaggio principale o squadra: Review: - + Revisione: @@ -2271,12 +2626,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Invalid cover - + Copertina non valida The image is invalid. - + L'immagine non è valida. @@ -2321,7 +2676,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Tags: - + tag: @@ -2368,12 +2723,28 @@ To stop an automatic update tap on the loading indicator next to the Libraries t of: - + Di: Arc number: - + Numero dell'arco: + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer è la versione headless (senza GUI) di YACReaderLibrary. + +Questa applicazione supporta le impostazioni persistenti, per configurarle modifica questo file %1 +Per conoscere le impostazioni disponibili, consultare la documentazione su https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md @@ -2391,89 +2762,73 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Trace - + Traccia Debug - + Diagnostica Info - + Informazioni Warning - + Avvertimento Error - + Errore Fatal - + Fatale - + Select custom cover - + Seleziona la copertina personalizzata - + Images (%1) - - - - - QsLogging::LogWindowModel - - - Time - - - - - Level - + Immagini (%1) - - Message - + + The file could not be read or is not valid JSON. + Impossibile leggere il file o non è un JSON valido. - - - QsLogging::Window - - &Pause - + + This theme is for %1, not %2. + Questo tema è per %1, non %2. - - &Resume - + + Libraries + Librerie - - Save log - + + Folders + Cartelle - - Log file (*.log) - + + Reading Lists + Lista di lettura RenameLibraryDialog - + Rename current library Rinomina la libreria corrente @@ -2496,18 +2851,18 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ScraperResultsPaginator - + Number of %1 found : %2 Numero di %1 trovati; %2 - - + + page %1 of %2 pagina %1 di %2 - + Number of volumes found : %1 Numero di volumi trovati: %1 @@ -2518,17 +2873,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information for this comic. Please provide some additional information. - Per favore aggiugi informazioni addizionali. + Per favore aggiugi informazioni addizionali. - + Series: Serie: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Utilizza la ricerca con corrispondenza esatta. Disabilitare se si desidera trovare volumi che corrispondono ad alcune delle parole nel nome. @@ -2539,40 +2894,40 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Per favore aggiugi informazioni addizionali. - + Series: Serie: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Utilizza la ricerca con corrispondenza esatta. Disabilitare se si desidera trovare volumi che corrispondono ad alcune delle parole nel nome. SelectComic - + loading description Caricamento descrizione - + comics Fumetti - + loading cover Caricamento copertine - + comic description unavailable - + descrizione del fumetto non disponibile - + Please, select the right comic info. Per favore seleziona le informazioni corrette per il fumetto. @@ -2584,37 +2939,37 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SelectVolume - + loading description Caricamento descrizione - + Please, select the right series for your comic. Per favore seleziona la serie corretta per il fumetto. - + Filter: - + Filtro: - + Nothing found, clear the filter if any. - + Non è stato trovato nulla, cancella il filtro se presente. - + loading cover Caricamento copertine - + volume description unavailable - + descrizione del volume non disponibile - + volumes Volumi @@ -2626,12 +2981,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SeriesQuestion - + no No - + yes Si @@ -2644,7 +2999,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ServerConfigDialog - + Port Porta @@ -2653,12 +3008,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t YACReader è disponibile per dispositivi iOS. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Provalo! </a> - + enable the server Abilita il server - + Server connectivity information Informazioni sulla connettività del server @@ -2669,7 +3024,7 @@ to improve the performance Migliora le prestazioni! - + Scan it! Scansiona! @@ -2678,17 +3033,17 @@ Migliora le prestazioni! Errore nel generatore QR! - + set port Configura porta - + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + YACReader è disponibile per dispositivi iOS e Android.<br/>Scoprilo per <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + Choose an IP address Scegli un indirizzo IP @@ -2696,27 +3051,27 @@ Migliora le prestazioni! SortVolumeComics - + remove selected comics Rimuovi i fumetti selezionati - + sort comics to match comic information Ordina i fumetti per far corrispondere le informazioni - + restore all removed comics Ripristina tutti i fumetti rimossi - + issues Emissione - + Please, sort the list of comics on the left until it matches the comics' information. Per favore ordina la lista dei fumetti a sinistra sino a che corrisponde alle informazioni dei fumetti. @@ -2726,296 +3081,1130 @@ Migliora le prestazioni! - TitleHeader + ThemeEditorDialog - - SEARCH - CERCA + + Theme Editor + Redattore del tema - - - UpdateLibraryDialog - - Update library - Aggiorna Libreria + + + + + - - Cancel - Cancella + + - + - - - Updating.... - Aggiornamento... + + i + io - - - VolumeComicsModel - - title - Titolo + + Expand all + Espandi tutto - - - VolumesModel - - year - Anno + + Collapse all + Comprimi tutto - - issues - Emissione + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Tieni premuto per far lampeggiare il valore selezionato nell'interfaccia utente (magenta / alternato / 0↔10). Le versioni ripristinano l'originale. - - publisher - Pubblicato da + + Search… + Ricerca… - - - YACReader::TrayIconController - - &Restore - + + Light + Luminoso - - Systray - + + Dark + Buio - - YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - + + ID: + Identificativo: - - - YACReader::WhatsNewDialog - - Close - + + Display name: + Nome da visualizzare: - - - YACReaderFieldEdit - - Restore to default - Resetta al Default + + Variant: + Variante: - - - Click to overwrite - Clikka per sovrascrivere + + Theme info + Informazioni sul tema - - - YACReaderFieldPlainTextEdit - - Restore to default - Resetta al Default + + Parameter + Parametro - - - - - Click to overwrite - Clikka per sovrascrivere + + Value + Valore - - - YACReaderFlowConfigWidget - - CoverFlow look - Aspetto del flusso copertine + + Save and apply + Salva e applica - - How to show covers: - Come mostrare le copertine: + + Export to file... + Esporta su file... - - Stripe look - Aspetto a striscia + + Load from file... + Carica da file... - - Overlapped Stripe look - Aspetto a striscia sovrapposta + + Close + Chiudi - - - YACReaderGLFlowConfigWidget - - Zoom - Zoom + + Double-click to edit color + Fare doppio clic per modificare il colore - - Light - Luminoso + + + + + + + true + VERO - - Show advanced settings - Mostra le impostazioni avanzate + + + + + false + falso - - Roulette look - Aspetto a Roulette + + Double-click to toggle + Fare doppio clic per attivare/disattivare - - Cover Angle - Angolo copertine + + Double-click to edit value + Fare doppio clic per modificare il valore - - Stripe look - Aspetto a striscia + + + + Edit: %1 + Modifica: %1 - - Position - Posizione + + Save theme + Salva tema - - Z offset - Traslazione Z + + + JSON files (*.json);;All files (*) + File JSON (*.json);;Tutti i file (*) - - Y offset - Traslazione Y + + Save failed + Salvataggio non riuscito - - Central gap - Distanza centrale + + Could not open file for writing: +%1 + Impossibile aprire il file per la scrittura: +%1 - - Presets: - Preselezione: + + Load theme + Carica tema - - Overlapped Stripe look - Aspetto a Striscia sovrapposto + + + + Load failed + Caricamento non riuscito - - Modern look - Aspetto moderno + + Could not open file: +%1 + Impossibile aprire il file: +%1 - - View angle - Vista ad Angolo + + Invalid JSON: +%1 + JSON non valido: +%1 - - Max angle - Angolo massimo + + Expected a JSON object. + Era previsto un oggetto JSON. + + + TitleHeader - - Custom: - Personalizza: + + SEARCH + CERCA + + + UpdateLibraryDialog - - Classic look - Aspetto Classico + + Update library + Aggiorna Libreria - - Cover gap - Distanza tra le Cover + + Cancel + Cancella - - High Performance - Alte Prestazioni + + Updating.... + Aggiornamento... - - + + + Viewer + + + + Press 'O' to open comic. + Premi "O" per aprire il fumettto. + + + + Not found + Non trovato + + + + Comic not found + Fumetto non trovato + + + + Error opening comic + Errore nell'apertura + + + + CRC Error + Errore CRC + + + + Loading...please wait! + In caricamento...Attendi! + + + + Page not available! + Pagina non disponibile! + + + + Cover! + Copertina! + + + + Last page! + Ultima pagina! + + + + VolumeComicsModel + + + title + Titolo + + + + VolumesModel + + + year + Anno + + + + issues + Emissione + + + + publisher + Pubblicato da + + + + YACReader3DFlowConfigWidget + + + Presets: + Preselezione: + + + + Classic look + Aspetto Classico + + + + Stripe look + Aspetto a striscia + + + + Overlapped Stripe look + Aspetto a strisce sovrapposto + + + + Modern look + Aspetto moderno + + + + Roulette look + Aspetto a Roulette + + + + Show advanced settings + Mostra le impostazioni avanzate + + + + Custom: + Personalizza: + + + + View angle + Vista ad Angolo + + + + Position + Posizione + + + + Cover gap + Distanza tra le Cover + + + + Central gap + Distanza centrale + + + + Zoom + Ingrandimento + + + + Y offset + Traslazione Y + + + + Z offset + Traslazione Z + + + + Cover Angle + Angolo copertine + + + + Visibility + Visibilità + + + + Light + Luminoso + + + + Max angle + Angolo massimo + + + + Low Performance + Basse Prestazioni + + + + High Performance + Alte Prestazioni + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + UIsa VSync. (Migliora la qualità dell'immagine a modalità tutto schermo, peggiora le prestazioni) + + + Performance: Prestazioni: + + + YACReader::MainWindowViewer + + + &Open + &Apri + + + + Open a comic + Apri un Fumetto + + + + New instance + Nuova istanza + + + + Open Folder + Apri una cartella + + + + Open image folder + Apri la crettal immagini + + + + Open latest comic + Apri l'ultimo fumetto + + + + Open the latest comic opened in the previous reading session + Apri l'ultimo fumetto aperto nella sessione precedente + + + + Clear + Cancella + + + + Clear open recent list + Svuota la lista degli aperti + + + + Save + Salva + + + + + Save current page + Salva la pagina corrente + + + + Previous Comic + Fumetto precendente + + + + + + Open previous comic + Apri il fumetto precendente + + + + Next Comic + Prossimo fumetto + + + + + + Open next comic + Apri il prossimo fumetto + + + + &Previous + &Precedente + + + + + + Go to previous page + Vai alla pagina precedente + + + + &Next + &Prossimo + + + + + + Go to next page + Vai alla prossima Pagina + + + + Fit Height + Adatta altezza + + + + Fit image to height + Adatta immagine all'altezza + + + + Fit Width + Adatta Larghezza + + + + Fit image to width + Adatta immagine in larghezza + + + + Show full size + Mostra dimesioni reali + + + + Fit to page + Adatta alla pagina + + + + Continuous scroll + Scorrimento continuo + + + + Switch to continuous scroll mode + Passa alla modalità di scorrimento continuo + + + + Reset zoom + Resetta Zoom + + + + Show zoom slider + Mostra cursore di zoom + + + + Zoom+ + Aumenta + + + + Zoom- + Riduci + + + + Rotate image to the left + Ruota immagine a sinistra + + + + Rotate image to the right + Ruota immagine a destra + + + + Double page mode + Modalita doppia pagina + + + + Switch to double page mode + Passa alla modalità doppia pagina + + + + Double page manga mode + Modalità doppia pagina Manga + + + + Reverse reading order in double page mode + Ordine lettura inverso in modo doppia pagina + + + + Go To + Vai a + + + + Go to page ... + Vai a Pagina ... + + + + Options + Opzioni + + + + YACReader options + Opzioni YACReader + + + + + Help + Aiuto + + + + Help, About YACReader + Aiuto, Crediti YACReader + + + + Magnifying glass + Lente ingrandimento + + + + Switch Magnifying glass + Passa a lente ingrandimento + + + + Set bookmark + Imposta Segnalibro + + + + Set a bookmark on the current page + Imposta segnalibro a pagina corrente + + + + Show bookmarks + Mostra segnalibro + + + + Show the bookmarks of the current comic + Mostra il segnalibro del fumetto corrente + + + + Show keyboard shortcuts + Mostra scorciatoie da tastiera + + + + Show Info + Mostra info + + + + Close + Chiudi + + + + Show Dictionary + Mostra dizionario + + + + Show go to flow + Mostra vai all'elenco + + + + Edit shortcuts + Edita scorciatoie + + + + &File + &Documento + + + + + Open recent + Apri i recenti + + + + File + Documento + + + + Edit + Edita + + + + View + Mostra + + + + Go + Vai + + + + Window + Finestra + + + + + + Open Comic + Apri Fumetto + + + + + + Comic files + File Fumetto + + + + Open folder + Apri cartella + + + + page_%1.jpg + Pagina_%1.jpg + + + + Image files (*.jpg) + File immagine (*.jpg) + + + + + Comics + Fumetto + + + + + General + Generale + + + + + Magnifiying glass + Lente ingrandimento + + + + + Page adjustement + Correzioni di pagna + + + + + Reading + Leggi + + + + Toggle fullscreen mode + Attiva/Disattiva schermo intero + + + + Hide/show toolbar + Mostra/Nascondi Barra strumenti + + + + Size up magnifying glass + Ingrandisci lente ingrandimento + + + + Size down magnifying glass + Riduci lente ingrandimento + + + + Zoom in magnifying glass + Ingrandisci in lente di ingrandimento + + + + Zoom out magnifying glass + Riduci in lente di ingrandimento + + + + Reset magnifying glass + Reimposta la lente d'ingrandimento + + + + Toggle between fit to width and fit to height + Passa tra adatta in larghezza ad altezza + + + + Autoscroll down + Autoscorri Giù + + + + Autoscroll up + Autoscorri Sù + + + + Autoscroll forward, horizontal first + Autoscorri avanti, priorità Orizzontale + + + + Autoscroll backward, horizontal first + Autoscorri indietro, priorità Orizzontale + + + + Autoscroll forward, vertical first + Autoscorri avanti, priorità Verticale + + + + Autoscroll backward, vertical first + Autoscorri indietro, priorità Verticale + + + + Move down + Muovi Giù + + + + Move up + Muovi Sù + + + + Move left + Muovi Sinistra + + + + Move right + Muovi Destra + + + + Go to the first page + Vai alla pagina iniziale + + + + Go to the last page + Vai all'ultima pagina + + + + Offset double page to the left + Doppia pagina spostata a sinistra + + + + Offset double page to the right + Doppia pagina spostata a destra + + + + There is a new version available + Nuova versione disponibile + + + + Do you want to download the new version? + Vuoi scaricare la nuova versione? + + + + Remind me in 14 days + Ricordamelo in 14 giorni + + + + Not now + Non ora + + + + YACReader::TrayIconController + + + &Restore + &Rnegozio + + + + Systray + Area di notifica + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary continuerà a essere eseguito nella barra delle applicazioni. Per terminare il programma, scegli <b>Esci</b> nel menu contestuale dell'icona nella barra delle applicazioni. + + + + YACReaderFieldEdit + + + Restore to default + Resetta al Default + + + + + Click to overwrite + Clikka per sovrascrivere + + + + YACReaderFieldPlainTextEdit + + + Restore to default + Resetta al Default + + + + + + + Click to overwrite + Clikka per sovrascrivere + + + + YACReaderFlowConfigWidget + + CoverFlow look + Aspetto del flusso copertine + + + How to show covers: + Come mostrare le copertine: + + + Stripe look + Aspetto a striscia + + + Overlapped Stripe look + Aspetto a striscia sovrapposta + + + + YACReaderGLFlowConfigWidget + + Zoom + Ingrandimento + + + Light + Luminoso + + + Show advanced settings + Mostra le impostazioni avanzate + + + Roulette look + Aspetto a Roulette + + + Cover Angle + Angolo copertine + + + Stripe look + Aspetto a striscia + + + Position + Posizione + + + Z offset + Traslazione Z + + + Y offset + Traslazione Y + + + Central gap + Distanza centrale + + + Presets: + Preselezione: + + + Overlapped Stripe look + Aspetto a Striscia sovrapposto + + + Modern look + Aspetto moderno + + + View angle + Vista ad Angolo + + + Max angle + Angolo massimo + + + Custom: + Personalizza: + + + Classic look + Aspetto Classico + + + Cover gap + Distanza tra le Cover + + + High Performance + Alte Prestazioni + + + Performance: + Prestazioni: + - Use VSync (improve the image quality in fullscreen mode, worse performance) - UIsa VSync. (Migliora la qualità dell'immagine a modalità tutto schermo, peggiora le prestazioni) + UIsa VSync. (Migliora la qualità dell'immagine a modalità tutto schermo, peggiora le prestazioni) - Visibility - Visibilità + Visibilità - Low Performance - Basse Prestazioni + Basse Prestazioni YACReaderNavigationController - You are not reading anything yet, come on!! - Non stai ancora leggendo nulla, Forza!! - - - - There are no recent comics! - + Non stai ancora leggendo nulla, Forza!! - No favorites - Nessun Favorito + Nessun Favorito YACReaderOptionsDialog - + Save Salva - Use hardware acceleration (restart needed) - Usa accelerazione hardware (necessita riavvio) + Usa accelerazione hardware (necessita riavvio) - + Cancel Cancella - + Shortcuts Scorciatoie - + Edit shortcuts Modifica scorciatoia @@ -3023,7 +4212,7 @@ Migliora le prestazioni! YACReaderSearchLineEdit - + type to search Digita per cercare @@ -3031,34 +4220,60 @@ Migliora le prestazioni! YACReaderSideBar - Reading Lists - Lista di lettura + Lista di lettura - LIBRARIES - LIBRERIE + LIBRERIE - Libraries - Librerie + Librerie - FOLDERS - CARTELLE + CARTELLE - Folders - Cartelle + Cartelle - READING LISTS - LISTA DI LETTURA + LISTA DI LETTURA + + + + YACReaderSlider + + + Reset + Resetta + + + + YACReaderTranslator + + + YACReader translator + Traduttore YACReader + + + + + Translation + Traduzione + + + + clear + Cancella + + + + Service not available + Servizio non disponibile diff --git a/YACReaderLibrary/yacreaderlibrary_nl.ts b/YACReaderLibrary/yacreaderlibrary_nl.ts index c81d99609..46b81edf3 100644 --- a/YACReaderLibrary/yacreaderlibrary_nl.ts +++ b/YACReaderLibrary/yacreaderlibrary_nl.ts @@ -6,90 +6,30 @@ None - + Geen AddLabelDialog - + cancel annuleren - + Label name: - + Labelnaam: - + Choose a color: - - - - - red - - - - - orange - - - - - yellow - - - - - green - - - - - cyan - - - - - blue - - - - - violet - - - - - purple - - - - - pink - - - - - white - - - - - light - - - - - dark - + Kies een kleur: - + accept - + accepteren @@ -100,7 +40,7 @@ Toevoegen - + Add an existing library Voeg een bestaand bibliotheek toe @@ -130,23 +70,163 @@ Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - + Voordat je verbinding kunt maken met Comic Vine, heb je een eigen API-sleutel nodig. Vraag er <a href="http://www.comicvine.com/api/">hier</a> één gratis aan Paste here your Comic Vine API key - + Plak hier uw Comic Vine API-sleutel Accept - + Accepteren + + + + AppearanceTabWidget + + + Color scheme + Kleurenschema + + + + System + Systeem + + + + Light + Licht + + + + Dark + Donker + + + + Custom + Aangepast + + + + Remove + Verwijderen + + + + Remove this user-imported theme + Verwijder dit door de gebruiker geïmporteerde thema + + + + Light: + Licht: + + + + Dark: + Donker: + + + + Custom: + Aangepast: + + + + Import theme... + Thema importeren... + + + + Theme + Thema + + + + Theme editor + Thema-editor + + + + Open Theme Editor... + Thema-editor openen... + + + + Theme editor error + Fout in de thema-editor + + + + The current theme JSON could not be loaded. + De huidige thema-JSON kan niet worden geladen. + + + + Import theme + Thema importeren + + + + JSON files (*.json);;All files (*) + JSON-bestanden (*.json);;Alle bestanden (*) + + + + Could not import theme from: +%1 + Kan thema niet importeren uit: +%1 + + + + Could not import theme from: +%1 + +%2 + Kan thema niet importeren uit: +%1 + +%2 + + + + Import failed + Importeren is mislukt + + + + BookmarksDialog + + + Lastest Page + Laatste Pagina + + + + Close + Sluiten + + + + Click on any image to go to the bookmark + Klik op een afbeelding om naar de bladwijzer te gaan + + + + + Loading... + Inladen... ClassicComicsView - + Hide comic flow Sluit de Omslagbrowser @@ -154,84 +234,84 @@ ComicInfoView - + + Characters + Personages + + + Main character or team - + Hoofdpersoon of team - + Teams - + Ploegen - + Locations - + Locaties - + Authors Auteurs - + writer - + schrijver - + penciller - + tekenaar - + inker - + inker - + colorist - + inkleurder - + letterer - + letteraar - + cover artist - + covertekenaar - + editor - + redacteur - + imprint - + fondslabel - + Publisher - + Uitgever - + color - + kleur - + b/w - - - - - Characters - + z/w @@ -274,105 +354,113 @@ Current Page - + Huidige pagina Publication Date - + Publicatiedatum Rating - + Beoordeling Series - + Serie Volume - + Deel Story Arc - + Verhaalboog ComicVineDialog - + skip - + overslaan - + back - + rug - + next - + volgende - + search - + zoekopdracht - + close - + dichtbij - - - + + + Looking for volume... - + Op zoek naar volumes... - - + + comic %1 of %2 - %3 - + strip %1 van %2 - %3 - + %1 comics selected - + %1 strips geselecteerd - + Error connecting to ComicVine - + Fout bij verbinden met ComicVine - - + + Retrieving tags for : %1 - + Tags ophalen voor: %1 - + Retrieving volume info... - + Volume-informatie ophalen... - + Looking for comic... - + Op zoek naar komische... + + + + ContinuousPageWidget + + + Loading page %1 + Pagina laden %1 CreateLibraryDialog - + Create new library Een nieuwe Bibliotheek aanmaken @@ -392,7 +480,7 @@ Een bibliotheek aanmaken kan enkele minuten duren. U kunt het proces stoppen en de bibliotheek later voltooien. - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder De geselecteerde pad bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map @@ -407,7 +495,7 @@ Bibliotheek Naam : - + Path not found Pad niet gevonden @@ -417,54 +505,43 @@ Restore defaults - + Standaardwaarden herstellen To change a shortcut, double click in the key combination and type the new keys. - + Om een ​​snelkoppeling te wijzigen, dubbelklikt u op de toetsencombinatie en typt u de nieuwe toetsen. Shortcuts settings - + Instellingen voor snelkoppelingen - + Shortcut in use - + Snelkoppeling in gebruik - + The shortcut "%1" is already assigned to other function - + De sneltoets "%1" is al aan een andere functie toegewezen EmptyFolderWidget - - - Subfolders in this folder - - - - - Empty folder - - - - - Drag and drop folders and comics here - + + This folder doesn't contain comics yet + Deze map bevat nog geen strips EmptyLabelWidget - + This label doesn't contain comics yet - + Dit label bevat nog geen strips @@ -472,7 +549,25 @@ This reading list does not contain any comics yet - + Deze leeslijst bevat nog geen strips + + + + EmptySpecialListWidget + + + No favorites + Geen favorieten + + + + You are not reading anything yet, come on!! + Je leest nog niets, kom op!! + + + + There are no recent comics! + Er zijn geen recente strips! @@ -483,7 +578,7 @@ Uitvoerbestand: - + Destination database name Bestemmingsdatabase naam @@ -498,17 +593,17 @@ Aanmaken - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder Het gekozen pad voor het uitvoerbestand bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map - + Export comics info Strip info exporteren - + Problem found while writing Probleem bij het schrijven @@ -526,7 +621,7 @@ Aanmaken - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder Het gekozen pad voor het uitvoerbestand bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map @@ -536,17 +631,17 @@ Uitvoermap : - + Problem found while writing Probleem bij het schrijven - + Create covers package Aanmaken omslag pakket - + Destination directory Doeldirectory @@ -561,57 +656,86 @@ CRC error on page (%1): some of the pages will not be displayed correctly - + CRC-fout op pagina (%1): sommige pagina's worden niet correct weergegeven Unknown error opening the file - + Onbekende fout bij het openen van het bestand Format not supported - + Formaat niet ondersteund FolderContentView - + Continue Reading... - + Verder lezen... - FolderContentView6 + GoToDialog - - Continue Reading... - + + Page : + Pagina : + + + + Go To + Ga Naar + + + + Cancel + Annuleren + + + + + Total pages : + Totaal aantal pagina's : + + + + Go to... + Ga naar... + + + + GoToFlowToolBar + + + Page : + Pagina : GridComicsView - + Show info - + Toon informatie HelpAboutDialog - + Help - Help + Hulp - + System info - + Systeeminformatie - + About Over @@ -639,7 +763,7 @@ Strip info Importeren - + Comics info file (*.ydb) Strips info bestand ( * .ydb) @@ -662,7 +786,7 @@ Uitpakken - + Compresed library covers (*.clc) Compresed omslag- bibliotheek ( * .clc) @@ -677,7 +801,7 @@ Bibliotheek Naam : - + Extract a catalog Een catalogus uitpakken @@ -685,54 +809,54 @@ ImportWidget - + stop - stop + Stoppen - + Importing comics Strips importeren - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> <P>YACReaderLibrary maak nu een nieuwe bibliotheek. < /p> <p>Een bibliotheek aanmaken kan enkele minuten duren. U kunt het proces stoppen en de bibliotheek later voltooien. < /p> - + Some of the comics being added... Enkele strips zijn toegevoegd ... - + Updating the library Actualisering van de bibliotheek - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> <P>De huidige bibliotheek wordt bijgewerkt. Voor snellere updates, update uw bibliotheken regelmatig. < /p> <p>u kunt het proces stoppen om later bij te werken. < /p> - + Upgrading the library - + Het upgraden van de bibliotheek - + <p>The current library is being upgraded, please wait.</p> - + <p>De huidige bibliotheek wordt geüpgraded. Een ogenblik geduld.</p> - + Scanning the library - + De bibliotheek scannen - + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> - + <p>De huidige bibliotheek wordt gescand op oudere XML-metadata-informatie.</p><p>Dit is slechts één keer nodig en alleen als de bibliotheek is ingepakt met YACReaderLibrary 9.8.2 of eerder.</p> @@ -742,17 +866,17 @@ Bewerken - + The selected folder doesn't contain any library. De geselecteerde map bevat geen bibliotheek. - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? Deze bibliotheek is gemaakt met een vorige versie van YACReaderLibrary. Het moet worden bijgewerkt. Nu bijwerken? - + Error opening the library Fout bij openen Bibliotheek @@ -773,12 +897,12 @@ Strip Instellen als gelezen - + Remove and delete metadata Verwijder metagegevens - + Old library Oude Bibliotheek @@ -787,7 +911,7 @@ Strip omslagen bijwerken - + Library Bibliotheek @@ -800,7 +924,7 @@ Volledig scherm modus aan/of - + This library was created with a newer version of YACReaderLibrary. Download the new version now? Deze bibliotheek is gemaakt met een nieuwere versie van YACReaderLibrary. Download de nieuwe versie? @@ -813,7 +937,7 @@ Huidige Bibliotheek bijwerken - + Library '%1' is no longer available. Do you want to remove it? Bibliotheek ' %1' is niet langer beschikbaar. Wilt u het verwijderen? @@ -822,17 +946,17 @@ Bibliotheek bijwerken - + Open folder... Map openen ... - + Do you want remove Wilt u verwijderen - + Error updating the library Fout bij bijwerken Bibliotheek @@ -841,7 +965,7 @@ Alle categorieën uitklappen - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? Bibliotheek ' %1' is gemaakt met een oudere versie van YACReaderLibrary. Zij moet opnieuw worden aangemaakt. Wilt u de bibliotheek nu aanmaken? @@ -850,7 +974,7 @@ Inpakken strip voorbladen - + Set as read Instellen als gelezen @@ -871,7 +995,7 @@ Maak een nieuwe Bibliotheek - + Library not available Bibliotheek niet beschikbaar @@ -884,12 +1008,12 @@ Huidige strip openen - + YACReader Library YACReader Bibliotheek - + Error creating the library Fout bij aanmaken Bibliotheek @@ -898,7 +1022,7 @@ Uitpakken voorbladen - + Update needed Bijwerken is nodig @@ -907,22 +1031,22 @@ Open een bestaande Bibliotheek - + Library name already exists Bibliotheek naam bestaat al - + There is another library with the name '%1'. Er is al een bibliotheek met de naam ' %1 '. - + Download new version Nieuwe versie ophalen - + Delete comics Strips verwijderen @@ -951,18 +1075,18 @@ Uitpaken van een catalogus - + All the selected comics will be deleted from your disk. Are you sure? Alle geselecteerde strips worden verwijderd van uw schijf. Weet u het zeker? - - + + Set as unread Instellen als ongelezen - + Library not found Bibliotheek niet gevonden @@ -975,734 +1099,738 @@ Bibliotheek verwijderen - - - + + + manga - + Manga - - - + + + comic - + grappig - - - + + + western manga (left to right) - + westerse manga (van links naar rechts) Open containing folder... Open map ... - - - + + + 4koma (top to botom) 4koma (top to botom - + 4koma (van boven naar beneden) - + library? Bibliotheek? - + Are you sure? Weet u het zeker? - + Rescan library for XML info - + Bibliotheek opnieuw scannen op XML-info - - - + + + web comic - + web-strip - + Add new folder - + Nieuwe map toevoegen - + Delete folder - + Map verwijderen - + Set as uncompleted - + Ingesteld als onvoltooid - + Set as completed - + Instellen als voltooid - + Update folder - + Map bijwerken - + Folder - + Map - + Comic - + Grappig - + Upgrade failed - + Upgrade mislukt - + There were errors during library upgrade in: - + Er zijn fouten opgetreden tijdens de bibliotheekupgrade in: - - + + Copying comics... - + Strips kopiëren... - - + + Moving comics... - + Strips verplaatsen... - + Folder name: - + Mapnaam: - + No folder selected - + Geen map geselecteerd - + Please, select a folder first - + Selecteer eerst een map - + Error in path - + Fout in pad - + There was an error accessing the folder's path - + Er is een fout opgetreden bij het verkrijgen van toegang tot het pad van de map - + The selected folder and all its contents will be deleted from your disk. Are you sure? - + De geselecteerde map en de volledige inhoud ervan worden van uw schijf verwijderd. Weet je het zeker? - - + + Unable to delete - + Kan niet verwijderen - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - + Er is een probleem opgetreden bij het verwijderen van de geselecteerde mappen. Controleer of er schrijfrechten zijn en zorg ervoor dat alle toepassingen deze mappen of een van de daarin opgenomen bestanden gebruiken. - + Add new reading lists - + Voeg nieuwe leeslijsten toe - - + + List name: - + Lijstnaam: - + Delete list/label - + Lijst/label verwijderen - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - + Het geselecteerde item wordt verwijderd, uw strips of mappen worden NIET van uw schijf verwijderd. Weet je het zeker? - + Rename list name - + Hernoem de lijstnaam - - - - + + + + Set type - + Soort instellen - + Set custom cover - + Aangepaste omslag instellen - + Delete custom cover - + Aangepaste omslag verwijderen - + Save covers - + Bewaar hoesjes - + You are adding too many libraries. - + U voegt te veel bibliotheken toe. - + You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - + U voegt te veel bibliotheken toe. + +Je hebt waarschijnlijk maar één bibliotheek nodig in je stripmap op het hoogste niveau. Je kunt door alle submappen bladeren met behulp van het mappengedeelte in de linkerzijbalk. + +YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, maar u moet het aantal bibliotheken laag houden. - - + + YACReader not found - + YACReader niet gevonden - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - + YACReader niet gevonden. YACReader moet in dezelfde map worden geïnstalleerd als YACReaderLibrary. - + YACReader not found. There might be a problem with your YACReader installation. - + YACReader niet gevonden. Er is mogelijk een probleem met uw YACReader-installatie. - + Error - + Fout - + Error opening comic with third party reader. - + Fout bij het openen van een strip met een lezer van een derde partij. - + Library info - + Bibliotheekinformatie - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - + Er is een probleem opgetreden bij het verwijderen van de geselecteerde strips. Controleer of er schrijfrechten zijn voor de geselecteerde bestanden of de map waarin deze zich bevinden. - + Assign comics numbers - + Wijs stripnummers toe - + Assign numbers starting in: - + Nummers toewijzen beginnend met: - + Invalid image - + Ongeldige afbeelding - + The selected file is not a valid image. - + Het geselecteerde bestand is geen geldige afbeelding. - + Error saving cover - + Fout bij opslaan van dekking - + There was an error saving the cover image. - + Er is een fout opgetreden bij het opslaan van de omslagafbeelding. - + Remove comics - + Verwijder strips - + Comics will only be deleted from the current label/list. Are you sure? - + Strips worden alleen verwijderd van het huidige label/de huidige lijst. Weet je het zeker? LibraryWindowActions - + Create a new library - Maak een nieuwe Bibliotheek + Maak een nieuwe Bibliotheek - + Open an existing library - Open een bestaande Bibliotheek + Open een bestaande Bibliotheek - - + + Export comics info - + Strip info exporteren - - + + Import comics info - + Strip info Importeren - + Pack covers - Inpakken strip voorbladen + Inpakken strip voorbladen - + Pack the covers of the selected library - Inpakken alle strip voorbladen van de geselecteerde Bibliotheek + Inpakken alle strip voorbladen van de geselecteerde Bibliotheek - + Unpack covers - Uitpakken voorbladen + Uitpakken voorbladen - + Unpack a catalog - Uitpaken van een catalogus + Uitpaken van een catalogus - + Update library - Bibliotheek bijwerken + Bibliotheek bijwerken - + Update current library - Huidige Bibliotheek bijwerken + Huidige Bibliotheek bijwerken - + Rename library - Bibliotheek hernoemen + Bibliotheek hernoemen - + Rename current library - + Huidige Bibliotheek hernoemen - + Remove library - Bibliotheek verwijderen + Bibliotheek verwijderen - + Remove current library from your collection - De huidige Bibliotheek verwijderen uit uw verzameling + De huidige Bibliotheek verwijderen uit uw verzameling - + Rescan library for XML info - + Bibliotheek opnieuw scannen op XML-info - + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. - + Probeert XML-informatie te vinden die is ingebed in stripbestanden. U hoeft dit alleen te doen als de bibliotheek is gemaakt met versie 9.8.2 of eerdere versies of als u software van derden gebruikt om XML-informatie in de bestanden in te sluiten. - + Show library info - + Bibliotheekinfo tonen - + Show information about the current library - + Toon informatie over de huidige bibliotheek - + Open current comic - Huidige strip openen + Huidige strip openen - + Open current comic on YACReader - Huidige strip openen in YACReader + Huidige strip openen in YACReader - + Save selected covers to... - + Geselecteerde omslagen opslaan in... - + Save covers of the selected comics as JPG files - + Sla covers van de geselecteerde strips op als JPG-bestanden - - + + Set as read - Instellen als gelezen + Instellen als gelezen - + Set comic as read - Strip Instellen als gelezen + Strip Instellen als gelezen - - + + Set as unread - Instellen als ongelezen + Instellen als ongelezen - + Set comic as unread - Strip Instellen als ongelezen + Strip Instellen als ongelezen - - + + manga - + Manga - + Set issue as manga - + Stel het probleem in als manga - - + + comic - + grappig - + Set issue as normal - + Stel het probleem in als normaal - + western manga - + westerse manga - + Set issue as western manga - + Stel het probleem in als westerse manga - - + + web comic - + web-strip - + Set issue as web comic - + Stel het probleem in als webstrip - - + + yonkoma - + yokoma - + Set issue as yonkoma - + Stel het probleem in als yonkoma - + Show/Hide marks - Toon/Verberg markeringen + Toon/Verberg markeringen - + Show or hide read marks - + Toon of verberg leesmarkeringen - + Show/Hide recent indicator - + Recente indicator tonen/verbergen - + Show or hide recent indicator - + Toon of verberg recente indicator - - + + Fullscreen mode on/off - Volledig scherm modus aan/of + Volledig scherm modus aan/of - + Help, About YACReader - Help, Over YACReader + Help, Over YACReader - + Add new folder - + Nieuwe map toevoegen - + Add new folder to the current library - + Voeg een nieuwe map toe aan de huidige bibliotheek - + Delete folder - + Map verwijderen - + Delete current folder from disk - + Verwijder de huidige map van schijf - + Select root node - Selecteer de hoofd categorie + Selecteer de hoofd categorie - + Expand all nodes - Alle categorieën uitklappen + Alle categorieën uitklappen - + Collapse all nodes - + Vouw alle knooppunten samen - + Show options dialog - Toon opties dialoog + Toon opties dialoog - + Show comics server options dialog - Toon strips-server opties dialoog + Toon strips-server opties dialoog - - + + Change between comics views - + Wisselen tussen stripweergaven - + Open folder... - Map openen ... + Map openen ... - + Set as uncompleted - + Ingesteld als onvoltooid - + Set as completed - + Instellen als voltooid - + Set custom cover - + Aangepaste omslag instellen - + Delete custom cover - + Aangepaste omslag verwijderen - + western manga (left to right) - + westerse manga (van links naar rechts) - + Open containing folder... - Open map ... + Open map ... - + Reset comic rating - + Stripbeoordeling opnieuw instellen - + Select all comics - Selecteer alle strips + Selecteer alle strips - + Edit - Bewerken + Bewerken - + Assign current order to comics - + Wijs de huidige volgorde toe aan strips - + Update cover - Strip omslagen bijwerken + Strip omslagen bijwerken - + Delete selected comics - Geselecteerde strips verwijderen + Geselecteerde strips verwijderen - + Delete metadata from selected comics - + Verwijder metadata uit geselecteerde strips - + Download tags from Comic Vine - + Tags downloaden van Comic Vine - + Focus search line - + Focus zoeklijn - + Focus comics view - + Focus stripweergave - + Edit shortcuts - + Snelkoppelingen bewerken - + &Quit - + &Afsluiten - + Update folder - + Map bijwerken - + Update current folder - + Werk de huidige map bij - + Scan legacy XML metadata - + Scan oudere XML-metagegevens - + Add new reading list - + Nieuwe leeslijst toevoegen - + Add a new reading list to the current library - + Voeg een nieuwe leeslijst toe aan de huidige bibliotheek - + Remove reading list - + Leeslijst verwijderen - + Remove current reading list from the library - + Verwijder de huidige leeslijst uit de bibliotheek - + Add new label - + Nieuw etiket toevoegen - + Add a new label to this library - + Voeg een nieuw label toe aan deze bibliotheek - + Rename selected list - + Hernoem de geselecteerde lijst - + Rename any selected labels or lists - + Hernoem alle geselecteerde labels of lijsten - + Add to... - + Toevoegen aan... - + Favorites - + Favorieten - + Add selected comics to favorites list - + Voeg geselecteerde strips toe aan de favorietenlijst @@ -1710,200 +1838,196 @@ YACReaderLibrary will not stop you from creating more libraries but you should k file name - - - - - LogWindow - - - Log window - - - - - &Pause - - - - - &Save - - - - - C&lear - - - - - &Copy - - - - - Level: - - - - - &Auto scroll - + bestandsnaam NoLibrariesWidget - + create your first library Maak uw eerste bibliotheek - + You don't have any libraries yet Je hebt geen nog libraries - + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <P>u kunt een bibliotheek maken in een willekeurige map, YACReaderLibrary importeert alle strips en mappen uit deze map. Alle bibliotheek aangemaakt in het verleden kan je openen. < /p> <p>vergeet niet dat u YACReader kan gebruiken als stand-alone applicatie voor het lezen van de strips op de computer. < /p> - + add an existing one voeg een bestaande bibliotheek toe + + NoSearchResultsWidget + + + No results + Geen resultaten + + OptionsDialog - + + + Appearance + Verschijning + + + + Options Opties - + + + Language + Taal + + + + + Application language + Applicatietaal + + + + + System default + Standaard van het systeem + + + Tray icon settings (experimental) - + Instellingen voor ladepictogram (experimenteel) - + Close to tray - + Dicht bij lade - + Start into the system tray - + Begin in het systeemvak - + Edit Comic Vine API key - + Bewerk de Comic Vine API-sleutel - + Comic Vine API key - + Comic Vine API-sleutel - + ComicInfo.xml legacy support - + ComicInfo.xml verouderde ondersteuning - + Import metadata from ComicInfo.xml when adding new comics Import metada from ComicInfo.xml when adding new comics - + Importeer metagegevens uit ComicInfo.xml wanneer u nieuwe strips toevoegt - + Consider 'recent' items added or updated since X days ago - + Overweeg 'recente' items die sinds X dagen geleden zijn toegevoegd of bijgewerkt - + Third party reader - + Lezer van derden - + Write {comic_file_path} where the path should go in the command - + Schrijf {comic_file_path} waar het pad naartoe moet in de opdracht - + + Clear - + Duidelijk - + Update libraries at startup - + Update bibliotheken bij het opstarten - + Try to detect changes automatically - + Probeer wijzigingen automatisch te detecteren - + Update libraries periodically - + Update bibliotheken regelmatig - + Interval: - + Tijdsinterval: - + 30 minutes - + 30 minuten - + 1 hour - + 1 uur - + 2 hours - + 2 uur - + 4 hours - + 4 uur - + 8 hours - + 8 uur - + 12 hours - + 12 uur - + daily - + dagelijks - + Update libraries at certain time - + Update bibliotheken op een bepaald tijdstip - + Time: - + Tijd: - + WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. @@ -1911,100 +2035,275 @@ To stop an automatic update tap on the loading indicator next to the Libraries t WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. - + WAARSCHUWING! Tijdens bibliotheekupdates is schrijven naar de database uitgeschakeld! +Plan geen updates terwijl u de app mogelijk actief gebruikt. +During automatic updates the app will block some of the actions until the update is finished. +Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de titel van Bibliotheken. - + Modifications detection - + Detectie van wijzigingen - + Compare the modified date of files when updating a library (not recommended) - + Vergelijk de wijzigingsdatum van bestanden bij het updaten van een bibliotheek (niet aanbevolen) - + Enable background image - + Achtergrondafbeelding inschakelen - + Opacity level - + Dekkingsniveau - + Blur level - + Vervagingsniveau - + Use selected comic cover as background - + Gebruik geselecteerde stripomslag als achtergrond - + Restore defautls - + Standaardwaarden herstellen - + Background - + Achtergrond - + Display continue reading banner - + Toon de banner voor verder lezen - + Display current comic banner - + Toon huidige stripbanner - + Continue reading - + Lees verder - + Comic Flow - + Komische stroom - - + + Libraries - + Bibliotheken - + Grid view - + Rasterweergave - + + General - + Algemeen - - - PropertiesDialog - - Day: - Dag: + + My comics path + Pad naar mijn strips - - Plot - Verhaal + + Display + Weergave - - Size: + + Show time in current page information label + Toon de tijd in het informatielabel van de huidige pagina + + + + "Go to flow" size + "Naar Omslagbrowser" afmetingen + + + + Background color + Achtergrondkleur + + + + Choose + Kies + + + + Scroll behaviour + Scrollgedrag + + + + Disable scroll animations and smooth scrolling + Schakel scrollanimaties en soepel scrollen uit + + + + Do not turn page using scroll + Sla de pagina niet om met scrollen + + + + Use single scroll step to turn page + Gebruik een enkele scrollstap om de pagina om te slaan + + + + Mouse mode + Muismodus + + + + Only Back/Forward buttons can turn pages + Alleen de knoppen Terug/Vooruit kunnen pagina's omslaan + + + + Use the Left/Right buttons to turn pages. + Gebruik de knoppen Links/Rechts om pagina's om te slaan. + + + + Click left or right half of the screen to turn pages. + Klik op de linker- of rechterhelft van het scherm om pagina's om te slaan. + + + + Quick Navigation Mode + Snelle navigatiemodus + + + + Disable mouse over activation + Schakel muis-over-activering uit + + + + Brightness + Helderheid + + + + Contrast + Contrastwaarde + + + + Gamma + Gammawaarde + + + + Reset + Standaardwaarden terugzetten + + + + Image options + Afbeelding opties + + + + Fit options + Pas opties + + + + Enlarge images to fit width/height + Vergroot afbeeldingen zodat ze in de breedte/hoogte passen + + + + Double Page options + Opties voor dubbele pagina's + + + + Show covers as single page + Toon omslagen als enkele pagina + + + + Scaling + Schalen + + + + Scaling method + Schaalmethode + + + + Nearest (fast, low quality) + Dichtstbijzijnde (snel, lage kwaliteit) + + + + Bilinear + Bilineair + + + + Lanczos (better quality) + Lanczos (betere kwaliteit) + + + + Page Flow + Omslagbrowser + + + + Image adjustment + Beeldaanpassing + + + + + Restart is needed + Herstart is nodig + + + + Comics directory + Strips map + + + + PropertiesDialog + + + Day: + Dag: + + + + Plot + Verhaal + + + + Size: Grootte(MB): @@ -2015,7 +2314,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Inker(s): - Inker(s): + Inkt(en): @@ -2055,37 +2354,37 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Genre: - Genre: + Genretype: Notes - + Opmerkingen Load previous page as cover - + Laad de vorige pagina als omslag Load next page as cover - + Laad de volgende pagina als omslag Reset cover to the default image - + Zet de omslag terug naar de standaardafbeelding Load custom cover image - + Aangepaste omslagafbeelding laden Series: - + Serie: @@ -2095,27 +2394,27 @@ To stop an automatic update tap on the loading indicator next to the Libraries t alt. number: - + alt. nummer: Alternate series: - + Alternatieve serie: Series Group: - + Seriegroep: Editor(s): - + Redacteur(en): Imprint: - + Opdruk: @@ -2125,32 +2424,32 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Type: - + Soort: Language (ISO): - + Taal (ISO): Teams: - + Ploegen: Locations: - + Locaties: Main character or team: - + Hoofdpersoon of team: Review: - + Beoordeling: @@ -2160,17 +2459,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Invalid cover - + Ongeldige dekking The image is invalid. - + De afbeelding is ongeldig. Synopsis: - Synopsis: + Samenvatting: @@ -2210,7 +2509,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Tags: - + Labels: @@ -2252,17 +2551,33 @@ To stop an automatic update tap on the loading indicator next to the Libraries t of: - + van: Arc number: - + Boognummer: Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - + Comic Vine-link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> bekijken </a> + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer is de headless (geen gui) versie van YACReaderLibrary. + +Deze applicatie ondersteunt permanente instellingen. Om ze in te stellen, bewerk dit bestand %1 +Voor meer informatie over de beschikbare instellingen kunt u de documentatie raadplegen op https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md @@ -2270,99 +2585,83 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 7z lib not found - + 7z-lib niet gevonden unable to load 7z lib from ./utils - + kan 7z lib niet laden vanuit ./utils Trace - + Spoor Debug - + Foutopsporing Info - + Informatie Warning - + Waarschuwing Error - + Fout Fatal - + Fataal - + Select custom cover - + Selecteer een aangepaste omslag - + Images (%1) - - - - - QsLogging::LogWindowModel - - - Time - - - - - Level - + Afbeeldingen (%1) - - Message - + + The file could not be read or is not valid JSON. + Het bestand kan niet worden gelezen of is geen geldige JSON. - - - QsLogging::Window - - &Pause - + + This theme is for %1, not %2. + Dit thema is voor %1, niet voor %2. - - &Resume - + + Libraries + Bibliotheken - - Save log - + + Folders + Mappen - - Log file (*.log) - + + Reading Lists + Leeslijsten RenameLibraryDialog - + Rename current library Hernoem de huidige bibiliotheek @@ -2385,20 +2684,20 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ScraperResultsPaginator - + Number of volumes found : %1 - + Aantal gevonden volumes: %1 - - + + page %1 of %2 - + pagina %1 van %2 - + Number of %1 found : %2 - + Aantal %1 gevonden: %2 @@ -2407,17 +2706,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information for this comic. Please provide some additional information. - + Geef wat aanvullende informatie op voor deze strip. - + Series: - + Serie: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Gebruik exacte matchzoekopdrachten. Schakel dit uit als u volumes wilt vinden die overeenkomen met enkele woorden in de naam. @@ -2425,503 +2724,1336 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information. - + Geef alstublieft wat aanvullende informatie op. - + Series: - + Serie: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Gebruik exacte matchzoekopdrachten. Schakel dit uit als u volumes wilt vinden die overeenkomen met enkele woorden in de naam. SelectComic - + Please, select the right comic info. - + Selecteer de juiste stripinformatie. - + comics - + strips - + loading cover - + laaddeksel - + loading description - + beschrijving laden - + comic description unavailable - + komische beschrijving niet beschikbaar SelectVolume - + Please, select the right series for your comic. - + Selecteer de juiste serie voor jouw strip. - + Filter: - + Selectiefilter: - + volumes - + delen - + Nothing found, clear the filter if any. - + Niets gevonden. Wis eventueel het filter. - + loading cover - + laaddeksel - + loading description - + beschrijving laden - + volume description unavailable - + volumebeschrijving niet beschikbaar SeriesQuestion - + no neen - + yes Ja You are trying to get information for various comics at once, are they part of the same series? - + Je probeert informatie voor verschillende strips tegelijk te krijgen. Maken ze deel uit van dezelfde serie? ServerConfigDialog - + Port Poort - + enable the server De server instellen - + set port Poort instellen - + Server connectivity information - + Informatie over serverconnectiviteit - + Scan it! - + Scan het! - + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + YACReader is beschikbaar voor iOS- en Android-apparaten.<br/>Ontdek het voor <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> of <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + Choose an IP address - + Kies een IP-adres SortVolumeComics - + Please, sort the list of comics on the left until it matches the comics' information. - + Sorteer de lijst met strips aan de linkerkant totdat deze overeenkomt met de informatie over de strips. - + sort comics to match comic information - + sorteer strips zodat ze overeenkomen met stripinformatie - + issues - + problemen - + remove selected comics - + verwijder geselecteerde strips - + restore all removed comics - + herstel alle verwijderde strips - TitleHeader + ThemeEditorDialog - - SEARCH - + + Theme Editor + Thema-editor - - - UpdateLibraryDialog - - Update library - Bibliotheek bijwerken + + + + + - - Cancel - Annuleren + + - + - - - Updating.... - Bijwerken.... + + i + ? - - - VolumeComicsModel - - title - + + Expand all + Alles uitvouwen - - - VolumesModel - - year - + + Collapse all + Alles samenvouwen - - issues - + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Houd ingedrukt om de geselecteerde waarde in de gebruikersinterface te laten knipperen (magenta / geschakeld / 0↔10). Releases herstellen het origineel. - - publisher - + + Search… + Zoekopdracht… - - - YACReader::TrayIconController - - &Restore - + + Light + Licht - - Systray - + + Dark + Donker - - YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - + + ID: + Identiteitskaart: - - - YACReader::WhatsNewDialog - - Close - + + Display name: + Weergavenaam: - - - YACReaderFieldEdit - - Restore to default - Standaardwaarden herstellen + + Variant: + Variatie: - - - Click to overwrite - Klik hier om te overschrijven + + Theme info + Thema-informatie - - - YACReaderFieldPlainTextEdit - - Restore to default - Standaardwaarden herstellen + + Parameter + Instelwaarde - - - - - Click to overwrite - Klik hier om te overschrijven + + Value + Waarde - - - YACReaderFlowConfigWidget - - CoverFlow look - Omslagbrowser uiterlijk + + Save and apply + Opslaan en toepassen - - How to show covers: - Hoe omslagbladen bekijken: + + Export to file... + Exporteren naar bestand... - - Stripe look - Brede band + + Load from file... + Laden uit bestand... - - Overlapped Stripe look - Overlappende band + + Close + Sluiten - - - YACReaderGLFlowConfigWidget - - Zoom - Zoom + + Double-click to edit color + Dubbelklik om de kleur te bewerken - - Light - Licht + + + + + + + true + WAAR - - Show advanced settings - Toon geavanceerde instellingen + + + + + false + vals - - Roulette look - Roulette + + Double-click to toggle + Dubbelklik om te schakelen - - Cover Angle - Omslag hoek + + Double-click to edit value + Dubbelklik om de waarde te bewerken - - Stripe look - Brede band + + + + Edit: %1 + Bewerken: %1 - - Position - Positie + + Save theme + Thema opslaan - - Z offset - Z- positie + + + JSON files (*.json);;All files (*) + JSON-bestanden (*.json);;Alle bestanden (*) - - Y offset - Y-positie + + Save failed + Opslaan mislukt - - Central gap - Centrale ruimte + + Could not open file for writing: +%1 + Kan bestand niet openen om te schrijven: +%1 - - Presets: - Voorinstellingen: + + Load theme + Thema laden - - Overlapped Stripe look - Overlappende band + + + + Load failed + Laden mislukt - - Modern look - Modern + + Could not open file: +%1 + Kan bestand niet openen: +%1 - - View angle - Kijkhoek + + Invalid JSON: +%1 + Ongeldige JSON: +%1 - - Max angle - Maximale hoek + + Expected a JSON object. + Er werd een JSON-object verwacht. + + + TitleHeader - - Custom: - Aangepast: + + SEARCH + ZOEKOPDRACHT + + + UpdateLibraryDialog - - Classic look - Klassiek + + Update library + Bibliotheek bijwerken - - Cover gap - Ruimte tss Omslag + + Cancel + Annuleren - - High Performance - Hoge Prestaties + + Updating.... + Bijwerken.... + + + Viewer - - Performance: - Prestatie: + + + Press 'O' to open comic. + Druk 'O' om een strip te openen. - - Use VSync (improve the image quality in fullscreen mode, worse performance) - Gebruik VSync (verbetering van de beeldkwaliteit in de modus volledig scherm, slechtere prestatie) + + Not found + Niet gevonden - - Visibility - Zichtbaarheid + + Comic not found + Strip niet gevonden - - Low Performance - Lage Prestaties + + Error opening comic + Fout bij openen strip - - - YACReaderNavigationController - - No favorites - + + CRC Error + CRC-fout - - You are not reading anything yet, come on!! - + + Loading...please wait! + Inladen...even wachten! - - There are no recent comics! - + + Page not available! + Pagina niet beschikbaar! - - - YACReaderOptionsDialog - - Save - Bewaar + + Cover! + Omslag! - - Use hardware acceleration (restart needed) - Gebruik hardware versnelling (opnieuw opstarten vereist) + + Last page! + Laatste pagina! + + + VolumeComicsModel - - Cancel - Annuleren - + + title + titel + + + + VolumesModel + + + year + jaar + + + + issues + problemen + + + + publisher + uitgever + + + + YACReader3DFlowConfigWidget + + + Presets: + Voorinstellingen: + + + + Classic look + Klassiek + + + + Stripe look + Brede band + + + + Overlapped Stripe look + Overlappende band + + + + Modern look + Modern + + + + Roulette look + Roulette + + + + Show advanced settings + Toon geavanceerde instellingen + + + + Custom: + Aangepast: + + + + View angle + Kijkhoek + + + + Position + Positie + + + + Cover gap + Ruimte tss Omslag + + + + Central gap + Centrale ruimte + + + + Zoom + Vergroting + + + + Y offset + Y-positie + + + + Z offset + Z- positie + + + + Cover Angle + Omslag hoek + + + + Visibility + Zichtbaarheid + + + + Light + Licht + + + + Max angle + Maximale hoek + + + + Low Performance + Lage Prestaties + + + + High Performance + Hoge Prestaties + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Gebruik VSync (verbetering van de beeldkwaliteit in de modus volledig scherm, slechtere prestatie) + + + + Performance: + Prestatie: + + + + YACReader::MainWindowViewer + + + &Open + &Openen + + + + Open a comic + Open een strip + + + + New instance + Nieuw exemplaar + + + + Open Folder + Map Openen + + + + Open image folder + Open afbeeldings map + + + + Open latest comic + Open de nieuwste strip + + + + Open the latest comic opened in the previous reading session + Open de nieuwste strip die in de vorige leessessie is geopend + + + + Clear + Duidelijk + + + + Clear open recent list + Wis geopende recente lijst + + + + Save + Bewaar + + + + + Save current page + Bewaren huidige pagina + + + + Previous Comic + Vorige Strip + + + + + + Open previous comic + Open de vorige strip + + + + Next Comic + Volgende Strip + + + + + + Open next comic + Open volgende strip + + + + &Previous + &Vorige + + + + + + Go to previous page + Ga naar de vorige pagina + + + + &Next + &Volgende + + + + + + Go to next page + Ga naar de volgende pagina + + + + Fit Height + Geschikte hoogte + + + + Fit image to height + Afbeelding aanpassen aan hoogte + + + + Fit Width + Vensterbreedte aanpassen + + + + Fit image to width + Afbeelding aanpassen aan breedte + + + + Show full size + Volledig Scherm + + + + Fit to page + Aanpassen aan pagina + + + + Continuous scroll + Continu scrollen + + + + Switch to continuous scroll mode + Schakel over naar de continue scrollmodus + + + + Reset zoom + Zoom opnieuw instellen + + + + Show zoom slider + Zoomschuifregelaar tonen + + + + Zoom+ + Inzoomen + + + + Zoom- + Uitzoomen + + + + Rotate image to the left + Links omdraaien + + + + Rotate image to the right + Rechts omdraaien + + + + Double page mode + Dubbele bladzijde modus + + + + Switch to double page mode + Naar dubbele bladzijde modus + + + + Double page manga mode + Manga-modus met dubbele pagina + + + + Reverse reading order in double page mode + Omgekeerde leesvolgorde in dubbele paginamodus + + + + Go To + Ga Naar + + + + Go to page ... + Ga naar bladzijde ... + + + + Options + Opties + + + + YACReader options + YACReader opties + + + + + Help + Hulp + + + + Help, About YACReader + Help, Over YACReader + + + + Magnifying glass + Vergrootglas + + + + Switch Magnifying glass + Overschakelen naar Vergrootglas + + + + Set bookmark + Bladwijzer instellen + + + + Set a bookmark on the current page + Een bladwijzer toevoegen aan de huidige pagina + + + + Show bookmarks + Bladwijzers weergeven + + + + Show the bookmarks of the current comic + Toon de bladwijzers van de huidige strip + + + + Show keyboard shortcuts + Toon de sneltoetsen + + + + Show Info + Info tonen + + + + Close + Sluiten + + + + Show Dictionary + Woordenlijst weergeven + + + + Show go to flow + Toon ga naar de Omslagbrowser + + + + Edit shortcuts + Snelkoppelingen bewerken + + + + &File + &Bestand + + + + + Open recent + Recent geopend + + + + File + Bestand + - + + Edit + Bewerken + + + + View + Weergave + + + + Go + Gaan + + + + Window + Raam + + + + + + Open Comic + Open een Strip + + + + + + Comic files + Strip bestanden + + + + Open folder + Open een Map + + + + page_%1.jpg + pagina_%1.jpg + + + + Image files (*.jpg) + Afbeelding bestanden (*.jpg) + + + + + Comics + Strips + + + + + General + Algemeen + + + + + Magnifiying glass + Vergrootglas + + + + + Page adjustement + Pagina-aanpassing + + + + + Reading + Lezing + + + + Toggle fullscreen mode + Schakel de modus Volledig scherm in + + + + Hide/show toolbar + Werkbalk verbergen/tonen + + + + Size up magnifying glass + Vergrootglas vergroten + + + + Size down magnifying glass + Vergrootglas kleiner maken + + + + Zoom in magnifying glass + Zoom in vergrootglas + + + + Zoom out magnifying glass + Uitzoomen vergrootglas + + + + Reset magnifying glass + Vergrootglas opnieuw instellen + + + + Toggle between fit to width and fit to height + Schakel tussen Aanpassen aan breedte en Aanpassen aan hoogte + + + + Autoscroll down + Automatisch naar beneden scrollen + + + + Autoscroll up + Automatisch omhoog scrollen + + + + Autoscroll forward, horizontal first + Automatisch vooruit scrollen, eerst horizontaal + + + + Autoscroll backward, horizontal first + Automatisch achteruit scrollen, eerst horizontaal + + + + Autoscroll forward, vertical first + Automatisch vooruit scrollen, eerst verticaal + + + + Autoscroll backward, vertical first + Automatisch achteruit scrollen, eerst verticaal + + + + Move down + Ga naar beneden + + + + Move up + Ga omhoog + + + + Move left + Ga naar links + + + + Move right + Ga naar rechts + + + + Go to the first page + Ga naar de eerste pagina + + + + Go to the last page + Ga naar de laatste pagina + + + + Offset double page to the left + Dubbele pagina naar links verschoven + + + + Offset double page to the right + Offset dubbele pagina naar rechts + + + + There is a new version available + Er is een nieuwe versie beschikbaar + + + + Do you want to download the new version? + Wilt u de nieuwe versie downloaden? + + + + Remind me in 14 days + Herinner mij er over 14 dagen aan + + + + Not now + Niet nu + + + + YACReader::TrayIconController + + + &Restore + &Herstellen + + + + Systray + Systeemvak + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary blijft actief in het systeemvak. Om het programma te beëindigen, kiest u <b>Quit</b> in het contextmenu van het systeemvakpictogram. + + + + YACReaderFieldEdit + + + Restore to default + Standaardwaarden herstellen + + + + + Click to overwrite + Klik hier om te overschrijven + + + + YACReaderFieldPlainTextEdit + + + Restore to default + Standaardwaarden herstellen + + + + + + + Click to overwrite + Klik hier om te overschrijven + + + + YACReaderFlowConfigWidget + + CoverFlow look + Omslagbrowser uiterlijk + + + How to show covers: + Hoe omslagbladen bekijken: + + + Stripe look + Brede band + + + Overlapped Stripe look + Overlappende band + + + + YACReaderGLFlowConfigWidget + + Zoom + Vergroting + + + Light + Licht + + + Show advanced settings + Toon geavanceerde instellingen + + + Roulette look + Roulette + + + Cover Angle + Omslag hoek + + + Stripe look + Brede band + + + Position + Positie + + + Z offset + Z- positie + + + Y offset + Y-positie + + + Central gap + Centrale ruimte + + + Presets: + Voorinstellingen: + + + Overlapped Stripe look + Overlappende band + + + Modern look + Modern + + + View angle + Kijkhoek + + + Max angle + Maximale hoek + + + Custom: + Aangepast: + + + Classic look + Klassiek + + + Cover gap + Ruimte tss Omslag + + + High Performance + Hoge Prestaties + + + Performance: + Prestatie: + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Gebruik VSync (verbetering van de beeldkwaliteit in de modus volledig scherm, slechtere prestatie) + + + Visibility + Zichtbaarheid + + + Low Performance + Lage Prestaties + + + + YACReaderOptionsDialog + + + Save + Bewaar + + + Use hardware acceleration (restart needed) + Gebruik hardware versnelling (opnieuw opstarten vereist) + + + + Cancel + Annuleren + + + Edit shortcuts - + Snelkoppelingen bewerken - + Shortcuts - + Snelkoppelingen YACReaderSearchLineEdit - + type to search - + typ om te zoeken YACReaderSideBar - LIBRARIES - BIBLIOTHEKEN + BIBLIOTHEKEN - FOLDERS - MAPPEN + MAPPEN + + + + YACReaderSlider + + + Reset + Standaardwaarden terugzetten + + + YACReaderTranslator - - Libraries - + + YACReader translator + YACReader-vertaler - - Folders - + + + Translation + Vertaling - - Reading Lists - + + clear + duidelijk - - READING LISTS - + + Service not available + Dienst niet beschikbaar diff --git a/YACReaderLibrary/yacreaderlibrary_pt.ts b/YACReaderLibrary/yacreaderlibrary_pt.ts index add794dd7..1b0efd7e1 100644 --- a/YACReaderLibrary/yacreaderlibrary_pt.ts +++ b/YACReaderLibrary/yacreaderlibrary_pt.ts @@ -6,90 +6,30 @@ None - + Nenhum AddLabelDialog - + Label name: - + Nome da etiqueta: - + Choose a color: - - - - - red - - - - - orange - - - - - yellow - - - - - green - - - - - cyan - - - - - blue - - - - - violet - - - - - purple - - - - - pink - - - - - white - - - - - light - - - - - dark - + Escolha uma cor: - + accept - + aceitar - + cancel - + cancelar @@ -100,7 +40,7 @@ Adicionar - + Add an existing library Adicionar uma biblioteca existente @@ -130,108 +70,248 @@ Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - + Antes de se conectar ao Comic Vine, você precisa de sua própria chave de API. Por favor, ganhe um <a href="http://www.comicvine.com/api/">aqui</a> grátis Paste here your Comic Vine API key - + Cole aqui sua chave API do Comic Vine Accept - + Aceitar + + + + AppearanceTabWidget + + + Color scheme + Esquema de cores + + + + System + Sistema + + + + Light + Luz + + + + Dark + Escuro + + + + Custom + Personalizado + + + + Remove + Remover + + + + Remove this user-imported theme + Remova este tema importado pelo usuário + + + + Light: + Luz: + + + + Dark: + Escuro: + + + + Custom: + Personalizado: + + + + Import theme... + Importar tema... + + + + Theme + Tema + + + + Theme editor + Editor de tema + + + + Open Theme Editor... + Abra o Editor de Tema... + + + + Theme editor error + Erro no editor de tema + + + + The current theme JSON could not be loaded. + O tema atual JSON não pôde ser carregado. + + + + Import theme + Importar tema + + + + JSON files (*.json);;All files (*) + Arquivos JSON (*.json);;Todos os arquivos (*) + + + + Could not import theme from: +%1 + Não foi possível importar o tema de: +%1 + + + + Could not import theme from: +%1 + +%2 + Não foi possível importar o tema de: +%1 + +%2 + + + + Import failed + Falha na importação + + + + BookmarksDialog + + + Lastest Page + Última Página + + + + Close + Fechar + + + + Click on any image to go to the bookmark + Clique em qualquer imagem para ir para o marcador + + + + + Loading... + Carregando... ClassicComicsView - + Hide comic flow - + Ocultar fluxo de quadrinhos ComicInfoView - + + Characters + Personagens + + + Main character or team - + Personagem principal ou equipa - + Teams - + Equipas - + Locations - + Localizações - + Authors - + Autores - + writer - + argumentista - + penciller - + desenhador (lápis) - + inker - + arte-finalista - + colorist - + colorista - + letterer - + letreirista - + cover artist - + artista de capa - + editor - + editor - + imprint - + chancela editorial - + Publisher - + Editora - + color - + cor - + b/w - - - - - Characters - + p/b @@ -239,140 +319,148 @@ yes - + sim no - + não Title - + Título File Name - + Nome do arquivo Pages - + Páginas Size - + Tamanho Read - + Ler Current Page - + Página atual Publication Date - + Data de publicação Rating - + Avaliação Series - + Série Volume - + Tomo Story Arc - + Arco de história ComicVineDialog - + skip - + pular - + back - + voltar - + next - + próximo - + search - + procurar - + close - + fechar - - - + + + Looking for volume... - + Procurando volume... - - + + comic %1 of %2 - %3 - + história em quadrinhos %1 de %2 - %3 - + %1 comics selected - + %1 quadrinhos selecionados - + Error connecting to ComicVine - + Erro ao conectar-se ao ComicVine - - + + Retrieving tags for : %1 - + Recuperando tags para: %1 - + Retrieving volume info... - + Recuperando informações de volume... - + Looking for comic... - + Procurando quadrinhos... + + + + ContinuousPageWidget + + + Loading page %1 + Carregando página %1 CreateLibraryDialog - + Create new library Criar uma nova biblioteca @@ -399,17 +487,17 @@ Create a library could take several minutes. You can stop the process and update the library later for completing the task. - + Criar uma biblioteca pode levar vários minutos. Você pode interromper o processo e atualizar a biblioteca posteriormente para concluir a tarefa. - + Path not found - + Caminho não encontrado - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder - + O caminho selecionado não existe ou não é um caminho válido. Certifique-se de ter acesso de gravação a esta pasta @@ -417,54 +505,43 @@ Restore defaults - + Restaurar padrões To change a shortcut, double click in the key combination and type the new keys. - + Para alterar um atalho, clique duas vezes na combinação de teclas e digite as novas teclas. Shortcuts settings - + Configurações de atalhos - + Shortcut in use - + Atalho em uso - + The shortcut "%1" is already assigned to other function - + O atalho "%1" já está atribuído a outra função EmptyFolderWidget - - - Subfolders in this folder - - - - - Empty folder - - - - - Drag and drop folders and comics here - + + This folder doesn't contain comics yet + Esta pasta ainda não contém quadrinhos EmptyLabelWidget - + This label doesn't contain comics yet - + Este rótulo ainda não contém quadrinhos @@ -472,7 +549,25 @@ This reading list does not contain any comics yet - + Esta lista de leitura ainda não contém quadrinhos + + + + EmptySpecialListWidget + + + No favorites + Sem favoritos + + + + You are not reading anything yet, come on!! + Você ainda não está lendo nada, vamos lá!! + + + + There are no recent comics! + Não há quadrinhos recentes! @@ -490,27 +585,27 @@ Output file : - + Arquivo de saída: - + Export comics info - + Exportar informa??es dos quadrinhos - + Destination database name - + Nome do banco de dados de destino - + Problem found while writing - + Problema encontrado ao escrever - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - + O caminho selecionado para o arquivo de saída não existe ou não é um caminho válido. Certifique-se de ter acesso de gravação a esta pasta @@ -531,24 +626,24 @@ Pasta de saída : - + Create covers package Criar pacote de capas - + Destination directory Diretório de destino - + Problem found while writing - + Problema encontrado ao escrever - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - + O caminho selecionado para o arquivo de saída não existe ou não é um caminho válido. Certifique-se de ter acesso de gravação a esta pasta @@ -561,59 +656,88 @@ CRC error on page (%1): some of the pages will not be displayed correctly - + Erro CRC na página (%1): algumas páginas não serão exibidas corretamente Unknown error opening the file - + Erro desconhecido ao abrir o arquivo Format not supported - + Formato não suportado FolderContentView - + Continue Reading... - + Continuar a ler... - FolderContentView6 + GoToDialog - - Continue Reading... - + + Page : + Página : + + + + Go To + Ir Para + + + + Cancel + Cancelar + + + + + Total pages : + Total de páginas : + + + + Go to... + Ir para... + + + + GoToFlowToolBar + + + Page : + Página : GridComicsView - + Show info - + Mostrar informações HelpAboutDialog - + About - + Sobre - + Help - + Ajuda - + System info - + Informações do sistema @@ -626,22 +750,22 @@ Import comics info - + Importar informa??es dos quadrinhos Info database location : - + Localização do banco de dados de informações: Import - + Importar - + Comics info file (*.ydb) - + Arquivo de informações de quadrinhos (*.ydb) @@ -662,7 +786,7 @@ Desempacotar - + Compresed library covers (*.clc) Capas da biblioteca compactada (*.clc) @@ -677,7 +801,7 @@ Nome da Biblioteca : - + Extract a catalog Extrair um catálogo @@ -685,54 +809,54 @@ ImportWidget - + stop - + parar - + Some of the comics being added... - + Alguns dos quadrinhos sendo adicionados... - + Importing comics - + Importando quadrinhos - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - + <p>YACReaderLibrary está criando uma nova biblioteca.</p><p>A criação de uma biblioteca pode levar vários minutos. Você pode interromper o processo e atualizar a biblioteca posteriormente para concluir a tarefa.</p> - + Updating the library - + Atualizando a biblioteca - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> - + <p>A biblioteca atual está sendo atualizada. Para atualizações mais rápidas, atualize suas bibliotecas com frequência.</p><p>Você pode interromper o processo e continuar atualizando esta biblioteca mais tarde.</p> - + Upgrading the library - + Atualizando a biblioteca - + <p>The current library is being upgraded, please wait.</p> - + <p>A biblioteca atual está sendo atualizada. Aguarde.</p> - + Scanning the library - + Digitalizando a biblioteca - + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> - + <p>A biblioteca atual está sendo verificada em busca de informações de metadados XML legados.</p><p>Isso só será necessário uma vez e somente se a biblioteca tiver sido criada com YACReaderLibrary 9.8.2 ou anterior.</p> @@ -742,7 +866,7 @@ Remover biblioteca atual da sua coleção - + Library Biblioteca @@ -759,27 +883,27 @@ Atualizar biblioteca atual - + Open folder... Abrir pasta... - - - + + + western manga (left to right) - + mangá ocidental (da esquerda para a direita) - - - + + + 4koma (top to botom) 4koma (top to botom - + 4koma (de cima para baixo) - + Do you want remove Você deseja remover @@ -796,7 +920,7 @@ Criar uma nova biblioteca - + YACReader Library Biblioteca YACReader @@ -809,18 +933,18 @@ Pacote de capas da biblioteca selecionada - - - + + + manga - + mangá - - - + + + comic - + cômico Help, About YACReader @@ -839,802 +963,806 @@ Abrir a pasta contendo... - + Are you sure? Você tem certeza? - + Rescan library for XML info - + Reanalisar biblioteca para informa??es XML - + Set as read - + Definir como lido - - + + Set as unread - + Definir como não lido - - - + + + web comic - + quadrinhos da web - + Add new folder - + Adicionar nova pasta - + Delete folder - + Excluir pasta - + Set as uncompleted - + Definir como incompleto - + Set as completed - + Definir como concluído - + Update folder - + Atualizar pasta - + Folder - + Pasta - + Comic - + Quadrinhos - + Upgrade failed - + Falha na atualização - + There were errors during library upgrade in: - + Ocorreram erros durante a atualização da biblioteca em: - + Update needed - + Atualização necessária - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? - + Esta biblioteca foi criada com uma versão anterior do YACReaderLibrary. Ele precisa ser atualizado. Atualizar agora? - + Download new version - + Baixe a nova versão - + This library was created with a newer version of YACReaderLibrary. Download the new version now? - + Esta biblioteca foi criada com uma versão mais recente do YACReaderLibrary. Baixe a nova versão agora? - + Library not available - + Biblioteca não disponível - + Library '%1' is no longer available. Do you want to remove it? - + A biblioteca '%1' não está mais disponível. Você quer removê-lo? - + Old library - + Biblioteca antiga - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - + A biblioteca '%1' foi criada com uma versão mais antiga do YACReaderLibrary. Deve ser criado novamente. Deseja criar a biblioteca agora? - - + + Copying comics... - + Copiando quadrinhos... - - + + Moving comics... - + Quadrinhos em movimento... - + Folder name: - + Nome da pasta: - + No folder selected - + Nenhuma pasta selecionada - + Please, select a folder first - + Por favor, selecione uma pasta primeiro - + Error in path - + Erro no caminho - + There was an error accessing the folder's path - + Ocorreu um erro ao acessar o caminho da pasta - + The selected folder and all its contents will be deleted from your disk. Are you sure? - + A pasta selecionada e todo o seu conteúdo serão excluídos do disco. Tem certeza? - - + + Unable to delete - + Não foi possível excluir - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - + Ocorreu um problema ao tentar excluir as pastas selecionadas. Por favor, verifique as permissões de gravação e certifique-se de que algum aplicativo esteja usando essas pastas ou qualquer um dos arquivos contidos. - + Add new reading lists - + Adicione novas listas de leitura - - + + List name: - + Nome da lista: - + Delete list/label - + Excluir lista/rótulo - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - + O item selecionado será excluído, seus quadrinhos ou pastas NÃO serão excluídos do disco. Tem certeza? - + Rename list name - + Renomear nome da lista - - - - + + + + Set type - + Definir tipo - + Set custom cover - + Definir capa personalizada - + Delete custom cover - + Excluir capa personalizada - + Save covers - + Salvar capas - + You are adding too many libraries. - + Você está adicionando muitas bibliotecas. - + You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - + Você está adicionando muitas bibliotecas. + +Você provavelmente só precisa de uma biblioteca em sua pasta de quadrinhos de nível superior. Você pode navegar em qualquer subpasta usando a seção de pastas na barra lateral esquerda. + +YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve manter o número de bibliotecas baixo. - - + + YACReader not found - + YACReader não encontrado - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - + YACReader não encontrado. YACReader deve ser instalado na mesma pasta que YACReaderLibrary. - + YACReader not found. There might be a problem with your YACReader installation. - + YACReader não encontrado. Pode haver um problema com a instalação do YACReader. - + Error - + Erro - + Error opening comic with third party reader. - + Erro ao abrir o quadrinho com leitor de terceiros. - + Library not found - + Biblioteca não encontrada - + The selected folder doesn't contain any library. - + A pasta selecionada não contém nenhuma biblioteca. - + library? - + biblioteca? - + Remove and delete metadata - + Remover e excluir metadados - + Library info - + Informações da biblioteca - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - + Ocorreu um problema ao tentar excluir os quadrinhos selecionados. Por favor, verifique as permissões de gravação nos arquivos selecionados ou na pasta que os contém. - + Assign comics numbers - + Atribuir números de quadrinhos - + Assign numbers starting in: - + Atribua números começando em: - + Invalid image - + Imagem inválida - + The selected file is not a valid image. - + O arquivo selecionado não é uma imagem válida. - + Error saving cover - + Erro ao salvar a capa - + There was an error saving the cover image. - + Ocorreu um erro ao salvar a imagem da capa. - + Error creating the library - + Erro ao criar a biblioteca - + Error updating the library - + Erro ao atualizar a biblioteca - + Error opening the library - + Erro ao abrir a biblioteca - + Delete comics - + Excluir quadrinhos - + All the selected comics will be deleted from your disk. Are you sure? - + Todos os quadrinhos selecionados serão excluídos do seu disco. Tem certeza? - + Remove comics - + Remover quadrinhos - + Comics will only be deleted from the current label/list. Are you sure? - + Os quadrinhos serão excluídos apenas do rótulo/lista atual. Tem certeza? - + Library name already exists - + O nome da biblioteca já existe - + There is another library with the name '%1'. - + Existe outra biblioteca com o nome '%1'. LibraryWindowActions - + Create a new library - Criar uma nova biblioteca + Criar uma nova biblioteca - + Open an existing library - Abrir uma biblioteca existente + Abrir uma biblioteca existente - - + + Export comics info - + Exportar informa??es dos quadrinhos - - + + Import comics info - + Importar informa??es dos quadrinhos - + Pack covers - + Empacotar capas - + Pack the covers of the selected library - Pacote de capas da biblioteca selecionada + Pacote de capas da biblioteca selecionada - + Unpack covers - + Desempacotar capas - + Unpack a catalog - Desempacotar um catálogo + Desempacotar um catálogo - + Update library - + Atualizar biblioteca - + Update current library - Atualizar biblioteca atual + Atualizar biblioteca atual - + Rename library - + Renomear biblioteca - + Rename current library - Renomear biblioteca atual + Renomear biblioteca atual - + Remove library - + Remover biblioteca - + Remove current library from your collection - Remover biblioteca atual da sua coleção + Remover biblioteca atual da sua coleção - + Rescan library for XML info - + Reanalisar biblioteca para informa??es XML - + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. - + Tenta encontrar informações XML incorporadas em arquivos de quadrinhos. Você só precisa fazer isso se a biblioteca foi criada com versões 9.8.2 ou anteriores ou se você estiver usando software de terceiros para incorporar informações XML nos arquivos. - + Show library info - + Mostrar informa??es da biblioteca - + Show information about the current library - + Mostrar informações sobre a biblioteca atual - + Open current comic - + Abrir quadrinho atual - + Open current comic on YACReader - Abrir quadrinho atual no YACReader + Abrir quadrinho atual no YACReader - + Save selected covers to... - + Salvar capas selecionadas em... - + Save covers of the selected comics as JPG files - + Salve as capas dos quadrinhos selecionados como arquivos JPG - - + + Set as read - + Definir como lido - + Set comic as read - + Definir quadrinhos como lidos - - + + Set as unread - + Definir como não lido - + Set comic as unread - + Definir quadrinhos como não lidos - - + + manga - + mangá - + Set issue as manga - + Definir problema como mangá - - + + comic - + cômico - + Set issue as normal - + Defina o problema como normal - + western manga - + mangá ocidental - + Set issue as western manga - + Definir problema como mangá ocidental - - + + web comic - + quadrinhos da web - + Set issue as web comic - + Definir o problema como web comic - - + + yonkoma - + tira yonkoma - + Set issue as yonkoma - + Definir problema como yonkoma - + Show/Hide marks - + Mostrar/ocultar marcas - + Show or hide read marks - + Mostrar ou ocultar marcas de leitura - + Show/Hide recent indicator - + Mostrar/ocultar indicador recente - + Show or hide recent indicator - + Mostrar ou ocultar indicador recente - - + + Fullscreen mode on/off - + Modo tela cheia ativado/desativado - + Help, About YACReader - Ajuda, Sobre o YACReader + Ajuda, Sobre o YACReader - + Add new folder - + Adicionar nova pasta - + Add new folder to the current library - + Adicionar nova pasta à biblioteca atual - + Delete folder - + Excluir pasta - + Delete current folder from disk - + Exclua a pasta atual do disco - + Select root node - Selecionar raiz + Selecionar raiz - + Expand all nodes - Expandir todos + Expandir todos - + Collapse all nodes - + Recolher todos os nós - + Show options dialog - Mostrar opções + Mostrar opções - + Show comics server options dialog - + Mostrar caixa de diálogo de opções do servidor de quadrinhos - - + + Change between comics views - + Alterar entre visualizações de quadrinhos - + Open folder... - Abrir pasta... + Abrir pasta... - + Set as uncompleted - + Definir como incompleto - + Set as completed - + Definir como concluído - + Set custom cover - + Definir capa personalizada - + Delete custom cover - + Excluir capa personalizada - + western manga (left to right) - + mangá ocidental (da esquerda para a direita) - + Open containing folder... - Abrir a pasta contendo... + Abrir a pasta contendo... - + Reset comic rating - + Redefinir classificação de quadrinhos - + Select all comics - + Selecione todos os quadrinhos - + Edit - + Editar - + Assign current order to comics - + Atribuir ordem atual aos quadrinhos - + Update cover - + Atualizar capa - + Delete selected comics - + Excluir quadrinhos selecionados - + Delete metadata from selected comics - + Excluir metadados dos quadrinhos selecionados - + Download tags from Comic Vine - + Baixe tags do Comic Vine - + Focus search line - + Linha de pesquisa de foco - + Focus comics view - + Visualização de quadrinhos em foco - + Edit shortcuts - + Editar atalhos - + &Quit - + &Qfato - + Update folder - + Atualizar pasta - + Update current folder - + Atualizar pasta atual - + Scan legacy XML metadata - + Digitalize metadados XML legados - + Add new reading list - + Adicionar nova lista de leitura - + Add a new reading list to the current library - + Adicione uma nova lista de leitura à biblioteca atual - + Remove reading list - + Remover lista de leitura - + Remove current reading list from the library - + Remover lista de leitura atual da biblioteca - + Add new label - + Adicionar novo rótulo - + Add a new label to this library - + Adicione um novo rótulo a esta biblioteca - + Rename selected list - + Renomear lista selecionada - + Rename any selected labels or lists - + Renomeie quaisquer rótulos ou listas selecionados - + Add to... - + Adicionar à... - + Favorites - + Favoritos - + Add selected comics to favorites list - + Adicione quadrinhos selecionados à lista de favoritos @@ -1642,195 +1770,184 @@ YACReaderLibrary will not stop you from creating more libraries but you should k file name - + nome do arquivo - LogWindow - - - Log window - - - - - &Pause - - - - - &Save - - + NoLibrariesWidget - - C&lear - + + You don't have any libraries yet + Você ainda não tem nenhuma biblioteca - - &Copy - + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Você pode criar uma biblioteca em qualquer pasta, YACReaderLibrary importará todos os quadrinhos e pastas desta pasta. Se você já criou alguma biblioteca, poderá abri-la.</p><p>Não se esqueça de que você pode usar o YACReader como um aplicativo independente para ler quadrinhos em seu computador.</p> - - Level: - + + create your first library + crie sua primeira biblioteca - - &Auto scroll - + + add an existing one + adicione um existente - NoLibrariesWidget + NoSearchResultsWidget - - You don't have any libraries yet - + + No results + Nenhum resultado + + + OptionsDialog - - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> - + + + Language + Idioma - - create your first library - + + + Application language + Idioma do aplicativo - - add an existing one - + + + System default + Padrão do sistema - - - OptionsDialog - + Tray icon settings (experimental) - + Configurações do ícone da bandeja (experimental) - + Close to tray - + Perto da bandeja - + Start into the system tray - + Comece na bandeja do sistema - + Edit Comic Vine API key - + Editar chave da API Comic Vine - + Comic Vine API key - + Chave de API do Comic Vine - + ComicInfo.xml legacy support - + Suporte legado ComicInfo.xml - + Import metadata from ComicInfo.xml when adding new comics Import metada from ComicInfo.xml when adding new comics - + Importe metadados de ComicInfo.xml ao adicionar novos quadrinhos - + Consider 'recent' items added or updated since X days ago - + Considere itens 'recentes' adicionados ou atualizados há X dias - + Third party reader - + Leitor de terceiros - + Write {comic_file_path} where the path should go in the command - + Escreva {comic_file_path} onde o caminho deve ir no comando - + + Clear - + Claro - + Update libraries at startup - + Atualizar bibliotecas na inicialização - + Try to detect changes automatically - + Tente detectar alterações automaticamente - + Update libraries periodically - + Atualize bibliotecas periodicamente - + Interval: - + Intervalo: - + 30 minutes - + 30 minutos - + 1 hour - + 1 hora - + 2 hours - + 2 horas - + 4 hours - + 4 horas - + 8 hours - + 8 horas - + 12 hours - + 12 horas - + daily - + diário - + Update libraries at certain time - + Atualizar bibliotecas em determinado momento - + Time: - + Tempo: - + WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. @@ -1838,363 +1955,561 @@ To stop an automatic update tap on the loading indicator next to the Libraries t WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. - + AVISO! Durante as atualizações da biblioteca, as gravações no banco de dados são desativadas! +Não agende atualizações enquanto estiver usando o aplicativo ativamente. +Durante as atualizações automáticas, o aplicativo bloqueará algumas ações até que a atualização seja concluída. +Para interromper uma atualização automática, toque no indicador de carregamento próximo ao título Bibliotecas. - + Modifications detection - + Detecção de modificações - + Compare the modified date of files when updating a library (not recommended) - + Compare a data de modificação dos arquivos ao atualizar uma biblioteca (não recomendado) - + Enable background image - + Ativar imagem de fundo - + Opacity level - + Nível de opacidade - + Blur level - + Nível de desfoque - + Use selected comic cover as background - + Use a capa de quadrinhos selecionada como plano de fundo - + Restore defautls - + Restaurar padrões - + Background - + Fundo - + Display continue reading banner - + Exibir banner para continuar lendo - + Display current comic banner - + Exibir banner de quadrinhos atual - + Continue reading - + Continuar lendo - + Comic Flow - + Fluxo de quadrinhos - - + + Libraries - + Bibliotecas - + Grid view - + Visualização em grade - + + General - + Em geral + + + + + Appearance + Aparência - + + Options - + Opções - - - PropertiesDialog - - General info - + + My comics path + Meu caminho de quadrinhos - - Authors - + + Display + Mostrar - - Publishing - + + Show time in current page information label + Mostrar hora no rótulo de informações da página atual - - Plot - + + "Go to flow" size + Tamanho do "Ir para cheia" - - Notes - + + Background color + Cor de fundo - - Cover page - + + Choose + Escolher - - Load previous page as cover - + + Scroll behaviour + Comportamento de rolagem - - Load next page as cover - + + Disable scroll animations and smooth scrolling + Desative animações de rolagem e rolagem suave - - Reset cover to the default image - + + Do not turn page using scroll + Não vire a página usando scroll - - Load custom cover image - + + Use single scroll step to turn page + Use uma única etapa de rolagem para virar a página - + + Mouse mode + Modo mouse + + + + Only Back/Forward buttons can turn pages + Apenas os botões Voltar/Avançar podem virar páginas + + + + Use the Left/Right buttons to turn pages. + Use os botões Esquerda/Direita para virar as páginas. + + + + Click left or right half of the screen to turn pages. + Clique na metade esquerda ou direita da tela para virar as páginas. + + + + Quick Navigation Mode + Modo de navegação rápida + + + + Disable mouse over activation + Desativar ativação do mouse sobre + + + + Brightness + Brilho + + + + Contrast + Contraste + + + + Gamma + Gama + + + + Reset + Reiniciar + + + + Image options + Opções de imagem + + + + Fit options + Opções de ajuste + + + + Enlarge images to fit width/height + Amplie as imagens para caber na largura/altura + + + + Double Page options + Opções de página dupla + + + + Show covers as single page + Mostrar capas como página única + + + + Scaling + Dimensionamento + + + + Scaling method + Método de dimensionamento + + + + Nearest (fast, low quality) + Mais próximo (rápido, baixa qualidade) + + + + Bilinear + Interpola??o bilinear + + + + Lanczos (better quality) + Lanczos (melhor qualidade) + + + + Page Flow + Fluxo de página + + + + Image adjustment + Ajuste de imagem + + + + + Restart is needed + Reiniciar é necessário + + + + Comics directory + Diretório de quadrinhos + + + + PropertiesDialog + + + General info + Informações gerais + + + + Authors + Autores + + + + Publishing + Publicação + + + + Plot + Trama + + + + Notes + Notas + + + + Cover page + Página de rosto + + + + Load previous page as cover + Carregar página anterior como capa + + + + Load next page as cover + Carregar a próxima página como capa + + + + Reset cover to the default image + Redefinir a capa para a imagem padrão + + + + Load custom cover image + Carregar imagem de capa personalizada + + + Series: - + Série: Title: - + Título: of: - + de: Issue number: - + Número de emissão: Volume: - + Tomo: Arc number: - + Número do arco: Story arc: - + Arco da história: alt. number: - + alt. número: Alternate series: - + Série alternativa: Series Group: - + Grupo de séries: Genre: - + Gênero: Size: - + Tamanho: Writer(s): - + Escritor(es): Penciller(s): - + Desenhador(es): Inker(s): - + Tinteiro(s): Colorist(s): - + Colorista(s): Letterer(s): - + Letrista(s): Cover Artist(s): - + Artista(s) da capa: Editor(s): - + Editor(es): Imprint: - + Imprimir: Day: - + Dia: Month: - + Mês: Year: - + Ano: Publisher: - + Editor: Format: - + Formatar: Color/BW: - + Cor/PB: Age rating: - + Classificação etária: Type: - + Tipo: Language (ISO): - + Idioma (ISO): Synopsis: - + Sinopse: Characters: - + Personagens: Teams: - + Equipes: Locations: - + Locais: Main character or team: - + Personagem principal ou equipe: Review: - + Análise: Notes: - + Notas: Tags: - + Etiquetas: Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - + Link do Comic Vine: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> visualizar </a> Not found - + Não encontrado Comic not found. You should update your library. - + Quadrinho não encontrado. Você deve atualizar sua biblioteca. Edit selected comics information - + Edite as informações dos quadrinhos selecionados Invalid cover - + Capa inválida The image is invalid. - + A imagem é inválida. Edit comic information - + Editar informações dos quadrinhos + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer é a versão sem cabeça (sem interface gráfica) do YACReaderLibrary. + +Este aplicativo suporta configurações persistentes, para configurá-las edite este arquivo %1 +Para saber mais sobre as configurações disponíveis, verifique a documentação em https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md @@ -2202,99 +2517,83 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 7z lib not found - + Biblioteca 7z não encontrada unable to load 7z lib from ./utils - + não é possível carregar 7z lib de ./utils Trace - + Rastreamento Debug - + Depurar Info - + Informações Warning - + Aviso Error - + Erro Fatal - + Cr?tico - + Select custom cover - + Selecione a capa personalizada - + Images (%1) - - - - - QsLogging::LogWindowModel - - - Time - - - - - Level - + Imagens (%1) - - Message - + + The file could not be read or is not valid JSON. + O arquivo não pôde ser lido ou não é JSON válido. - - - QsLogging::Window - - &Pause - + + This theme is for %1, not %2. + Este tema é para %1, não %2. - - &Resume - + + Libraries + Bibliotecas - - Save log - + + Folders + Pastas - - Log file (*.log) - + + Reading Lists + Listas de leitura RenameLibraryDialog - + Rename current library Renomear biblioteca atual @@ -2317,20 +2616,20 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ScraperResultsPaginator - + Number of volumes found : %1 - + Número de volumes encontrados: %1 - - + + page %1 of %2 - + página %1 de %2 - + Number of %1 found : %2 - + Número de %1 encontrado: %2 @@ -2339,17 +2638,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information for this comic. Please provide some additional information. - + Forneça algumas informações adicionais para esta história em quadrinhos. - + Series: - + Série: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Use a pesquisa de correspondência exata. Desative se quiser encontrar volumes que correspondam a algumas das palavras do nome. @@ -2357,83 +2656,83 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information. - + Forneça algumas informações adicionais. - + Series: - + Série: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Use a pesquisa de correspondência exata. Desative se quiser encontrar volumes que correspondam a algumas das palavras do nome. SelectComic - + Please, select the right comic info. - + Por favor, selecione as informações corretas dos quadrinhos. - + comics - + quadrinhos - + loading cover - + tampa de carregamento - + loading description - + descrição de carregamento - + comic description unavailable - + descrição do quadrinho indisponível SelectVolume - + Please, select the right series for your comic. - + Por favor, selecione a série certa para o seu quadrinho. - + Filter: - + Filtro: - + volumes - + tomos - + Nothing found, clear the filter if any. - + Nada encontrado, limpe o filtro, se houver. - + loading cover - + tampa de carregamento - + loading description - + descrição de carregamento - + volume description unavailable - + descrição do volume indisponível @@ -2441,419 +2740,1153 @@ To stop an automatic update tap on the loading indicator next to the Libraries t You are trying to get information for various comics at once, are they part of the same series? - + Você está tentando obter informações sobre vários quadrinhos ao mesmo tempo. Eles fazem parte da mesma série? - + yes - + sim - + no - + não ServerConfigDialog - + set port - + definir porta - + Server connectivity information - + Informações de conectividade do servidor - + Scan it! - + Digitalize! - + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + O YACReader está disponível para dispositivos iOS e Android.<br/>Descubra-o para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + Choose an IP address - + Escolha um endereço IP - + Port - + Porta - + enable the server - + habilitar o servidor SortVolumeComics - + Please, sort the list of comics on the left until it matches the comics' information. - + Por favor, classifique a lista de quadrinhos à esquerda até que corresponda às informações dos quadrinhos. - + sort comics to match comic information - + classifique os quadrinhos para corresponder às informações dos quadrinhos - + issues - + problemas - + remove selected comics - + remover quadrinhos selecionados - + restore all removed comics - - - - - TitleHeader - - - SEARCH - - - - - UpdateLibraryDialog - - - Cancel - Cancelar - - - - Updating.... - Atualizando.... - - - - Update library - + restaurar todos os quadrinhos removidos - VolumeComicsModel + ThemeEditorDialog - - title - + + Theme Editor + Editor de Tema - - - VolumesModel - - year - + + + + + - - issues - + + - + - - - publisher - + + i + eu - - - YACReader::TrayIconController - - &Restore - + + Expand all + Expandir tudo - - Systray - + + Collapse all + Recolher tudo - - YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Segure para piscar o valor selecionado na UI (magenta/alternado/0↔10). Os lançamentos restauram o original. - - - YACReader::WhatsNewDialog - - Close - + + Search… + Procurar… - - - YACReaderFieldEdit - - - Click to overwrite - + + Light + Luz - - Restore to default - + + Dark + Escuro - - - YACReaderFieldPlainTextEdit - - - - - Click to overwrite - + + ID: + EU IA: - - Restore to default - + + Display name: + Nome de exibição: - - - YACReaderFlowConfigWidget - - CoverFlow look - Olhar capa cheia + + Variant: + Variante: - - How to show covers: - Como mostrar capas: + + Theme info + Informações do tema - - Stripe look - Olhar lista + + Parameter + Parâmetro - - Overlapped Stripe look - Olhar lista sobreposta + + Value + Valor - - - YACReaderGLFlowConfigWidget - - Stripe look - Olhar lista + + Save and apply + Salvar e aplicar - - Overlapped Stripe look - Olhar lista sobreposta + + Export to file... + Exportar para arquivo... - - Presets: - + + Load from file... + Carregar do arquivo... - - Classic look - + + Close + Fechar - - Modern look - + + Double-click to edit color + Clique duas vezes para editar a cor - - Roulette look - + + + + + + + true + verdadeiro - - Show advanced settings - + + + + + false + falso - - Custom: - + + Double-click to toggle + Clique duas vezes para alternar - - View angle - + + Double-click to edit value + Clique duas vezes para editar o valor - - Position - + + + + Edit: %1 + Editar: %1 - - Cover gap - + + Save theme + Salvar tema - - Central gap - + + + JSON files (*.json);;All files (*) + Arquivos JSON (*.json);;Todos os arquivos (*) - - Zoom - + + Save failed + Falha ao salvar - - Y offset - + + Could not open file for writing: +%1 + Não foi possível abrir o arquivo para gravação: +%1 - - Z offset - + + Load theme + Carregar tema - - Cover Angle - + + + + Load failed + Falha no carregamento - - Visibility - + + Could not open file: +%1 + Não foi possível abrir o arquivo: +%1 - - Light - + + Invalid JSON: +%1 + JSON inválido: +%1 - - Max angle - + + Expected a JSON object. + Esperava um objeto JSON. + + + TitleHeader - - Low Performance - + + SEARCH + PROCURAR + + + UpdateLibraryDialog - - High Performance - + + Cancel + Cancelar - - Use VSync (improve the image quality in fullscreen mode, worse performance) - + + Updating.... + Atualizando.... - - Performance: - + + Update library + Atualizar biblioteca - YACReaderNavigationController + Viewer - - No favorites - + + + Press 'O' to open comic. + Pressione 'O' para abrir um quadrinho. - - You are not reading anything yet, come on!! - + + Not found + Não encontrado - - There are no recent comics! - + + Comic not found + Quadrinho não encontrado - - - YACReaderOptionsDialog - - Save - Salvar + + Error opening comic + Erro ao abrir quadrinho - - Cancel - Cancelar + + CRC Error + Erro CRC - - Edit shortcuts - + + Loading...please wait! + Carregando... por favor, aguarde! - - Shortcuts - + + Page not available! + Página não disponível! + + + + Cover! + Cobrir! - - Use hardware acceleration (restart needed) - + + Last page! + Última página! - YACReaderSearchLineEdit + VolumeComicsModel - - type to search - + + title + título - YACReaderSideBar + VolumesModel - - Libraries - + + year + ano - - Folders - + + issues + problemas - - Reading Lists - + + publisher + editor + + + + YACReader3DFlowConfigWidget + + + Presets: + Predefinições: + + + + Classic look + Aparência clássica + + + + Stripe look + Olhar lista + + + + Overlapped Stripe look + Olhar lista sobreposta + + + + Modern look + Aparência moderna + + + + Roulette look + Aparência de roleta + + + + Show advanced settings + Mostrar configurações avançadas + + + + Custom: + Personalizado: + + + + View angle + Ângulo de visão + + + + Position + Posição + + + + Cover gap + Cubra a lacuna + + + + Central gap + Lacuna central + + + + Zoom + Amplia??o + + + + Y offset + Deslocamento Y + + + + Z offset + Deslocamento Z + + + + Cover Angle + Ângulo de cobertura + + + + Visibility + Visibilidade + + + + Light + Luz + + + + Max angle + Ângulo máximo + + + + Low Performance + Baixo desempenho + + + + High Performance + Alto desempenho + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Use VSync (melhora a qualidade da imagem em modo tela cheia, pior desempenho) + + + + Performance: + Desempenho: + + + + YACReader::MainWindowViewer + + + &Open + &Abrir + + + + Open a comic + Abrir um quadrinho + + + + New instance + Nova instância + + + + Open Folder + Abrir Pasta + + + + Open image folder + Abra a pasta de imagens + + + + Open latest comic + Abra o último quadrinho + + + + Open the latest comic opened in the previous reading session + Abra o último quadrinho aberto na sessão de leitura anterior + + + + Clear + Claro + + + + Clear open recent list + Limpar lista recente aberta + + + + Save + Salvar + + + + + Save current page + Salvar página atual + + + + Previous Comic + Quadrinho Anterior + + + + + + Open previous comic + Abrir quadrinho anterior + + + + Next Comic + Próximo Quadrinho + + + + + + Open next comic + Abrir próximo quadrinho + + + + &Previous + A&nterior + + + + + + Go to previous page + Ir para a página anterior + + + + &Next + &Próxima + + + + + + Go to next page + Ir para a próxima página + + + + Fit Height + Ajustar Altura + + + + Fit image to height + Ajustar imagem à altura + + + + Fit Width + Ajustar à Largura + + + + Fit image to width + Ajustar imagem à largura + + + + Show full size + Mostrar tamanho grande + + + + Fit to page + Ajustar à página + + + + Continuous scroll + Rolagem contínua + + + + Switch to continuous scroll mode + Mudar para o modo de rolagem contínua + + + + Reset zoom + Redefinir zoom + + + + Show zoom slider + Mostrar controle deslizante de zoom + + + + Zoom+ + Ampliar + + + + Zoom- + Reduzir + + + + Rotate image to the left + Girar imagem à esquerda + + + + Rotate image to the right + Girar imagem à direita + + + + Double page mode + Modo dupla página + + + + Switch to double page mode + Alternar para o modo dupla página + + + + Double page manga mode + Modo mangá de página dupla + + + + Reverse reading order in double page mode + Ordem de leitura inversa no modo de página dupla + + + + Go To + Ir Para + + + + Go to page ... + Ir para a página... + + + + Options + Opções + + + + YACReader options + Opções do YACReader + + + + + Help + Ajuda + + + + Help, About YACReader + Ajuda, Sobre o YACReader + + + + Magnifying glass + Lupa + + + + Switch Magnifying glass + Alternar Lupa + + + + Set bookmark + Definir marcador + + + + Set a bookmark on the current page + Definir um marcador na página atual + + + + Show bookmarks + Mostrar marcadores + + + + Show the bookmarks of the current comic + Mostrar os marcadores do quadrinho atual + + + + Show keyboard shortcuts + Mostrar teclas de atalhos + + + + Show Info + Mostrar Informações + + + + Close + Fechar + + + + Show Dictionary + Mostrar dicionário + + + + Show go to flow + Mostrar ir para o fluxo + + + + Edit shortcuts + Editar atalhos + + + + &File + &Arquivo + + + + + Open recent + Abrir recente + + + + File + Arquivo + + + + Edit + Editar + + + + View + Visualizar + + + + Go + Ir + + + + Window + Janela + + + + + + Open Comic + Abrir Quadrinho + + + + + + Comic files + Arquivos de quadrinhos + + + + Open folder + Abrir pasta + + + + page_%1.jpg + página_%1.jpg + + + + Image files (*.jpg) + Arquivos de imagem (*.jpg) + + + + + Comics + Quadrinhos + + + + + General + Em geral + + + + + Magnifiying glass + Lupa + + + + + Page adjustement + Ajuste de página + + + + + Reading + Leitura + + + + Toggle fullscreen mode + Alternar modo de tela cheia + + + + Hide/show toolbar + Ocultar/mostrar barra de ferramentas + + + + Size up magnifying glass + Dimensione a lupa + + + + Size down magnifying glass + Diminuir o tamanho da lupa + + + + Zoom in magnifying glass + Zoom na lupa + + + + Zoom out magnifying glass + Diminuir o zoom da lupa + + + + Reset magnifying glass + Redefinir lupa + + + + Toggle between fit to width and fit to height + Alternar entre ajustar à largura e ajustar à altura + + + + Autoscroll down + Rolagem automática para baixo + + + + Autoscroll up + Rolagem automática para cima + + + + Autoscroll forward, horizontal first + Rolagem automática para frente, horizontal primeiro + + + + Autoscroll backward, horizontal first + Rolagem automática para trás, horizontal primeiro + + + + Autoscroll forward, vertical first + Rolagem automática para frente, vertical primeiro + + + + Autoscroll backward, vertical first + Rolagem automática para trás, vertical primeiro + + + + Move down + Mover para baixo + + + + Move up + Subir + + + + Move left + Mover para a esquerda + + + + Move right + Mover para a direita + + + + Go to the first page + Vá para a primeira página + + + + Go to the last page + Ir para a última página + + + + Offset double page to the left + Deslocar página dupla para a esquerda + + + + Offset double page to the right + Deslocar página dupla para a direita + + + + There is a new version available + Há uma nova versão disponível + + + + Do you want to download the new version? + Você deseja baixar a nova versão? + + + + Remind me in 14 days + Lembre-me em 14 dias + + + + Not now + Agora não + + + + YACReader::TrayIconController + + + &Restore + &Rloja + + + + Systray + Bandeja do sistema + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary continuará em execução na bandeja do sistema. Para encerrar o programa, escolha <b>Quit</b> no menu de contexto do ícone da bandeja do sistema. + + + + YACReaderFieldEdit + + + + Click to overwrite + Clique para substituir + + + + Restore to default + Restaurar para o padrão + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + Clique para substituir + + + + Restore to default + Restaurar para o padrão + + + + YACReaderFlowConfigWidget + + CoverFlow look + Olhar capa cheia + + + How to show covers: + Como mostrar capas: + + + Stripe look + Olhar lista + + + Overlapped Stripe look + Olhar lista sobreposta + + + + YACReaderGLFlowConfigWidget + + Stripe look + Olhar lista + + + Overlapped Stripe look + Olhar lista sobreposta + + + + YACReaderOptionsDialog + + + Save + Salvar + + + + Cancel + Cancelar + + + + Edit shortcuts + Editar atalhos + + + + Shortcuts + Atalhos + + + + YACReaderSearchLineEdit + + + type to search + digite para pesquisar + + + + YACReaderSlider + + + Reset + Reiniciar + + + + YACReaderTranslator + + + YACReader translator + Tradutor YACReader - - LIBRARIES - + + + Translation + Tradução - - FOLDERS - + + clear + claro - - READING LISTS - + + Service not available + Serviço não disponível diff --git a/YACReaderLibrary/yacreaderlibrary_ru.ts b/YACReaderLibrary/yacreaderlibrary_ru.ts index 306c4972a..039989172 100644 --- a/YACReaderLibrary/yacreaderlibrary_ru.ts +++ b/YACReaderLibrary/yacreaderlibrary_ru.ts @@ -6,88 +6,76 @@ None - + Никто AddLabelDialog - red - красный + красный - blue - синий + синий - dark - темный + темный - cyan - голубой + голубой - pink - розовый + розовый - green - зеленый + зеленый - light - серый + серый - white - белый + белый - + Choose a color: Выбрать цвет: - + accept добавить - + cancel отменить - orange - оранжевый + оранжевый - purple - пурпурный + пурпурный - violet - фиолетовый + фиолетовый - yellow - желтый + желтый - + Label name: Название ярлыка: @@ -100,7 +88,7 @@ Добавить - + Add an existing library Добавить в существующую библиотеку @@ -143,10 +131,150 @@ Вставьте сюда ваш Comic Vine API ключ + + AppearanceTabWidget + + + Color scheme + Цветовая гамма + + + + System + Система + + + + Light + Осветить + + + + Dark + Темный + + + + Custom + Обычай + + + + Remove + Удалять + + + + Remove this user-imported theme + Удалить эту импортированную пользователем тему + + + + Light: + Свет: + + + + Dark: + Темный: + + + + Custom: + Пользовательский: + + + + Import theme... + Импортировать тему... + + + + Theme + Тема + + + + Theme editor + Редактор тем + + + + Open Theme Editor... + Открыть редактор тем... + + + + Theme editor error + Ошибка редактора темы + + + + The current theme JSON could not be loaded. + Не удалось загрузить JSON текущей темы. + + + + Import theme + Импортировать тему + + + + JSON files (*.json);;All files (*) + Файлы JSON (*.json);;Все файлы (*) + + + + Could not import theme from: +%1 + Не удалось импортировать тему из: +%1 + + + + Could not import theme from: +%1 + +%2 + Не удалось импортировать тему из: +%1 + +%2 + + + + Import failed + Импорт не удался + + + + BookmarksDialog + + + Lastest Page + Последняя страница + + + + Close + Закрыть + + + + Click on any image to go to the bookmark + Нажмите на любое изображение чтобы перейти к закладке + + + + + Loading... + Загрузка... + + ClassicComicsView - + Hide comic flow Показать/скрыть поток комиксов @@ -154,84 +282,84 @@ ComicInfoView - + + Characters + Персонажи + + + Main character or team - + Главный герой или команда - + Teams - + Команды - + Locations - + Местоположение - + Authors Авторы - + writer - + сценарист - + penciller - + художник - + inker - + инкер - + colorist - + колорист - + letterer - + леттерер - + cover artist - + художник обложки - + editor - + редактор - + imprint - + импринт - + Publisher - + Издатель - + color - + цвет - + b/w - - - - - Characters - + ч/б @@ -254,17 +382,17 @@ Series - + Ряд Volume - + Объем Story Arc - + Сюжетная арка @@ -294,7 +422,7 @@ Publication Date - + Дата публикации @@ -305,74 +433,82 @@ ComicVineDialog - + back назад - + next дальше - + skip пропустить - + close закрыть - - + + Retrieving tags for : %1 Получение тегов для : %1 - + Looking for comic... Поиск комикса... - + search искать - - - + + + Looking for volume... Поиск информации... - - + + comic %1 of %2 - %3 комикс %1 of %2 - %3 - + %1 comics selected %1 было выбрано - + Error connecting to ComicVine Ошибка поключения к ComicVine - + Retrieving volume info... Получение информации... + + ContinuousPageWidget + + + Loading page %1 + Загрузка страницы %1 + + CreateLibraryDialog - + Create new library Создать новую библиотеку @@ -392,7 +528,7 @@ Создание библиотеки может занять несколько минут. Вы можете остановить процесс и обновить библиотеку позже для завершения задачи. - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder Выбранный путь отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке @@ -407,7 +543,7 @@ Имя библиотеки: - + Path not found Путь не найден @@ -415,7 +551,7 @@ EditShortcutsDialog - + Shortcut in use Горячая клавиша уже занята @@ -430,7 +566,7 @@ Горячие клавиши - + The shortcut "%1" is already assigned to other function Сочетание клавиш "%1" уже назначено для другой функции @@ -443,26 +579,27 @@ EmptyFolderWidget - Empty folder - Пустая папка + Пустая папка - - Subfolders in this folder - Подпапки в этой папке + Подпапки в этой папке - Drag and drop folders and comics here - Перетащите папки и комиксы сюда + Перетащите папки и комиксы сюда + + + + This folder doesn't contain comics yet + В этой папке еще нет комиксов EmptyLabelWidget - + This label doesn't contain comics yet Этот ярлык пока ничего не содержит @@ -475,6 +612,24 @@ Этот список чтения пока ничего не содержит + + EmptySpecialListWidget + + + No favorites + Нет избранного + + + + You are not reading anything yet, come on!! + Вы пока ничего не читаете. Может самое время почитать? + + + + There are no recent comics! + Свежих комиксов нет! + + ExportComicsInfoDialog @@ -483,7 +638,7 @@ Выходной файл (*.ydb) : - + Destination database name Имя этой базы данных @@ -498,17 +653,17 @@ Создать - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder Выбранный путь для импортируемого файла отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке - + Export comics info Экспортировать информацию комикса - + Problem found while writing Обнаружена Ошибка записи @@ -526,7 +681,7 @@ Создать - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder Выбранный путь для импортируемого файла отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке @@ -536,17 +691,17 @@ Папка вывода : - + Problem found while writing Проблема при написании - + Create covers package Создать комплект обложек - + Destination directory Назначенная директория @@ -577,23 +732,52 @@ FolderContentView - + Continue Reading... - + Продолжить чтение... - FolderContentView6 + GoToDialog - - Continue Reading... - + + Page : + Страница : + + + + Go To + Перейти к странице... + + + + Cancel + Отмена + + + + + Total pages : + Общее количество страниц : + + + + Go to... + Перейти к странице... + + + + GoToFlowToolBar + + + Page : + Страница : GridComicsView - + Show info Показать информацию @@ -601,17 +785,17 @@ HelpAboutDialog - + Help Настройки - + System info - + Информация о системе - + About О программе @@ -639,7 +823,7 @@ Импортировать информацию комикса - + Comics info file (*.ydb) Инфо файл комикса (*.ydb) @@ -662,7 +846,7 @@ Распаковать - + Compresed library covers (*.clc) Сжатая библиотека обложек (*.clc) @@ -677,7 +861,7 @@ Имя библиотеки : - + Extract a catalog Извлечь каталог @@ -685,54 +869,54 @@ ImportWidget - + stop Остановить - + Importing comics Импорт комиксов - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> <p>YACReaderLibrary сейчас создает библиотеку.</p><p> Создание библиотеки может занять несколько минут. Вы можете остановить процесс и обновить библиотеку позже для завершения задачи.</p> - + Some of the comics being added... Поиск новых комиксов... - + Updating the library Обновление библиотеки - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> <p>Текущая библиотека обновляется. Для более быстрого обновления в дальнейшем старайтесь почаще обновлять вашу библиотеку после добавления новых комиксов.</p><p>Вы можете остановить этот процесс и продолжить обновление этой библиотеки позже.</p> - + Upgrading the library - + Обновление библиотеки - + <p>The current library is being upgraded, please wait.</p> - + <p>Текущая библиотека обновляется, подождите.</p> - + Scanning the library - + Сканирование библиотеки - + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> - + <p>Текущая библиотека сканируется на предмет устаревших метаданных XML.</p><p>Это необходимо только один раз и только в том случае, если библиотека была создана с помощью YACReaderLibrary 9.8.2 или более ранней версии.</p> @@ -742,27 +926,27 @@ Редактировать информацию - + The selected folder doesn't contain any library. Выбранная папка не содержит ни одной библиотеки. - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? Эта библиотека была создана с предыдущей версией YACReaderLibrary. Она должна быть обновлена. Обновить сейчас? - + Comic Комикс - + Folder name: Имя папки: - + The selected folder and all its contents will be deleted from your disk. Are you sure? Выбранная папка и все ее содержимое будет удалено с вашего жёсткого диска. Вы уверены? @@ -771,7 +955,7 @@ Обновить выбранную папку - + Error opening the library Ошибка открытия библиотеки @@ -780,8 +964,8 @@ Показать/Спрятать пометки - - + + YACReader not found YACReader не найден @@ -790,7 +974,7 @@ Настройки сервера YACReader - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. Возникла проблема при удалении выбранных папок. Пожалуйста, проверьте права на запись и убедитесь что другие приложения не используют эти папки или файлы. @@ -803,7 +987,7 @@ Отметить комикс как прочитано - + Rename list name Изменить имя списка @@ -812,12 +996,12 @@ Добавить выбранные комиксы в список избранного - + Remove and delete metadata Удаление метаданных - + Old library Библиотека из старой версии YACreader @@ -830,17 +1014,17 @@ Переименовать выбранный ярлык/список чтения - + Set as completed Отметить как завершено - + There was an error accessing the folder's path Ошибка доступа к пути папки - + Library Библиотека @@ -849,7 +1033,7 @@ Добавить новую папку в текущую библиотеку - + Comics will only be deleted from the current label/list. Are you sure? Комиксы будут удалены только из выбранного списка/ярлыка. Вы уверены? @@ -862,13 +1046,13 @@ Полноэкранный режим включить/выключить - + This library was created with a newer version of YACReaderLibrary. Download the new version now? Эта библиотека была создана новой версией YACReaderLibrary. Скачать новую версию сейчас? - - + + Moving comics... Переместить комиксы... @@ -881,13 +1065,13 @@ Обновить эту библиотеку - - + + Copying comics... Скопировать комиксы... - + Library '%1' is no longer available. Do you want to remove it? Библиотека '%1' больше не доступна. Вы хотите удалить ее? @@ -896,22 +1080,22 @@ Обновить библиотеку - + Open folder... Открыть папку... - + Do you want remove Вы хотите удалить библиотеку - + Set as uncompleted Отметить как не завершено - + Error in path Ошибка в пути @@ -920,17 +1104,17 @@ Сбросить рейтинг комикса - + Error updating the library Ошибка обновления библиотеки - + Folder Папка - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? Выбранные элементы будут удалены, ваши комиксы или папки НЕ БУДУТ удалены с вашего жёсткого диска. Вы уверены? @@ -943,8 +1127,8 @@ Удалить выбранную папку с жёсткого диска - - + + List name: Имя списка: @@ -953,7 +1137,7 @@ Добавить в... - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? Библиотека '%1' была создана старой версией YACReaderLibrary. Она должна быть вновь создана. Вы хотите создать библиотеку сейчас? @@ -962,7 +1146,7 @@ Запаковать обложки - + Save covers Сохранить обложки @@ -975,12 +1159,12 @@ Удалить выбранный ярлык/список чтения - + Add new reading lists Добавить новый список чтения - + You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. @@ -993,17 +1177,17 @@ YACReaderLibrary will not stop you from creating more libraries but you should k YACReaderLibrary не помешает вам создать больше библиотек, но вы должны иметь не большое количество библиотек. - + Set as read Отметить как прочитано - + Library info - + Информация о библиотеке - + Assign comics numbers Порядковый номер @@ -1020,7 +1204,7 @@ YACReaderLibrary не помешает вам создать больше биб Настройки - + Please, select a folder first Пожалуйста, сначала выберите папку @@ -1029,7 +1213,7 @@ YACReaderLibrary не помешает вам создать больше биб Создать новую библиотеку - + Library not available Библиотека не доступна @@ -1038,7 +1222,7 @@ YACReaderLibrary не помешает вам создать больше биб Импортировать информацию комикса - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. Возникла проблема при удалении выбранных комиксов. Пожалуйста, проверьте права на запись для выбранных файлов или содержащую их папку. @@ -1055,7 +1239,7 @@ YACReaderLibrary не помешает вам создать больше биб Открыть выбранный комикс - + YACReader Library Библиотека YACReader @@ -1064,17 +1248,17 @@ YACReaderLibrary не помешает вам создать больше биб Создать новый список чтения - + Error creating the library Ошибка создания библиотеки - + You are adding too many libraries. Вы добавляете слишком много библиотек. - + Update folder Обновить папку @@ -1083,7 +1267,7 @@ YACReaderLibrary не помешает вам создать больше биб Распаковать обложки - + Update needed Необходимо обновление @@ -1096,12 +1280,12 @@ YACReaderLibrary не помешает вам создать больше биб Показать или спрятать отметку прочтено - + Library name already exists Имя папки уже используется - + There is another library with the name '%1'. Уже существует другая папка с именем '%1'. @@ -1110,47 +1294,47 @@ YACReaderLibrary не помешает вам создать больше биб Удалить список чтения - + Delete folder Удалить папку - + Assign numbers starting in: Назначить порядковый номер начиная с: - + Download new version Загрузить новую версию - + Invalid image - + Неверное изображение - + The selected file is not a valid image. - + Выбранный файл не является допустимым изображением. - + Error saving cover - + Не удалось сохранить обложку. - + There was an error saving the cover image. - + Не удалось сохранить изображение обложки. - + Delete comics Удалить комиксы - + Add new folder Добавить новую папку @@ -1183,7 +1367,7 @@ YACReaderLibrary не помешает вам создать больше биб Переименовать выбранный список - + Delete list/label Удалить список/ярлык @@ -1200,7 +1384,7 @@ YACReaderLibrary не помешает вам создать больше биб Домашняя папка - + No folder selected Ни одна папка не была выбрана @@ -1209,7 +1393,7 @@ YACReaderLibrary не помешает вам создать больше биб Распаковать каталог - + All the selected comics will be deleted from your disk. Are you sure? Все выбранные комиксы будут удалены с вашего жёсткого диска. Вы уверены? @@ -1218,7 +1402,7 @@ YACReaderLibrary не помешает вам создать больше биб Скачать теги из Comic Vine - + Remove comics Убрать комиксы @@ -1227,13 +1411,13 @@ YACReaderLibrary не помешает вам создать больше биб Создать новый ярлык - - + + Set as unread Отметить как не прочитано - + Library not found Библиотека не найдена @@ -1246,32 +1430,32 @@ YACReaderLibrary не помешает вам создать больше биб Удалить библиотеку - - - + + + manga - + манга - - - + + + comic - + комикс - - - + + + web comic - + веб-комикс - - - + + + western manga (left to right) - + западная манга (слева направо) Open containing folder... @@ -1282,48 +1466,48 @@ YACReaderLibrary не помешает вам создать больше биб Создать новый ярлык - - + + Unable to delete Не удалось удалить - - - + + + 4koma (top to botom) - + 4кома (сверху вниз) - - - - + + + + Set type - + Тип установки - + Set custom cover - + Установить собственную обложку - + Delete custom cover - + Удалить пользовательскую обложку - + Error - + Ошибка - + Error opening comic with third party reader. - + Ошибка при открытии комикса с помощью сторонней программы чтения. - + library? ? @@ -1332,472 +1516,472 @@ YACReaderLibrary не помешает вам создать больше биб Сохранить обложки выбранных комиксов как JPG файлы - + Are you sure? Вы уверены? - + Rescan library for XML info - + Повторное сканирование библиотеки для получения информации XML - + Upgrade failed - + Обновление не удалось - + There were errors during library upgrade in: - + При обновлении библиотеки возникли ошибки: - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - + YACReader не найден. YACReader должен быть установлен в ту же папку, что и YACReaderLibrary. - + YACReader not found. There might be a problem with your YACReader installation. - + YACReader не найден. Возможно, возникла проблема с установкой YACReader. LibraryWindowActions - + Create a new library - Создать новую библиотеку + Создать новую библиотеку - + Open an existing library - Открыть существующую библиотеку + Открыть существующую библиотеку - - + + Export comics info - Экспортировать информацию комикса + Экспортировать информацию комикса - - + + Import comics info - Импортировать информацию комикса + Импортировать информацию комикса - + Pack covers - Запаковать обложки + Запаковать обложки - + Pack the covers of the selected library - Запаковать обложки выбранной библиотеки + Запаковать обложки выбранной библиотеки - + Unpack covers - Распаковать обложки + Распаковать обложки - + Unpack a catalog - Распаковать каталог + Распаковать каталог - + Update library - Обновить библиотеку + Обновить библиотеку - + Update current library - Обновить эту библиотеку + Обновить эту библиотеку - + Rename library - Переименовать библиотеку + Переименовать библиотеку - + Rename current library - Переименовать эту библиотеку + Переименовать эту библиотеку - + Remove library - Удалить библиотеку + Удалить библиотеку - + Remove current library from your collection - Удалить эту библиотеку из своей коллекции + Удалить эту библиотеку из своей коллекции - + Rescan library for XML info - + Повторное сканирование библиотеки для получения информации XML - + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. - + Пытается найти информацию XML, встроенную в файлы комиксов. Это необходимо делать только в том случае, если библиотека была создана с помощью версии 9.8.2 или более ранней, или если вы используете стороннее программное обеспечение для встраивания информации XML в файлы. - + Show library info - + Показать информацию о библиотеке - + Show information about the current library - + Показать информацию о текущей библиотеке - + Open current comic - Открыть выбранный комикс + Открыть выбранный комикс - + Open current comic on YACReader - Открыть комикс в YACReader + Открыть комикс в YACReader - + Save selected covers to... - Сохранить выбранные обложки в... + Сохранить выбранные обложки в... - + Save covers of the selected comics as JPG files - Сохранить обложки выбранных комиксов как JPG файлы + Сохранить обложки выбранных комиксов как JPG файлы - - + + Set as read - Отметить как прочитано + Отметить как прочитано - + Set comic as read - Отметить комикс как прочитано + Отметить комикс как прочитано - - + + Set as unread - Отметить как не прочитано + Отметить как не прочитано - + Set comic as unread - Отметить комикс как не прочитано + Отметить комикс как не прочитано - - + + manga - + манга - + Set issue as manga - + Установить выпуск как мангу - - + + comic - + комикс - + Set issue as normal - + Установите проблему как обычно - + western manga - + вестерн манга - + Set issue as western manga - + Установить выпуск как западную мангу - - + + web comic - + веб-комикс - + Set issue as web comic - + Установить выпуск как веб-комикс - - + + yonkoma - + йонкома - + Set issue as yonkoma - + Установить проблему как йонкома - + Show/Hide marks - Показать/Спрятать пометки + Показать/Спрятать пометки - + Show or hide read marks - Показать или спрятать отметку прочтено + Показать или спрятать отметку прочтено - + Show/Hide recent indicator - + Показать/скрыть индикатор последних событий - + Show or hide recent indicator - + Показать или скрыть недавний индикатор - - + + Fullscreen mode on/off - Полноэкранный режим включить/выключить + Полноэкранный режим включить/выключить - + Help, About YACReader - О программе + О программе - + Add new folder - Добавить новую папку + Добавить новую папку - + Add new folder to the current library - Добавить новую папку в текущую библиотеку + Добавить новую папку в текущую библиотеку - + Delete folder - Удалить папку + Удалить папку - + Delete current folder from disk - Удалить выбранную папку с жёсткого диска + Удалить выбранную папку с жёсткого диска - + Select root node - Домашняя папка + Домашняя папка - + Expand all nodes - Раскрыть все папки + Раскрыть все папки - + Collapse all nodes - Свернуть все папки + Свернуть все папки - + Show options dialog - Настройки + Настройки - + Show comics server options dialog - Настройки сервера YACReader + Настройки сервера YACReader - - + + Change between comics views - Изменение внешнего вида потока комиксов + Изменение внешнего вида потока комиксов - + Open folder... - Открыть папку... + Открыть папку... - + Set as uncompleted - Отметить как не завершено + Отметить как не завершено - + Set as completed - Отметить как завершено + Отметить как завершено - + Set custom cover - + Установить собственную обложку - + Delete custom cover - + Удалить пользовательскую обложку - + western manga (left to right) - + западная манга (слева направо) - + Open containing folder... - Открыть выбранную папку... + Открыть выбранную папку... - + Reset comic rating - Сбросить рейтинг комикса + Сбросить рейтинг комикса - + Select all comics - Выбрать все комиксы + Выбрать все комиксы - + Edit - Редактировать информацию + Редактировать информацию - + Assign current order to comics - Назначить порядковый номер + Назначить порядковый номер - + Update cover - Обновить обложки + Обновить обложки - + Delete selected comics - Удалить выбранное + Удалить выбранное - + Delete metadata from selected comics - + Удалить метаданные из выбранных комиксов - + Download tags from Comic Vine - Скачать теги из Comic Vine + Скачать теги из Comic Vine - + Focus search line - + Строка поиска фокуса - + Focus comics view - + Просмотр комиксов в фокусе - + Edit shortcuts - Редактировать горячие клавиши + Редактировать горячие клавиши - + &Quit - + &Qкостюм - + Update folder - Обновить папку + Обновить папку - + Update current folder - Обновить выбранную папку + Обновить выбранную папку - + Scan legacy XML metadata - + Сканировать устаревшие метаданные XML - + Add new reading list - Создать новый список чтения + Создать новый список чтения - + Add a new reading list to the current library - Создать новый список чтения + Создать новый список чтения - + Remove reading list - Удалить список чтения + Удалить список чтения - + Remove current reading list from the library - Удалить выбранный ярлык/список чтения + Удалить выбранный ярлык/список чтения - + Add new label - Создать новый ярлык + Создать новый ярлык - + Add a new label to this library - Создать новый ярлык + Создать новый ярлык - + Rename selected list - Переименовать выбранный список + Переименовать выбранный список - + Rename any selected labels or lists - Переименовать выбранный ярлык/список чтения + Переименовать выбранный ярлык/список чтения - + Add to... - Добавить в... + Добавить в... - + Favorites - Избранное + Избранное - + Add selected comics to favorites list - Добавить выбранные комиксы в список избранного + Добавить выбранные комиксы в список избранного @@ -1808,248 +1992,245 @@ YACReaderLibrary не помешает вам создать больше биб имя файла - - LogWindow - - - Log window - - - - - &Pause - - - - - &Save - - - - - C&lear - - - - - &Copy - - - - - Level: - - - - - &Auto scroll - - - NoLibrariesWidget - + create your first library создайте свою первую библиотеку - + You don't have any libraries yet У вас нет ни одной библиотеки - + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Вы можете создать библиотеку в любой папке, YACReaderLibrary будет импортировать все комиксы и папки из этой папки. Если вы уже ранее создавали библиотеки, их можно будет открыть.< / p > <p>Не забывайте, что Вы можете использовать YACReader в качестве отдельного приложения для чтения комиксов на вашем компьютере.</п> - + add an existing one добавить уже существующую + + NoSearchResultsWidget + + + No results + Нет результатов + + OptionsDialog - + Restore defautls Вернуть к первоначальным значениям - + Background Фоновое изображение - + Blur level Уровень размытия - + Enable background image Включить фоновое изображение - + + Options Настройки - + Comic Vine API key Comic Vine API ключ - + Edit Comic Vine API key Редактировать Comic Vine API ключ - + Opacity level Уровень непрозрачности - + + General Основные - + Use selected comic cover as background Обложка комикса фоновое изображение - + Comic Flow Поток комиксов - - + + Libraries - Библиотеки + Библиотеки - + Grid view Фоновое изображение - + + + Appearance + Появление + + + + + Language + Язык + + + + + Application language + Язык приложения + + + + + System default + Системный по умолчанию + + + Tray icon settings (experimental) - + Настройки значков в трее (экспериментально) - + Close to tray - + Рядом с лотком - + Start into the system tray - + Запустите в системном трее - + ComicInfo.xml legacy support - + Поддержка устаревших версий ComicInfo.xml - + Import metadata from ComicInfo.xml when adding new comics Import metada from ComicInfo.xml when adding new comics - + Импортируйте метаданные из ComicInfo.xml при добавлении новых комиксов. - + Consider 'recent' items added or updated since X days ago - + Учитывайте «недавние» элементы, добавленные или обновленные X дней назад. - + Third party reader - + Сторонний читатель - + Write {comic_file_path} where the path should go in the command - + Напишите {comic_file_path}, где должен идти путь в команде. - + + Clear - + Очистить - + Update libraries at startup - + Обновлять библиотеки при запуске - + Try to detect changes automatically - + Попробуйте обнаружить изменения автоматически - + Update libraries periodically - + Периодически обновляйте библиотеки - + Interval: - + Интервал: - + 30 minutes - + 30 минут - + 1 hour - + 1 час - + 2 hours - + 2 часа - + 4 hours - + 4 часа - + 8 hours - + 8 часов - + 12 hours - + 12 часов - + daily - + ежедневно - + Update libraries at certain time - + Обновлять библиотеки в определенное время - + Time: - + Время: - + WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. @@ -2057,79 +2238,253 @@ To stop an automatic update tap on the loading indicator next to the Libraries t WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. - + ПРЕДУПРЕЖДЕНИЕ! Во время обновления библиотеки запись в базу данных отключена! +Не планируйте обновления, пока вы активно используете приложение. +Во время автоматического обновления приложение будет блокировать некоторые действия до завершения обновления. +Чтобы остановить автоматическое обновление, нажмите на индикатор загрузки рядом с названием «Библиотеки». - + Modifications detection - + Обнаружение модификаций - + Compare the modified date of files when updating a library (not recommended) - + Сравните дату изменения файлов при обновлении библиотеки (не рекомендуется) - + Display continue reading banner - + Отображение баннера продолжения чтения - + Display current comic banner - + Отображать текущий комикс-баннер - + Continue reading - + Продолжить чтение - - - PropertiesDialog - - Day: - День: + + My comics path + Папка комиксов - - Plot - Сюжет + + Display + Отображать - - Size: - Размер: + + Show time in current page information label + Показывать время в информационной метке текущей страницы - - Year: - Год: + + "Go to flow" size + Размер потока страниц - - Inker(s): - Контуровщик(и): + + Background color + Фоновый цвет - - Publishing - Издатели + + Choose + Выбрать - - Publisher: - Издатель: + + Scroll behaviour + Поведение прокрутки - - General info - Общая информация + + Disable scroll animations and smooth scrolling + Отключить анимацию прокрутки и плавную прокрутку - - Color/BW: + + Do not turn page using scroll + Не переворачивайте страницу с помощью прокрутки + + + + Use single scroll step to turn page + Используйте один шаг прокрутки, чтобы перевернуть страницу + + + + Mouse mode + Режим мыши + + + + Only Back/Forward buttons can turn pages + Только кнопки «Назад/Вперед» могут перелистывать страницы. + + + + Use the Left/Right buttons to turn pages. + Используйте кнопки «Влево/Вправо», чтобы перелистывать страницы. + + + + Click left or right half of the screen to turn pages. + Нажмите левую или правую половину экрана, чтобы перелистывать страницы. + + + + Quick Navigation Mode + Ползунок для быстрой навигации по страницам + + + + Disable mouse over activation + Отключить активацию потока при наведении мыши + + + + Brightness + Яркость + + + + Contrast + Контраст + + + + Gamma + Гамма + + + + Reset + Вернуть к первоначальным значениям + + + + Image options + Настройки изображения + + + + Fit options + Варианты подгонки + + + + Enlarge images to fit width/height + Увеличьте изображения по ширине/высоте + + + + Double Page options + Параметры двойной страницы + + + + Show covers as single page + Показывать обложки на одной странице + + + + Scaling + Масштабирование + + + + Scaling method + Метод масштабирования + + + + Nearest (fast, low quality) + Ближайший (быстро, низкое качество) + + + + Bilinear + Билинейный + + + + Lanczos (better quality) + Ланцос (лучшее качество) + + + + Page Flow + Поток Страниц + + + + Image adjustment + Настройка изображения + + + + + Restart is needed + Требуется перезагрузка + + + + Comics directory + Папка комиксов + + + + PropertiesDialog + + + Day: + День: + + + + Plot + Сюжет + + + + Size: + Размер: + + + + Year: + Год: + + + + Inker(s): + Контуровщик(и): + + + + Publishing + Издатели + + + + Publisher: + Издатель: + + + + General info + Общая информация + + + + Color/BW: Цвет/BW: @@ -2155,32 +2510,32 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Notes - + Примечания Load previous page as cover - + Загрузить предыдущую страницу в качестве обложки Load next page as cover - + Загрузить следующую страницу в качестве обложки Reset cover to the default image - + Сбросить обложку к изображению по умолчанию Load custom cover image - + Загрузить собственное изображение обложки Series: - Серия: + Серия: @@ -2190,27 +2545,27 @@ To stop an automatic update tap on the loading indicator next to the Libraries t alt. number: - + альт. число: Alternate series: - + Альтернативный сериал: Series Group: - + Группа серий: Editor(s): - + Редактор(ы): Imprint: - + Выходные данные: @@ -2220,32 +2575,32 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Type: - + Тип: Language (ISO): - + Язык (ISO): Teams: - + Команды: Locations: - + Местоположение: Main character or team: - + Главный герой или команда: Review: - + Обзор: @@ -2255,12 +2610,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Invalid cover - + Неверное покрытие The image is invalid. - + Изображение недействительно. @@ -2305,7 +2660,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Tags: - + Теги: @@ -2352,12 +2707,28 @@ To stop an automatic update tap on the loading indicator next to the Libraries t of: - + из: Arc number: - + Номер дуги: + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer — это безголовая (без графического интерфейса) версия YACReaderLibrary. + +Это приложение поддерживает постоянные настройки. Чтобы настроить их, отредактируйте этот файл %1. +Чтобы узнать о доступных настройках, ознакомьтесь с документацией по адресу https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md. @@ -2375,89 +2746,73 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Trace - + След Debug - + Отлаживать Info - + Информация Warning - + Предупреждение Error - + Ошибка Fatal - + Фатальный - + Select custom cover - + Выбрать индивидуальную обложку - + Images (%1) - - - - - QsLogging::LogWindowModel - - - Time - - - - - Level - + Изображения (%1) - - Message - + + The file could not be read or is not valid JSON. + Файл не может быть прочитан или имеет недопустимый формат JSON. - - - QsLogging::Window - - &Pause - + + This theme is for %1, not %2. + Эта тема предназначена для %1, а не для %2. - - &Resume - + + Libraries + Библиотеки - - Save log - + + Folders + Папки - - Log file (*.log) - + + Reading Lists + Списки чтения RenameLibraryDialog - + Rename current library Переименовать эту библиотеку @@ -2480,18 +2835,18 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ScraperResultsPaginator - + Number of %1 found : %2 Количество из %1 найдено : %2 - - + + page %1 of %2 страница %1 из %2 - + Number of volumes found : %1 Количество найденных томов : %1 @@ -2502,17 +2857,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information for this comic. Please provide some additional information. - Пожалуйста, введите инфомарцию для поиска. + Пожалуйста, введите инфомарцию для поиска. - + Series: Серия: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Используйте поиск по точному совпадению. Отключите, если хотите найти тома, соответствующие некоторым словам в названии. @@ -2523,40 +2878,40 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Пожалуйста, введите инфомарцию для поиска. - + Series: Серия: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Используйте поиск по точному совпадению. Отключите, если хотите найти тома, соответствующие некоторым словам в названии. SelectComic - + loading description загрузка описания - + comics комиксы - + loading cover загрузка обложки - + comic description unavailable - + Описание комикса недоступно - + Please, select the right comic info. Пожалуйста, выберите правильную информацию об комиксе. @@ -2568,37 +2923,37 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SelectVolume - + loading description загрузка описания - + Please, select the right series for your comic. Пожалуйста, выберите правильную серию для вашего комикса. - + Filter: - + Фильтр: - + Nothing found, clear the filter if any. - + Ничего не найдено, очистите фильтр, если есть. - + loading cover загрузка обложки - + volume description unavailable - + описание тома недоступно - + volumes тома @@ -2610,12 +2965,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SeriesQuestion - + no нет - + yes да @@ -2628,7 +2983,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ServerConfigDialog - + Port Порт @@ -2637,12 +2992,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t <a href='http://ios.yacreader.com' style='color:rgb(102,102,102)'>YACReader доступен для устройств с iOS.</a> - + enable the server активировать сервер - + Server connectivity information Информация о подключении @@ -2653,22 +3008,22 @@ to improve the performance для улучшения производительности - + Scan it! Сканируйте! - + set port указать порт - + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + YACReader доступен для устройств iOS и Android.<br/>Найдите его для <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> или <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + Choose an IP address Выбрать IP адрес @@ -2676,322 +3031,1156 @@ to improve the performance SortVolumeComics - + remove selected comics удалить выбранные комиксы - + sort comics to match comic information сортировать комиксы, чтобы соответствовать информации комиксов - + restore all removed comics восстановить все удаленные комиксы - + issues выпуск - + Please, sort the list of comics on the left until it matches the comics' information. Пожалуйста, отсортируйте список комиксов слева, пока он не будет соответствовать информации комикса. - TitleHeader - - - SEARCH - ПОИСК - - - - UpdateLibraryDialog + ThemeEditorDialog - - Update library - Обновить библиотеку + + Theme Editor + Редактор тем - - Cancel - Отмена + + + + + - - Updating.... - Обновление... + + - + - - - - VolumeComicsModel - - title - название + + i + я - - - VolumesModel - - year - год + + Expand all + Развернуть все - - issues - выпуск + + Collapse all + Свернуть все - - publisher - издатель + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Удерживайте, чтобы выбранное значение мигало в пользовательском интерфейсе (пурпурный / переключено / 0↔10). Релизы восстанавливают оригинал. - - - YACReader::TrayIconController - - &Restore - + + Search… + Поиск… - - Systray - + + Light + Осветить - - YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - + + Dark + Темный - - - YACReader::WhatsNewDialog - - Close - + + ID: + ИДЕНТИФИКАТОР: - - - YACReaderFieldEdit - - Restore to default - Вернуть к первоначальным значениям + + Display name: + Отображаемое имя: - - - Click to overwrite - Изменить + + Variant: + Вариант: - - - YACReaderFieldPlainTextEdit - - Restore to default - Вернуть к первоначальным значениям + + Theme info + Информация о теме - - - - - Click to overwrite - Изменить + + Parameter + Параметр - - - YACReaderFlowConfigWidget - - CoverFlow look - Рулеткой + + Value + Ценить - - How to show covers: - Выбрать внешний вид потока обложек: + + Save and apply + Сохраните и примените - - Stripe look - Вид полосами + + Export to file... + Экспортировать в файл... - - Overlapped Stripe look - Вид перекрывающимися полосами + + Load from file... + Загрузить из файла... - - - YACReaderGLFlowConfigWidget - - Zoom - Масштабировать + + Close + Закрыть - - Light - Осветить + + Double-click to edit color + Дважды щелкните, чтобы изменить цвет - - Show advanced settings - Показать дополнительные настройки + + + + + + + true + истинный - - Roulette look - Вид рулеткой + + + + + false + ЛОЖЬ - - Cover Angle - Охватить угол + + Double-click to toggle + Дважды щелкните, чтобы переключиться - - Stripe look - Вид полосами + + Double-click to edit value + Дважды щелкните, чтобы изменить значение - - Position - Позиция + + + + Edit: %1 + Изменить: %1 - - Z offset - Смещение по Z + + Save theme + Сохранить тему - - Y offset - Смещение по Y + + + JSON files (*.json);;All files (*) + Файлы JSON (*.json);;Все файлы (*) - - Central gap - Сфокусировать разрыв + + Save failed + Сохранить не удалось - - Presets: - Предустановки: + + Could not open file for writing: +%1 + Не удалось открыть файл для записи: +%1 - - Overlapped Stripe look - Вид перекрывающимися полосами + + Load theme + Загрузить тему - - Modern look - Современный вид + + + + Load failed + Загрузка не удалась - - View angle - Угол зрения + + Could not open file: +%1 + Не удалось открыть файл: +%1 - - Max angle - Максимальный угол + + Invalid JSON: +%1 + Неверный JSON: +%1 - - Custom: - Пользовательский: + + Expected a JSON object. + Ожидается объект JSON. + + + TitleHeader - - Classic look - Классический вид + + SEARCH + ПОИСК + + + UpdateLibraryDialog - - Cover gap - Охватить разрыв + + Update library + Обновить библиотеку - - High Performance - Максимальная производительность + + Cancel + Отмена - + + Updating.... + Обновление... + + + + Viewer + + + + Press 'O' to open comic. + Нажмите "O" чтобы открыть комикс. + + + + Not found + Не найдено + + + + Comic not found + Комикс не найден + + + + Error opening comic + Ошибка открытия комикса + + + + CRC Error + Ошибка CRC + + + + Loading...please wait! + Загрузка... Пожалуйста подождите! + + + + Page not available! + Страница недоступна! + + + + Cover! + Начало! + + + + Last page! + Конец! + + + + VolumeComicsModel + + + title + название + + + + VolumesModel + + + year + год + + + + issues + выпуск + + + + publisher + издатель + + + + YACReader3DFlowConfigWidget + + + Presets: + Предустановки: + + + + Classic look + Классический вид + + + + Stripe look + Вид полосами + + + + Overlapped Stripe look + Вид перекрывающимися полосами + + + + Modern look + Современный вид + + + + Roulette look + Вид рулеткой + + + + Show advanced settings + Показать дополнительные настройки + + + + Custom: + Пользовательский: + + + + View angle + Угол зрения + + + + Position + Позиция + + + + Cover gap + Охватить разрыв + + + + Central gap + Сфокусировать разрыв + + + + Zoom + Масштабировать + + + + Y offset + Смещение по Y + + + + Z offset + Смещение по Z + + + + Cover Angle + Охватить угол + + + + Visibility + Прозрачность + + + + Light + Осветить + + + + Max angle + Максимальный угол + + + + Low Performance + Минимальная производительность + + + + High Performance + Максимальная производительность + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Использовать VSync (повысить качество изображения в полноэкранном режиме , хуже производительность) + + + Performance: Производительность: + + + YACReader::MainWindowViewer + + + &Open + &Открыть + + + + Open a comic + Открыть комикс + + + + New instance + Новый экземпляр + + + + Open Folder + Открыть папку + + + + Open image folder + Открыть папку с изображениями + + + + Open latest comic + Открыть последний комикс + + + + Open the latest comic opened in the previous reading session + Открыть комикс открытый в предыдущем сеансе чтения + + + + Clear + Очистить + + + + Clear open recent list + Очистить список недавно открытых файлов + + + + Save + Сохранить + + + + + Save current page + Сохранить текущию страницу + + + + Previous Comic + Предыдущий комикс + + + + + + Open previous comic + Открыть предыдуший комикс + + + + Next Comic + Следующий комикс + + + + + + Open next comic + Открыть следующий комикс + + + + &Previous + &Предыдущий + + + + + + Go to previous page + Перейти к предыдущей странице + + + + &Next + &Следующий + + + + + + Go to next page + Перейти к следующей странице + + + + Fit Height + Подогнать по высоте + + + + Fit image to height + Подогнать по высоте + + + + Fit Width + Подогнать по ширине + + + + Fit image to width + Подогнать по ширине + + + + Show full size + Показать в полном размере + + + + Fit to page + Подогнать под размер страницы + + + + Continuous scroll + Непрерывная прокрутка + + + + Switch to continuous scroll mode + Переключиться в режим непрерывной прокрутки + + + + Reset zoom + Сбросить масштаб + + + + Show zoom slider + Показать ползунок масштабирования + + + + Zoom+ + Увеличить масштаб + + + + Zoom- + Уменьшить масштаб + + + + Rotate image to the left + Повернуть изображение против часовой стрелки + + + + Rotate image to the right + Повернуть изображение по часовой стрелке + + + + Double page mode + Двухстраничный режим + + + + Switch to double page mode + Двухстраничный режим + + + + Double page manga mode + Двухстраничный режим манги + + + + Reverse reading order in double page mode + Двухстраничный режим манги + + + + Go To + Перейти к странице... + + + + Go to page ... + Перейти к странице... + + + + Options + Настройки + + + + YACReader options + Настройки + + + + + Help + Настройки + + + + Help, About YACReader + О программе + + + + Magnifying glass + Увеличительное стекло + + + + Switch Magnifying glass + Увеличительное стекло + + + + Set bookmark + Установить закладку + + + + Set a bookmark on the current page + Установить закладку на текущей странице + + + + Show bookmarks + Показать закладки + + + + Show the bookmarks of the current comic + Показать закладки в текущем комиксе + + + + Show keyboard shortcuts + Показать горячие клавиши + + + + Show Info + Показать/скрыть номер страницы и текущее время + + + + Close + Закрыть + + + + Show Dictionary + Переводчик YACreader + + + + Show go to flow + Показать поток страниц + + + + Edit shortcuts + Редактировать горячие клавиши + + + + &File + &Отображать панель инструментов + + + + + Open recent + Открыть недавние + + + + File + Файл + + + + Edit + Редактировать информацию + + + + View + Посмотреть + + + + Go + Перейти + + + + Window + Окно + + + + + + Open Comic + Открыть комикс + + + + + + Comic files + Файлы комикса + + + + Open folder + Открыть папку + + + + page_%1.jpg + страница_%1.jpg + + + + Image files (*.jpg) + Файлы изображений (*.jpg) + + + + + Comics + Комикс + + + + + General + Основные + + + + + Magnifiying glass + Увеличительное стекло + + + + + Page adjustement + Настройка страницы + + + + + Reading + Чтение + + + + Toggle fullscreen mode + Полноэкранный режим включить/выключить + + + + Hide/show toolbar + Показать/скрыть панель инструментов + + + + Size up magnifying glass + Увеличение размера окошка увеличительного стекла + + + + Size down magnifying glass + Уменьшение размера окошка увеличительного стекла + + + + Zoom in magnifying glass + Увеличить + + + + Zoom out magnifying glass + Уменьшить + + + + Reset magnifying glass + Сбросить увеличительное стекло + + + + Toggle between fit to width and fit to height + Переключение режима подгонки страницы по ширине/высоте + + + + Autoscroll down + Автопрокрутка вниз + + + + Autoscroll up + Автопрокрутка вверх + + + + Autoscroll forward, horizontal first + Автопрокрутка вперед, горизонтальная + + + + Autoscroll backward, horizontal first + Автопрокрутка назад, горизонтальная + + + + Autoscroll forward, vertical first + Автопрокрутка вперед, вертикальная + + + + Autoscroll backward, vertical first + Автопрокрутка назад, вертикальная + + + + Move down + Переместить вниз + + + + Move up + Переместить вверх + + + + Move left + Переместить влево + + + + Move right + Переместить вправо + + + + Go to the first page + Перейти к первой странице + + + + Go to the last page + Перейти к последней странице + + + + Offset double page to the left + Смещение разворота влево + + + + Offset double page to the right + Смещение разворота вправо + + + + There is a new version available + Доступна новая версия + + + + Do you want to download the new version? + Хотите загрузить новую версию ? + + + + Remind me in 14 days + Напомнить через 14 дней + + + + Not now + Не сейчас + + + + YACReader::TrayIconController + + + &Restore + &Rмагазин + + + + Systray + Систрей + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary продолжит работать в системном трее. Чтобы завершить работу программы, выберите <b>Quit</b> в контекстном меню значка на панели задач. + + + + YACReaderFieldEdit + + + Restore to default + Вернуть к первоначальным значениям + + + + + Click to overwrite + Изменить + + + + YACReaderFieldPlainTextEdit + + + Restore to default + Вернуть к первоначальным значениям + + + + + + + Click to overwrite + Изменить + + + + YACReaderFlowConfigWidget + + CoverFlow look + Рулеткой + + + How to show covers: + Выбрать внешний вид потока обложек: + + + Stripe look + Вид полосами + + + Overlapped Stripe look + Вид перекрывающимися полосами + + + + YACReaderGLFlowConfigWidget + + Zoom + Масштабировать + + + Light + Осветить + + + Show advanced settings + Показать дополнительные настройки + + + Roulette look + Вид рулеткой + + + Cover Angle + Охватить угол + + + Stripe look + Вид полосами + + + Position + Позиция + + + Z offset + Смещение по Z + + + Y offset + Смещение по Y + + + Central gap + Сфокусировать разрыв + + + Presets: + Предустановки: + + + Overlapped Stripe look + Вид перекрывающимися полосами + + + Modern look + Современный вид + + + View angle + Угол зрения + + + Max angle + Максимальный угол + + + Custom: + Пользовательский: + + + Classic look + Классический вид + + + Cover gap + Охватить разрыв + + + High Performance + Максимальная производительность + + + Performance: + Производительность: + - Use VSync (improve the image quality in fullscreen mode, worse performance) - Использовать VSync (повысить качество изображения в полноэкранном режиме , хуже производительность) + Использовать VSync (повысить качество изображения в полноэкранном режиме , хуже производительность) - Visibility - Прозрачность + Прозрачность - Low Performance - Минимальная производительность + Минимальная производительность YACReaderNavigationController - You are not reading anything yet, come on!! - Вы пока ничего не читаете. Может самое время почитать? - - - - There are no recent comics! - + Вы пока ничего не читаете. Может самое время почитать? - No favorites - Нет избранного + Нет избранного YACReaderOptionsDialog - + Save Сохранить - Use hardware acceleration (restart needed) - Использовать аппаратное ускорение (необходима перезагрузка) + Использовать аппаратное ускорение (необходима перезагрузка) - + Cancel Отмена - + Shortcuts Горячие клавиши - + Edit shortcuts Редактировать горячие клавиши @@ -2999,7 +4188,7 @@ to improve the performance YACReaderSearchLineEdit - + type to search Начать поиск @@ -3007,34 +4196,60 @@ to improve the performance YACReaderSideBar - Reading Lists - Списки чтения + Списки чтения - LIBRARIES - БИБЛИОТЕКИ + БИБЛИОТЕКИ - Libraries - Библиотеки + Библиотеки - FOLDERS - ПАПКИ + ПАПКИ - Folders - Папки + Папки - READING LISTS - СПИСКИ ЧТЕНИЯ + СПИСКИ ЧТЕНИЯ + + + + YACReaderSlider + + + Reset + Вернуть к первоначальным значениям + + + + YACReaderTranslator + + + YACReader translator + Переводчик YACReader + + + + + Translation + Перевод + + + + clear + очистить + + + + Service not available + Сервис недоступен diff --git a/YACReaderLibrary/yacreaderlibrary_source.ts b/YACReaderLibrary/yacreaderlibrary_source.ts index 17e29eea2..11890d95a 100644 --- a/YACReaderLibrary/yacreaderlibrary_source.ts +++ b/YACReaderLibrary/yacreaderlibrary_source.ts @@ -4,7 +4,7 @@ ActionsShortcutsModel - + None @@ -12,142 +12,217 @@ AddLabelDialog - + Label name: - + Choose a color: - - red + + accept - - orange + + cancel + + + AddLibraryDialog - - yellow + + Add - - green + + Add an existing library - - cyan + + Cancel - - blue + + Comics folder : - - violet + + Library name : + + + ApiKeyDialog - - purple + + Cancel - - pink + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - - white + + Paste here your Comic Vine API key - - light + + Accept + + + AppearanceTabWidget - - dark + + Color scheme - - accept + + System - - cancel + + Light - - - AddLibraryDialog - - Comics folder : + + Dark - - Library name : - Library Name : + + Custom - - Add + + Remove - - Cancel + + Remove this user-imported theme - - Add an existing library + + Light: + + + + + Dark: + + + + + Custom: + + + + + Import theme... + + + + + Theme + + + + + Theme editor + + + + + Open Theme Editor... + + + + + Theme editor error + + + + + The current theme JSON could not be loaded. + + + + + Import theme + + + + + JSON files (*.json);;All files (*) + + + + + Could not import theme from: +%1 + + + + + Could not import theme from: +%1 + +%2 + + + + + Import failed - ApiKeyDialog + BookmarksDialog - - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + + Lastest Page - - Paste here your Comic Vine API key + + Close - - Accept + + Click on any image to go to the bookmark - - Cancel + + + Loading... ClassicComicsView - + Hide comic flow @@ -155,108 +230,153 @@ ComicInfoView - + + Characters + + + + + Main character or team + + + + + Teams + + + + + Locations + + + + Authors - + writer - + penciller - + inker - + colorist - + letterer - + cover artist - - Publisher + + editor - - color + + imprint - - b/w + + Publisher - - Characters + + color + + + + + b/w ComicModel - + yes - + no - + Title - + File Name - + Pages - + Size - + Read - + Current Page - + + Publication Date + + + + Rating + + + Series + + + + + Volume + + + + + Story Arc + + ComicVineDialog @@ -287,85 +407,91 @@ - - - - + + Looking for volume... - - + + comic %1 of %2 - %3 - + %1 comics selected - + Error connecting to ComicVine - - + + Retrieving tags for : %1 - + Retrieving volume info... - + Looking for comic... + + ContinuousPageWidget + + + Loading page %1 + + + CreateLibraryDialog - - Comics folder : + + Create new library - - Library Name : + + Cancel - + Create - - Cancel + + Comics folder : - - Create a library could take several minutes. You can stop the process and update the library later for completing the task. + + Library Name : - - Create new library + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. - + Path not found - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder @@ -373,27 +499,27 @@ EditShortcutsDialog - + Restore defaults - + To change a shortcut, double click in the key combination and type the new keys. - + Shortcuts settings - + Shortcut in use - + The shortcut "%1" is already assigned to other function @@ -401,26 +527,15 @@ EmptyFolderWidget - - - Subfolders in this folder - - - - - Empty folder - - - - - Drag and drop folders and comics here + + This folder doesn't contain comics yet EmptyLabelWidget - + This label doesn't contain comics yet @@ -430,15 +545,32 @@ This reading list does not contain any comics yet - This reading list doesn't contain any comics yet + + + + + EmptySpecialListWidget + + + No favorites + + + + + You are not reading anything yet, come on!! + + + + + There are no recent comics! ExportComicsInfoDialog - - Output file : + + Cancel @@ -447,27 +579,27 @@ - - Cancel + + Output file : - + Export comics info - + Destination database name - + Problem found while writing - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder @@ -475,8 +607,8 @@ ExportLibraryDialog - - Output folder : + + Cancel @@ -485,33 +617,38 @@ - - Cancel + + Output folder : - + Create covers package - - Problem found while writing + + Destination directory - - The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + + Problem found while writing - - Destination directory + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder FileComic + + + 7z not found + + CRC error on page (%1): some of the pages will not be displayed correctly @@ -523,20 +660,60 @@ - - 7z not found + + Format not supported + + + FolderContentView - - Format not supported + + Continue Reading... + + + + + GoToDialog + + + Page : + + + + + Go To + + + + + Cancel + + + + + + Total pages : + + + + + Go to... + + + + + GoToFlowToolBar + + + Page : GridComicsView - + Show info @@ -544,18 +721,28 @@ HelpAboutDialog - + About - + Help + + + System info + + ImportComicsInfoDialog + + + Cancel + + Import comics info @@ -572,1687 +759,3115 @@ - - Cancel - - - - + Comics info file (*.ydb) ImportLibraryDialog - - - Library Name : - - - - - Package location : - - Destination folder : - - - Unpack - - Cancel - - Extract a catalog + + Unpack - + Compresed library covers (*.clc) - - - ImportWidget - + + Package location : + + + + + Library Name : + + + + + Extract a catalog + + + + + ImportWidget + + stop - + Some of the comics being added... - + Importing comics - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - + Updating the library - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> - + Upgrading the library - + <p>The current library is being upgraded, please wait.</p> + + + Scanning the library + + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + + LibraryWindow - - YACReader Library - + Remove current library from your collection + Remover biblioteca atual da sua coleção - + Library - - Create a new library - + Rename current library + Renomear biblioteca atual - - Open an existing library - + Open current comic on YACReader + Abrir quadrinho atual no YACReader - - - Export comics info - + Update current library + Atualizar biblioteca atual - - - Import comics info + + Open folder... - - Pack covers + + + + western manga (left to right) - - Pack the covers of the selected library + + + + 4koma (top to botom) + 4koma (top to botom - - Unpack covers + + Do you want remove - - Unpack a catalog - + Expand all nodes + Expandir todos - - Update library - + Show options dialog + Mostrar opções - - Update current library - + Create a new library + Criar uma nova biblioteca - - Rename library + + YACReader Library - - Rename current library - + Open an existing library + Abrir uma biblioteca existente - - Remove library - + Pack the covers of the selected library + Pacote de capas da biblioteca selecionada - - Remove current library from your collection + + + + manga - - Open current comic + + + + comic - - Open current comic on YACReader - + Help, About YACReader + Ajuda, Sobre o YACReader - - Save selected covers to... - + Select root node + Selecionar raiz - - Save covers of the selected comics as JPG files + Unpack a catalog + Desempacotar um catálogo + + + Open containing folder... + Abrir a pasta contendo... + + + + Are you sure? - - - Set as read + + Rescan library for XML info - - Set comic as read + + Set as read - - + + Set as unread - - Set comic as unread + + + + web comic - - Show/Hide marks + + Add new folder - - Collapse all nodes + + Delete folder - - Assign current order to comics + + Set as uncompleted - - Library not available - Library ' + + Set as completed - - - Fullscreen mode on/off + + Update folder - - - Set as manga + + Folder - - Set issue as manga + + Comic - - Set as normal + + Upgrade failed - - Set issue as normal + + There were errors during library upgrade in: - - Help, About YACReader + + Update needed - - - Delete folder + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? - - Select root node + + Download new version - - Expand all nodes + + This library was created with a newer version of YACReaderLibrary. Download the new version now? - - Show options dialog + + Library not available - - Show comics server options dialog + + Library '%1' is no longer available. Do you want to remove it? - - Open folder... + + Old library - - Set as uncompleted + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - - Set as completed + + + Copying comics... - - Set as comic + + + Moving comics... - - Open containing folder... + + Folder name: - - Reset comic rating + + No folder selected - - Select all comics + + Please, select a folder first - - Edit + + Error in path - - Update cover + + There was an error accessing the folder's path - - Delete selected comics + + The selected folder and all its contents will be deleted from your disk. Are you sure? - - Download tags from Comic Vine + + + Unable to delete - - Edit shortcuts + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - - Update folder + + Add new reading lists - - Update current folder + + + List name: - - Add new reading list + + Delete list/label - - Add a new reading list to the current library + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - - Remove reading list + + Rename list name - - Remove current reading list from the library + + + + + Set type - - Add new label + + Set custom cover - - Add a new label to this library + + Delete custom cover - - Rename selected list + + Save covers - - Rename any selected labels or lists + + You are adding too many libraries. - - Add to... + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - - Favorites + + + YACReader not found - - Add selected comics to favorites list + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. - - Folder + + YACReader not found. There might be a problem with your YACReader installation. - - Comic + + Error - - Upgrade failed + + Error opening comic with third party reader. - - There were errors during library upgrade in: + + Library not found - - Update needed + + The selected folder doesn't contain any library. - - This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + + library? - - Download new version + + Remove and delete metadata - - This library was created with a newer version of YACReaderLibrary. Download the new version now? + + Library info - - Library '%1' is no longer available. Do you want to remove it? + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - - Old library + + Assign comics numbers - - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + + Assign numbers starting in: - - - Copying comics... + + Invalid image - - - Moving comics... + + The selected file is not a valid image. - - Folder name: + + Error saving cover - - No folder selected + + There was an error saving the cover image. - - Please, select a folder first + + Error creating the library - - Error in path + + Error updating the library - - There was an error accessing the folder's path + + Error opening the library - - The selected folder and all its contents will be deleted from your disk. Are you sure? + + Delete comics - - There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + + All the selected comics will be deleted from your disk. Are you sure? - - Add new reading lists + + Remove comics - - - List name: + + Comics will only be deleted from the current label/list. Are you sure? - - Delete list/label + + Library name already exists - - The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + + There is another library with the name '%1'. + + + LibraryWindowActions - - Rename list name + + Create a new library - - Save covers + + Open an existing library - - You are adding too many libraries. + + + Export comics info - - You are adding too many libraries. - -You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. - -YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + + + Import comics info - - - YACReader not found + + Pack covers - - Library not found + + Pack the covers of the selected library - - The selected folder doesn't contain any library. + + Unpack covers - - Are you sure? + + Unpack a catalog - - Do you want remove + + Update library - - library? + + Update current library - - Remove and delete metadata + + Rename library - - Assign comics numbers + + Rename current library - - Assign numbers starting in: + + Remove library - - - Unable to delete + + Remove current library from your collection - - Show or hide read marks + + Rescan library for XML info - - - Add new folder + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. - - Add new folder to the current library + + Show library info - - Delete current folder from disk + + Show information about the current library - - - Change between comics views + + Open current comic - - YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + + Open current comic on YACReader - - YACReader not found. There might be a problem with your YACReader installation. + + Save selected covers to... - - There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + + Save covers of the selected comics as JPG files - - Error creating the library + + + Set as read - - Error updating the library + + Set comic as read - - Error opening the library + + + Set as unread - - Delete comics + + Set comic as unread - - All the selected comics will be deleted from your disk. Are you sure? + + + manga - - Remove comics + + Set issue as manga - - Comics will only be deleted from the current label/list. Are you sure? + + + comic - - Library name already exists + + Set issue as normal + + + + + western manga + + + + + Set issue as western manga + + + + + + web comic + + + + + Set issue as web comic + + + + + + yonkoma + + + + + Set issue as yonkoma + + + + + Show/Hide marks + + + + + Show or hide read marks + + + + + Show/Hide recent indicator + + + + + Show or hide recent indicator + + + + + + Fullscreen mode on/off + + + + + Help, About YACReader + + + + + Add new folder + + + + + Add new folder to the current library + + + + + Delete folder + + + + + Delete current folder from disk + + + + + Select root node + + + + + Expand all nodes + + + + + Collapse all nodes + + + + + Show options dialog + + + + + Show comics server options dialog + + + + + + Change between comics views + + + + + Open folder... + + + + + Set as uncompleted + + + + + Set as completed + + + + + Set custom cover + + + + + Delete custom cover + + + + + western manga (left to right) + + + + + Open containing folder... + + + + + Reset comic rating + + + + + Select all comics + + + + + Edit + + + + + Assign current order to comics + + + + + Update cover + + + + + Delete selected comics + + + + + Delete metadata from selected comics + + + + + Download tags from Comic Vine + + + + + Focus search line + + + + + Focus comics view + + + + + Edit shortcuts + + + + + &Quit + + + + + Update folder + + + + + Update current folder + + + + + Scan legacy XML metadata + + + + + Add new reading list + + + + + Add a new reading list to the current library + + + + + Remove reading list + + + + + Remove current reading list from the library + + + + + Add new label + + + + + Add a new label to this library + + + + + Rename selected list + + + + + Rename any selected labels or lists + + + + + Add to... + + + + + Favorites + + + + + Add selected comics to favorites list + + + + + LocalComicListModel + + + file name + + + + + NoLibrariesWidget + + + You don't have any libraries yet + + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + + + + + create your first library + + + + + add an existing one + + + + + NoSearchResultsWidget + + + No results + + + + + OptionsDialog + + + + Language + + + + + + Application language + + + + + + System default + + + + + Tray icon settings (experimental) + + + + + Close to tray + + + + + Start into the system tray + + + + + Edit Comic Vine API key + + + + + Comic Vine API key + + + + + ComicInfo.xml legacy support + + + + + Import metadata from ComicInfo.xml when adding new comics + Import metada from ComicInfo.xml when adding new comics + + + + + Consider 'recent' items added or updated since X days ago + + + + + Third party reader + + + + + Write {comic_file_path} where the path should go in the command + + + + + + Clear + + + + + Update libraries at startup + + + + + Try to detect changes automatically + + + + + Update libraries periodically + + + + + Interval: + + + + + 30 minutes + + + + + 1 hour + + + + + 2 hours + + + + + 4 hours + + + + + 8 hours + + + + + 12 hours + + + + + daily + + + + + Update libraries at certain time + + + + + Time: + + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +To stop an automatic update tap on the loading indicator next to the Libraries title. + + + + + Modifications detection + + + + + Compare the modified date of files when updating a library (not recommended) + + + + + Enable background image + + + + + Opacity level + + + + + Blur level + + + + + Use selected comic cover as background + + + + + Restore defautls + + + + + Background + + + + + Display continue reading banner + + + + + Display current comic banner + + + + + Continue reading + + + + + Comic Flow + + + + + + Libraries + + + + + Grid view + + + + + + General + + + + + + Appearance + + + + + + Options + + + + + My comics path + + + + + Display + + + + + Show time in current page information label + + + + + "Go to flow" size + + + + + Background color + + + + + Choose + + + + + Scroll behaviour + + + + + Disable scroll animations and smooth scrolling + + + + + Do not turn page using scroll + + + + + Use single scroll step to turn page + + + + + Mouse mode + + + + + Only Back/Forward buttons can turn pages + + + + + Use the Left/Right buttons to turn pages. + + + + + Click left or right half of the screen to turn pages. + + + + + Quick Navigation Mode + + + + + Disable mouse over activation + + + + + Brightness + + + + + Contrast + + + + + Gamma + + + + + Reset + + + + + Image options + + + + + Fit options + + + + + Enlarge images to fit width/height + + + + + Double Page options + + + + + Show covers as single page + + + + + Scaling + + + + + Scaling method + + + + + Nearest (fast, low quality) + + + + + Bilinear + + + + + Lanczos (better quality) + + + + + Page Flow + + + + + Image adjustment + + + + + + Restart is needed + + + + + Comics directory + + + + + PropertiesDialog + + + General info + + + + + Authors + + + + + Publishing + + + + + Plot + + + + + Notes + + + + + Cover page + + + + + Load previous page as cover + + + + + Load next page as cover + + + + + Reset cover to the default image + + + + + Load custom cover image + + + + + Series: + + + + + Title: + + + + + + + of: + + + + + Issue number: + + + + + Volume: + + + + + Arc number: + + + + + Story arc: + + + + + alt. number: + + + + + Alternate series: + + + + + Series Group: + + + + + Genre: + + + + + Size: + + + + + Writer(s): + + + + + Penciller(s): + + + + + Inker(s): + + + + + Colorist(s): + + + + + Letterer(s): + + + + + Cover Artist(s): + + + + + Editor(s): + + + + + Imprint: + + + + + Day: + + + + + Month: + + + + + Year: + + + + + Publisher: + + + + + Format: + + + + + Color/BW: + + + + + Age rating: + + + + + Type: + + + + + Language (ISO): + + + + + Synopsis: + + + + + Characters: + + + + + Teams: + + + + + Locations: + + + + + Main character or team: + + + + + Review: + + + + + Notes: + + + + + Tags: + + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + + + + + Not found + + + + + Comic not found. You should update your library. + + + + + Edit selected comics information + + + + + Invalid cover + + + + + The image is invalid. + + + + + Edit comic information + + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + + QObject + + + 7z lib not found + + + + + unable to load 7z lib from ./utils + + + + + Trace + + + + + Debug + + + + + Info + + + + + Warning + + + + + Error + + + + + Fatal + + + + + Select custom cover + + + + + Images (%1) + + + + + The file could not be read or is not valid JSON. + + + + + This theme is for %1, not %2. + + + + + Libraries + + + + + Folders + + + + + Reading Lists + + + + + RenameLibraryDialog + + + Rename current library + + + + + Cancel + + + + + Rename + + + + + New Library Name : + + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + + + + + + page %1 of %2 + + + + + Number of %1 found : %2 + + + + + SearchSingleComic + + + Please provide some additional information for this comic. + Please provide some additional information. + + + + + Series: + + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + + + + + SearchVolume + + + Please provide some additional information. + + + + + Series: + + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + + + + + SelectComic + + + Please, select the right comic info. + + + + + comics + + + + + loading cover + + + + + loading description + + + + + comic description unavailable + + + + + SelectVolume + + + Please, select the right series for your comic. + + + + + Filter: + + + + + volumes - - There is another library with the name '%1'. + + Nothing found, clear the filter if any. + + + + + loading cover + + + + + loading description + + + + + volume description unavailable - LocalComicListModel + SeriesQuestion - - file name + + You are trying to get information for various comics at once, are they part of the same series? + + + + + yes + + + + + no - LogWindow + ServerConfigDialog - - Log window + + set port - - &Pause + + Server connectivity information - - &Save + + Scan it! - - C&lear + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - - &Copy + + Choose an IP address - - Level: + + Port - - &Auto scroll + + enable the server - NoLibrariesWidget + SortVolumeComics - - You don't have any libraries yet + + Please, sort the list of comics on the left until it matches the comics' information. - - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + + sort comics to match comic information - - create your first library + + issues - - add an existing one + + remove selected comics + + + + + restore all removed comics - OptionsDialog + ThemeEditorDialog - - Tray icon settings (experimental) + + Theme Editor - - Close to tray + + + - - Start into the system tray + + - - - Edit Comic Vine API key + + i - - Comic Vine API key + + Expand all - - Enable background image + + Collapse all - - Opacity level + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - - Blur level + + Search… - - Use selected comic cover as background + + Light - - Restore defautls + + Dark - - Background + + ID: - - Display continue reading banner + + Display name: - - Continue reading + + Variant: - - Comic Flow + + Theme info - - Grid view + + Parameter - - General + + Value - - Options + + Save and apply + + + + + Export to file... + + + + + Load from file... + + + + + Close + + + + + Double-click to edit color + + + + + + + + + + true + + + + + + + + false + + + + + Double-click to toggle + + + + + Double-click to edit value + + + + + + + Edit: %1 + + + + + Save theme + + + + + + JSON files (*.json);;All files (*) + + + + + Save failed + + + + + Could not open file for writing: +%1 + + + + + Load theme + + + + + + + Load failed + + + + + Could not open file: +%1 + + + + + Invalid JSON: +%1 + + + + + Expected a JSON object. - PropertiesDialog + TitleHeader - - General info + + SEARCH + + + UpdateLibraryDialog - - Authors + + Cancel - - Publishing + + Updating.... - - Plot + + Update library + + + Viewer - - Cover page + + + Press 'O' to open comic. - - Title: + + Not found - - - of: + + Comic not found - - Issue number: + + Error opening comic - - Volume: + + CRC Error - - Arc number: + + Loading...please wait! - - Story arc: + + Page not available! - - Genre: - Genere: + + Cover! - - Size: + + Last page! + + + VolumeComicsModel - - Writer(s): + + title + + + VolumesModel - - Penciller(s): + + year - - Inker(s): + + issues - - Colorist(s): + + publisher + + + YACReader3DFlowConfigWidget - - Letterer(s): + + Presets: - - Cover Artist(s): + + Classic look - - Day: + + Stripe look - - Month: + + Overlapped Stripe look - - Year: + + Modern look + + + + + Roulette look + + + + + Show advanced settings + + + + + Custom: + + + + + View angle + + + + + Position + + + + + Cover gap + + + + + Central gap + + + + + Zoom + + + + + Y offset + + + + + Z offset + + + + + Cover Angle + + + + + Visibility + + + + + Light + + + + + Max angle + + + + + Low Performance + + + + + High Performance + + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) - - Publisher: + + Performance: + + + YACReader::MainWindowViewer - - Format: + + &Open - - Color/BW: + + Open a comic - - Age rating: + + New instance - - Manga: + + Open Folder - - Synopsis: + + Open image folder - - Characters: + + Open latest comic - - Notes: + + Open the latest comic opened in the previous reading session - - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + + Clear - - Not found + + Clear open recent list - - Comic not found. You should update your library. + + Save - - Edit selected comics information + + + Save current page - - Edit comic information + + Previous Comic - - - QObject - - 7z lib not found + + + + Open previous comic - - unable to load 7z lib from ./utils + + Next Comic - - Trace + + + + Open next comic - - Debug + + &Previous - - Info + + + + Go to previous page - - Warning + + &Next - - Error + + + + Go to next page - - Fatal + + Fit Height - - - QsLogging::LogWindowModel - - Time + + Fit image to height - - Level + + Fit Width - - Message + + Fit image to width - - - QsLogging::Window - - &Pause + + Show full size - - &Resume + + Fit to page - - Save log + + Continuous scroll - - Log file (*.log) + + Switch to continuous scroll mode - - - RenameLibraryDialog - - New Library Name : + + Reset zoom - - Rename + + Show zoom slider - - Cancel + + Zoom+ - - Rename current library + + Zoom- - - - ScraperResultsPaginator - - Number of volumes found : %1 + + Rotate image to the left - - - page %1 of %2 + + Rotate image to the right - - Number of %1 found : %2 + + Double page mode - - - SearchSingleComic - - Please provide some additional information. + + Switch to double page mode - - Series: + + Double page manga mode - - - SearchVolume - - Please provide some additional information. + + Reverse reading order in double page mode - - Series: + + Go To - - - SelectComic - - Please, select the right comic info. + + Go to page ... - - comics + + Options - - loading cover + + YACReader options - - loading description + + + Help - - description unavailable + + Help, About YACReader - - - SelectVolume - - Please, select the right series for your comic. + + Magnifying glass - - volumes + + Switch Magnifying glass - - loading cover + + Set bookmark - - loading description + + Set a bookmark on the current page - - description unavailable + + Show bookmarks - - - SeriesQuestion - - You are trying to get information for various comics at once, are they part of the same series? + + Show the bookmarks of the current comic - - yes + + Show keyboard shortcuts - - no + + Show Info - - - ServerConfigDialog - - set port + + Close - - Server connectivity information + + Show Dictionary - - Scan it! + + Show go to flow - - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> + + Edit shortcuts - - Choose an IP address + + &File - - Port + + + Open recent - - enable the server + + File - - display less information about folders in the browser -to improve the performance + + Edit - - Could not load libqrencode. + + View - - - SortVolumeComics - - Please, sort the list of comics on the left until it matches the comics' information. + + Go - - sort comics to match comic information + + Window - - issues + + + + Open Comic - - remove selected comics + + + + Comic files - - restore all removed comics + + Open folder - - - TitleHeader - - SEARCH + + page_%1.jpg - - - UpdateLibraryDialog - - Updating.... + + Image files (*.jpg) - - Cancel + + + Comics - - Update library + + + General - - - VolumeComicsModel - - title + + + Magnifiying glass - - - VolumesModel - - year + + + Page adjustement - - issues + + + Reading - - publisher + + Toggle fullscreen mode - - - YACReader::TrayIconController - - &Restore + + Hide/show toolbar - - &Quit + + Size up magnifying glass - - Systray + + Size down magnifying glass - - YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + + Zoom in magnifying glass - - - YACReader::WhatsNewDialog - - Close + + Zoom out magnifying glass - - - YACReaderFieldEdit - - - Click to overwrite + + Reset magnifying glass - - Restore to default + + Toggle between fit to width and fit to height - - - YACReaderFieldPlainTextEdit - - - - - Click to overwrite + + Autoscroll down - - Restore to default + + Autoscroll up - - - YACReaderFlowConfigWidget - - How to show covers: + + Autoscroll forward, horizontal first - - CoverFlow look + + Autoscroll backward, horizontal first - - Stripe look + + Autoscroll forward, vertical first - - Overlapped Stripe look + + Autoscroll backward, vertical first - - - YACReaderGLFlowConfigWidget - - Presets: + + Move down - - Classic look + + Move up - - Stripe look + + Move left - - Overlapped Stripe look + + Move right - - Modern look + + Go to the first page - - Roulette look + + Go to the last page - - Show advanced settings + + Offset double page to the left - - Custom: + + Offset double page to the right - - View angle + + There is a new version available - - Position + + Do you want to download the new version? - - Cover gap + + Remind me in 14 days - - Central gap + + Not now + + + YACReader::TrayIconController - - Zoom + + &Restore - - Y offset + + Systray - - Z offset + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + + + YACReaderFieldEdit - - Cover Angle + + + Click to overwrite - - Visibility + + Restore to default + + + YACReaderFieldPlainTextEdit - - Light + + + + + Click to overwrite - - Max angle + + Restore to default + + + YACReaderFlowConfigWidget - - Low Performance - + CoverFlow look + Olhar capa cheia - - High Performance - + How to show covers: + Como mostrar capas: - - Use VSync (improve the image quality in fullscreen mode, worse performance) - + Stripe look + Olhar lista - - Performance: - + Overlapped Stripe look + Olhar lista sobreposta - YACReaderNavigationController + YACReaderGLFlowConfigWidget - - No favorites - + Stripe look + Olhar lista - - You are not reading anything yet, come on!! - + Overlapped Stripe look + Olhar lista sobreposta YACReaderOptionsDialog - + Save - + Cancel - + Edit shortcuts - + Shortcuts - - - Use hardware acceleration (restart needed) - - YACReaderSearchLineEdit - + type to search - YACReaderSideBar + YACReaderSlider - - Libraries - - - - - Folders + + Reset + + + YACReaderTranslator - - Reading Lists + + YACReader translator - - LIBRARIES + + + Translation - - FOLDERS + + clear - - READING LISTS + + Service not available diff --git a/YACReaderLibrary/yacreaderlibrary_tr.ts b/YACReaderLibrary/yacreaderlibrary_tr.ts index 04e56a168..0339a9641 100644 --- a/YACReaderLibrary/yacreaderlibrary_tr.ts +++ b/YACReaderLibrary/yacreaderlibrary_tr.ts @@ -12,82 +12,70 @@ AddLabelDialog - + cancel vazgeç - + Label name: Etiket adı: - + Choose a color: Renk seçiniz: - red - kırmızı + kırmızı - orange - turuncu + turuncu - yellow - sarı + sarı - green - yeşil + yeşil - cyan - camgöbeği + camgöbeği - blue - mavi + mavi - violet - menekşe + menekşe - purple - mor + mor - pink - pembe + pembe - white - beyaz + beyaz - light - açık + açık - dark - koyu + koyu - + accept kabul et @@ -100,7 +88,7 @@ Ekle - + Add an existing library Kütüphaneye ekle @@ -143,10 +131,150 @@ Kabul et + + AppearanceTabWidget + + + Color scheme + Renk şeması + + + + System + Sistem + + + + Light + Işık + + + + Dark + Karanlık + + + + Custom + Gelenek + + + + Remove + Kaldırmak + + + + Remove this user-imported theme + Kullanıcı tarafından içe aktarılan bu temayı kaldır + + + + Light: + Işık: + + + + Dark: + Karanlık: + + + + Custom: + Kişisel: + + + + Import theme... + Temayı içe aktar... + + + + Theme + Tema + + + + Theme editor + Tema düzenleyici + + + + Open Theme Editor... + Tema Düzenleyiciyi Aç... + + + + Theme editor error + Tema düzenleyici hatası + + + + The current theme JSON could not be loaded. + Geçerli tema JSON yüklenemedi. + + + + Import theme + Temayı içe aktar + + + + JSON files (*.json);;All files (*) + JSON dosyaları (*.json);;Tüm dosyalar (*) + + + + Could not import theme from: +%1 + Tema şu kaynaktan içe aktarılamadı: +%1 + + + + Could not import theme from: +%1 + +%2 + Tema şu kaynaktan içe aktarılamadı: +%1 + +%2 + + + + Import failed + İçe aktarma başarısız oldu + + + + BookmarksDialog + + + Lastest Page + Son Sayfa + + + + Close + Kapat + + + + Click on any image to go to the bookmark + Yer imine git + + + + + Loading... + Yükleniyor... + + ClassicComicsView - + Hide comic flow Çizgi roman akışını gizle @@ -154,82 +282,82 @@ ComicInfoView - + Main character or team - + Ana karakter veya takım - + Teams - + Takımlar - + Locations - + Konumlar - + Authors Yazarlar - + writer yazar - + penciller - kalemci + çizer - + inker - mürekkepçi + mürekkepleyen - + colorist renklendiren - + letterer - metinlendiren + harflendiren - + cover artist - kapak sanatçısı + kapak çizeri - + editor - + editör - + imprint - + yayın markası - + Publisher - Yayıncı + Yayınevi - + color renk - + b/w s/b - + Characters Karakterler @@ -279,7 +407,7 @@ Publication Date - + Yayın Tarihi @@ -289,90 +417,98 @@ Series - + Seri Volume - + Hacim Story Arc - + Hikaye Arkı ComicVineDialog - + skip geç - + back geri - + next sonraki - + search ara - + close kapat - - - + + + Looking for volume... Sayılar aranıyor... - - + + comic %1 of %2 - %3 çizgi roman %1 / %2 - %3 - + %1 comics selected %1 çizgi roman seçildi - + Error connecting to ComicVine ComicVine sitesine bağlanılırken hata - - + + Retrieving tags for : %1 %1 için etiketler alınıyor - + Retrieving volume info... Sayı bilgileri alınıyor... - + Looking for comic... Çizgi romanlar aranıyor... + + ContinuousPageWidget + + + Loading page %1 + %1 sayfası yükleniyor + + CreateLibraryDialog - + Create new library Yeni kütüphane oluştur @@ -392,7 +528,7 @@ Yeni kütüphanenin oluşturulması birkaç dakika sürecek. - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder Seçilen dizine yazma iznimiz yok yazma izni olduğundan emin ol @@ -407,7 +543,7 @@ Kütüphane Adı : - + Path not found Dizin bulunamadı @@ -430,12 +566,12 @@ Kısayol ayarları - + Shortcut in use Kısayol kullanımda - + The shortcut "%1" is already assigned to other function "%1" kısayalou zaten başka bir işlev tarafından kullanılıyor @@ -443,26 +579,27 @@ EmptyFolderWidget - - Subfolders in this folder - Bu klasörde alt klasörler + Bu klasörde alt klasörler - Empty folder - Boş klasör + Boş klasör - Drag and drop folders and comics here - Klasörleri ve çizgi romanları sürükleyip buraya bırakın + Klasörleri ve çizgi romanları sürükleyip buraya bırakın + + + + This folder doesn't contain comics yet + Bu klasör henüz çizgi roman içermiyor EmptyLabelWidget - + This label doesn't contain comics yet Bu etiket henüz çizgi roman içermiyor @@ -475,6 +612,24 @@ Bu okuma listesi henüz çizgi roman içermiyor + + EmptySpecialListWidget + + + No favorites + Favoriler boş + + + + You are not reading anything yet, come on!! + Henüz bir şey okumuyorsun, hadi ama! + + + + There are no recent comics! + Yeni çizgi roman yok! + + ExportComicsInfoDialog @@ -483,7 +638,7 @@ Çıkış dosyası : - + Destination database name Hedef adı @@ -498,17 +653,17 @@ Oluştur - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder Seçilen dizine yazma iznimiz yok yazma izni olduğundan emin ol - + Export comics info Çizgi roman bilgilerini göster - + Problem found while writing Yazma sırasında bir problem oldu @@ -526,7 +681,7 @@ Yeni bir tane yap - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder Seçilen konuma yeni bir kütüphane yazılamıyor @@ -536,17 +691,17 @@ Çıktı klasörü : - + Problem found while writing Yazım aşamasında bir problem bulundu - + Create covers package Kapak paketi oluştur - + Destination directory Hedef dizin @@ -577,23 +732,52 @@ FolderContentView - + Continue Reading... - + Okumaya Devam Et... - FolderContentView6 + GoToDialog - - Continue Reading... - + + Page : + Sayfa : + + + + Go To + Git + + + + Cancel + Vazgeç + + + + + Total pages : + Toplam sayfa: + + + + Go to... + Git... + + + + GoToFlowToolBar + + + Page : + Sayfa : GridComicsView - + Show info Bilgi göster @@ -601,17 +785,17 @@ HelpAboutDialog - + Help Yardım - + System info - + Sistem bilgisi - + About Hakkında @@ -639,7 +823,7 @@ Çizgi roman bilgilerini çıkart - + Comics info file (*.ydb) Çizgi roman bilgi dosyası (*.ydb) @@ -662,7 +846,7 @@ Paketten çıkar - + Compresed library covers (*.clc) Sıkıştırılmış kütüphane kapakları (*.clc) @@ -677,7 +861,7 @@ Kütüphane Adı : - + Extract a catalog Katalog ayıkla @@ -685,54 +869,54 @@ ImportWidget - + stop dur - + Importing comics önemli çizgi romanlar - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> <p>YACReaderKütüphane şu anda yeni bir kütüphane oluşturuyor</p><p>Kütüphanenin oluşturulması birkaç dakika alacak.</p> - + Some of the comics being added... Bazı çizgi romanlar önceden eklenmiş... - + Updating the library Kütüphaneyi güncelle - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> <p>Kütüphane güncelleniyor</p><p>Güncellemeyi daha sonra iptal edebilirsin.</p> - + Upgrading the library Kütüphane güncelleniyor - + <p>The current library is being upgraded, please wait.</p> <p>Mevcut kütüphane güncelleniyor, lütfen bekleyin.</p> - + Scanning the library - + Kütüphaneyi taramak - + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> - + <p>Geçerli kitaplık, eski XML meta veri bilgileri için taranıyor.</p><p>Bu yalnızca bir kez gereklidir ve yalnızca kitaplığın YACReaderLibrary 9.8.2 veya daha eski bir sürümle oluşturulmuş olması durumunda gereklidir.</p> @@ -742,17 +926,17 @@ Düzenle - + The selected folder doesn't contain any library. Seçilen dosya kütüphanede yok. - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? Bu kütüphane YACReaderKütüphabenin bir önceki versiyonun oluşturulmuş, güncellemeye ihtiyacın var. Şimdi güncellemek ister misin ? - + Error opening the library Haa kütüphanesini aç @@ -773,12 +957,12 @@ Çizgi romanı okundu olarak işaretle - + Remove and delete metadata Metadata'yı kaldır ve sil - + Old library Eski kütüphane @@ -787,7 +971,7 @@ Kapağı güncelle - + Library Kütüphane @@ -800,7 +984,7 @@ Tam ekran modu açık/kapalı - + This library was created with a newer version of YACReaderLibrary. Download the new version now? Bu kütüphane YACRKütüphanenin üst bir versiyonunda oluşturulmu. Yeni versiyonu indirmek ister misiniz ? @@ -814,7 +998,7 @@ Kütüphaneyi güncelle - + Library '%1' is no longer available. Do you want to remove it? Kütüphane '%1'ulaşılabilir değil. Kaldırmak ister misin? @@ -823,17 +1007,17 @@ Kütüphaneyi güncelle - + Open folder... Dosyayı aç... - + Do you want remove Kaldırmak ister misin - + Error updating the library Kütüphane güncelleme sorunu @@ -842,7 +1026,7 @@ Tüm düğümleri büyüt - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? Kütüphane '%1 YACRKütüphanenin eski bir sürümünde oluşturulmuş, Kütüphaneyi yeniden oluşturmak ister misin? @@ -851,7 +1035,7 @@ Paket kapakları - + Set as read Okundu olarak işaretle @@ -872,7 +1056,7 @@ Yeni kütüphane oluştur - + Library not available Kütüphane ulaşılabilir değil @@ -885,12 +1069,12 @@ Seçili çizgi romanı aç - + YACReader Library YACReader Kütüphane - + Error creating the library Kütüphane oluşturma sorunu @@ -899,7 +1083,7 @@ Kapakları aç - + Update needed Güncelleme gerekli @@ -908,22 +1092,22 @@ Çıkış kütüphanesini aç - + Library name already exists Kütüphane ismi zaten alınmış - + There is another library with the name '%1'. Bu başka bir kütüphanenin adı '%1'. - + Download new version Yeni versiyonu indir - + Delete comics Çizgi romanları sil @@ -952,18 +1136,18 @@ Kataloğu çkart - + All the selected comics will be deleted from your disk. Are you sure? Seçilen tüm çizgi romanlar diskten silinecek emin misin ? - - + + Set as unread Hepsini okunmadı işaretle - + Library not found Kütüphane bulunamadı @@ -976,45 +1160,45 @@ Kütüphaneyi sil - - - + + + manga - + manga t?r? - - - + + + comic - + komik - - - + + + western manga (left to right) - + Batı mangası (soldan sağa) Open containing folder... Klasör açılıyor... - - - + + + 4koma (top to botom) 4koma (top to botom - + 4koma (yukarıdan aşağıya) - + library? kütüphane? - + Are you sure? Emin misin? @@ -1023,9 +1207,9 @@ Seçilen kapakları şuraya kaydet... - + Rescan library for XML info - + XML bilgisi için kitaplığı yeniden tarayın Save covers of the selected comics as JPG files @@ -1048,18 +1232,18 @@ Sayıyı normal olarak ayarla - - - + + + web comic - + web çizgi romanı Show or hide read marks Okundu işaretlerini göster yada gizle - + Add new folder Yeni klasör ekle @@ -1068,7 +1252,7 @@ Geçerli kitaplığa yeni klasör ekle - + Delete folder Klasörü sil @@ -1085,12 +1269,12 @@ Çizgi roman görünümleri arasında değiştir - + Set as uncompleted Tamamlanmamış olarak ayarla - + Set as completed Tamamlanmış olarak ayarla @@ -1119,7 +1303,7 @@ &Çıkış - + Update folder Klasörü güncelle @@ -1172,134 +1356,134 @@ Seçilen çizgi romanları favoriler listesine ekle - + Folder Klasör - + Comic Çizgi roman - + Upgrade failed Yükseltme başarısız oldu - + There were errors during library upgrade in: Kütüphane yükseltmesi sırasında hatalar oluştu: - - + + Copying comics... Çizgi romanlar kopyalanıyor... - - + + Moving comics... Çizgi romanlar taşınıyor... - + Folder name: Klasör adı: - + No folder selected Hiçbir klasör seçilmedi - + Please, select a folder first Lütfen, önce bir klasör seçiniz - + Error in path Yolda hata - + There was an error accessing the folder's path Klasörün yoluna erişilirken hata oluştu - + The selected folder and all its contents will be deleted from your disk. Are you sure? Seçilen klasör ve tüm içeriği diskinizden silinecek. Emin misin? - - + + Unable to delete Silinemedi - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. Seçili klasörleri silmeye çalışırken bir sorun oluştu. Lütfen yazma izinlerini kontrol edin ve herhangi bir uygulamanın bu klasörleri veya içerdiği dosyalardan herhangi birini kullandığından emin olun. - + Add new reading lists Yeni okuma listeleri ekle - - + + List name: Liste adı: - + Delete list/label Listeyi/Etiketi sil - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? Seçilen öğe silinecek, çizgi romanlarınız veya klasörleriniz diskinizden SİLİNMEYECEKTİR. Emin misin? - + Rename list name Listeyi yeniden adlandır - - - - + + + + Set type - + Türü ayarla - + Set custom cover - + Özel kapak ayarla - + Delete custom cover - + Özel kapağı sil - + Save covers Kapakları kaydet - + You are adding too many libraries. Çok fazla kütüphane ekliyorsunuz. - + You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. @@ -1312,78 +1496,78 @@ Muhtemelen üst düzey çizgi roman klasörünüzde yalnızca bir kütüphaneye YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütüphane sayısını düşük tutmalısınız. - - + + YACReader not found YACReader bulunamadı - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. YACReader bulunamadı. YACReader, YACReaderLibrary ile aynı klasöre kurulmalıdır. - + YACReader not found. There might be a problem with your YACReader installation. YACReader bulunamadı. YACReader kurulumunuzda bir sorun olabilir. - + Error - Hata + Hata - + Error opening comic with third party reader. - + Çizgi roman üçüncü taraf okuyucuyla açılırken hata oluştu. - + Library info - + Kütüphane bilgisi - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. Seçilen çizgi romanlar silinmeye çalışılırken bir sorun oluştu. Lütfen seçilen dosyalarda veya klasörleri içeren yazma izinlerini kontrol edin. - + Assign comics numbers Çizgi roman numaraları ata - + Assign numbers starting in: Şunlardan başlayarak numaralar ata: - + Invalid image - + Geçersiz resim - + The selected file is not a valid image. - + Seçilen dosya geçerli bir resim değil. - + Error saving cover - + Kapak kaydedilirken hata oluştu - + There was an error saving the cover image. - + Kapak resmi kaydedilirken bir hata oluştu. - + Remove comics Çizgi romanları kaldır - + Comics will only be deleted from the current label/list. Are you sure? Çizgi romanlar yalnızca mevcut etiketten/listeden silinecektir. Emin misin? @@ -1391,439 +1575,439 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü LibraryWindowActions - + Create a new library - Yeni kütüphane oluştur + Yeni kütüphane oluştur - + Open an existing library - Çıkış kütüphanesini aç + Çıkış kütüphanesini aç - - + + Export comics info - + Çizgi roman bilgilerini göster - - + + Import comics info - + Çizgi roman bilgilerini çıkart - + Pack covers - Paket kapakları + Paket kapakları - + Pack the covers of the selected library - Kütüphanede ki kapakları paketle + Kütüphanede ki kapakları paketle - + Unpack covers - Kapakları aç + Kapakları aç - + Unpack a catalog - Kataloğu çkart + Kataloğu çkart - + Update library - Kütüphaneyi güncelle + Kütüphaneyi güncelle - + Update current library - Kütüphaneyi güncelle + Kütüphaneyi güncelle - + Rename library - Kütüphaneyi yeniden adlandır + Kütüphaneyi yeniden adlandır - + Rename current library - + Kütüphaneyi adlandır - + Remove library - Kütüphaneyi sil + Kütüphaneyi sil - + Remove current library from your collection - Kütüphaneyi koleksiyonundan kaldır + Kütüphaneyi koleksiyonundan kaldır - + Rescan library for XML info - + XML bilgisi için kitaplığı yeniden tarayın - + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. - + Komik dosyalara gömülü XML bilgilerini bulmaya çalışır. Bunu yalnızca kitaplık 9.8.2 veya önceki sürümlerle oluşturulmuşsa veya XML bilgilerini dosyalara eklemek için üçüncü taraf yazılım kullanıyorsanız yapmanız gerekir. - + Show library info - + Kitaplık bilgilerini göster - + Show information about the current library - + Geçerli kitaplık hakkındaki bilgileri göster - + Open current comic - Seçili çizgi romanı aç + Seçili çizgi romanı aç - + Open current comic on YACReader - YACReader'ı geçerli çizgi roman okuyucsu seç + YACReader'ı geçerli çizgi roman okuyucsu seç - + Save selected covers to... - Seçilen kapakları şuraya kaydet... + Seçilen kapakları şuraya kaydet... - + Save covers of the selected comics as JPG files - Seçilen çizgi romanların kapaklarını JPG dosyaları olarak kaydet + Seçilen çizgi romanların kapaklarını JPG dosyaları olarak kaydet - - + + Set as read - Okundu olarak işaretle + Okundu olarak işaretle - + Set comic as read - Çizgi romanı okundu olarak işaretle + Çizgi romanı okundu olarak işaretle - - + + Set as unread - Hepsini okunmadı işaretle + Hepsini okunmadı işaretle - + Set comic as unread - Çizgi Romanı okunmadı olarak seç + Çizgi Romanı okunmadı olarak seç - - + + manga - + manga t?r? - + Set issue as manga - Sayıyı manga olarak ayarla + Sayıyı manga olarak ayarla - - + + comic - + komik - + Set issue as normal - Sayıyı normal olarak ayarla + Sayıyı normal olarak ayarla - + western manga - + batı mangası - + Set issue as western manga - + Konuyu western mangası olarak ayarla - - + + web comic - + web çizgi romanı - + Set issue as web comic - + Sorunu web çizgi romanı olarak ayarla - - + + yonkoma - + d?rt panelli - + Set issue as yonkoma - + Sorunu yonkoma olarak ayarla - + Show/Hide marks - Altçizgileri aç/kapa + Altçizgileri aç/kapa - + Show or hide read marks - Okundu işaretlerini göster yada gizle + Okundu işaretlerini göster yada gizle - + Show/Hide recent indicator - + Son göstergeyi Göster/Gizle - + Show or hide recent indicator - + Son göstergeyi göster veya gizle - - + + Fullscreen mode on/off - Tam ekran modu açık/kapalı + Tam ekran modu açık/kapalı - + Help, About YACReader - Yardım, Bigli, YACReader + Yardım, Bigli, YACReader - + Add new folder - Yeni klasör ekle + Yeni klasör ekle - + Add new folder to the current library - Geçerli kitaplığa yeni klasör ekle + Geçerli kitaplığa yeni klasör ekle - + Delete folder - Klasörü sil + Klasörü sil - + Delete current folder from disk - Geçerli klasörü diskten sil + Geçerli klasörü diskten sil - + Select root node - Kökü seçin + Kökü seçin - + Expand all nodes - Tüm düğümleri büyüt + Tüm düğümleri büyüt - + Collapse all nodes - Tüm düğümleri kapat + Tüm düğümleri kapat - + Show options dialog - Ayarları göster + Ayarları göster - + Show comics server options dialog - Çizgi romanların server ayarlarını göster + Çizgi romanların server ayarlarını göster - - + + Change between comics views - Çizgi roman görünümleri arasında değiştir + Çizgi roman görünümleri arasında değiştir - + Open folder... - Dosyayı aç... + Dosyayı aç... - + Set as uncompleted - Tamamlanmamış olarak ayarla + Tamamlanmamış olarak ayarla - + Set as completed - Tamamlanmış olarak ayarla + Tamamlanmış olarak ayarla - + Set custom cover - + Özel kapak ayarla - + Delete custom cover - + Özel kapağı sil - + western manga (left to right) - + Batı mangası (soldan sağa) - + Open containing folder... - Klasör açılıyor... + Klasör açılıyor... - + Reset comic rating - Çizgi roman reytingini sıfırla + Çizgi roman reytingini sıfırla - + Select all comics - Tüm çizgi romanları seç + Tüm çizgi romanları seç - + Edit - Düzenle + Düzenle - + Assign current order to comics - Geçerli sırayı çizgi romanlara ata + Geçerli sırayı çizgi romanlara ata - + Update cover - Kapağı güncelle + Kapağı güncelle - + Delete selected comics - Seçili çizgi romanları sil + Seçili çizgi romanları sil - + Delete metadata from selected comics - + Seçilen çizgi romanlardan meta verileri sil - + Download tags from Comic Vine - Etiketleri Comic Vine sitesinden indir + Etiketleri Comic Vine sitesinden indir - + Focus search line - + Arama satırına odaklan - + Focus comics view - + Çizgi roman görünümüne odaklanın - + Edit shortcuts - Kısayolları düzenle + Kısayolları düzenle - + &Quit - &Çıkış + &Çıkış - + Update folder - Klasörü güncelle + Klasörü güncelle - + Update current folder - Geçerli klasörü güncelle + Geçerli klasörü güncelle - + Scan legacy XML metadata - + Eski XML meta verilerini tarayın - + Add new reading list - Yeni okuma listesi ekle + Yeni okuma listesi ekle - + Add a new reading list to the current library - Geçerli kitaplığa yeni bir okuma listesi ekle + Geçerli kitaplığa yeni bir okuma listesi ekle - + Remove reading list - Okuma listesini kaldır + Okuma listesini kaldır - + Remove current reading list from the library - Geçerli okuma listesini kütüphaneden kaldır + Geçerli okuma listesini kütüphaneden kaldır - + Add new label - Yeni etiket ekle + Yeni etiket ekle - + Add a new label to this library - Bu kitaplığa yeni bir etiket ekle + Bu kitaplığa yeni bir etiket ekle - + Rename selected list - Seçilen listeyi yeniden adlandır + Seçilen listeyi yeniden adlandır - + Rename any selected labels or lists - Seçilen etiketleri ya da listeleri yeniden adlandır + Seçilen etiketleri ya da listeleri yeniden adlandır - + Add to... - Şuraya ekle... + Şuraya ekle... - + Favorites - Favoriler + Favoriler - + Add selected comics to favorites list - Seçilen çizgi romanları favoriler listesine ekle + Seçilen çizgi romanları favoriler listesine ekle @@ -1837,194 +2021,221 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü LogWindow - Log window - Günlük penceresi + Günlük penceresi - &Pause - &Duraklak + &Duraklak - &Save - &Kaydet + &Kaydet - C&lear - &Temizle + &Temizle - &Copy - &Kopyala + &Kopyala - Level: - Düzey: + Düzey: - &Auto scroll - &Otomatik kaydır + &Otomatik kaydır NoLibrariesWidget - + create your first library İlk kütüphaneni oluştur - + You don't have any libraries yet Henüz bir kütüphaneye sahip değilsin - + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Yeni bir kütüphane oluşturabilmeniçin kütüphane</p><p>No olvides que puedes usar YACReader como una aplicación independiente para leer los cómics en tu ordenador.</p> - + add an existing one Var olan bir tane ekle + + NoSearchResultsWidget + + + No results + Sonuç yok + + OptionsDialog - + + + Appearance + Dış görünüş + + + + Options Ayarlar - + + + Language + Dil + + + + + Application language + Uygulama dili + + + + + System default + Sistem varsayılanı + + + Tray icon settings (experimental) Tepsi simgesi ayarları (deneysel) - + Close to tray Tepsiyi kapat - + Start into the system tray Sistem tepsisinde başlat - + Edit Comic Vine API key Comic Vine API anahtarını düzenle - + Comic Vine API key Comic Vine API anahtarı - + ComicInfo.xml legacy support - + ComicInfo.xml eski desteği - + Import metadata from ComicInfo.xml when adding new comics Import metada from ComicInfo.xml when adding new comics - + Yeni çizgi roman eklerken meta verileri ComicInfo.xml'den içe aktarın - + Consider 'recent' items added or updated since X days ago - + X gün öncesinden bu yana eklenen veya güncellenen 'en son' öğeleri göz önünde bulundurun - + Third party reader - + Üçüncü taraf okuyucu - + Write {comic_file_path} where the path should go in the command - + Komutta yolun gitmesi gereken yere {comic_file_path} yazın - + + Clear - + Temizle - + Update libraries at startup - + Başlangıçta kitaplıkları güncelleyin - + Try to detect changes automatically - + Değişiklikleri otomatik olarak algılamayı deneyin - + Update libraries periodically - + Kitaplıkları düzenli aralıklarla güncelleyin - + Interval: - + Aralık: - + 30 minutes - + 30 dakika - + 1 hour - + 1 saat - + 2 hours - + 2 saat - + 4 hours - + 4 saat - + 8 hours - + 8 saat - + 12 hours - + 12 saat - + daily - + günlük - + Update libraries at certain time - + Kitaplıkları belirli bir zamanda güncelle - + Time: - + Zaman: - + WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. @@ -2032,166 +2243,341 @@ To stop an automatic update tap on the loading indicator next to the Libraries t WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. - + UYARI! Kütüphane güncellemeleri sırasında veritabanına yazma işlemi devre dışı bırakılır! +Uygulamayı aktif olarak kullanırken güncelleme planlamayın. +Otomatik güncellemeler sırasında uygulama, güncelleme bitene kadar bazı eylemleri engelleyecektir. +Otomatik güncellemeyi durdurmak için Kitaplıklar başlığının yanındaki yükleme göstergesine dokunun. - + Modifications detection - + Değişiklik tespiti - + Compare the modified date of files when updating a library (not recommended) - + Kitaplığı güncellerken dosyaların değiştirilme tarihini karşılaştırın (önerilmez) - + Enable background image Arka plan resmini etkinleştir - + Opacity level Matlık düzeyi - + Blur level Bulanıklık düzeyi - + Use selected comic cover as background Seçilen çizgi roman kapanığı arka plan olarak kullan - + Restore defautls Varsayılanları geri yükle - + Background Arka plan - + Display continue reading banner Okuma devam et bannerını göster - + Display current comic banner - + Mevcut çizgi roman banner'ını görüntüle - + Continue reading Okumaya devam et - + Comic Flow Çizgi Roman Akışı - - + + Libraries - Kütüphaneler + Kütüphaneler - + Grid view Izgara görünümü - + + General Genel - - - PropertiesDialog - - Day: - Gün: + + My comics path + Çizgi Romanlarım - - Plot - Argumento + + Display + Görüntülemek - - Size: - Boyut: + + Show time in current page information label + Geçerli sayfa bilgisi etiketinde zamanı göster - - Year: - Yıl: + + "Go to flow" size + Akış görünümüne git - - Inker(s): - Mürekkep(ler): + + Background color + Arka plan rengi - - Publishing - Yayın + + Choose + Seç - - Publisher: - Yayıncı: + + Scroll behaviour + Kaydırma davranışı - - General info - Genel bilgi + + Disable scroll animations and smooth scrolling + Kaydırma animasyonlarını ve düzgün kaydırmayı devre dışı bırakın - - Color/BW: - Renk/BW: + + Do not turn page using scroll + Kaydırmayı kullanarak sayfayı çevirmeyin - - Edit selected comics information - Seçilen çizgi roman bilgilerini düzenle + + Use single scroll step to turn page + Sayfayı çevirmek için tek kaydırma adımını kullanın - - Penciller(s): - Çizenler: + + Mouse mode + Fare modu - - Colorist(s): - Renklendiren: + + Only Back/Forward buttons can turn pages + Yalnızca Geri/İleri düğmeleri sayfaları çevirebilir - - Issue number: - Yayın numarası: + + Use the Left/Right buttons to turn pages. + Sayfaları çevirmek için Sol/Sağ tuşlarını kullanın. - - Month: - Ay: + + Click left or right half of the screen to turn pages. + Sayfaları çevirmek için ekranın sol veya sağ yarısına tıklayın. - - Notes: - Notlar: + + Quick Navigation Mode + Hızlı Gezinti Kipi - - Synopsis: - Özet: + + Disable mouse over activation + Etkinleştirme üzerinde fareyi devre dışı bırak + + + + Brightness + Parlaklık + + + + Contrast + Kontrast + + + + Gamma + Gama + + + + Reset + Yeniden başlat + + + + Image options + Sayfa ayarları + + + + Fit options + Sığdırma seçenekleri + + + + Enlarge images to fit width/height + Genişliğe/yüksekliği sığmaları için resimleri genişlet + + + + Double Page options + Çift Sayfa seçenekleri + + + + Show covers as single page + Kapakları tek sayfa olarak göster + + + + Scaling + Ölçeklendirme + + + + Scaling method + Ölçeklendirme yöntemi + + + + Nearest (fast, low quality) + En yakın (hızlı, düşük kalite) + + + + Bilinear + Çift doğrusal + + + + Lanczos (better quality) + Lanczos (daha kaliteli) + + + + Page Flow + Sayfa akışı + + + + Image adjustment + Resim ayarları + + + + + Restart is needed + Yeniden başlatılmalı + + + + Comics directory + Çizgi roman konumu + + + + PropertiesDialog + + + Day: + Gün: + + + + Plot + Argumento + + + + Size: + Boyut: + + + + Year: + Yıl: + + + + Inker(s): + Mürekkep(ler): + + + + Publishing + Yayın + + + + Publisher: + Yayıncı: + + + + General info + Genel bilgi + + + + Color/BW: + Renk/BW: + + + + Edit selected comics information + Seçilen çizgi roman bilgilerini düzenle + + + + Penciller(s): + Çizenler: + + + + Colorist(s): + Renklendiren: + + + + Issue number: + Yayın numarası: + + + + Month: + Ay: + + + + Notes: + Notlar: + + + + Synopsis: + Özet: @@ -2226,47 +2612,47 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Notes - + Notlar Load previous page as cover - + Önceki sayfayı kapak olarak yükle Load next page as cover - + Sonraki sayfayı kapak olarak yükle Reset cover to the default image - + Kapağı varsayılan görüntüye sıfırla Load custom cover image - + Özel kapak resmini yükle Series: - Seriler: + Seriler: alt. number: - + alternatif sayı: Alternate series: - + Alternatif seri: Series Group: - + Seri Grubu: @@ -2276,47 +2662,47 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Editor(s): - + Editör(ler): Imprint: - + Künye: Type: - + Tip: Language (ISO): - + Dil (ISO): Teams: - + Takımlar: Locations: - + Konumlar: Main character or team: - + Ana karakter veya takım: Review: - + Gözden geçirmek: Tags: - + Etiketler: @@ -2331,12 +2717,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Invalid cover - + Geçersiz kapak The image is invalid. - + Resim geçersiz. @@ -2368,12 +2754,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t of: - + ile ilgili: Arc number: - + Ark numarası: @@ -2382,7 +2768,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Manga: - Manga: + Manga t?r?: @@ -2390,6 +2776,22 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Comic Vine bağlantısı: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> görüntüle </a> + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer, YACReaderLibrary'nin başsız (gui yok) sürümüdür. + +Bu uygulama kalıcı ayarları destekler, bunları ayarlamak için bu dosyayı düzenleyin %1 +Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md adresindeki belgelere bakın. + + QObject @@ -2433,61 +2835,79 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Ölümcül - + Select custom cover - + Özel kapak seçin - + Images (%1) - + Resimler (%1) + + + + The file could not be read or is not valid JSON. + Dosya okunamadı veya geçerli bir JSON değil. + + + + This theme is for %1, not %2. + Bu tema %2 için değil, %1 içindir. + + + + Libraries + Kütüphaneler + + + + Folders + Klasör + + + + Reading Lists + Okuma Listeleri QsLogging::LogWindowModel - Time - Süre + Süre - Level - Düzel + Düzel - Message - Mesaj + Mesaj QsLogging::Window - &Pause - &Duraklak + &Duraklak - &Resume - &Sürdür + &Sürdür - Save log - Günlük tut + Günlük tut - Log file (*.log) - Günlük dosyası (*.log) + Günlük dosyası (*.log) RenameLibraryDialog - + Rename current library Kütüphaneyi yeniden adlandır @@ -2510,18 +2930,18 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ScraperResultsPaginator - + Number of volumes found : %1 Bulunan bölüm sayısı: %1 - - + + page %1 of %2 sayfa %1 / %2 - + Number of %1 found : %2 Sayı %1, bulunan : %2 @@ -2532,17 +2952,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information for this comic. Please provide some additional information. - Lütfen bazı ek bilgiler sağlayın. + Lütfen bazı ek bilgiler sağlayın. - + Series: Seriler: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Tam eşleme aramasını kullanın. Addaki bazı sözcüklerle eşleşen ciltleri bulmak istiyorsanız devre dışı bırakın. @@ -2553,42 +2973,42 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Lütfen bazı ek bilgiler sağlayın. - + Series: Seriler: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + Tam eşleme aramasını kullanın. Addaki bazı sözcüklerle eşleşen ciltleri bulmak istiyorsanız devre dışı bırakın. SelectComic - + Please, select the right comic info. Lütfen, doğru çizgi roman bilgisini seçin. - + comics çizgi roman - + loading cover kapak yükleniyor - + loading description açıklama yükleniyor - + comic description unavailable - + çizgi roman açıklaması mevcut değil description unavailable @@ -2598,39 +3018,39 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SelectVolume - + Please, select the right series for your comic. Çizgi romanınız için doğru seriyi seçin. - + Filter: - + Filtre: - + volumes sayı - + Nothing found, clear the filter if any. - + Hiçbir şey bulunamadı, varsa filtreyi temizleyin. - + loading cover kapak yükleniyor - + loading description açıklama yükleniyor - + volume description unavailable - + cilt açıklaması kullanılamıyor description unavailable @@ -2640,12 +3060,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SeriesQuestion - + no hayır - + yes evet @@ -2658,41 +3078,41 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ServerConfigDialog - + Port - Port + Liman - + enable the server erişilebilir server - + set port Port Ayarla - + Server connectivity information Sunucu bağlantı bilgileri - + Scan it! Tara! - + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + YACReader, iOS ve Android cihazlarda kullanılabilir.<br/>Bunu <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> veya <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a> için keşfedin. YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> YACReader, iOS cihazlar için kullanılabilir. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Keşfedin! </a> - + Choose an IP address IP adresi seçin @@ -2710,326 +3130,1167 @@ performansı iyileştirmek için SortVolumeComics - + Please, sort the list of comics on the left until it matches the comics' information. Lütfen, çizgi romanların bilgileriyle eşleşene kadar soldaki çizgi roman listesini sıralayın. - + sort comics to match comic information çizgi roman bilgilerini eşleştirmek için çizgi romanları sıralayın - + issues sayı - + remove selected comics seçilen çizgi romanları kaldır - + restore all removed comics tüm seçilen çizgi romanları geri yükle - TitleHeader + ThemeEditorDialog - - SEARCH - ARA + + Theme Editor + Tema Düzenleyici - - - UpdateLibraryDialog - - Update library - Kütüphaneyi güncelle + + + + + - - Cancel - Vazgeç + + - + - - - Updating.... - Güncelleniyor... + + i + Ben - - - VolumeComicsModel - - title - başlık + + Expand all + Tümünü genişlet - - - VolumesModel - - year - yıl + + Collapse all + Tümünü daralt - - issues - sayı + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Kullanıcı arayüzünde seçilen değeri (macenta / geçişli / 0↔10) yanıp sönmek için basılı tutun. Sürümler orijinali geri yükler. - - publisher - yayıncı + + Search… + Aramak… - - - YACReader::TrayIconController - - &Restore - &Geri Yükle + + Light + Işık - &Quit - &Çıkış + + Dark + Karanlık - - Systray - Sistem tepsisi + + ID: + İD: - - YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary sistem tepsisinde çalışmaya devam edecektir. Programı sonlandırmak için sistem tepsisi simgesinin bağlam menüsünden <b>Çık</b>'ı seçin. + + Display name: + Ekran adı: - - - YACReader::WhatsNewDialog - - Close - Kapat + + Variant: + Varyant: - - - YACReaderFieldEdit - - Restore to default - Varsayılana dön + + Theme info + Tema bilgisi - - - Click to overwrite - Üstüne yazmak için tıkla + + Parameter + Parametre - - - YACReaderFieldPlainTextEdit - - Restore to default - Varsayılana dön + + Value + Değer - - - - - Click to overwrite - Üstüne yazmak için tıkla + + Save and apply + Kaydet ve uygula - - - YACReaderFlowConfigWidget - - CoverFlow look - Kapak akışı görünümü + + Export to file... + Dosyaya aktar... - - How to show covers: - Kapaklar nasıl gözüksün: + + Load from file... + Dosyadan yükle... - - Stripe look - Şerit görünüm + + Close + Kapat - - Overlapped Stripe look - Çakışan şerit görünüm + + Double-click to edit color + Rengi düzenlemek için çift tıklayın - - - YACReaderGLFlowConfigWidget - - Zoom - Zoom + + + + + + + true + doğru - - Light - Işık + + + + + false + YANLIŞ - - Show advanced settings - Daha fazla ayar göster + + Double-click to toggle + Geçiş yapmak için çift tıklayın - - Roulette look - Rulet görünüm + + Double-click to edit value + Değeri düzenlemek için çift tıklayın - - Cover Angle - Kapak Açısı + + + + Edit: %1 + Düzenleme: %1 - - Stripe look - Strip görünüm + + Save theme + Temayı kaydet - - Position - Pozisyon + + + JSON files (*.json);;All files (*) + JSON dosyaları (*.json);;Tüm dosyalar (*) - - Z offset - Z dengesi + + Save failed + Kaydetme başarısız oldu - - Y offset - Y dengesi + + Could not open file for writing: +%1 + Dosya yazmak için açılamadı: +%1 - - Central gap - Boş merkez + + Load theme + Temayı yükle - - Presets: - Hazırlayan: + + + + Load failed + Yükleme başarısız oldu - - Overlapped Stripe look + + Could not open file: +%1 + Dosya açılamadı: +%1 + + + + Invalid JSON: +%1 + Geçersiz JSON: +%1 + + + + Expected a JSON object. + Bir JSON nesnesi bekleniyordu. + + + + TitleHeader + + + SEARCH + ARA + + + + UpdateLibraryDialog + + + Update library + Kütüphaneyi güncelle + + + + Cancel + Vazgeç + + + + Updating.... + Güncelleniyor... + + + + Viewer + + + + Press 'O' to open comic. + 'O'ya basarak aç. + + + + Not found + Bulunamad + + + + Comic not found + Çizgi roman bulunamadı + + + + Error opening comic + Çizgi roman açılırken hata + + + + CRC Error + CRC Hatası + + + + Loading...please wait! + Yükleniyor... lütfen bekleyin! + + + + Page not available! + Sayfa bulunamadı! + + + + Cover! + Kapak! + + + + Last page! + Son sayfa! + + + + VolumeComicsModel + + + title + başlık + + + + VolumesModel + + + year + yıl + + + + issues + sayı + + + + publisher + yayıncı + + + + YACReader3DFlowConfigWidget + + + Presets: + Hazırlayan: + + + + Classic look + Klasik görünüm + + + + Stripe look + Şerit görünüm + + + + Overlapped Stripe look Çakışan şerit görünüm - + + Modern look + Modern görünüm + + + + Roulette look + Rulet görünüm + + + + Show advanced settings + Daha fazla ayar göster + + + + Custom: + Kişisel: + + + + View angle + Bakış açısı + + + + Position + Pozisyon + + + + Cover gap + Kapak boşluğu + + + + Central gap + Boş merkez + + + + Zoom + Yakınlaş + + + + Y offset + Y dengesi + + + + Z offset + Z dengesi + + + + Cover Angle + Kapak Açısı + + + + Visibility + Görünülebilirlik + + + + Light + Işık + + + + Max angle + Maksimum açı + + + + Low Performance + Düşük Performans + + + + High Performance + Yüksek Performans + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + VSync kullan + + + + Performance: + Performans: + + + + YACReader::MainWindowViewer + + + &Open + &Aç + + + + Open a comic + Çizgi romanı aç + + + + New instance + Yeni örnek + + + + Open Folder + Dosyayı Aç + + + + Open image folder + Resim dosyasınıaç + + + + Open latest comic + En son çizgi romanı aç + + + + Open the latest comic opened in the previous reading session + Önceki okuma oturumunda açılan en son çizgi romanı aç + + + + Clear + Temizle + + + + Clear open recent list + Son açılanlar listesini temizle + + + + Save + Kaydet + + + + + Save current page + Geçerli sayfayı kaydet + + + + Previous Comic + Önce ki çizgi roman + + + + + + Open previous comic + Önceki çizgi romanı aç + + + + Next Comic + Sırada ki çizgi roman + + + + + + Open next comic + Sıradaki çizgi romanı aç + + + + &Previous + &Geri + + + + + + Go to previous page + Önceki sayfaya dön + + + + &Next + &İleri + + + + + + Go to next page + Sonra ki sayfaya geç + + + + Fit Height + Yüksekliğe Sığdır + + + + Fit image to height + Uygun yüksekliğe getir + + + + Fit Width + Uygun Genişlik + + + + Fit image to width + Görüntüyü sığdır + + + + Show full size + Tam erken + + + + Fit to page + Sayfaya sığdır + + + + Continuous scroll + Sürekli kaydırma + + + + Switch to continuous scroll mode + Sürekli kaydırma moduna geç + + + + Reset zoom + Yakınlaştırmayı sıfırla + + + + Show zoom slider + Yakınlaştırma çubuğunu göster + + + + Zoom+ + Yakınlaştır + + + + Zoom- + Uzaklaştır + + + + Rotate image to the left + Sayfayı sola yatır + + + + Rotate image to the right + Sayfayı sağa yator + + + + Double page mode + Çift sayfa modu + + + + Switch to double page mode + Çift sayfa moduna geç + + + + Double page manga mode + Çift sayfa manga kipi + + + + Reverse reading order in double page mode + Çift sayfa kipinde ters okuma sırası + + + + Go To + Git + + + + Go to page ... + Sayfata git... + + + + Options + Ayarlar + + + + YACReader options + YACReader ayarları + + + + + Help + Yardım + + + + Help, About YACReader + Yardım, Bigli, YACReader + + + + Magnifying glass + Büyüteç + + + + Switch Magnifying glass + Büyüteç + + + + Set bookmark + Yer imi yap + + + + Set a bookmark on the current page + Sayfayı yer imi olarak ayarla + + + + Show bookmarks + Yer imlerini göster + + + + Show the bookmarks of the current comic + Bu çizgi romanın yer imlerini göster + + + + Show keyboard shortcuts + Klavye kısayollarını göster + + + + Show Info + Bilgiyi göster + + + + Close + Kapat + + + + Show Dictionary + Sözlüğü göster + + + + Show go to flow + Akışı göster + + + + Edit shortcuts + Kısayolları düzenle + + + + &File + &Dosya + + + + + Open recent + Son dosyaları aç + + + + File + Dosya + + + + Edit + Düzenle + + + + View + Görünüm + + + + Go + Git + + + + Window + Pencere + + + + + + Open Comic + Çizgi Romanı Aç + + + + + + Comic files + Çizgi Roman Dosyaları + + + + Open folder + Dosyayı aç + + + + page_%1.jpg + sayfa_%1.jpg + + + + Image files (*.jpg) + Resim dosyaları (*.jpg) + + + + + Comics + Çizgi Roman + + + + + General + Genel + + + + + Magnifiying glass + Büyüteç + + + + + Page adjustement + Sayfa ayarı + + + + + Reading + Okuma + + + + Toggle fullscreen mode + Tam ekran kipini aç/kapat + + + + Hide/show toolbar + Araç çubuğunu göster/gizle + + + + Size up magnifying glass + Büyüteci büyüt + + + + Size down magnifying glass + Büyüteci küçült + + + + Zoom in magnifying glass + Büyüteci yakınlaştır + + + + Zoom out magnifying glass + Büyüteci uzaklaştır + + + + Reset magnifying glass + Büyüteci sıfırla + + + + Toggle between fit to width and fit to height + Genişliğe sığdır ile yüksekliğe sığdır arasında geçiş yap + + + + Autoscroll down + Otomatik aşağı kaydır + + + + Autoscroll up + Otomatik yukarı kaydır + + + + Autoscroll forward, horizontal first + Otomatik ileri kaydır, önce yatay + + + + Autoscroll backward, horizontal first + Otomatik geri kaydır, önce yatay + + + + Autoscroll forward, vertical first + Otomatik ileri kaydır, önce dikey + + + + Autoscroll backward, vertical first + Otomatik geri kaydır, önce dikey + + + + Move down + Aşağı git + + + + Move up + Yukarı git + + + + Move left + Sola git + + + + Move right + Sağa git + + + + Go to the first page + İlk sayfaya git + + + + Go to the last page + En son sayfaya git + + + + Offset double page to the left + Çift sayfayı sola kaydır + + + + Offset double page to the right + Çift sayfayı sağa kaydır + + + + There is a new version available + Yeni versiyon mevcut + + + + Do you want to download the new version? + Yeni versiyonu indirmek ister misin ? + + + + Remind me in 14 days + 14 gün içinde hatırlat + + + + Not now + Şimdi değil + + + + YACReader::TrayIconController + + + &Restore + &Geri Yükle + + + &Quit + &Çıkış + + + + Systray + Sistem tepsisi + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary sistem tepsisinde çalışmaya devam edecektir. Programı sonlandırmak için sistem tepsisi simgesinin bağlam menüsünden <b>Çık</b>'ı seçin. + + + + YACReader::WhatsNewDialog + + Close + Kapat + + + + YACReaderFieldEdit + + + Restore to default + Varsayılana dön + + + + + Click to overwrite + Üstüne yazmak için tıkla + + + + YACReaderFieldPlainTextEdit + + + Restore to default + Varsayılana dön + + + + + + + Click to overwrite + Üstüne yazmak için tıkla + + + + YACReaderFlowConfigWidget + + CoverFlow look + Kapak akışı görünümü + + + How to show covers: + Kapaklar nasıl gözüksün: + + + Stripe look + Şerit görünüm + + + Overlapped Stripe look + Çakışan şerit görünüm + + + + YACReaderGLFlowConfigWidget + + Zoom + Yakınlaş + + + Light + Işık + + + Show advanced settings + Daha fazla ayar göster + + + Roulette look + Rulet görünüm + + + Cover Angle + Kapak Açısı + + + Stripe look + Strip görünüm + + + Position + Pozisyon + + + Z offset + Z dengesi + + + Y offset + Y dengesi + + + Central gap + Boş merkez + + + Presets: + Hazırlayan: + + + Overlapped Stripe look + Çakışan şerit görünüm + + Modern look - Modern görünüm + Modern görünüm - View angle - Bakış açısı + Bakış açısı - Max angle - Maksimum açı + Maksimum açı - Custom: - Kişisel: + Kişisel: - Classic look - Klasik görünüm + Klasik görünüm - Cover gap - Kapak boşluğu + Kapak boşluğu - High Performance - Yüksek Performans + Yüksek Performans - Performance: - Performans: + Performans: - Use VSync (improve the image quality in fullscreen mode, worse performance) - VSync kullan + VSync kullan - Visibility - Görünülebilirlik + Görünülebilirlik - Low Performance - Düşük Performans + Düşük Performans YACReaderNavigationController - No favorites - Favoriler boş + Favoriler boş - You are not reading anything yet, come on!! - Henüz bir şey okumuyorsun, hadi ama! - - - - There are no recent comics! - + Henüz bir şey okumuyorsun, hadi ama! YACReaderOptionsDialog - + Save Kaydet - Use hardware acceleration (restart needed) - Yüksek donanımlı kullan (yeniden başlatmak gerekli) + Yüksek donanımlı kullan (yeniden başlatmak gerekli) - + Cancel Vazgeç - + Edit shortcuts Kısayolları düzenle - + Shortcuts Kısayollar @@ -3037,7 +4298,7 @@ performansı iyileştirmek için YACReaderSearchLineEdit - + type to search aramak için yazınız @@ -3045,34 +4306,60 @@ performansı iyileştirmek için YACReaderSideBar - LIBRARIES - KÜTÜPHANELER + KÜTÜPHANELER - FOLDERS - DOSYALAR + DOSYALAR - Libraries - Kütüphaneler + Kütüphaneler - Folders - Klasör + Klasör - Reading Lists - Okuma Listeleri + Okuma Listeleri - READING LISTS - OKUMA LİSTELERİ + OKUMA LİSTELERİ + + + + YACReaderSlider + + + Reset + Yeniden başlat + + + + YACReaderTranslator + + + YACReader translator + YACReader çevirmeni + + + + + Translation + Çeviri + + + + clear + temizle + + + + Service not available + Servis kullanılamıyor diff --git a/YACReaderLibrary/yacreaderlibrary_zh_CN.ts b/YACReaderLibrary/yacreaderlibrary_zh_CN.ts index dcf002484..f975c8e8a 100644 --- a/YACReaderLibrary/yacreaderlibrary_zh_CN.ts +++ b/YACReaderLibrary/yacreaderlibrary_zh_CN.ts @@ -12,82 +12,70 @@ AddLabelDialog - red - + - blue - + - dark - 深色 + 深色 - cyan - + - pink - + - green - 绿 + 绿 - light - 浅色 + 浅色 - white - + - + Choose a color: 选择标签颜色: - + accept 接受 - + cancel 取消 - orange - + - purple - + - violet - 紫罗兰 + 紫罗兰 - yellow - + - + Label name: 标签名称: @@ -100,7 +88,7 @@ 添加 - + Add an existing library 添加一个现有库 @@ -143,10 +131,150 @@ 在此粘贴你的Comic Vine API + + AppearanceTabWidget + + + Color scheme + 配色方案 + + + + System + 系统 + + + + Light + 亮度 + + + + Dark + 黑暗的 + + + + Custom + 风俗 + + + + Remove + 消除 + + + + Remove this user-imported theme + 删除此用户导入的主题 + + + + Light: + 光: + + + + Dark: + 黑暗的: + + + + Custom: + 自定义: + + + + Import theme... + 导入主题... + + + + Theme + 主题 + + + + Theme editor + 主题编辑器 + + + + Open Theme Editor... + 打开主题编辑器... + + + + Theme editor error + 主题编辑器错误 + + + + The current theme JSON could not be loaded. + 无法加载当前主题 JSON。 + + + + Import theme + 导入主题 + + + + JSON files (*.json);;All files (*) + JSON 文件 (*.json);;所有文件 (*) + + + + Could not import theme from: +%1 + 无法从以下位置导入主题: +%1 + + + + Could not import theme from: +%1 + +%2 + 无法从以下位置导入主题: +%1 + +%2 + + + + Import failed + 导入失败 + + + + BookmarksDialog + + + Lastest Page + 尾页 + + + + Close + 关闭 + + + + Click on any image to go to the bookmark + 点击任意图片以跳转至相应书签位置 + + + + + Loading... + 载入中... + + ClassicComicsView - + Hide comic flow 隐藏漫画流 @@ -154,84 +282,84 @@ ComicInfoView - + b/w 黑白 - + cover artist - 封面设计 + 封面画师 - + imprint - 压印 + 出版品牌 - + Teams 团队 - + color 彩色 - + inker - 上墨师 + 墨线师 - + Main character or team 主要角色或团队 - + penciller - 线稿师 + 铅笔画师 - + colorist 上色师 - + editor 编辑 - + writer - 作者 + 编剧 - + Characters 角色 - + Authors 作者 - + Publisher - 出版商 + 出版社 - + Locations 地点 - + letterer - 嵌字师 + 字效师 @@ -305,74 +433,82 @@ ComicVineDialog - + back 返回 - + next 下一步 - + skip 忽略 - + close 关闭 - - + + Retrieving tags for : %1 正在检索标签: %1 - + Looking for comic... 搜索漫画中... - + search 搜索 - - - + + + Looking for volume... 搜索卷... - - + + comic %1 of %2 - %3 第 %1 本 共 %2 本 - %3 - + %1 comics selected 已选择 %1 本漫画 - + Error connecting to ComicVine ComicVine 连接时出错 - + Retrieving volume info... 正在接收卷信息... + + ContinuousPageWidget + + + Loading page %1 + 正在加载页面 %1 + + CreateLibraryDialog - + Create new library 创建新的漫画库 @@ -392,7 +528,7 @@ 创建一个新的库可能需要几分钟时间,您可以先停止该进程,稍后可以通过更新库选项来更新数据。 - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder 所选路径不存在或不是有效路径. 确保您具有此文件夹的写入权限 @@ -407,7 +543,7 @@ 库名: - + Path not found 未找到路径 @@ -415,7 +551,7 @@ EditShortcutsDialog - + Shortcut in use 快捷键被占用 @@ -430,7 +566,7 @@ 快捷键设置 - + The shortcut "%1" is already assigned to other function 快捷键 "%1" 已被映射至其他功能 @@ -443,26 +579,27 @@ EmptyFolderWidget - Empty folder - 空文件夹 + 空文件夹 - - Subfolders in this folder - 建立子文件夹 + 建立子文件夹 - Drag and drop folders and comics here - 拖动文件夹或者漫画到这里 + 拖动文件夹或者漫画到这里 + + + + This folder doesn't contain comics yet + 该文件夹还没有漫画 EmptyLabelWidget - + This label doesn't contain comics yet 此标签尚未包含漫画 @@ -475,6 +612,24 @@ 此阅读列表尚未包含任何漫画 + + EmptySpecialListWidget + + + No favorites + 没有收藏 + + + + You are not reading anything yet, come on!! + 你还没有阅读任何东西,加油!! + + + + There are no recent comics! + 没有最近的漫画! + + ExportComicsInfoDialog @@ -483,7 +638,7 @@ 输出文件: - + Destination database name 目标数据库名称 @@ -498,17 +653,17 @@ 创建 - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder 选定的输出文件路径不存在或路径无效. 确保您具有此文件夹的写入权限 - + Export comics info 导出漫画信息 - + Problem found while writing 写入时出现问题 @@ -526,7 +681,7 @@ 创建 - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder 选定的输出文件路径不存在或路径无效. 确保您具有此文件夹的写入权限 @@ -536,17 +691,17 @@ 输出文件夹: - + Problem found while writing 写入时出现问题 - + Create covers package 创建封面包 - + Destination directory 目标目录 @@ -577,7 +732,7 @@ FolderContentView - + Continue Reading... 继续阅读... @@ -585,15 +740,51 @@ FolderContentView6 - Continue Reading... - 继续阅读... + 继续阅读... + + + + GoToDialog + + + Page : + 页码 : + + + + Go To + 跳转 + + + + Cancel + 取消 + + + + + Total pages : + 总页数: + + + + Go to... + 跳转至 ... + + + + GoToFlowToolBar + + + Page : + 页码 : GridComicsView - + Show info 显示信息 @@ -601,17 +792,17 @@ HelpAboutDialog - + Help 帮助 - + About 关于 - + System info 系统信息 @@ -639,7 +830,7 @@ 导入漫画信息 - + Comics info file (*.ydb) 漫画信息文件(*.ydb) @@ -662,7 +853,7 @@ 解压 - + Compresed library covers (*.clc) 已压缩的库封面 (*.clc) @@ -677,7 +868,7 @@ 库名: - + Extract a catalog 提取目录 @@ -685,52 +876,52 @@ ImportWidget - + stop 停止 - + Importing comics 正在导入漫画 - + Scanning the library 正在扫描库 - + Upgrading the library 正在更新库 - + <p>The current library is being upgraded, please wait.</p> <p>正在更新当前漫画库, 请稍候.</p> - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> <p>YACReaderLibrary现在正在创建一个新库。</p><p>这可能需要几分钟时间,您可以先停止该进程,稍后可以通过更新库选项来更新数据。</p> - + Some of the comics being added... 正在添加漫画... - + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> <p>正在扫描当前库的旧版 XML metadata 信息。</p><p>这只需要执行一次,且只有当创建库的 YACReaderLibrary 版本低于 9.8.2 时。</p> - + Updating the library 正在更新库 - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> <p>正在更新当前库。要获得更快的更新,请经常更新您的库。</p><p>您可以停止该进程,稍后继续更新操作。</p> @@ -742,12 +933,12 @@ 编辑 - + The selected folder doesn't contain any library. 所选文件夹不包含任何库。 - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? 此库是使用旧版本的YACReaderLibrary创建的. 它需要更新. 现在更新? @@ -756,12 +947,12 @@ 退出(&Q) - + Upgrade failed 更新失败 - + Comic 漫画 @@ -770,16 +961,16 @@ 四格漫画 - - - + + + comic 漫画 - - - + + + manga 日本漫画 @@ -788,12 +979,12 @@ 设置为正常向 - + Folder name: 文件夹名称: - + The selected folder and all its contents will be deleted from your disk. Are you sure? 所选文件夹及其所有内容将从磁盘中删除。 你确定吗? @@ -810,12 +1001,12 @@ 设为日漫 - + Rescan library for XML info 重新扫描库的 XML 信息 - + Error opening the library 打开库时出错 @@ -824,8 +1015,8 @@ 显示/隐藏标记 - - + + YACReader not found YACReader 未找到 @@ -834,7 +1025,7 @@ 显示漫画服务器选项对话框 - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. 尝试删除所选文件夹时出现问题。 请检查写入权限,并确保没有其他应用程序在使用这些文件夹或文件。 @@ -847,7 +1038,7 @@ 漫画设为已读 - + Rename list name 重命名列表 @@ -856,17 +1047,17 @@ 将所选漫画添加到收藏夹列表 - + Remove and delete metadata 移除并删除元数据 - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. 未找到YACReader. YACReader应安装在与YACReaderLibrary相同的文件夹中. - + Old library 旧的库 @@ -879,17 +1070,17 @@ 重命名任何选定的标签或列表 - + Set as completed 设为已完成 - + There was an error accessing the folder's path 访问文件夹的路径时出错 - + Library @@ -898,7 +1089,7 @@ 在当前库下添加新的文件夹 - + Comics will only be deleted from the current label/list. Are you sure? 漫画只会从当前标签/列表中删除。 你确定吗? @@ -911,13 +1102,13 @@ 全屏模式 开/关 - + This library was created with a newer version of YACReaderLibrary. Download the new version now? 此库是使用较新版本的YACReaderLibrary创建的。 立即下载新版本? - - + + Moving comics... 移动漫画中... @@ -930,13 +1121,13 @@ 更新当前库 - - + + Copying comics... 复制漫画中... - + Library '%1' is no longer available. Do you want to remove it? 库 '%1' 不再可用。 你想删除它吗? @@ -945,49 +1136,49 @@ 更新库 - - - + + + web comic 网络漫画 - + Open folder... 打开文件夹... - + Set custom cover - + 设置自定义封面 - + Delete custom cover - + 删除自定义封面 - + Error - 错误 + 错误 - + Error opening comic with third party reader. - + 使用第三方阅读器打开漫画时出错。 - + Do you want remove 你想要删除 - + Set as uncompleted 设为未完成 - + Error in path 路径错误 @@ -996,24 +1187,24 @@ 重置漫画评分 - + Error updating the library 更新库时出错 - + Folder 文件夹 - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? 所选项目将被删除,您的漫画或文件夹将不会从您的磁盘中删除。 你确定吗? - - - + + + western manga (left to right) 欧美漫画(从左到右) @@ -1042,8 +1233,8 @@ 设置漫画为 - - + + List name: 列表名称: @@ -1052,7 +1243,7 @@ 添加到... - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? 库 '%1' 是通过旧版本的YACReaderLibrary创建的。 必须再次创建。 你想现在创建吗? @@ -1061,7 +1252,7 @@ 打包封面 - + Save covers 保存封面 @@ -1074,17 +1265,17 @@ 从当前库移除阅读列表 - + YACReader not found. There might be a problem with your YACReader installation. 未找到YACReader. YACReader的安装可能有问题. - + Add new reading lists 添加新的阅读列表 - + You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. @@ -1097,17 +1288,17 @@ YACReaderLibrary will not stop you from creating more libraries but you should k YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低的库数量来提升性能。 - + Set as read 设为已读 - + Assign comics numbers 分配漫画编号 - + There were errors during library upgrade in: 漫画库更新时出现错误: @@ -1124,7 +1315,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 显示选项对话框 - + Please, select a folder first 请先选择一个文件夹 @@ -1133,7 +1324,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 创建一个新的库 - + Library not available 库不可用 @@ -1142,7 +1333,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 导入漫画信息 - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. 尝试删除所选漫画时出现问题。 请检查所选文件或包含文件夹中的写入权限。 @@ -1163,30 +1354,30 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 打开当前漫画 - + YACReader Library YACReader 库 Set issue as manga - Set issue as manga + 将问题设置为漫画 Add a new reading list to the current library 在当前库添加新的阅读列表 - + Error creating the library 创建库时出错 - + You are adding too many libraries. 您添加的库太多了。 - + Update folder 更新文件夹 @@ -1199,7 +1390,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 解压封面 - + Update needed 需要更新 @@ -1212,12 +1403,12 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 显示或隐藏阅读标记 - + Library name already exists 库名已存在 - + There is another library with the name '%1'. 已存在另一个名为'%1'的库。 @@ -1226,55 +1417,55 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 移除阅读列表 - + Delete folder 删除文件夹 - + Assign numbers starting in: 从以下位置开始分配编号: - + Download new version 下载新版本 - - - - + + + + Set type 设置类型 - + Library info - + 图书馆信息 - + Invalid image - + 图片无效 - + The selected file is not a valid image. - + 所选文件不是有效图像。 - + Error saving cover - + 保存封面时出错 - + There was an error saving the cover image. - + 保存封面图像时出错。 - + Delete comics 删除漫画 @@ -1283,7 +1474,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 聚焦于搜索行 - + Add new folder 添加新的文件夹 @@ -1316,7 +1507,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 重命名列表 - + Delete list/label 删除 列表/标签 @@ -1337,7 +1528,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 选择根节点 - + No folder selected 没有选中的文件夹 @@ -1350,7 +1541,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 解压目录 - + All the selected comics will be deleted from your disk. Are you sure? 所有选定的漫画都将从您的磁盘中删除。你确定吗? @@ -1363,7 +1554,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 从 Comic Vine 下载标签 - + Remove comics 移除漫画 @@ -1372,8 +1563,8 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 在当前库添加标签 - - + + Set as unread 设为未读 @@ -1382,7 +1573,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 尝试查找漫画文件内嵌的 XML 信息。只有当创建库的 YACReaderLibrary 版本低于 9.8.2 或者使用第三方软件嵌入 XML 信息时,才需要执行该操作。 - + Library not found 未找到库 @@ -1407,20 +1598,20 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 聚焦于漫画视图 - - + + Unable to delete 无法删除 - - - + + + 4koma (top to botom) 四格漫画(从上到下) - + library? 库? @@ -1429,7 +1620,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 保存所选的封面为jpg - + Are you sure? 你确定吗? @@ -1437,439 +1628,439 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 LibraryWindowActions - + Create a new library - 创建一个新的库 + 创建一个新的库 - + Open an existing library - 打开现有的库 + 打开现有的库 - - + + Export comics info - 导出漫画信息 + 导出漫画信息 - - + + Import comics info - 导入漫画信息 + 导入漫画信息 - + Pack covers - 打包封面 + 打包封面 - + Pack the covers of the selected library - 打包所选库的封面 + 打包所选库的封面 - + Unpack covers - 解压封面 + 解压封面 - + Unpack a catalog - 解压目录 + 解压目录 - + Update library - 更新库 + 更新库 - + Update current library - 更新当前库 + 更新当前库 - + Rename library - 重命名库 + 重命名库 - + Rename current library - 重命名当前库 + 重命名当前库 - + Remove library - 移除库 + 移除库 - + Remove current library from your collection - 从您的集合中移除当前库 + 从您的集合中移除当前库 - + Rescan library for XML info - 重新扫描库的 XML 信息 + 重新扫描库的 XML 信息 - + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. - 尝试查找漫画文件内嵌的 XML 信息。只有当创建库的 YACReaderLibrary 版本低于 9.8.2 或者使用第三方软件嵌入 XML 信息时,才需要执行该操作。 + 尝试查找漫画文件内嵌的 XML 信息。只有当创建库的 YACReaderLibrary 版本低于 9.8.2 或者使用第三方软件嵌入 XML 信息时,才需要执行该操作。 - + Show library info - + 显示图书馆信息 - + Show information about the current library - + 显示当前库的信息 - + Open current comic - 打开当前漫画 + 打开当前漫画 - + Open current comic on YACReader - 用YACReader打开漫画 + 用YACReader打开漫画 - + Save selected covers to... - 选中的封面保存到... + 选中的封面保存到... - + Save covers of the selected comics as JPG files - 保存所选的封面为jpg + 保存所选的封面为jpg - - + + Set as read - 设为已读 + 设为已读 - + Set comic as read - 漫画设为已读 + 漫画设为已读 - - + + Set as unread - 设为未读 + 设为未读 - + Set comic as unread - 漫画设为未读 + 漫画设为未读 - - + + manga - 日本漫画 + 日本漫画 - + Set issue as manga - Set issue as manga + 将问题设置为漫画 - - + + comic - 漫画 + 漫画 - + Set issue as normal - 设置漫画为 + 设置漫画为 - + western manga - 欧美漫画 + 欧美漫画 - + Set issue as western manga - 设置为欧美漫画 + 设置为欧美漫画 - - + + web comic - 网络漫画 + 网络漫画 - + Set issue as web comic - 设置为网络漫画 + 设置为网络漫画 - - + + yonkoma - 四格漫画 + 四格漫画 - + Set issue as yonkoma - 设置为四格漫画 + 设置为四格漫画 - + Show/Hide marks - 显示/隐藏标记 + 显示/隐藏标记 - + Show or hide read marks - 显示或隐藏阅读标记 + 显示或隐藏阅读标记 - + Show/Hide recent indicator - 显示/隐藏最近的指示标志 + 显示/隐藏最近的指示标志 - + Show or hide recent indicator - 显示或隐藏最近的指示标志 + 显示或隐藏最近的指示标志 - - + + Fullscreen mode on/off - 全屏模式 开/关 + 全屏模式 开/关 - + Help, About YACReader - 帮助, 关于 YACReader + 帮助, 关于 YACReader - + Add new folder - 添加新的文件夹 + 添加新的文件夹 - + Add new folder to the current library - 在当前库下添加新的文件夹 + 在当前库下添加新的文件夹 - + Delete folder - 删除文件夹 + 删除文件夹 - + Delete current folder from disk - 从磁盘上删除当前文件夹 + 从磁盘上删除当前文件夹 - + Select root node - 选择根节点 + 选择根节点 - + Expand all nodes - 展开所有节点 + 展开所有节点 - + Collapse all nodes - 折叠所有节点 + 折叠所有节点 - + Show options dialog - 显示选项对话框 + 显示选项对话框 - + Show comics server options dialog - 显示漫画服务器选项对话框 + 显示漫画服务器选项对话框 - - + + Change between comics views - 漫画视图之间的变化 + 漫画视图之间的变化 - + Open folder... - 打开文件夹... + 打开文件夹... - + Set as uncompleted - 设为未完成 + 设为未完成 - + Set as completed - 设为已完成 + 设为已完成 - + Set custom cover - + 设置自定义封面 - + Delete custom cover - + 删除自定义封面 - + western manga (left to right) - 欧美漫画(从左到右) + 欧美漫画(从左到右) - + Open containing folder... - 打开包含文件夹... + 打开包含文件夹... - + Reset comic rating - 重置漫画评分 + 重置漫画评分 - + Select all comics - 全选漫画 + 全选漫画 - + Edit - 编辑 + 编辑 - + Assign current order to comics - 将当前序号分配给漫画 + 将当前序号分配给漫画 - + Update cover - 更新封面 + 更新封面 - + Delete selected comics - 删除所选的漫画 + 删除所选的漫画 - + Delete metadata from selected comics - 从选定的漫画中删除元数据 + 从选定的漫画中删除元数据 - + Download tags from Comic Vine - 从 Comic Vine 下载标签 + 从 Comic Vine 下载标签 - + Focus search line - 聚焦于搜索行 + 聚焦于搜索行 - + Focus comics view - 聚焦于漫画视图 + 聚焦于漫画视图 - + Edit shortcuts - 编辑快捷键 + 编辑快捷键 - + &Quit - 退出(&Q) + 退出(&Q) - + Update folder - 更新文件夹 + 更新文件夹 - + Update current folder - 更新当前文件夹 + 更新当前文件夹 - + Scan legacy XML metadata - 扫描旧版 XML 元数据 + 扫描旧版 XML 元数据 - + Add new reading list - 添加新的阅读列表 + 添加新的阅读列表 - + Add a new reading list to the current library - 在当前库添加新的阅读列表 + 在当前库添加新的阅读列表 - + Remove reading list - 移除阅读列表 + 移除阅读列表 - + Remove current reading list from the library - 从当前库移除阅读列表 + 从当前库移除阅读列表 - + Add new label - 添加新标签 + 添加新标签 - + Add a new label to this library - 在当前库添加标签 + 在当前库添加标签 - + Rename selected list - 重命名列表 + 重命名列表 - + Rename any selected labels or lists - 重命名任何选定的标签或列表 + 重命名任何选定的标签或列表 - + Add to... - 添加到... + 添加到... - + Favorites - 收藏夹 + 收藏夹 - + Add selected comics to favorites list - 将所选漫画添加到收藏夹列表 + 将所选漫画添加到收藏夹列表 @@ -1883,88 +2074,89 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 LogWindow - &Copy - 复制(&C) + 复制(&C) - &Save - 保存(&S) + 保存(&S) - &Pause - 中止(&P) + 中止(&P) - C&lear - 清空(&l) + 清空(&l) - Level: - 等级: + 等级: - &Auto scroll - 自动滚动(&A) + 自动滚动(&A) - Log window - 日志窗口 + 日志窗口 NoLibrariesWidget - + create your first library 创建你的第一个库 - + You don't have any libraries yet 你还没有库 - + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>您可以在任何文件夹中创建库,YACReaderLibrary将导入此文件夹中的所有漫画和文件夹。如果已有库,则可以打开它们。</p><p>您可以把YACReader当成独立应用来阅读电脑上的漫画。</p> - + add an existing one 添加一个现有库 + + NoSearchResultsWidget + + + No results + 没有结果 + + OptionsDialog - + Modifications detection 修改检测 - + Time: 时间: - + daily 每天 - + Restore defautls 恢复默认值 - + Close to tray 关闭至托盘 @@ -1973,143 +2165,169 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 添加新漫画时从 ComicInfo.xml 导入元数据 - + Background 背景 - + Update libraries at certain time 定时更新库 - + 1 hour 1小时 - + Start into the system tray 启动至系统托盘 - + Display current comic banner - + 显示当前漫画横幅 - + Continue reading 继续阅读 - + Update libraries at startup 启动时更新库 - + + + Appearance + 外貌 + + + + + Language + 语言 + + + + + Application language + 应用程序语言 + + + + + System default + 系统默认 + + + Third party reader - + 第三方阅读器 - + Write {comic_file_path} where the path should go in the command - + 在命令中应将路径写入 {comic_file_path} - + + Clear - + 清空 - + 30 minutes 30分钟 - + 2 hours 2小时 - + 12 hours 12小时 - + Blur level 模糊 - + Compare the modified date of files when updating a library (not recommended) 更新库时比较文件的修改日期(不推荐) - + Import metadata from ComicInfo.xml when adding new comics 添加新漫画时从 ComicInfo.xml 导入元数据 - + Enable background image 启用背景图片 - + 4 hours 4小时 - + + Options 选项 - + Comic Vine API key Comic Vine API 密匙 - + Edit Comic Vine API key 编辑Comic Vine API 密匙 - + Tray icon settings (experimental) 托盘图标设置 (实验特性) - - + + Libraries - + 8 hours 8小时 - + Try to detect changes automatically 尝试自动检测变化 - + Interval: 间隔: - + ComicInfo.xml legacy support ComicInfo.xml 旧版支持 - + WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. @@ -2120,119 +2338,291 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 要停止自动更新,请点击库标题旁边的加载指示器。 - + Opacity level 透明度 - + Display continue reading banner 显示继续阅读横幅 - + + General 常规 - + Consider 'recent' items added or updated since X days ago 参考自 X 天前添加或更新的“最近”项目 - + Update libraries periodically 定期更新库 - + Use selected comic cover as background 使用选定的漫画封面做背景 - + Comic Flow 漫画流 - + Grid view 网格视图 - - - PropertiesDialog - - - - of: - of: + + My comics path + 我的漫画路径 - - Day: - 日: + + Display + 展示 - - Plot - 情节 + + Show time in current page information label + 在当前页面信息标签中显示时间 - - Notes - 笔记 + + "Go to flow" size + 页面流尺寸 - - Load previous page as cover - + + Background color + 背景颜色 - - Load next page as cover - + + Choose + 选择 - - Reset cover to the default image - + + Scroll behaviour + 滚动效果 - - Load custom cover image - + + Disable scroll animations and smooth scrolling + 禁用滚动动画和平滑滚动 - - Size: - 大小: + + Do not turn page using scroll + 滚动时不翻页 - - Tags: - 标签: + + Use single scroll step to turn page + 使用单滚动步骤翻页 - - Invalid cover - + + Mouse mode + 鼠标模式 - - The image is invalid. - + + Only Back/Forward buttons can turn pages + 只有后退/前进按钮可以翻页 - - Type: - 类型: + + Use the Left/Right buttons to turn pages. + 使用向左/向右按钮翻页。 - - Year: - 年: + + Click left or right half of the screen to turn pages. + 单击屏幕的左半部分或右半部分即可翻页。 + + + + Quick Navigation Mode + 快速导航模式 + + + + Disable mouse over activation + 禁用鼠标激活 + + + + Brightness + 亮度 + + + + Contrast + 对比度 + + + + Gamma + Gamma值 + + + + Reset + 重置 + + + + Image options + 图片选项 + + + + Fit options + 适应项 + + + + Enlarge images to fit width/height + 放大图片以适应宽度/高度 + + + + Double Page options + 双页选项 + + + + Show covers as single page + 显示封面为单页 + + + + Scaling + 缩放 + + + + Scaling method + 缩放方法 + + + + Nearest (fast, low quality) + 最近(快速,低质量) + + + + Bilinear + 双线性 + + + + Lanczos (better quality) + Lanczos(质量更好) + + + + Page Flow + 页面流 + + + + Image adjustment + 图像调整 + + + + + Restart is needed + 需要重启 + + + + Comics directory + 漫画目录 + + + + PropertiesDialog + + + + + of: + 的: + + + + Day: + 日: + + + + Plot + 情节 + + + + Notes + 笔记 + + + + Load previous page as cover + 加载上一页作为封面 + + + + Load next page as cover + 加载下一页作为封面 + + + + Reset cover to the default image + 将封面重置为默认图像 + + + + Load custom cover image + 加载自定义封面图片 + + + + Size: + 大小: + + + + Tags: + 标签: + + + + Invalid cover + 封面无效 + + + + The image is invalid. + 该图像无效。 + + + + Type: + 类型: + + + + Year: + 年: @@ -2439,6 +2829,22 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 嵌字师: + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 + +此应用程序支持持久设置,要设置它们,请编辑此文件 %1 +要了解可用设置,请查看文档:https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + QObject @@ -2482,61 +2888,79 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 警告 - + Select custom cover - + 选择自定义封面 - + Images (%1) - + 图片 (%1) + + + + The file could not be read or is not valid JSON. + 无法读取该文件或者该文件不是有效的 JSON。 + + + + This theme is for %1, not %2. + 此主题适用于 %1,而不是 %2。 + + + + Libraries + + + + + Folders + 文件夹 + + + + Reading Lists + 阅读列表 QsLogging::LogWindowModel - Time - 时间 + 时间 - Level - 等级 + 等级 - Message - 信息 + 信息 QsLogging::Window - &Pause - 中止(&P) + 中止(&P) - Save log - 保存日志 + 保存日志 - &Resume - 恢复(&R) + 恢复(&R) - Log file (*.log) - 日志文件 (*.log) + 日志文件 (*.log) RenameLibraryDialog - + Rename current library 重命名当前库 @@ -2559,18 +2983,18 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ScraperResultsPaginator - + Number of %1 found : %2 第 %1 页 共: %2 条 - - + + page %1 of %2 第 %1 页 共 %2 页 - + Number of volumes found : %1 搜索结果: %1 @@ -2581,17 +3005,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information for this comic. Please provide some additional information. - 请提供附加信息. + 请提供附加信息. - + Series: 系列: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + 使用精确匹配搜索。如果您想要查找与名称中某些单词匹配的卷,请禁用。 @@ -2602,40 +3026,40 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 请提供附加信息. - + Series: 系列: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + 使用精确匹配搜索。如果您想要查找与名称中某些单词匹配的卷,请禁用。 SelectComic - + loading description 加载描述 - + comics 漫画 - + loading cover 加载封面 - + comic description unavailable - + 漫画描述不可用 - + Please, select the right comic info. 请正确选择漫画信息. @@ -2647,37 +3071,37 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SelectVolume - + loading description 加载描述 - + Nothing found, clear the filter if any. 未找到任何内容,如果有,请清除筛选器。 - + Please, select the right series for your comic. 请选择正确的漫画系列。 - + loading cover 加载封面 - + volume description unavailable - + 卷描述不可用 - + Filter: 筛选: - + volumes @@ -2689,12 +3113,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SeriesQuestion - + no - + yes @@ -2707,7 +3131,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ServerConfigDialog - + Port 端口 @@ -2716,7 +3140,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t YACReader适用于iOS设备. <a href='http://ios.yacreader.com'style ='color:rgb(193,148,65)'>下载</a> - + enable the server 启用服务器 @@ -2725,7 +3149,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 无法载入libqrencode. - + Server connectivity information 服务器连接信息 @@ -2736,22 +3160,22 @@ to improve the performance 以提升浏览性能 - + Scan it! 扫一扫! - + set port 设置端口 - + Choose an IP address 选择IP地址 - + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. YACReader 适用于 iOS 和 Android 设备。<br/>搜索 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2759,322 +3183,1167 @@ to improve the performance SortVolumeComics - + remove selected comics 移除所选漫画 - + sort comics to match comic information 排序漫画以匹配漫画信息 - + restore all removed comics 恢复所有移除的漫画 - + issues 发行 - + Please, sort the list of comics on the left until it matches the comics' information. 请在左侧对漫画列表进行排序,直到它与漫画的信息相符。 - TitleHeader + ThemeEditorDialog - - SEARCH - 搜索 + + Theme Editor + 主题编辑器 - - - UpdateLibraryDialog - - Update library - 更新库 + + + + + - - Cancel - 取消 + + - + - - - Updating.... - 更新中... + + i + - - - VolumeComicsModel - - title - 标题 + + Expand all + 全部展开 - - - VolumesModel - - year - + + Collapse all + 全部折叠 - - issues - 发行 + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + 按住可在 UI 中闪烁所选值(洋红色/切换/0↔10)。发布后恢复原样。 - - publisher - 出版者 + + Search… + 搜索… - - - YACReader::TrayIconController - - &Restore - 复位(&R) + + Light + 亮度 - - Systray - 系统托盘 + + Dark + 黑暗的 - - YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary 将继续在系统托盘中运行. 想要终止程序, 请在系统托盘图标的上下文菜单中选择<b>退出</b>. + + ID: + ID: - - - YACReader::WhatsNewDialog - - Close - 关闭 + + Display name: + 显示名称: - - - YACReaderFieldEdit - - Restore to default - 恢复默认 + + Variant: + 变体: - - - Click to overwrite - 点击以覆盖 + + Theme info + 主题信息 - - - YACReaderFieldPlainTextEdit - - Restore to default - 恢复默认 + + Parameter + 范围 - - - - - Click to overwrite - 点击以覆盖 + + Value + 价值 - - - YACReaderFlowConfigWidget - - CoverFlow look - 封面流 + + Save and apply + 保存并应用 - - How to show covers: - 封面显示方式: + + Export to file... + 导出到文件... - - Stripe look - 条状 + + Load from file... + 从文件加载... - - Overlapped Stripe look - 重叠条状 + + Close + 关闭 - - - YACReaderGLFlowConfigWidget - - Zoom - 缩放 + + Double-click to edit color + 双击编辑颜色 - - Light - 亮度 + + + + + + + true + 真的 - - Show advanced settings - 显示高级选项 + + + + + false + 错误的 - - Roulette look - 轮盘 + + Double-click to toggle + 双击切换 - - Cover Angle - 封面角度 + + Double-click to edit value + 双击编辑值 - - Stripe look - 条状 + + + + Edit: %1 + 编辑:%1 - - Position - 位置 + + Save theme + 保存主题 - - Z offset - Z位移 + + + JSON files (*.json);;All files (*) + JSON 文件 (*.json);;所有文件 (*) - - Y offset - Y位移 + + Save failed + 保存失败 - - Central gap - 中心间距 + + Could not open file for writing: +%1 + 无法打开文件进行写入: +%1 - - Presets: - 预设: + + Load theme + 加载主题 - - Overlapped Stripe look - 重叠条状 + + + + Load failed + 加载失败 - - Modern look - 现代 + + Could not open file: +%1 + 无法打开文件: +%1 - - View angle - 视角 + + Invalid JSON: +%1 + 无效的 JSON: +%1 - - Max angle - 最大角度 + + Expected a JSON object. + 需要一个 JSON 对象。 - - - Custom: + + + TitleHeader + + + SEARCH + 搜索 + + + + UpdateLibraryDialog + + + Update library + 更新库 + + + + Cancel + 取消 + + + + Updating.... + 更新中... + + + + Viewer + + + + Press 'O' to open comic. + 按下 'O' 以打开漫画. + + + + Not found + 未找到 + + + + Comic not found + 未找到漫画 + + + + Error opening comic + 打开漫画时发生错误 + + + + CRC Error + CRC 校验失败 + + + + Loading...please wait! + 载入中... 请稍候! + + + + Page not available! + 页面不可用! + + + + Cover! + 封面! + + + + Last page! + 尾页! + + + + VolumeComicsModel + + + title + 标题 + + + + VolumesModel + + + year + + + + + issues + 发行 + + + + publisher + 出版者 + + + + YACReader3DFlowConfigWidget + + + Presets: + 预设: + + + + Classic look + 经典 + + + + Stripe look + 条状 + + + + Overlapped Stripe look + 重叠条状 + + + + Modern look + 现代 + + + + Roulette look + 轮盘 + + + + Show advanced settings + 显示高级选项 + + + + Custom: 自定义: - + + View angle + 视角 + + + + Position + 位置 + + + + Cover gap + 封面间距 + + + + Central gap + 中心间距 + + + + Zoom + 缩放 + + + + Y offset + Y位移 + + + + Z offset + Z位移 + + + + Cover Angle + 封面角度 + + + + Visibility + 透明度 + + + + Light + 亮度 + + + + Max angle + 最大角度 + + + + Low Performance + 低性能 + + + + High Performance + 高性能 + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + 使用VSync (在全屏模式下提高图像质量, 性能更差) + + + + Performance: + 性能: + + + + YACReader::MainWindowViewer + + + &Open + 打开(&O) + + + + Open a comic + 打开漫画 + + + + New instance + 新建实例 + + + + Open Folder + 打开文件夹 + + + + Open image folder + 打开图片文件夹 + + + + Open latest comic + 打开最近的漫画 + + + + Open the latest comic opened in the previous reading session + 打开最近阅读漫画 + + + + Clear + 清空 + + + + Clear open recent list + 清空最近访问列表 + + + + Save + 保存 + + + + + Save current page + 保存当前页面 + + + + Previous Comic + 上一个漫画 + + + + + + Open previous comic + 打开上一个漫画 + + + + Next Comic + 下一个漫画 + + + + + + Open next comic + 打开下一个漫画 + + + + &Previous + 上一页(&P) + + + + + + Go to previous page + 转至上一页 + + + + &Next + 下一页(&N) + + + + + + Go to next page + 转至下一页 + + + + Fit Height + 适应高度 + + + + Fit image to height + 缩放图片以适应高度 + + + + Fit Width + 适合宽度 + + + + Fit image to width + 缩放图片以适应宽度 + + + + Show full size + 显示全尺寸 + + + + Fit to page + 适应页面 + + + + Continuous scroll + 连续滚动 + + + + Switch to continuous scroll mode + 切换到连续滚动模式 + + + + Reset zoom + 重置缩放 + + + + Show zoom slider + 显示缩放滑块 + + + + Zoom+ + 放大 + + + + Zoom- + 缩小 + + + + Rotate image to the left + 向左旋转图片 + + + + Rotate image to the right + 向右旋转图片 + + + + Double page mode + 双页模式 + + + + Switch to double page mode + 切换至双页模式 + + + + Double page manga mode + 双页漫画模式 + + + + Reverse reading order in double page mode + 双页模式 (逆序阅读) + + + + Go To + 跳转 + + + + Go to page ... + 跳转至页面 ... + + + + Options + 选项 + + + + YACReader options + YACReader 选项 + + + + + Help + 帮助 + + + + Help, About YACReader + 帮助, 关于 YACReader + + + + Magnifying glass + 放大镜 + + + + Switch Magnifying glass + 切换放大镜 + + + + Set bookmark + 设置书签 + + + + Set a bookmark on the current page + 在当前页面设置书签 + + + + Show bookmarks + 显示书签 + + + + Show the bookmarks of the current comic + 显示当前漫画的书签 + + + + Show keyboard shortcuts + 显示键盘快捷键 + + + + Show Info + 显示信息 + + + + Close + 关闭 + + + + Show Dictionary + 显示字典 + + + + Show go to flow + 显示页面流 + + + + Edit shortcuts + 编辑快捷键 + + + + &File + 文件(&F) + + + + + Open recent + 最近打开的文件 + + + + File + 文件 + + + + Edit + 编辑 + + + + View + 查看 + + + + Go + 转到 + + + + Window + 窗口 + + + + + + Open Comic + 打开漫画 + + + + + + Comic files + 漫画文件 + + + + Open folder + 打开文件夹 + + + + page_%1.jpg + 页_%1.jpg + + + + Image files (*.jpg) + 图像文件 (*.jpg) + + + + + Comics + 漫画 + + + + + General + 常规 + + + + + Magnifiying glass + 放大镜 + + + + + Page adjustement + 页面调整 + + + + + Reading + 阅读 + + + + Toggle fullscreen mode + 切换全屏模式 + + + + Hide/show toolbar + 隐藏/显示 工具栏 + + + + Size up magnifying glass + 增大放大镜尺寸 + + + + Size down magnifying glass + 减小放大镜尺寸 + + + + Zoom in magnifying glass + 增大缩放级别 + + + + Zoom out magnifying glass + 减小缩放级别 + + + + Reset magnifying glass + 重置放大镜 + + + + Toggle between fit to width and fit to height + 切换显示为"适应宽度"或"适应高度" + + + + Autoscroll down + 向下自动滚动 + + + + Autoscroll up + 向上自动滚动 + + + + Autoscroll forward, horizontal first + 向前自动滚动,水平优先 + + + + Autoscroll backward, horizontal first + 向后自动滚动,水平优先 + + + + Autoscroll forward, vertical first + 向前自动滚动,垂直优先 + + + + Autoscroll backward, vertical first + 向后自动滚动,垂直优先 + + + + Move down + 向下移动 + + + + Move up + 向上移动 + + + + Move left + 向左移动 + + + + Move right + 向右移动 + + + + Go to the first page + 转到第一页 + + + + Go to the last page + 转到最后一页 + + + + Offset double page to the left + 双页向左偏移 + + + + Offset double page to the right + 双页向右偏移 + + + + There is a new version available + 有新版本可用 + + + + Do you want to download the new version? + 你要下载新版本吗? + + + + Remind me in 14 days + 14天后提醒我 + + + + Not now + 现在不 + + + + YACReader::TrayIconController + + + &Restore + 复位(&R) + + + + Systray + 系统托盘 + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary 将继续在系统托盘中运行. 想要终止程序, 请在系统托盘图标的上下文菜单中选择<b>退出</b>. + + + + YACReader::WhatsNewDialog + + Close + 关闭 + + + + YACReaderFieldEdit + + + Restore to default + 恢复默认 + + + + + Click to overwrite + 点击以覆盖 + + + + YACReaderFieldPlainTextEdit + + + Restore to default + 恢复默认 + + + + + + + Click to overwrite + 点击以覆盖 + + + + YACReaderFlowConfigWidget + + CoverFlow look + 封面流 + + + How to show covers: + 封面显示方式: + + + Stripe look + 条状 + + + Overlapped Stripe look + 重叠条状 + + + + YACReaderGLFlowConfigWidget + + Zoom + 缩放 + + + Light + 亮度 + + + Show advanced settings + 显示高级选项 + + + Roulette look + 轮盘 + + + Cover Angle + 封面角度 + + + Stripe look + 条状 + + + Position + 位置 + + + Z offset + Z位移 + + + Y offset + Y位移 + + + Central gap + 中心间距 + + + Presets: + 预设: + + + Overlapped Stripe look + 重叠条状 + + + Modern look + 现代 + + + View angle + 视角 + + + Max angle + 最大角度 + + + Custom: + 自定义: + + Classic look - 经典 + 经典 - Cover gap - 封面间距 + 封面间距 - High Performance - 高性能 + 高性能 - Performance: - 性能: + 性能: - Use VSync (improve the image quality in fullscreen mode, worse performance) - 使用VSync (在全屏模式下提高图像质量, 性能更差) + 使用VSync (在全屏模式下提高图像质量, 性能更差) - Visibility - 透明度 + 透明度 - Low Performance - 低性能 + 低性能 YACReaderNavigationController - You are not reading anything yet, come on!! - 你还没有阅读任何东西,加油!! + 你还没有阅读任何东西,加油!! - There are no recent comics! - 没有最近的漫画! + 没有最近的漫画! - No favorites - 没有收藏 + 没有收藏 YACReaderOptionsDialog - + Save 保存 - Use hardware acceleration (restart needed) - 使用硬件加速 (需要重启) + 使用硬件加速 (需要重启) - + Cancel 取消 - + Shortcuts 快捷键 - + Edit shortcuts 编辑快捷键 @@ -3082,7 +4351,7 @@ to improve the performance YACReaderSearchLineEdit - + type to search 搜索类型 @@ -3090,34 +4359,60 @@ to improve the performance YACReaderSideBar - Reading Lists - 阅读列表 + 阅读列表 - LIBRARIES - + - Libraries - + - FOLDERS - 文件夹 + 文件夹 - Folders - 文件夹 + 文件夹 - READING LISTS - 阅读列表 + 阅读列表 + + + + YACReaderSlider + + + Reset + 重置 + + + + YACReaderTranslator + + + YACReader translator + YACReader 翻译 + + + + + Translation + 翻译 + + + + clear + 清空 + + + + Service not available + 服务不可用 diff --git a/YACReaderLibrary/yacreaderlibrary_zh_HK.ts b/YACReaderLibrary/yacreaderlibrary_zh_HK.ts index 32a397dc5..49114dc2a 100644 --- a/YACReaderLibrary/yacreaderlibrary_zh_HK.ts +++ b/YACReaderLibrary/yacreaderlibrary_zh_HK.ts @@ -12,82 +12,70 @@ AddLabelDialog - + Label name: 標籤名稱: - + Choose a color: 選擇標籤顏色: - red - + - orange - + - yellow - + - green - + - cyan - + - blue - + - violet - 紫羅蘭 + 紫羅蘭 - purple - + - pink - + - white - + - light - 淺色 + 淺色 - dark - 深色 + 深色 - + accept 接受 - + cancel 取消 @@ -116,7 +104,7 @@ 取消 - + Add an existing library 添加一個現有庫 @@ -144,10 +132,150 @@ 取消 + + AppearanceTabWidget + + + Color scheme + 配色方案 + + + + System + 系統 + + + + Light + 亮度 + + + + Dark + 黑暗的 + + + + Custom + 風俗 + + + + Remove + 消除 + + + + Remove this user-imported theme + 刪除此使用者匯入的主題 + + + + Light: + 光: + + + + Dark: + 黑暗的: + + + + Custom: + 自定義: + + + + Import theme... + 導入主題... + + + + Theme + 主題 + + + + Theme editor + 主題編輯器 + + + + Open Theme Editor... + 開啟主題編輯器... + + + + Theme editor error + 主題編輯器錯誤 + + + + The current theme JSON could not be loaded. + 無法載入目前主題 JSON。 + + + + Import theme + 導入主題 + + + + JSON files (*.json);;All files (*) + JSON 檔案 (*.json);;所有檔案 (*) + + + + Could not import theme from: +%1 + 無法從以下位置匯入主題: +%1 + + + + Could not import theme from: +%1 + +%2 + 無法從以下位置匯入主題: +%1 + +%2 + + + + Import failed + 導入失敗 + + + + BookmarksDialog + + + Lastest Page + 尾頁 + + + + Close + 關閉 + + + + Click on any image to go to the bookmark + 點擊任意圖片以跳轉至相應書簽位置 + + + + + Loading... + 載入中... + + ClassicComicsView - + Hide comic flow 隱藏漫畫流 @@ -155,84 +283,84 @@ ComicInfoView - + + Characters + 角色 + + + Main character or team - + 主要角色或團隊 - + Teams - + 團隊 - + Locations - + 地點 - + Authors - 作者 + 作者 - + writer - + 編劇 - + penciller - + 鉛筆畫師 - + inker - + 墨線師 - + colorist - + 上色師 - + letterer - + 字效師 - + cover artist - + 封面畫師 - + editor - + 編輯 - + imprint - + 出版品牌 - + Publisher - + 出版社 - + color - + 彩色 - + b/w - - - - - Characters - + 黑白 @@ -290,86 +418,94 @@ Series - + 系列 Volume - + 體積 Story Arc - + 故事線 ComicVineDialog - + skip 忽略 - + back 返回 - + next 下一步 - + search 搜索 - + close 關閉 - - - + + + Looking for volume... 搜索卷... - - + + comic %1 of %2 - %3 第 %1 本 共 %2 本 - %3 - + %1 comics selected 已選擇 %1 本漫畫 - + Error connecting to ComicVine ComicVine 連接時出錯 - - + + Retrieving tags for : %1 正在檢索標籤: %1 - + Retrieving volume info... 正在接收卷資訊... - + Looking for comic... 搜索漫畫中... + + ContinuousPageWidget + + + Loading page %1 + 正在載入頁面 %1 + + CreateLibraryDialog @@ -398,17 +534,17 @@ 創建一個新的庫可能需要幾分鐘時間,您可以先停止該進程,稍後可以通過更新庫選項來更新數據。 - + Create new library 創建新的漫畫庫 - + Path not found 未找到路徑 - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder 所選路徑不存在或不是有效路徑. 確保您具有此檔夾的寫入許可權 @@ -431,12 +567,12 @@ 快捷鍵設置 - + Shortcut in use 快捷鍵被佔用 - + The shortcut "%1" is already assigned to other function 快捷鍵 "%1" 已被映射至其他功能 @@ -444,26 +580,27 @@ EmptyFolderWidget - - Subfolders in this folder - 建立子檔夾 + 建立子檔夾 - Empty folder - 空文件夾 + 空文件夾 - Drag and drop folders and comics here - 拖動檔夾或者漫畫到這裏 + 拖動檔夾或者漫畫到這裏 + + + + This folder doesn't contain comics yet + 該資料夾還沒有漫畫 EmptyLabelWidget - + This label doesn't contain comics yet 此標籤尚未包含漫畫 @@ -477,6 +614,24 @@ 此閱讀列表尚未包含任何漫畫 + + EmptySpecialListWidget + + + No favorites + 沒有收藏 + + + + You are not reading anything yet, come on!! + 你還沒有閱讀任何東西,加油!! + + + + There are no recent comics! + 沒有最近的漫畫! + + ExportComicsInfoDialog @@ -495,22 +650,22 @@ 取消 - + Export comics info 導出漫畫資訊 - + Destination database name 目標資料庫名稱 - + Problem found while writing 寫入時出現問題 - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder 選定的輸出檔路徑不存在或路徑無效. 確保您具有此檔夾的寫入許可權 @@ -533,22 +688,22 @@ 取消 - + Create covers package 創建封面包 - + Problem found while writing 寫入時出現問題 - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder 選定的輸出檔路徑不存在或路徑無效. 確保您具有此檔夾的寫入許可權 - + Destination directory 目標目錄 @@ -579,23 +734,52 @@ FolderContentView - + Continue Reading... - + 繼續閱讀... - FolderContentView6 + GoToDialog - - Continue Reading... - + + Page : + 頁碼 : + + + + Go To + 跳轉 + + + + Cancel + 取消 + + + + + Total pages : + 總頁數: + + + + Go to... + 跳轉至 ... + + + + GoToFlowToolBar + + + Page : + 頁碼 : GridComicsView - + Show info 顯示資訊 @@ -603,17 +787,17 @@ HelpAboutDialog - + About 關於 - + Help 幫助 - + System info 系統資訊 @@ -641,7 +825,7 @@ 取消 - + Comics info file (*.ydb) 漫畫資訊檔(*.ydb) @@ -674,12 +858,12 @@ 取消 - + Extract a catalog 提取目錄 - + Compresed library covers (*.clc) 已壓縮的庫封面 (*.clc) @@ -687,52 +871,52 @@ ImportWidget - + stop 停止 - + Some of the comics being added... 正在添加漫畫... - + Importing comics 正在導入漫畫 - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> <p>YACReaderLibrary現在正在創建一個新庫。</p><p>這可能需要幾分鐘時間,您可以先停止該進程,稍後可以通過更新庫選項來更新數據。</p> - + Updating the library 正在更新庫 - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> <p>正在更新當前庫。要獲得更快的更新,請經常更新您的庫。</p><p>您可以停止該進程,稍後繼續更新操作。</p> - + Upgrading the library 正在更新庫 - + <p>The current library is being upgraded, please wait.</p> <p>正在更新當前漫畫庫, 請稍候.</p> - + Scanning the library 正在掃描庫 - + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> <p>正在掃描當前庫的舊版 XML metadata 資訊。</p><p>這只需要執行一次,且只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 時。</p> @@ -740,12 +924,12 @@ LibraryWindow - + YACReader Library YACReader 庫 - + Library @@ -822,7 +1006,7 @@ 保存所選的封面為jpg - + Set as read 設為已讀 @@ -831,8 +1015,8 @@ 漫畫設為已讀 - - + + Set as unread 設為未讀 @@ -841,25 +1025,25 @@ 漫畫設為未讀 - - - + + + manga - + 漫畫 - - - + + + comic - + 漫畫 - - - + + + web comic - + 網路漫畫 Show/Hide marks @@ -870,18 +1054,18 @@ 折疊所有節點 - - - + + + western manga (left to right) - + 西方漫畫(從左到右) Assign current order to comics 將當前序號分配給漫畫 - + Library not available Library ' 庫不可用 @@ -891,7 +1075,7 @@ 全屏模式 開/關 - + Rescan library for XML info 重新掃描庫的 XML 資訊 @@ -905,7 +1089,7 @@ Set issue as manga - Set issue as manga + 將問題設定為漫畫 Set as normal @@ -920,7 +1104,7 @@ 幫助, 關於 YACReader - + Delete folder 刪除檔夾 @@ -941,17 +1125,17 @@ 顯示漫畫伺服器選項對話框 - + Open folder... 打開檔夾... - + Set as uncompleted 設為未完成 - + Set as completed 設為已完成 @@ -1004,7 +1188,7 @@ 退出(&Q) - + Update folder 更新檔夾 @@ -1057,170 +1241,170 @@ 將所選漫畫添加到收藏夾列表 - + Folder 檔夾 - + Comic 漫畫 - + Upgrade failed 更新失敗 - + There were errors during library upgrade in: 漫畫庫更新時出現錯誤: - + Update needed 需要更新 - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? 此庫是使用舊版本的YACReaderLibrary創建的. 它需要更新. 現在更新? - + Download new version 下載新版本 - + This library was created with a newer version of YACReaderLibrary. Download the new version now? 此庫是使用較新版本的YACReaderLibrary創建的。 立即下載新版本? - + Library '%1' is no longer available. Do you want to remove it? 庫 '%1' 不再可用。 你想刪除它嗎? - + Old library 舊的庫 - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? - - + + Copying comics... 複製漫畫中... - - + + Moving comics... 移動漫畫中... - + Folder name: 檔夾名稱: - + No folder selected 沒有選中的檔夾 - + Please, select a folder first 請先選擇一個檔夾 - + Error in path 路徑錯誤 - + There was an error accessing the folder's path 訪問檔夾的路徑時出錯 - + The selected folder and all its contents will be deleted from your disk. Are you sure? 所選檔夾及其所有內容將從磁片中刪除。 你確定嗎? - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. 嘗試刪除所選檔夾時出現問題。 請檢查寫入許可權,並確保沒有其他應用程式在使用這些檔夾或檔。 - + Add new reading lists 添加新的閱讀列表 - - + + List name: 列表名稱: - + Delete list/label 刪除 列表/標籤 - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? 所選項目將被刪除,您的漫畫或檔夾將不會從您的磁片中刪除。 你確定嗎? - + Rename list name 重命名列表 - - - + + + 4koma (top to botom) - + 4koma(由上至下) - - - - + + + + Set type - + 套裝類型 - + Set custom cover - + 設定自訂封面 - + Delete custom cover - + 刪除自訂封面 - + Save covers 保存封面 - + You are adding too many libraries. 您添加的庫太多了。 - + You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. @@ -1233,69 +1417,69 @@ YACReaderLibrary will not stop you from creating more libraries but you should k YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低的庫數量來提升性能。 - - + + YACReader not found YACReader 未找到 - + Error - 錯誤 + 錯誤 - + Error opening comic with third party reader. - + 使用第三方閱讀器開啟漫畫時出錯。 - + Library not found 未找到庫 - + The selected folder doesn't contain any library. 所選檔夾不包含任何庫。 - + Are you sure? 你確定嗎? - + Do you want remove 你想要刪除 - + library? 庫? - + Remove and delete metadata 移除並刪除元數據 - + Library info - + 圖書館資訊 - + Assign comics numbers 分配漫畫編號 - + Assign numbers starting in: 從以下位置開始分配編號: - - + + Unable to delete 無法刪除 @@ -1304,7 +1488,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 顯示或隱藏閱讀標記 - + Add new folder 添加新的檔夾 @@ -1321,82 +1505,82 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 漫畫視圖之間的變化 - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. 未找到YACReader. YACReader應安裝在與YACReaderLibrary相同的檔夾中. - + YACReader not found. There might be a problem with your YACReader installation. 未找到YACReader. YACReader的安裝可能有問題. - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. 嘗試刪除所選漫畫時出現問題。 請檢查所選檔或包含檔夾中的寫入許可權。 - + Invalid image - + 圖片無效 - + The selected file is not a valid image. - + 所選檔案不是有效影像。 - + Error saving cover - + 儲存封面時發生錯誤 - + There was an error saving the cover image. - + 儲存封面圖片時發生錯誤。 - + Error creating the library 創建庫時出錯 - + Error updating the library 更新庫時出錯 - + Error opening the library 打開庫時出錯 - + Delete comics 刪除漫畫 - + All the selected comics will be deleted from your disk. Are you sure? 所有選定的漫畫都將從您的磁片中刪除。你確定嗎? - + Remove comics 移除漫畫 - + Comics will only be deleted from the current label/list. Are you sure? 漫畫只會從當前標籤/列表中刪除。 你確定嗎? - + Library name already exists 庫名已存在 - + There is another library with the name '%1'. 已存在另一個名為'%1'的庫。 @@ -1404,439 +1588,439 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 LibraryWindowActions - + Create a new library - 創建一個新的庫 + 創建一個新的庫 - + Open an existing library - 打開現有的庫 + 打開現有的庫 - - + + Export comics info - 導出漫畫資訊 + 導出漫畫資訊 - - + + Import comics info - 導入漫畫資訊 + 導入漫畫資訊 - + Pack covers - 打包封面 + 打包封面 - + Pack the covers of the selected library - 打包所選庫的封面 + 打包所選庫的封面 - + Unpack covers - 解壓封面 + 解壓封面 - + Unpack a catalog - 解壓目錄 + 解壓目錄 - + Update library - 更新庫 + 更新庫 - + Update current library - 更新當前庫 + 更新當前庫 - + Rename library - 重命名庫 + 重命名庫 - + Rename current library - 重命名當前庫 + 重命名當前庫 - + Remove library - 移除庫 + 移除庫 - + Remove current library from your collection - 從您的集合中移除當前庫 + 從您的集合中移除當前庫 - + Rescan library for XML info - 重新掃描庫的 XML 資訊 + 重新掃描庫的 XML 資訊 - + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. - 嘗試查找漫畫檔內嵌的 XML 資訊。只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 或者使用第三方軟體嵌入 XML 資訊時,才需要執行該操作。 + 嘗試查找漫畫檔內嵌的 XML 資訊。只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 或者使用第三方軟體嵌入 XML 資訊時,才需要執行該操作。 - + Show library info - + 顯示圖書館資訊 - + Show information about the current library - + 顯示當前庫的信息 - + Open current comic - 打開當前漫畫 + 打開當前漫畫 - + Open current comic on YACReader - 用YACReader打開漫畫 + 用YACReader打開漫畫 - + Save selected covers to... - 選中的封面保存到... + 選中的封面保存到... - + Save covers of the selected comics as JPG files - 保存所選的封面為jpg + 保存所選的封面為jpg - - + + Set as read - 設為已讀 + 設為已讀 - + Set comic as read - 漫畫設為已讀 + 漫畫設為已讀 - - + + Set as unread - 設為未讀 + 設為未讀 - + Set comic as unread - 漫畫設為未讀 + 漫畫設為未讀 - - + + manga - + 漫畫 - + Set issue as manga - Set issue as manga + 將問題設定為漫畫 - - + + comic - + 漫畫 - + Set issue as normal - 設置發行狀態為正常發行 + 設置發行狀態為正常發行 - + western manga - + 西方漫畫 - + Set issue as western manga - + 將問題設定為西方漫畫 - - + + web comic - + 網路漫畫 - + Set issue as web comic - + 將問題設定為網路漫畫 - - + + yonkoma - + 四科馬 - + Set issue as yonkoma - + 將問題設定為 yonkoma - + Show/Hide marks - 顯示/隱藏標記 + 顯示/隱藏標記 - + Show or hide read marks - 顯示或隱藏閱讀標記 + 顯示或隱藏閱讀標記 - + Show/Hide recent indicator - + 顯示/隱藏最近的指標 - + Show or hide recent indicator - + 顯示或隱藏最近的指示器 - - + + Fullscreen mode on/off - 全屏模式 開/關 + 全屏模式 開/關 - + Help, About YACReader - 幫助, 關於 YACReader + 幫助, 關於 YACReader - + Add new folder - 添加新的檔夾 + 添加新的檔夾 - + Add new folder to the current library - 在當前庫下添加新的檔夾 + 在當前庫下添加新的檔夾 - + Delete folder - 刪除檔夾 + 刪除檔夾 - + Delete current folder from disk - 從磁片上刪除當前檔夾 + 從磁片上刪除當前檔夾 - + Select root node - 選擇根節點 + 選擇根節點 - + Expand all nodes - 展開所有節點 + 展開所有節點 - + Collapse all nodes - 折疊所有節點 + 折疊所有節點 - + Show options dialog - 顯示選項對話框 + 顯示選項對話框 - + Show comics server options dialog - 顯示漫畫伺服器選項對話框 + 顯示漫畫伺服器選項對話框 - - + + Change between comics views - 漫畫視圖之間的變化 + 漫畫視圖之間的變化 - + Open folder... - 打開檔夾... + 打開檔夾... - + Set as uncompleted - 設為未完成 + 設為未完成 - + Set as completed - 設為已完成 + 設為已完成 - + Set custom cover - + 設定自訂封面 - + Delete custom cover - + 刪除自訂封面 - + western manga (left to right) - + 西方漫畫(從左到右) - + Open containing folder... - 打開包含檔夾... + 打開包含檔夾... - + Reset comic rating - 重置漫畫評分 + 重置漫畫評分 - + Select all comics - 全選漫畫 + 全選漫畫 - + Edit - 編輯 + 編輯 - + Assign current order to comics - 將當前序號分配給漫畫 + 將當前序號分配給漫畫 - + Update cover - 更新封面 + 更新封面 - + Delete selected comics - 刪除所選的漫畫 + 刪除所選的漫畫 - + Delete metadata from selected comics - + 從選定的漫畫中刪除元數據 - + Download tags from Comic Vine - 從 Comic Vine 下載標籤 + 從 Comic Vine 下載標籤 - + Focus search line - 聚焦於搜索行 + 聚焦於搜索行 - + Focus comics view - 聚焦於漫畫視圖 + 聚焦於漫畫視圖 - + Edit shortcuts - 編輯快捷鍵 + 編輯快捷鍵 - + &Quit - 退出(&Q) + 退出(&Q) - + Update folder - 更新檔夾 + 更新檔夾 - + Update current folder - 更新當前檔夾 + 更新當前檔夾 - + Scan legacy XML metadata - + 掃描舊版 XML 元數據 - + Add new reading list - 添加新的閱讀列表 + 添加新的閱讀列表 - + Add a new reading list to the current library - 在當前庫添加新的閱讀列表 + 在當前庫添加新的閱讀列表 - + Remove reading list - 移除閱讀列表 + 移除閱讀列表 - + Remove current reading list from the library - 從當前庫移除閱讀列表 + 從當前庫移除閱讀列表 - + Add new label - 添加新標籤 + 添加新標籤 - + Add a new label to this library - 在當前庫添加標籤 + 在當前庫添加標籤 - + Rename selected list - 重命名列表 + 重命名列表 - + Rename any selected labels or lists - 重命名任何選定的標籤或列表 + 重命名任何選定的標籤或列表 - + Add to... - 添加到... + 添加到... - + Favorites - 收藏夾 + 收藏夾 - + Add selected comics to favorites list - 將所選漫畫添加到收藏夾列表 + 將所選漫畫添加到收藏夾列表 @@ -1850,189 +2034,209 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 LogWindow - Log window - 日誌窗口 + 日誌窗口 - &Pause - 中止(&P) + 中止(&P) - &Save - 保存(&S) + 保存(&S) - C&lear - 清空(&l) + 清空(&l) - &Copy - 複製(&C) + 複製(&C) - Level: - 等級: + 等級: - &Auto scroll - 自動滾動(&A) + 自動滾動(&A) NoLibrariesWidget - + You don't have any libraries yet 你還沒有庫 - + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>您可以在任何檔夾中創建庫,YACReaderLibrary將導入此檔夾中的所有漫畫和文件夾。如果已有庫,則可以打開它們。</p><p>您可以把YACReader當成獨立應用來閱讀電腦上的漫畫。</p> - + create your first library 創建你的第一個庫 - + add an existing one 添加一個現有庫 + + NoSearchResultsWidget + + + No results + 沒有結果 + + OptionsDialog - + + + Language + 語言 + + + + + Application language + 應用程式語言 + + + + + System default + 系統預設 + + + Tray icon settings (experimental) 託盤圖示設置 (實驗特性) - + Close to tray 關閉至託盤 - + Start into the system tray 啟動至系統託盤 - + Edit Comic Vine API key 編輯Comic Vine API 密匙 - + Comic Vine API key Comic Vine API 密匙 - + ComicInfo.xml legacy support - + ComicInfo.xml 遺留支持 - + Import metadata from ComicInfo.xml when adding new comics Import metada from ComicInfo.xml when adding new comics - + 新增漫畫時從 ComicInfo.xml 匯入元數據 - + Consider 'recent' items added or updated since X days ago - + 考慮自 X 天前新增或更新的「最近」項目 - + Third party reader - + 第三方閱讀器 - + Write {comic_file_path} where the path should go in the command - + 在命令中應將路徑寫入 {comic_file_path} - + + Clear - + 清空 - + Update libraries at startup - + 啟動時更新庫 - + Try to detect changes automatically - + 嘗試自動偵測變化 - + Update libraries periodically - + 定期更新庫 - + Interval: - + 間隔: - + 30 minutes - + 30分鐘 - + 1 hour - + 1小時 - + 2 hours - + 2小時 - + 4 hours - + 4小時 - + 8 hours - + 8小時 - + 12 hours - + 12小時 - + daily - + 日常的 - + Update libraries at certain time - + 定時更新庫 - + Time: - + 時間: - + WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. @@ -2040,162 +2244,344 @@ To stop an automatic update tap on the loading indicator next to the Libraries t WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. - + 警告!在庫更新期間,將停用對資料庫的寫入! +當您可能正在積極使用應用程式時,請勿安排更新。 +在自動更新期間,應用程式將阻止某些操作,直到更新完成。 +若要停止自動更新,請點選庫標題旁的載入指示器。 - + Modifications detection - + 修改檢測 - + Compare the modified date of files when updating a library (not recommended) - + 更新庫時比較文件的修改日期(不建議) - + Enable background image 啟用背景圖片 - + Opacity level 透明度 - + Blur level 模糊 - + Use selected comic cover as background 使用選定的漫畫封面做背景 - + Restore defautls 恢復默認值 - + Background 背景 - + Display continue reading banner 顯示繼續閱讀橫幅 - + Display current comic banner - + 顯示目前漫畫橫幅 - + Continue reading 繼續閱讀 - + Comic Flow 漫畫流 - - + + Libraries - + - + Grid view 網格視圖 - + + General 常規 - + + + Appearance + 外貌 + + + + Options 選項 - - - PropertiesDialog - - General info - 基本資訊 + + My comics path + 我的漫畫路徑 - - Authors - 作者 + + Display + 展示 - - Publishing - 出版 + + Show time in current page information label + 在目前頁面資訊標籤中顯示時間 - - Plot - 情節 + + "Go to flow" size + 頁面流尺寸 - - Notes - + + Background color + 背景顏色 - - Cover page - 封面 + + Choose + 選擇 - - Load previous page as cover - + + Scroll behaviour + 滾動效果 - - Load next page as cover - + + Disable scroll animations and smooth scrolling + 停用滾動動畫和平滑滾動 - - Reset cover to the default image - + + Do not turn page using scroll + 滾動時不翻頁 - - Load custom cover image - + + Use single scroll step to turn page + 使用單滾動步驟翻頁 - - Series: - 系列: + + Mouse mode + 滑鼠模式 - - Title: - 標題: + + Only Back/Forward buttons can turn pages + 只有後退/前進按鈕可以翻頁 - - - - of: - of: + + Use the Left/Right buttons to turn pages. + 使用向左/向右按鈕翻頁。 - - Issue number: + + Click left or right half of the screen to turn pages. + 點擊螢幕的左半部或右半部即可翻頁。 + + + + Quick Navigation Mode + 快速導航模式 + + + + Disable mouse over activation + 禁用滑鼠啟動 + + + + Brightness + 亮度 + + + + Contrast + 對比度 + + + + Gamma + Gamma值 + + + + Reset + 重置 + + + + Image options + 圖片選項 + + + + Fit options + 適應項 + + + + Enlarge images to fit width/height + 放大圖片以適應寬度/高度 + + + + Double Page options + 雙頁選項 + + + + Show covers as single page + 顯示封面為單頁 + + + + Scaling + 縮放 + + + + Scaling method + 縮放方法 + + + + Nearest (fast, low quality) + 最近(快速,低品質) + + + + Bilinear + 雙線性 + + + + Lanczos (better quality) + Lanczos(品質更好) + + + + Page Flow + 頁面流 + + + + Image adjustment + 圖像調整 + + + + + Restart is needed + 需要重啟 + + + + Comics directory + 漫畫目錄 + + + + PropertiesDialog + + + General info + 基本資訊 + + + + Authors + 作者 + + + + Publishing + 出版 + + + + Plot + 情節 + + + + Notes + 筆記 + + + + Cover page + 封面 + + + + Load previous page as cover + 載入上一頁作為封面 + + + + Load next page as cover + 載入下一頁作為封面 + + + + Reset cover to the default image + 將封面重設為預設圖片 + + + + Load custom cover image + 載入自訂封面圖片 + + + + Series: + 系列: + + + + Title: + 標題: + + + + + + of: + 的: + + + + Issue number: 發行數量: @@ -2216,17 +2602,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t alt. number: - + 替代。數字: Alternate series: - + 替代系列: Series Group: - + 系列組: @@ -2272,12 +2658,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Editor(s): - + 編輯: Imprint: - + 印記: @@ -2317,22 +2703,22 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Type: - + 類型: Language (ISO): - + 語言(ISO): Invalid cover - + 封面無效 The image is invalid. - + 該圖像無效。 Manga: @@ -2351,22 +2737,22 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Teams: - + 團隊: Locations: - + 地點: Main character or team: - + 主要角色或團隊: Review: - + 審查: @@ -2376,7 +2762,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Tags: - + 標籤: @@ -2404,6 +2790,22 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 編輯漫畫資訊 + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 + +此應用程式支援持久性設置,要設定它們,請編輯此文件 %1 +若要了解可用設置,請查看文件:https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + QObject @@ -2447,55 +2849,73 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 嚴重錯誤 - + Select custom cover - + 選擇自訂封面 - + Images (%1) - + 圖片 (%1) + + + + The file could not be read or is not valid JSON. + 無法讀取該檔案或該檔案不是有效的 JSON。 + + + + This theme is for %1, not %2. + 此主題適用於 %1,而不是 %2。 + + + + Libraries + + + + + Folders + 檔夾 + + + + Reading Lists + 閱讀列表 QsLogging::LogWindowModel - Time - 時間 + 時間 - Level - 等級 + 等級 - Message - 資訊 + 資訊 QsLogging::Window - &Pause - 中止(&P) + 中止(&P) - &Resume - 恢復(&R) + 恢復(&R) - Save log - 保存日誌 + 保存日誌 - Log file (*.log) - 日誌檔 (*.log) + 日誌檔 (*.log) @@ -2516,7 +2936,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 取消 - + Rename current library 重命名當前庫 @@ -2524,18 +2944,18 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ScraperResultsPaginator - + Number of volumes found : %1 搜索結果: %1 - - + + page %1 of %2 第 %1 頁 共 %2 頁 - + Number of %1 found : %2 第 %1 頁 共: %2 條 @@ -2546,17 +2966,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information for this comic. Please provide some additional information. - 請提供附加資訊. + 請提供附加資訊. - + Series: 系列: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + 使用精確匹配搜尋。如果您想要尋找與名稱中某些單字相符的捲,請停用。 @@ -2567,42 +2987,42 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 請提供附加資訊. - + Series: 系列: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + 使用精確匹配搜尋。如果您想要尋找與名稱中某些單字相符的捲,請停用。 SelectComic - + Please, select the right comic info. 請正確選擇漫畫資訊. - + comics 漫畫 - + loading cover 加載封面 - + loading description 加載描述 - + comic description unavailable - + 漫畫描述不可用 description unavailable @@ -2612,39 +3032,39 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SelectVolume - + Please, select the right series for your comic. 請選擇正確的漫畫系列。 - + Filter: - + 篩選: - + volumes - + Nothing found, clear the filter if any. - + 未找到任何內容,如果有,請清除過濾器。 - + loading cover 加載封面 - + loading description 加載描述 - + volume description unavailable - + 卷描述不可用 description unavailable @@ -2659,12 +3079,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 您正在嘗試同時獲取各種漫畫的資訊,它們是同一系列的嗎? - + yes - + no @@ -2672,41 +3092,41 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ServerConfigDialog - + set port 設置端口 - + Server connectivity information 伺服器連接資訊 - + Scan it! 掃一掃! - + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> YACReader適用於iOS設備. <a href='http://ios.yacreader.com'style ='color:rgb(193,148,65)'>下載</a> - + Choose an IP address 選擇IP地址 - + Port 端口 - + enable the server 啟用伺服器 @@ -2724,330 +3144,1171 @@ to improve the performance SortVolumeComics - + Please, sort the list of comics on the left until it matches the comics' information. 請在左側對漫畫列表進行排序,直到它與漫畫的資訊相符。 - + sort comics to match comic information 排序漫畫以匹配漫畫資訊 - + issues 發行 - + remove selected comics 移除所選漫畫 - + restore all removed comics 恢復所有移除的漫畫 - TitleHeader + ThemeEditorDialog - - SEARCH - 搜索 + + Theme Editor + 主題編輯器 - - - UpdateLibraryDialog - - Updating.... - 更新中... + + + + + - - Cancel - 取消 + + - + - - - Update library - 更新庫 + + i + - - - VolumeComicsModel - - title - 標題 + + Expand all + 全部展開 - - - VolumesModel - - year - + + Collapse all + 全部折疊 - - issues - 發行 + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + 按住可在 UI 中閃爍所選值(洋紅色/切換/0↔10)。發布後恢復原樣。 - - publisher - 出版者 + + Search… + 搜尋… - - - YACReader::TrayIconController - - &Restore - 複位(&R) + + Light + 亮度 - - Systray - 系統託盤 + + Dark + 黑暗的 - - YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary 將繼續在系統託盤中運行. 想要終止程式, 請在系統託盤圖示的上下文菜單中選擇<b>退出</b>. + + ID: + ID: - - - YACReader::WhatsNewDialog - - Close - 關閉 + + Display name: + 顯示名稱: - - - YACReaderFieldEdit - - - Click to overwrite - 點擊以覆蓋 + + Variant: + 變體: - - Restore to default - 恢復默認 + + Theme info + 主題訊息 - - - YACReaderFieldPlainTextEdit - - - - - Click to overwrite - 點擊以覆蓋 + + Parameter + 範圍 - - Restore to default - 恢復默認 + + Value + 價值 - - - YACReaderFlowConfigWidget - - How to show covers: - 封面顯示方式: + + Save and apply + 儲存並應用 - - CoverFlow look - 封面流 + + Export to file... + 匯出到文件... - - Stripe look - 條狀 + + Load from file... + 從檔案載入... - - Overlapped Stripe look - 重疊條狀 + + Close + 關閉 - - - YACReaderGLFlowConfigWidget - - Presets: - 預設: + + Double-click to edit color + 雙擊編輯顏色 - - Classic look - 經典 + + + + + + + true + 真的 - - Stripe look - 條狀 + + + + + false + 錯誤的 - - Overlapped Stripe look - 重疊條狀 + + Double-click to toggle + 按兩下切換 - - Modern look - 現代 + + Double-click to edit value + 雙擊編輯值 - - Roulette look - 輪盤 + + + + Edit: %1 + 編輯:%1 - - Show advanced settings - 顯示高級選項 + + Save theme + 儲存主題 - - Custom: - 自定義: + + + JSON files (*.json);;All files (*) + JSON 檔案 (*.json);;所有檔案 (*) - - View angle - 視角 + + Save failed + 保存失敗 - - Position - 位置 + + Could not open file for writing: +%1 + 無法開啟文件進行寫入: +%1 - - Cover gap - 封面間距 + + Load theme + 載入主題 - - Central gap - 中心間距 + + + + Load failed + 載入失敗 - - Zoom - 縮放 + + Could not open file: +%1 + 無法開啟檔案: +%1 - - Y offset - Y位移 + + Invalid JSON: +%1 + 無效的 JSON: +%1 - - Z offset - Z位移 + + Expected a JSON object. + 需要一個 JSON 物件。 - - - Cover Angle + + + TitleHeader + + + SEARCH + 搜索 + + + + UpdateLibraryDialog + + + Updating.... + 更新中... + + + + Cancel + 取消 + + + + Update library + 更新庫 + + + + Viewer + + + + Press 'O' to open comic. + 按下 'O' 以打開漫畫. + + + + Not found + 未找到 + + + + Comic not found + 未找到漫畫 + + + + Error opening comic + 打開漫畫時發生錯誤 + + + + CRC Error + CRC 校驗失敗 + + + + Loading...please wait! + 載入中... 請稍候! + + + + Page not available! + 頁面不可用! + + + + Cover! + 封面! + + + + Last page! + 尾頁! + + + + VolumeComicsModel + + + title + 標題 + + + + VolumesModel + + + year + + + + + issues + 發行 + + + + publisher + 出版者 + + + + YACReader3DFlowConfigWidget + + + Presets: + 預設: + + + + Classic look + 經典 + + + + Stripe look + 條狀 + + + + Overlapped Stripe look + 重疊條狀 + + + + Modern look + 現代 + + + + Roulette look + 輪盤 + + + + Show advanced settings + 顯示高級選項 + + + + Custom: + 自定義: + + + + View angle + 視角 + + + + Position + 位置 + + + + Cover gap + 封面間距 + + + + Central gap + 中心間距 + + + + Zoom + 縮放 + + + + Y offset + Y位移 + + + + Z offset + Z位移 + + + + Cover Angle 封面角度 - + + Visibility + 透明度 + + + + Light + 亮度 + + + + Max angle + 最大角度 + + + + Low Performance + 低性能 + + + + High Performance + 高性能 + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + 使用VSync (在全屏模式下提高圖像品質, 性能更差) + + + + Performance: + 性能: + + + + YACReader::MainWindowViewer + + + &Open + 打開(&O) + + + + Open a comic + 打開漫畫 + + + + New instance + 新建實例 + + + + Open Folder + 打開檔夾 + + + + Open image folder + 打開圖片檔夾 + + + + Open latest comic + 打開最近的漫畫 + + + + Open the latest comic opened in the previous reading session + 打開最近閱讀漫畫 + + + + Clear + 清空 + + + + Clear open recent list + 清空最近訪問列表 + + + + Save + 保存 + + + + + Save current page + 保存當前頁面 + + + + Previous Comic + 上一個漫畫 + + + + + + Open previous comic + 打開上一個漫畫 + + + + Next Comic + 下一個漫畫 + + + + + + Open next comic + 打開下一個漫畫 + + + + &Previous + 上一頁(&P) + + + + + + Go to previous page + 轉至上一頁 + + + + &Next + 下一頁(&N) + + + + + + Go to next page + 轉至下一頁 + + + + Fit Height + 適應高度 + + + + Fit image to height + 縮放圖片以適應高度 + + + + Fit Width + 適合寬度 + + + + Fit image to width + 縮放圖片以適應寬度 + + + + Show full size + 顯示全尺寸 + + + + Fit to page + 適應頁面 + + + + Continuous scroll + 連續滾動 + + + + Switch to continuous scroll mode + 切換到連續滾動模式 + + + + Reset zoom + 重置縮放 + + + + Show zoom slider + 顯示縮放滑塊 + + + + Zoom+ + 放大 + + + + Zoom- + 縮小 + + + + Rotate image to the left + 向左旋轉圖片 + + + + Rotate image to the right + 向右旋轉圖片 + + + + Double page mode + 雙頁模式 + + + + Switch to double page mode + 切換至雙頁模式 + + + + Double page manga mode + 雙頁漫畫模式 + + + + Reverse reading order in double page mode + 雙頁模式 (逆序閱讀) + + + + Go To + 跳轉 + + + + Go to page ... + 跳轉至頁面 ... + + + + Options + 選項 + + + + YACReader options + YACReader 選項 + + + + + Help + 幫助 + + + + Help, About YACReader + 幫助, 關於 YACReader + + + + Magnifying glass + 放大鏡 + + + + Switch Magnifying glass + 切換放大鏡 + + + + Set bookmark + 設置書簽 + + + + Set a bookmark on the current page + 在當前頁面設置書簽 + + + + Show bookmarks + 顯示書簽 + + + + Show the bookmarks of the current comic + 顯示當前漫畫的書簽 + + + + Show keyboard shortcuts + 顯示鍵盤快捷鍵 + + + + Show Info + 顯示資訊 + + + + Close + 關閉 + + + + Show Dictionary + 顯示字典 + + + + Show go to flow + 顯示頁面流 + + + + Edit shortcuts + 編輯快捷鍵 + + + + &File + 檔(&F) + + + + + Open recent + 最近打開的檔 + + + + File + + + + + Edit + 編輯 + + + + View + 查看 + + + + Go + 轉到 + + + + Window + 窗口 + + + + + + Open Comic + 打開漫畫 + + + + + + Comic files + 漫畫檔 + + + + Open folder + 打開檔夾 + + + + page_%1.jpg + 頁_%1.jpg + + + + Image files (*.jpg) + 圖像檔 (*.jpg) + + + + + Comics + 漫畫 + + + + + General + 常規 + + + + + Magnifiying glass + 放大鏡 + + + + + Page adjustement + 頁面調整 + + + + + Reading + 閱讀 + + + + Toggle fullscreen mode + 切換全屏模式 + + + + Hide/show toolbar + 隱藏/顯示 工具欄 + + + + Size up magnifying glass + 增大放大鏡尺寸 + + + + Size down magnifying glass + 減小放大鏡尺寸 + + + + Zoom in magnifying glass + 增大縮放級別 + + + + Zoom out magnifying glass + 減小縮放級別 + + + + Reset magnifying glass + 重置放大鏡 + + + + Toggle between fit to width and fit to height + 切換顯示為"適應寬度"或"適應高度" + + + + Autoscroll down + 向下自動滾動 + + + + Autoscroll up + 向上自動滾動 + + + + Autoscroll forward, horizontal first + 向前自動滾動,水準優先 + + + + Autoscroll backward, horizontal first + 向後自動滾動,水準優先 + + + + Autoscroll forward, vertical first + 向前自動滾動,垂直優先 + + + + Autoscroll backward, vertical first + 向後自動滾動,垂直優先 + + + + Move down + 向下移動 + + + + Move up + 向上移動 + + + + Move left + 向左移動 + + + + Move right + 向右移動 + + + + Go to the first page + 轉到第一頁 + + + + Go to the last page + 轉到最後一頁 + + + + Offset double page to the left + 雙頁向左偏移 + + + + Offset double page to the right + 雙頁向右偏移 + + + + There is a new version available + 有新版本可用 + + + + Do you want to download the new version? + 你要下載新版本嗎? + + + + Remind me in 14 days + 14天後提醒我 + + + + Not now + 現在不 + + + + YACReader::TrayIconController + + + &Restore + 複位(&R) + + + + Systray + 系統託盤 + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary 將繼續在系統託盤中運行. 想要終止程式, 請在系統託盤圖示的上下文菜單中選擇<b>退出</b>. + + + + YACReader::WhatsNewDialog + + Close + 關閉 + + + + YACReaderFieldEdit + + + + Click to overwrite + 點擊以覆蓋 + + + + Restore to default + 恢復默認 + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + 點擊以覆蓋 + + + + Restore to default + 恢復默認 + + + + YACReaderFlowConfigWidget + + How to show covers: + 封面顯示方式: + + + CoverFlow look + 封面流 + + + Stripe look + 條狀 + + + Overlapped Stripe look + 重疊條狀 + + + + YACReaderGLFlowConfigWidget + + Presets: + 預設: + + + Classic look + 經典 + + + Stripe look + 條狀 + + + Overlapped Stripe look + 重疊條狀 + + + Modern look + 現代 + + + Roulette look + 輪盤 + + + Show advanced settings + 顯示高級選項 + + + Custom: + 自定義: + + + View angle + 視角 + + + Position + 位置 + + + Cover gap + 封面間距 + + + Central gap + 中心間距 + + + Zoom + 縮放 + + + Y offset + Y位移 + + + Z offset + Z位移 + + + Cover Angle + 封面角度 + + Visibility - 透明度 + 透明度 - Light - 亮度 + 亮度 - Max angle - 最大角度 + 最大角度 - Low Performance - 低性能 + 低性能 - High Performance - 高性能 + 高性能 - Use VSync (improve the image quality in fullscreen mode, worse performance) - 使用VSync (在全屏模式下提高圖像品質, 性能更差) + 使用VSync (在全屏模式下提高圖像品質, 性能更差) - Performance: - 性能: + 性能: YACReaderNavigationController - No favorites - 沒有收藏 + 沒有收藏 - You are not reading anything yet, come on!! - 你還沒有閱讀任何東西,加油!! - - - - There are no recent comics! - + 你還沒有閱讀任何東西,加油!! YACReaderOptionsDialog - + Save 保存 - + Cancel 取消 - + Edit shortcuts 編輯快捷鍵 - + Shortcuts 快捷鍵 - Use hardware acceleration (restart needed) - 使用硬體加速 (需要重啟) + 使用硬體加速 (需要重啟) YACReaderSearchLineEdit - + type to search 搜索類型 @@ -3055,34 +4316,60 @@ to improve the performance YACReaderSideBar - Libraries - + - Folders - 檔夾 + 檔夾 - Reading Lists - 閱讀列表 + 閱讀列表 - LIBRARIES - + - FOLDERS - 檔夾 + 檔夾 - READING LISTS - 閱讀列表 + 閱讀列表 + + + + YACReaderSlider + + + Reset + 重置 + + + + YACReaderTranslator + + + YACReader translator + YACReader 翻譯 + + + + + Translation + 翻譯 + + + + clear + 清空 + + + + Service not available + 服務不可用 diff --git a/YACReaderLibrary/yacreaderlibrary_zh_TW.ts b/YACReaderLibrary/yacreaderlibrary_zh_TW.ts index 1b66465eb..ffb428bed 100644 --- a/YACReaderLibrary/yacreaderlibrary_zh_TW.ts +++ b/YACReaderLibrary/yacreaderlibrary_zh_TW.ts @@ -12,82 +12,70 @@ AddLabelDialog - + Label name: 標籤名稱: - + Choose a color: 選擇標籤顏色: - red - + - orange - + - yellow - + - green - + - cyan - + - blue - + - violet - 紫羅蘭 + 紫羅蘭 - purple - + - pink - + - white - + - light - 淺色 + 淺色 - dark - 深色 + 深色 - + accept 接受 - + cancel 取消 @@ -116,7 +104,7 @@ 取消 - + Add an existing library 添加一個現有庫 @@ -144,10 +132,150 @@ 取消 + + AppearanceTabWidget + + + Color scheme + 配色方案 + + + + System + 系統 + + + + Light + 亮度 + + + + Dark + 黑暗的 + + + + Custom + 風俗 + + + + Remove + 消除 + + + + Remove this user-imported theme + 刪除此使用者匯入的主題 + + + + Light: + 光: + + + + Dark: + 黑暗的: + + + + Custom: + 自定義: + + + + Import theme... + 導入主題... + + + + Theme + 主題 + + + + Theme editor + 主題編輯器 + + + + Open Theme Editor... + 開啟主題編輯器... + + + + Theme editor error + 主題編輯器錯誤 + + + + The current theme JSON could not be loaded. + 無法載入目前主題 JSON。 + + + + Import theme + 導入主題 + + + + JSON files (*.json);;All files (*) + JSON 檔案 (*.json);;所有檔案 (*) + + + + Could not import theme from: +%1 + 無法從以下位置匯入主題: +%1 + + + + Could not import theme from: +%1 + +%2 + 無法從以下位置匯入主題: +%1 + +%2 + + + + Import failed + 導入失敗 + + + + BookmarksDialog + + + Lastest Page + 尾頁 + + + + Close + 關閉 + + + + Click on any image to go to the bookmark + 點擊任意圖片以跳轉至相應書簽位置 + + + + + Loading... + 載入中... + + ClassicComicsView - + Hide comic flow 隱藏漫畫流 @@ -155,84 +283,84 @@ ComicInfoView - + + Characters + 角色 + + + Main character or team - + 主要角色或團隊 - + Teams - + 團隊 - + Locations - + 地點 - + Authors - 作者 + 作者 - + writer - + 編劇 - + penciller - + 鉛筆畫師 - + inker - + 墨線師 - + colorist - + 上色師 - + letterer - + 字效師 - + cover artist - + 封面畫師 - + editor - + 編輯 - + imprint - + 出版品牌 - + Publisher - + 出版社 - + color - + 彩色 - + b/w - - - - - Characters - + 黑白 @@ -290,86 +418,94 @@ Series - + 系列 Volume - + 體積 Story Arc - + 故事線 ComicVineDialog - + skip 忽略 - + back 返回 - + next 下一步 - + search 搜索 - + close 關閉 - - - + + + Looking for volume... 搜索卷... - - + + comic %1 of %2 - %3 第 %1 本 共 %2 本 - %3 - + %1 comics selected 已選擇 %1 本漫畫 - + Error connecting to ComicVine ComicVine 連接時出錯 - - + + Retrieving tags for : %1 正在檢索標籤: %1 - + Retrieving volume info... 正在接收卷資訊... - + Looking for comic... 搜索漫畫中... + + ContinuousPageWidget + + + Loading page %1 + 正在載入頁面 %1 + + CreateLibraryDialog @@ -398,17 +534,17 @@ 創建一個新的庫可能需要幾分鐘時間,您可以先停止該進程,稍後可以通過更新庫選項來更新數據。 - + Create new library 創建新的漫畫庫 - + Path not found 未找到路徑 - + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder 所選路徑不存在或不是有效路徑. 確保您具有此檔夾的寫入許可權 @@ -431,12 +567,12 @@ 快捷鍵設置 - + Shortcut in use 快捷鍵被佔用 - + The shortcut "%1" is already assigned to other function 快捷鍵 "%1" 已被映射至其他功能 @@ -444,26 +580,27 @@ EmptyFolderWidget - - Subfolders in this folder - 建立子檔夾 + 建立子檔夾 - Empty folder - 空文件夾 + 空文件夾 - Drag and drop folders and comics here - 拖動檔夾或者漫畫到這裏 + 拖動檔夾或者漫畫到這裏 + + + + This folder doesn't contain comics yet + 該資料夾還沒有漫畫 EmptyLabelWidget - + This label doesn't contain comics yet 此標籤尚未包含漫畫 @@ -477,6 +614,24 @@ 此閱讀列表尚未包含任何漫畫 + + EmptySpecialListWidget + + + No favorites + 沒有收藏 + + + + You are not reading anything yet, come on!! + 你還沒有閱讀任何東西,加油!! + + + + There are no recent comics! + 沒有最近的漫畫! + + ExportComicsInfoDialog @@ -495,22 +650,22 @@ 取消 - + Export comics info 導出漫畫資訊 - + Destination database name 目標資料庫名稱 - + Problem found while writing 寫入時出現問題 - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder 選定的輸出檔路徑不存在或路徑無效. 確保您具有此檔夾的寫入許可權 @@ -533,22 +688,22 @@ 取消 - + Create covers package 創建封面包 - + Problem found while writing 寫入時出現問題 - + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder 選定的輸出檔路徑不存在或路徑無效. 確保您具有此檔夾的寫入許可權 - + Destination directory 目標目錄 @@ -579,23 +734,52 @@ FolderContentView - + Continue Reading... - + 繼續閱讀... - FolderContentView6 + GoToDialog - - Continue Reading... - + + Page : + 頁碼 : + + + + Go To + 跳轉 + + + + Cancel + 取消 + + + + + Total pages : + 總頁數: + + + + Go to... + 跳轉至 ... + + + + GoToFlowToolBar + + + Page : + 頁碼 : GridComicsView - + Show info 顯示資訊 @@ -603,17 +787,17 @@ HelpAboutDialog - + About 關於 - + Help 幫助 - + System info 系統資訊 @@ -641,7 +825,7 @@ 取消 - + Comics info file (*.ydb) 漫畫資訊檔(*.ydb) @@ -674,12 +858,12 @@ 取消 - + Extract a catalog 提取目錄 - + Compresed library covers (*.clc) 已壓縮的庫封面 (*.clc) @@ -687,52 +871,52 @@ ImportWidget - + stop 停止 - + Some of the comics being added... 正在添加漫畫... - + Importing comics 正在導入漫畫 - + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> <p>YACReaderLibrary現在正在創建一個新庫。</p><p>這可能需要幾分鐘時間,您可以先停止該進程,稍後可以通過更新庫選項來更新數據。</p> - + Updating the library 正在更新庫 - + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> <p>正在更新當前庫。要獲得更快的更新,請經常更新您的庫。</p><p>您可以停止該進程,稍後繼續更新操作。</p> - + Upgrading the library 正在更新庫 - + <p>The current library is being upgraded, please wait.</p> <p>正在更新當前漫畫庫, 請稍候.</p> - + Scanning the library 正在掃描庫 - + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> <p>正在掃描當前庫的舊版 XML metadata 資訊。</p><p>這只需要執行一次,且只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 時。</p> @@ -740,12 +924,12 @@ LibraryWindow - + YACReader Library YACReader 庫 - + Library @@ -822,7 +1006,7 @@ 保存所選的封面為jpg - + Set as read 設為已讀 @@ -831,8 +1015,8 @@ 漫畫設為已讀 - - + + Set as unread 設為未讀 @@ -841,25 +1025,25 @@ 漫畫設為未讀 - - - + + + manga - + 漫畫 - - - + + + comic - + 漫畫 - - - + + + web comic - + 網路漫畫 Show/Hide marks @@ -870,18 +1054,18 @@ 折疊所有節點 - - - + + + western manga (left to right) - + 西方漫畫(從左到右) Assign current order to comics 將當前序號分配給漫畫 - + Library not available Library ' 庫不可用 @@ -891,7 +1075,7 @@ 全屏模式 開/關 - + Rescan library for XML info 重新掃描庫的 XML 資訊 @@ -905,7 +1089,7 @@ Set issue as manga - Set issue as manga + 將問題設定為漫畫 Set as normal @@ -920,7 +1104,7 @@ 幫助, 關於 YACReader - + Delete folder 刪除檔夾 @@ -941,17 +1125,17 @@ 顯示漫畫伺服器選項對話框 - + Open folder... 打開檔夾... - + Set as uncompleted 設為未完成 - + Set as completed 設為已完成 @@ -1004,7 +1188,7 @@ 退出(&Q) - + Update folder 更新檔夾 @@ -1057,170 +1241,170 @@ 將所選漫畫添加到收藏夾列表 - + Folder 檔夾 - + Comic 漫畫 - + Upgrade failed 更新失敗 - + There were errors during library upgrade in: 漫畫庫更新時出現錯誤: - + Update needed 需要更新 - + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? 此庫是使用舊版本的YACReaderLibrary創建的. 它需要更新. 現在更新? - + Download new version 下載新版本 - + This library was created with a newer version of YACReaderLibrary. Download the new version now? 此庫是使用較新版本的YACReaderLibrary創建的。 立即下載新版本? - + Library '%1' is no longer available. Do you want to remove it? 庫 '%1' 不再可用。 你想刪除它嗎? - + Old library 舊的庫 - + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? - - + + Copying comics... 複製漫畫中... - - + + Moving comics... 移動漫畫中... - + Folder name: 檔夾名稱: - + No folder selected 沒有選中的檔夾 - + Please, select a folder first 請先選擇一個檔夾 - + Error in path 路徑錯誤 - + There was an error accessing the folder's path 訪問檔夾的路徑時出錯 - + The selected folder and all its contents will be deleted from your disk. Are you sure? 所選檔夾及其所有內容將從磁片中刪除。 你確定嗎? - + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. 嘗試刪除所選檔夾時出現問題。 請檢查寫入許可權,並確保沒有其他應用程式在使用這些檔夾或檔。 - + Add new reading lists 添加新的閱讀列表 - - + + List name: 列表名稱: - + Delete list/label 刪除 列表/標籤 - + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? 所選項目將被刪除,您的漫畫或檔夾將不會從您的磁片中刪除。 你確定嗎? - + Rename list name 重命名列表 - - - + + + 4koma (top to botom) - + 4koma(由上至下) - - - - + + + + Set type - + 套裝類型 - + Set custom cover - + 設定自訂封面 - + Delete custom cover - + 刪除自訂封面 - + Save covers 保存封面 - + You are adding too many libraries. 您添加的庫太多了。 - + You are adding too many libraries. You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. @@ -1233,69 +1417,69 @@ YACReaderLibrary will not stop you from creating more libraries but you should k YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低的庫數量來提升性能。 - - + + YACReader not found YACReader 未找到 - + Error - 錯誤 + 錯誤 - + Error opening comic with third party reader. - + 使用第三方閱讀器開啟漫畫時出錯。 - + Library not found 未找到庫 - + The selected folder doesn't contain any library. 所選檔夾不包含任何庫。 - + Are you sure? 你確定嗎? - + Do you want remove 你想要刪除 - + library? 庫? - + Remove and delete metadata 移除並刪除元數據 - + Library info - + 圖書館資訊 - + Assign comics numbers 分配漫畫編號 - + Assign numbers starting in: 從以下位置開始分配編號: - - + + Unable to delete 無法刪除 @@ -1304,7 +1488,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 顯示或隱藏閱讀標記 - + Add new folder 添加新的檔夾 @@ -1321,82 +1505,82 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 漫畫視圖之間的變化 - + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. 未找到YACReader. YACReader應安裝在與YACReaderLibrary相同的檔夾中. - + YACReader not found. There might be a problem with your YACReader installation. 未找到YACReader. YACReader的安裝可能有問題. - + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. 嘗試刪除所選漫畫時出現問題。 請檢查所選檔或包含檔夾中的寫入許可權。 - + Invalid image - + 圖片無效 - + The selected file is not a valid image. - + 所選檔案不是有效影像。 - + Error saving cover - + 儲存封面時發生錯誤 - + There was an error saving the cover image. - + 儲存封面圖片時發生錯誤。 - + Error creating the library 創建庫時出錯 - + Error updating the library 更新庫時出錯 - + Error opening the library 打開庫時出錯 - + Delete comics 刪除漫畫 - + All the selected comics will be deleted from your disk. Are you sure? 所有選定的漫畫都將從您的磁片中刪除。你確定嗎? - + Remove comics 移除漫畫 - + Comics will only be deleted from the current label/list. Are you sure? 漫畫只會從當前標籤/列表中刪除。 你確定嗎? - + Library name already exists 庫名已存在 - + There is another library with the name '%1'. 已存在另一個名為'%1'的庫。 @@ -1404,439 +1588,439 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 LibraryWindowActions - + Create a new library - 創建一個新的庫 + 創建一個新的庫 - + Open an existing library - 打開現有的庫 + 打開現有的庫 - - + + Export comics info - 導出漫畫資訊 + 導出漫畫資訊 - - + + Import comics info - 導入漫畫資訊 + 導入漫畫資訊 - + Pack covers - 打包封面 + 打包封面 - + Pack the covers of the selected library - 打包所選庫的封面 + 打包所選庫的封面 - + Unpack covers - 解壓封面 + 解壓封面 - + Unpack a catalog - 解壓目錄 + 解壓目錄 - + Update library - 更新庫 + 更新庫 - + Update current library - 更新當前庫 + 更新當前庫 - + Rename library - 重命名庫 + 重命名庫 - + Rename current library - 重命名當前庫 + 重命名當前庫 - + Remove library - 移除庫 + 移除庫 - + Remove current library from your collection - 從您的集合中移除當前庫 + 從您的集合中移除當前庫 - + Rescan library for XML info - 重新掃描庫的 XML 資訊 + 重新掃描庫的 XML 資訊 - + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. - 嘗試查找漫畫檔內嵌的 XML 資訊。只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 或者使用第三方軟體嵌入 XML 資訊時,才需要執行該操作。 + 嘗試查找漫畫檔內嵌的 XML 資訊。只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 或者使用第三方軟體嵌入 XML 資訊時,才需要執行該操作。 - + Show library info - + 顯示圖書館資訊 - + Show information about the current library - + 顯示當前庫的信息 - + Open current comic - 打開當前漫畫 + 打開當前漫畫 - + Open current comic on YACReader - 用YACReader打開漫畫 + 用YACReader打開漫畫 - + Save selected covers to... - 選中的封面保存到... + 選中的封面保存到... - + Save covers of the selected comics as JPG files - 保存所選的封面為jpg + 保存所選的封面為jpg - - + + Set as read - 設為已讀 + 設為已讀 - + Set comic as read - 漫畫設為已讀 + 漫畫設為已讀 - - + + Set as unread - 設為未讀 + 設為未讀 - + Set comic as unread - 漫畫設為未讀 + 漫畫設為未讀 - - + + manga - + 漫畫 - + Set issue as manga - Set issue as manga + 將問題設定為漫畫 - - + + comic - + 漫畫 - + Set issue as normal - 設置發行狀態為正常發行 + 設置發行狀態為正常發行 - + western manga - + 西方漫畫 - + Set issue as western manga - + 將問題設定為西方漫畫 - - + + web comic - + 網路漫畫 - + Set issue as web comic - + 將問題設定為網路漫畫 - - + + yonkoma - + 四科馬 - + Set issue as yonkoma - + 將問題設定為 yonkoma - + Show/Hide marks - 顯示/隱藏標記 + 顯示/隱藏標記 - + Show or hide read marks - 顯示或隱藏閱讀標記 + 顯示或隱藏閱讀標記 - + Show/Hide recent indicator - + 顯示/隱藏最近的指標 - + Show or hide recent indicator - + 顯示或隱藏最近的指示器 - - + + Fullscreen mode on/off - 全屏模式 開/關 + 全屏模式 開/關 - + Help, About YACReader - 幫助, 關於 YACReader + 幫助, 關於 YACReader - + Add new folder - 添加新的檔夾 + 添加新的檔夾 - + Add new folder to the current library - 在當前庫下添加新的檔夾 + 在當前庫下添加新的檔夾 - + Delete folder - 刪除檔夾 + 刪除檔夾 - + Delete current folder from disk - 從磁片上刪除當前檔夾 + 從磁片上刪除當前檔夾 - + Select root node - 選擇根節點 + 選擇根節點 - + Expand all nodes - 展開所有節點 + 展開所有節點 - + Collapse all nodes - 折疊所有節點 + 折疊所有節點 - + Show options dialog - 顯示選項對話框 + 顯示選項對話框 - + Show comics server options dialog - 顯示漫畫伺服器選項對話框 + 顯示漫畫伺服器選項對話框 - - + + Change between comics views - 漫畫視圖之間的變化 + 漫畫視圖之間的變化 - + Open folder... - 打開檔夾... + 打開檔夾... - + Set as uncompleted - 設為未完成 + 設為未完成 - + Set as completed - 設為已完成 + 設為已完成 - + Set custom cover - + 設定自訂封面 - + Delete custom cover - + 刪除自訂封面 - + western manga (left to right) - + 西方漫畫(從左到右) - + Open containing folder... - 打開包含檔夾... + 打開包含檔夾... - + Reset comic rating - 重置漫畫評分 + 重置漫畫評分 - + Select all comics - 全選漫畫 + 全選漫畫 - + Edit - 編輯 + 編輯 - + Assign current order to comics - 將當前序號分配給漫畫 + 將當前序號分配給漫畫 - + Update cover - 更新封面 + 更新封面 - + Delete selected comics - 刪除所選的漫畫 + 刪除所選的漫畫 - + Delete metadata from selected comics - + 從選定的漫畫中刪除元數據 - + Download tags from Comic Vine - 從 Comic Vine 下載標籤 + 從 Comic Vine 下載標籤 - + Focus search line - 聚焦於搜索行 + 聚焦於搜索行 - + Focus comics view - 聚焦於漫畫視圖 + 聚焦於漫畫視圖 - + Edit shortcuts - 編輯快捷鍵 + 編輯快捷鍵 - + &Quit - 退出(&Q) + 退出(&Q) - + Update folder - 更新檔夾 + 更新檔夾 - + Update current folder - 更新當前檔夾 + 更新當前檔夾 - + Scan legacy XML metadata - + 掃描舊版 XML 元數據 - + Add new reading list - 添加新的閱讀列表 + 添加新的閱讀列表 - + Add a new reading list to the current library - 在當前庫添加新的閱讀列表 + 在當前庫添加新的閱讀列表 - + Remove reading list - 移除閱讀列表 + 移除閱讀列表 - + Remove current reading list from the library - 從當前庫移除閱讀列表 + 從當前庫移除閱讀列表 - + Add new label - 添加新標籤 + 添加新標籤 - + Add a new label to this library - 在當前庫添加標籤 + 在當前庫添加標籤 - + Rename selected list - 重命名列表 + 重命名列表 - + Rename any selected labels or lists - 重命名任何選定的標籤或列表 + 重命名任何選定的標籤或列表 - + Add to... - 添加到... + 添加到... - + Favorites - 收藏夾 + 收藏夾 - + Add selected comics to favorites list - 將所選漫畫添加到收藏夾列表 + 將所選漫畫添加到收藏夾列表 @@ -1850,189 +2034,209 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 LogWindow - Log window - 日誌窗口 + 日誌窗口 - &Pause - 中止(&P) + 中止(&P) - &Save - 保存(&S) + 保存(&S) - C&lear - 清空(&l) + 清空(&l) - &Copy - 複製(&C) + 複製(&C) - Level: - 等級: + 等級: - &Auto scroll - 自動滾動(&A) + 自動滾動(&A) NoLibrariesWidget - + You don't have any libraries yet 你還沒有庫 - + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>您可以在任何檔夾中創建庫,YACReaderLibrary將導入此檔夾中的所有漫畫和文件夾。如果已有庫,則可以打開它們。</p><p>您可以把YACReader當成獨立應用來閱讀電腦上的漫畫。</p> - + create your first library 創建你的第一個庫 - + add an existing one 添加一個現有庫 + + NoSearchResultsWidget + + + No results + 沒有結果 + + OptionsDialog - + + + Language + 語言 + + + + + Application language + 應用程式語言 + + + + + System default + 系統預設 + + + Tray icon settings (experimental) 託盤圖示設置 (實驗特性) - + Close to tray 關閉至託盤 - + Start into the system tray 啟動至系統託盤 - + Edit Comic Vine API key 編輯Comic Vine API 密匙 - + Comic Vine API key Comic Vine API 密匙 - + ComicInfo.xml legacy support - + ComicInfo.xml 遺留支持 - + Import metadata from ComicInfo.xml when adding new comics Import metada from ComicInfo.xml when adding new comics - + 新增漫畫時從 ComicInfo.xml 匯入元數據 - + Consider 'recent' items added or updated since X days ago - + 考慮自 X 天前新增或更新的「最近」項目 - + Third party reader - + 第三方閱讀器 - + Write {comic_file_path} where the path should go in the command - + 在命令中應將路徑寫入 {comic_file_path} - + + Clear - + 清空 - + Update libraries at startup - + 啟動時更新庫 - + Try to detect changes automatically - + 嘗試自動偵測變化 - + Update libraries periodically - + 定期更新庫 - + Interval: - + 間隔: - + 30 minutes - + 30分鐘 - + 1 hour - + 1小時 - + 2 hours - + 2小時 - + 4 hours - + 4小時 - + 8 hours - + 8小時 - + 12 hours - + 12小時 - + daily - + 日常的 - + Update libraries at certain time - + 定時更新庫 - + Time: - + 時間: - + WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. @@ -2040,162 +2244,344 @@ To stop an automatic update tap on the loading indicator next to the Libraries t WARNING! During library updates writes to the database are disabled! Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. - + 警告!在庫更新期間,將停用對資料庫的寫入! +當您可能正在積極使用應用程式時,請勿安排更新。 +在自動更新期間,應用程式將阻止某些操作,直到更新完成。 +若要停止自動更新,請點選庫標題旁的載入指示器。 - + Modifications detection - + 修改檢測 - + Compare the modified date of files when updating a library (not recommended) - + 更新庫時比較文件的修改日期(不建議) - + Enable background image 啟用背景圖片 - + Opacity level 透明度 - + Blur level 模糊 - + Use selected comic cover as background 使用選定的漫畫封面做背景 - + Restore defautls 恢復默認值 - + Background 背景 - + Display continue reading banner 顯示繼續閱讀橫幅 - + Display current comic banner - + 顯示目前漫畫橫幅 - + Continue reading 繼續閱讀 - + Comic Flow 漫畫流 - - + + Libraries - + - + Grid view 網格視圖 - + + General 常規 - + + + Appearance + 外貌 + + + + Options 選項 - - - PropertiesDialog - - General info - 基本資訊 + + My comics path + 我的漫畫路徑 - - Authors - 作者 + + Display + 展示 - - Publishing - 出版 + + Show time in current page information label + 在目前頁面資訊標籤中顯示時間 - - Plot - 情節 + + "Go to flow" size + 頁面流尺寸 - - Notes - + + Background color + 背景顏色 - - Cover page - 封面 + + Choose + 選擇 - - Load previous page as cover - + + Scroll behaviour + 滾動效果 - - Load next page as cover - + + Disable scroll animations and smooth scrolling + 停用滾動動畫和平滑滾動 - - Reset cover to the default image - + + Do not turn page using scroll + 滾動時不翻頁 - - Load custom cover image - + + Use single scroll step to turn page + 使用單滾動步驟翻頁 - - Series: - 系列: + + Mouse mode + 滑鼠模式 - - Title: - 標題: + + Only Back/Forward buttons can turn pages + 只有後退/前進按鈕可以翻頁 - - - - of: - of: + + Use the Left/Right buttons to turn pages. + 使用向左/向右按鈕翻頁。 - - Issue number: + + Click left or right half of the screen to turn pages. + 點擊螢幕的左半部或右半部即可翻頁。 + + + + Quick Navigation Mode + 快速導航模式 + + + + Disable mouse over activation + 禁用滑鼠啟動 + + + + Brightness + 亮度 + + + + Contrast + 對比度 + + + + Gamma + Gamma值 + + + + Reset + 重置 + + + + Image options + 圖片選項 + + + + Fit options + 適應項 + + + + Enlarge images to fit width/height + 放大圖片以適應寬度/高度 + + + + Double Page options + 雙頁選項 + + + + Show covers as single page + 顯示封面為單頁 + + + + Scaling + 縮放 + + + + Scaling method + 縮放方法 + + + + Nearest (fast, low quality) + 最近(快速,低品質) + + + + Bilinear + 雙線性 + + + + Lanczos (better quality) + Lanczos(品質更好) + + + + Page Flow + 頁面流 + + + + Image adjustment + 圖像調整 + + + + + Restart is needed + 需要重啟 + + + + Comics directory + 漫畫目錄 + + + + PropertiesDialog + + + General info + 基本資訊 + + + + Authors + 作者 + + + + Publishing + 出版 + + + + Plot + 情節 + + + + Notes + 筆記 + + + + Cover page + 封面 + + + + Load previous page as cover + 載入上一頁作為封面 + + + + Load next page as cover + 載入下一頁作為封面 + + + + Reset cover to the default image + 將封面重設為預設圖片 + + + + Load custom cover image + 載入自訂封面圖片 + + + + Series: + 系列: + + + + Title: + 標題: + + + + + + of: + 的: + + + + Issue number: 發行數量: @@ -2216,17 +2602,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t alt. number: - + 替代。數字: Alternate series: - + 替代系列: Series Group: - + 系列組: @@ -2272,12 +2658,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Editor(s): - + 編輯: Imprint: - + 印記: @@ -2317,22 +2703,22 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Type: - + 類型: Language (ISO): - + 語言(ISO): Invalid cover - + 封面無效 The image is invalid. - + 該圖像無效。 Manga: @@ -2351,22 +2737,22 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Teams: - + 團隊: Locations: - + 地點: Main character or team: - + 主要角色或團隊: Review: - + 審查: @@ -2376,7 +2762,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Tags: - + 標籤: @@ -2404,6 +2790,22 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 編輯漫畫資訊 + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 + +此應用程式支援持久性設置,要設定它們,請編輯此文件 %1 +若要了解可用設置,請查看文件:https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + QObject @@ -2447,55 +2849,73 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 嚴重錯誤 - + Select custom cover - + 選擇自訂封面 - + Images (%1) - + 圖片 (%1) + + + + The file could not be read or is not valid JSON. + 無法讀取該檔案或該檔案不是有效的 JSON。 + + + + This theme is for %1, not %2. + 此主題適用於 %1,而不是 %2。 + + + + Libraries + + + + + Folders + 檔夾 + + + + Reading Lists + 閱讀列表 QsLogging::LogWindowModel - Time - 時間 + 時間 - Level - 等級 + 等級 - Message - 資訊 + 資訊 QsLogging::Window - &Pause - 中止(&P) + 中止(&P) - &Resume - 恢復(&R) + 恢復(&R) - Save log - 保存日誌 + 保存日誌 - Log file (*.log) - 日誌檔 (*.log) + 日誌檔 (*.log) @@ -2516,7 +2936,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 取消 - + Rename current library 重命名當前庫 @@ -2524,18 +2944,18 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ScraperResultsPaginator - + Number of volumes found : %1 搜索結果: %1 - - + + page %1 of %2 第 %1 頁 共 %2 頁 - + Number of %1 found : %2 第 %1 頁 共: %2 條 @@ -2546,17 +2966,17 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Please provide some additional information for this comic. Please provide some additional information. - 請提供附加資訊. + 請提供附加資訊. - + Series: 系列: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + 使用精確匹配搜尋。如果您想要尋找與名稱中某些單字相符的捲,請停用。 @@ -2567,42 +2987,42 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 請提供附加資訊. - + Series: 系列: - + Use exact match search. Disable if you want to find volumes that match some of the words in the name. - + 使用精確匹配搜尋。如果您想要尋找與名稱中某些單字相符的捲,請停用。 SelectComic - + Please, select the right comic info. 請正確選擇漫畫資訊. - + comics 漫畫 - + loading cover 加載封面 - + loading description 加載描述 - + comic description unavailable - + 漫畫描述不可用 description unavailable @@ -2612,39 +3032,39 @@ To stop an automatic update tap on the loading indicator next to the Libraries t SelectVolume - + Please, select the right series for your comic. 請選擇正確的漫畫系列。 - + Filter: - + 篩選: - + volumes - + Nothing found, clear the filter if any. - + 未找到任何內容,如果有,請清除過濾器。 - + loading cover 加載封面 - + loading description 加載描述 - + volume description unavailable - + 卷描述不可用 description unavailable @@ -2659,12 +3079,12 @@ To stop an automatic update tap on the loading indicator next to the Libraries t 您正在嘗試同時獲取各種漫畫的資訊,它們是同一系列的嗎? - + yes - + no @@ -2672,41 +3092,41 @@ To stop an automatic update tap on the loading indicator next to the Libraries t ServerConfigDialog - + set port 設置端口 - + Server connectivity information 伺服器連接資訊 - + Scan it! 掃一掃! - + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - + YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> YACReader適用於iOS設備. <a href='http://ios.yacreader.com'style ='color:rgb(193,148,65)'>下載</a> - + Choose an IP address 選擇IP地址 - + Port 端口 - + enable the server 啟用伺服器 @@ -2724,330 +3144,1171 @@ to improve the performance SortVolumeComics - + Please, sort the list of comics on the left until it matches the comics' information. 請在左側對漫畫列表進行排序,直到它與漫畫的資訊相符。 - + sort comics to match comic information 排序漫畫以匹配漫畫資訊 - + issues 發行 - + remove selected comics 移除所選漫畫 - + restore all removed comics 恢復所有移除的漫畫 - TitleHeader + ThemeEditorDialog - - SEARCH - 搜索 + + Theme Editor + 主題編輯器 - - - UpdateLibraryDialog - - Updating.... - 更新中... + + + + + - - Cancel - 取消 + + - + - - - Update library - 更新庫 + + i + - - - VolumeComicsModel - - title - 標題 + + Expand all + 全部展開 - - - VolumesModel - - year - + + Collapse all + 全部折疊 - - issues - 發行 + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + 按住可在 UI 中閃爍所選值(洋紅色/切換/0↔10)。發布後恢復原樣。 - - publisher - 出版者 + + Search… + 搜尋… - - - YACReader::TrayIconController - - &Restore - 複位(&R) + + Light + 亮度 - - Systray - 系統託盤 + + Dark + 黑暗的 - - YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary 將繼續在系統託盤中運行. 想要終止程式, 請在系統託盤圖示的上下文菜單中選擇<b>退出</b>. + + ID: + ID: - - - YACReader::WhatsNewDialog - - Close - 關閉 + + Display name: + 顯示名稱: - - - YACReaderFieldEdit - - - Click to overwrite - 點擊以覆蓋 + + Variant: + 變體: - - Restore to default - 恢復默認 + + Theme info + 主題訊息 - - - YACReaderFieldPlainTextEdit - - - - - Click to overwrite - 點擊以覆蓋 + + Parameter + 範圍 - - Restore to default - 恢復默認 + + Value + 價值 - - - YACReaderFlowConfigWidget - - How to show covers: - 封面顯示方式: + + Save and apply + 儲存並應用 - - CoverFlow look - 封面流 + + Export to file... + 匯出到文件... - - Stripe look - 條狀 + + Load from file... + 從檔案載入... - - Overlapped Stripe look - 重疊條狀 + + Close + 關閉 - - - YACReaderGLFlowConfigWidget - - Presets: - 預設: + + Double-click to edit color + 雙擊編輯顏色 - - Classic look - 經典 + + + + + + + true + 真的 - - Stripe look - 條狀 + + + + + false + 錯誤的 - - Overlapped Stripe look - 重疊條狀 + + Double-click to toggle + 按兩下切換 - - Modern look - 現代 + + Double-click to edit value + 雙擊編輯值 - - Roulette look - 輪盤 + + + + Edit: %1 + 編輯:%1 - - Show advanced settings - 顯示高級選項 + + Save theme + 儲存主題 - - Custom: - 自定義: + + + JSON files (*.json);;All files (*) + JSON 檔案 (*.json);;所有檔案 (*) - - View angle - 視角 + + Save failed + 保存失敗 - - Position - 位置 + + Could not open file for writing: +%1 + 無法開啟文件進行寫入: +%1 - - Cover gap - 封面間距 + + Load theme + 載入主題 - - Central gap - 中心間距 + + + + Load failed + 載入失敗 - - Zoom - 縮放 + + Could not open file: +%1 + 無法開啟檔案: +%1 - - Y offset - Y位移 + + Invalid JSON: +%1 + 無效的 JSON: +%1 - - Z offset - Z位移 + + Expected a JSON object. + 需要一個 JSON 物件。 - - - Cover Angle + + + TitleHeader + + + SEARCH + 搜索 + + + + UpdateLibraryDialog + + + Updating.... + 更新中... + + + + Cancel + 取消 + + + + Update library + 更新庫 + + + + Viewer + + + + Press 'O' to open comic. + 按下 'O' 以打開漫畫. + + + + Not found + 未找到 + + + + Comic not found + 未找到漫畫 + + + + Error opening comic + 打開漫畫時發生錯誤 + + + + CRC Error + CRC 校驗失敗 + + + + Loading...please wait! + 載入中... 請稍候! + + + + Page not available! + 頁面不可用! + + + + Cover! + 封面! + + + + Last page! + 尾頁! + + + + VolumeComicsModel + + + title + 標題 + + + + VolumesModel + + + year + + + + + issues + 發行 + + + + publisher + 出版者 + + + + YACReader3DFlowConfigWidget + + + Presets: + 預設: + + + + Classic look + 經典 + + + + Stripe look + 條狀 + + + + Overlapped Stripe look + 重疊條狀 + + + + Modern look + 現代 + + + + Roulette look + 輪盤 + + + + Show advanced settings + 顯示高級選項 + + + + Custom: + 自定義: + + + + View angle + 視角 + + + + Position + 位置 + + + + Cover gap + 封面間距 + + + + Central gap + 中心間距 + + + + Zoom + 縮放 + + + + Y offset + Y位移 + + + + Z offset + Z位移 + + + + Cover Angle 封面角度 - + + Visibility + 透明度 + + + + Light + 亮度 + + + + Max angle + 最大角度 + + + + Low Performance + 低性能 + + + + High Performance + 高性能 + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + 使用VSync (在全屏模式下提高圖像品質, 性能更差) + + + + Performance: + 性能: + + + + YACReader::MainWindowViewer + + + &Open + 打開(&O) + + + + Open a comic + 打開漫畫 + + + + New instance + 新建實例 + + + + Open Folder + 打開檔夾 + + + + Open image folder + 打開圖片檔夾 + + + + Open latest comic + 打開最近的漫畫 + + + + Open the latest comic opened in the previous reading session + 打開最近閱讀漫畫 + + + + Clear + 清空 + + + + Clear open recent list + 清空最近訪問列表 + + + + Save + 保存 + + + + + Save current page + 保存當前頁面 + + + + Previous Comic + 上一個漫畫 + + + + + + Open previous comic + 打開上一個漫畫 + + + + Next Comic + 下一個漫畫 + + + + + + Open next comic + 打開下一個漫畫 + + + + &Previous + 上一頁(&P) + + + + + + Go to previous page + 轉至上一頁 + + + + &Next + 下一頁(&N) + + + + + + Go to next page + 轉至下一頁 + + + + Fit Height + 適應高度 + + + + Fit image to height + 縮放圖片以適應高度 + + + + Fit Width + 適合寬度 + + + + Fit image to width + 縮放圖片以適應寬度 + + + + Show full size + 顯示全尺寸 + + + + Fit to page + 適應頁面 + + + + Continuous scroll + 連續滾動 + + + + Switch to continuous scroll mode + 切換到連續滾動模式 + + + + Reset zoom + 重置縮放 + + + + Show zoom slider + 顯示縮放滑塊 + + + + Zoom+ + 放大 + + + + Zoom- + 縮小 + + + + Rotate image to the left + 向左旋轉圖片 + + + + Rotate image to the right + 向右旋轉圖片 + + + + Double page mode + 雙頁模式 + + + + Switch to double page mode + 切換至雙頁模式 + + + + Double page manga mode + 雙頁漫畫模式 + + + + Reverse reading order in double page mode + 雙頁模式 (逆序閱讀) + + + + Go To + 跳轉 + + + + Go to page ... + 跳轉至頁面 ... + + + + Options + 選項 + + + + YACReader options + YACReader 選項 + + + + + Help + 幫助 + + + + Help, About YACReader + 幫助, 關於 YACReader + + + + Magnifying glass + 放大鏡 + + + + Switch Magnifying glass + 切換放大鏡 + + + + Set bookmark + 設置書簽 + + + + Set a bookmark on the current page + 在當前頁面設置書簽 + + + + Show bookmarks + 顯示書簽 + + + + Show the bookmarks of the current comic + 顯示當前漫畫的書簽 + + + + Show keyboard shortcuts + 顯示鍵盤快捷鍵 + + + + Show Info + 顯示資訊 + + + + Close + 關閉 + + + + Show Dictionary + 顯示字典 + + + + Show go to flow + 顯示頁面流 + + + + Edit shortcuts + 編輯快捷鍵 + + + + &File + 檔(&F) + + + + + Open recent + 最近打開的檔 + + + + File + + + + + Edit + 編輯 + + + + View + 查看 + + + + Go + 轉到 + + + + Window + 窗口 + + + + + + Open Comic + 打開漫畫 + + + + + + Comic files + 漫畫檔 + + + + Open folder + 打開檔夾 + + + + page_%1.jpg + 頁_%1.jpg + + + + Image files (*.jpg) + 圖像檔 (*.jpg) + + + + + Comics + 漫畫 + + + + + General + 常規 + + + + + Magnifiying glass + 放大鏡 + + + + + Page adjustement + 頁面調整 + + + + + Reading + 閱讀 + + + + Toggle fullscreen mode + 切換全屏模式 + + + + Hide/show toolbar + 隱藏/顯示 工具欄 + + + + Size up magnifying glass + 增大放大鏡尺寸 + + + + Size down magnifying glass + 減小放大鏡尺寸 + + + + Zoom in magnifying glass + 增大縮放級別 + + + + Zoom out magnifying glass + 減小縮放級別 + + + + Reset magnifying glass + 重置放大鏡 + + + + Toggle between fit to width and fit to height + 切換顯示為"適應寬度"或"適應高度" + + + + Autoscroll down + 向下自動滾動 + + + + Autoscroll up + 向上自動滾動 + + + + Autoscroll forward, horizontal first + 向前自動滾動,水準優先 + + + + Autoscroll backward, horizontal first + 向後自動滾動,水準優先 + + + + Autoscroll forward, vertical first + 向前自動滾動,垂直優先 + + + + Autoscroll backward, vertical first + 向後自動滾動,垂直優先 + + + + Move down + 向下移動 + + + + Move up + 向上移動 + + + + Move left + 向左移動 + + + + Move right + 向右移動 + + + + Go to the first page + 轉到第一頁 + + + + Go to the last page + 轉到最後一頁 + + + + Offset double page to the left + 雙頁向左偏移 + + + + Offset double page to the right + 雙頁向右偏移 + + + + There is a new version available + 有新版本可用 + + + + Do you want to download the new version? + 你要下載新版本嗎? + + + + Remind me in 14 days + 14天後提醒我 + + + + Not now + 現在不 + + + + YACReader::TrayIconController + + + &Restore + 複位(&R) + + + + Systray + 系統託盤 + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary 將繼續在系統託盤中運行. 想要終止程式, 請在系統託盤圖示的上下文菜單中選擇<b>退出</b>. + + + + YACReader::WhatsNewDialog + + Close + 關閉 + + + + YACReaderFieldEdit + + + + Click to overwrite + 點擊以覆蓋 + + + + Restore to default + 恢復默認 + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + 點擊以覆蓋 + + + + Restore to default + 恢復默認 + + + + YACReaderFlowConfigWidget + + How to show covers: + 封面顯示方式: + + + CoverFlow look + 封面流 + + + Stripe look + 條狀 + + + Overlapped Stripe look + 重疊條狀 + + + + YACReaderGLFlowConfigWidget + + Presets: + 預設: + + + Classic look + 經典 + + + Stripe look + 條狀 + + + Overlapped Stripe look + 重疊條狀 + + + Modern look + 現代 + + + Roulette look + 輪盤 + + + Show advanced settings + 顯示高級選項 + + + Custom: + 自定義: + + + View angle + 視角 + + + Position + 位置 + + + Cover gap + 封面間距 + + + Central gap + 中心間距 + + + Zoom + 縮放 + + + Y offset + Y位移 + + + Z offset + Z位移 + + + Cover Angle + 封面角度 + + Visibility - 透明度 + 透明度 - Light - 亮度 + 亮度 - Max angle - 最大角度 + 最大角度 - Low Performance - 低性能 + 低性能 - High Performance - 高性能 + 高性能 - Use VSync (improve the image quality in fullscreen mode, worse performance) - 使用VSync (在全屏模式下提高圖像品質, 性能更差) + 使用VSync (在全屏模式下提高圖像品質, 性能更差) - Performance: - 性能: + 性能: YACReaderNavigationController - No favorites - 沒有收藏 + 沒有收藏 - You are not reading anything yet, come on!! - 你還沒有閱讀任何東西,加油!! - - - - There are no recent comics! - + 你還沒有閱讀任何東西,加油!! YACReaderOptionsDialog - + Save 保存 - + Cancel 取消 - + Edit shortcuts 編輯快捷鍵 - + Shortcuts 快捷鍵 - Use hardware acceleration (restart needed) - 使用硬體加速 (需要重啟) + 使用硬體加速 (需要重啟) YACReaderSearchLineEdit - + type to search 搜索類型 @@ -3055,34 +4316,60 @@ to improve the performance YACReaderSideBar - Libraries - + - Folders - 檔夾 + 檔夾 - Reading Lists - 閱讀列表 + 閱讀列表 - LIBRARIES - + - FOLDERS - 檔夾 + 檔夾 - READING LISTS - 閱讀列表 + 閱讀列表 + + + + YACReaderSlider + + + Reset + 重置 + + + + YACReaderTranslator + + + YACReader translator + YACReader 翻譯 + + + + + Translation + 翻譯 + + + + clear + 清空 + + + + Service not available + 服務不可用 diff --git a/YACReaderLibraryServer/CMakeLists.txt b/YACReaderLibraryServer/CMakeLists.txt index fd70e77ef..9accc389f 100644 --- a/YACReaderLibraryServer/CMakeLists.txt +++ b/YACReaderLibraryServer/CMakeLists.txt @@ -34,6 +34,7 @@ qt_add_translations(YACReaderLibraryServer yacreaderlibraryserver_zh_CN.ts yacreaderlibraryserver_zh_TW.ts yacreaderlibraryserver_zh_HK.ts + yacreaderlibraryserver_source.ts ) target_link_libraries(YACReaderLibraryServer PRIVATE diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_de.ts b/YACReaderLibraryServer/yacreaderlibraryserver_de.ts index 5bdf41ea3..f3726463e 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_de.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_de.ts @@ -2,150 +2,3711 @@ - FileComic + ActionsShortcutsModel - - CRC error on page (%1): some of the pages will not be displayed correctly - + + None + Keine + + + AddLabelDialog - - Unknown error opening the file - + + Label name: + Label-Name: - - 7z not found - + + Choose a color: + Wähle eine Farbe: - - Format not supported - + + accept + Akzeptieren + + + + cancel + Abbrechen - LogWindow + AddLibraryDialog + + + Comics folder : + Comics-Ordner : + + + + Library name : + Bibliothek-Name : + - - Log window - + + Add + Hinzufügen - - &Pause - + + Cancel + Abbrechen - - &Save - + + Add an existing library + Eine vorhandene Bibliothek hinzufügen + + + ApiKeyDialog - - C&lear - + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Bevor du dich mit Comic Vine verbindest, brauchst du deinen eigenen API-Schlüssel. Du kannst <a href="http://www.comicvine.com/api/">hier</a> einen kostenlosen bekommen. - - &Copy - + + Paste here your Comic Vine API key + Füge hier deinen Comic Vine API-Schlüssel ein. - - Level: - + + Accept + Akzeptieren - - &Auto scroll - + + Cancel + Abbrechen - QCoreApplication + AppearanceTabWidget - - -YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + + Color scheme + Farbschema + + + + System + Systemumgebung + + + + Light + Licht + + + + Dark + Dunkel + + + + Custom + Brauch + + + + Remove + Entfernen + + + + Remove this user-imported theme + Entfernen Sie dieses vom Benutzer importierte Design + + + + Light: + Licht: + + + + Dark: + Dunkel: + + + + Custom: + Benutzerdefiniert: + + + + Import theme... + Theme importieren... + + + + Theme + Thema + + + + Theme editor + Theme-Editor + + + + Open Theme Editor... + Theme-Editor öffnen... + + + + Theme editor error + Fehler im Theme-Editor + + + + The current theme JSON could not be loaded. + Der aktuelle Theme-JSON konnte nicht geladen werden. + + + + Import theme + Thema importieren + + + + JSON files (*.json);;All files (*) + JSON-Dateien (*.json);;Alle Dateien (*) + + + + Could not import theme from: +%1 + Theme konnte nicht importiert werden von: +%1 + + + + Could not import theme from: +%1 -This appplication supports persistent settings, to set them up edit this file %1 -To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md - +%2 + Theme konnte nicht importiert werden von: +%1 + +%2 + + + + Import failed + Der Import ist fehlgeschlagen - QObject + BookmarksDialog - - Trace - + + Lastest Page + Neueste Seite - - Debug - + + Close + Schliessen - - Info - + + Click on any image to go to the bookmark + Klicke auf ein beliebiges Bild, um zum Lesezeichen zu gehen - - Warning - + + + Loading... + Laden... + + + ClassicComicsView - - Error - + + Hide comic flow + Comic "Flow" verstecken + + + + ComicModel + + + yes + Ja - - Fatal - + + no + Nein + + + + Title + Titel + + + + File Name + Dateiname + + + + Pages + Seiten + + + + Size + Größe + + + + Read + Lesen + + + + Current Page + Aktuelle Seite + + + + Publication Date + Veröffentlichungsdatum + + + + Rating + Bewertung + + + + Series + Serie + + + + Volume + Volumen + + + + Story Arc + Handlungsbogen + + + + ComicVineDialog + + + skip + überspringen + + + + back + zurück + + + + next + nächste + + + + search + suche + + + + close + schließen + + + + + comic %1 of %2 - %3 + Comic %1 von %2 - %3 + + + + + + Looking for volume... + Suche nach Band.... + + + + %1 comics selected + %1 Comic ausgewählt + + + + Error connecting to ComicVine + Fehler bei Verbindung zu ComicVine + + + + + Retrieving tags for : %1 + Herunterladen von Tags für : %1 + + + + Retrieving volume info... + Herunterladen von Info zu Ausgabe... + + + + Looking for comic... + Suche nach Comic... + + + + ContinuousPageWidget + + + Loading page %1 + Seite wird geladen %1 + + + + CreateLibraryDialog + + + Comics folder : + Comics-Ordner : + + + + Library Name : + Bibliothek-Name : + + + + Create + Erstellen + + + + Cancel + Abbrechen + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Es kann einige Minuten dauern, eine neue Bibliothek zu erstellen. Sie können den Prozess abbrechen und die Bibliothek später aktualisieren, um den Vorgang abzuschließen. + + + + Create new library + Erstelle eine neue Bibliothek + + + + Path not found + Pfad nicht gefunden + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben + + + + EditShortcutsDialog + + + Restore defaults + Standardwerte wiederherstellen + + + + To change a shortcut, double click in the key combination and type the new keys. + Um ein Kürzel zu ändern, klicke doppelt auf die Tastenkombination und füge die neuen Tasten ein. + + + + Shortcuts settings + Kürzel-Einstellungen + + + + Shortcut in use + Genutzte Kürzel + + + + The shortcut "%1" is already assigned to other function + Das Kürzel "%1" ist bereits für eine andere Funktion in Verwendung + + + + EmptyFolderWidget + + + This folder doesn't contain comics yet + Dieser Ordner enthält noch keine Comics + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + Dieses Label enthält noch keine Comics + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + Diese Leseliste enthält noch keine Comics + + + + EmptySpecialListWidget + + + No favorites + Keine Favoriten + + + + You are not reading anything yet, come on!! + Sie lesen noch nichts, starten Sie!! + + + + There are no recent comics! + Es gibt keine aktuellen Comics! + + + + ExportComicsInfoDialog + + + Output file : + Zieldatei : + + + + Create + Erstellen + + + + Cancel + Abbrechen + + + + Export comics info + Comicinfo exportieren + + + + Destination database name + Ziel-Datenbank Name + + + + Problem found while writing + Problem beim Schreiben + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben + + + + ExportLibraryDialog + + + Output folder : + Ziel-Ordner : + + + + Create + Erstellen + + + + Cancel + Abbrechen + + + + Create covers package + Erzeuge Titelbild-Paket + + + + Problem found while writing + Problem beim Schreiben + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Der gewählte Pfad existiert nicht oder ist kein gültiger Pfad. Stellen Sie sicher, dass Sie Schreibzugriff zu dem Ordner haben + + + + Destination directory + Ziel-Verzeichnis + + + + FileComic + + + CRC error on page (%1): some of the pages will not be displayed correctly + CRC Error auf Seite (%1): Einige Seiten werden nicht korrekt dargestellt + + + + Unknown error opening the file + Unbekannter Fehler beim Öffnen des Files + + + + 7z not found + 7z nicht gefunden + + + + Format not supported + Format wird nicht unterstützt + + + + GoToDialog + + + Page : + Seite : + + + + Go To + Gehe zu + + + + Cancel + Abbrechen + + + + + Total pages : + Seiten gesamt : + + + + Go to... + Gehe zu... + + + + GoToFlowToolBar + + + Page : + Seite : - QsLogging::LogWindowModel + GridComicsView - - Time - + + Show info + Info anzeigen + + + HelpAboutDialog - - Level - + + About + Über - - Message - + + Help + Hilfe + + + + System info + Systeminformationen + + + + ImportComicsInfoDialog + + + Import comics info + Importiere Comic-Info + + + + Info database location : + Info-Datenbank Speicherort : + + + + Import + Importieren + + + + Cancel + Abbrechen + + + + Comics info file (*.ydb) + Comics-Info-Datei (*.ydb) + + + + ImportLibraryDialog + + + Library Name : + Bibliothek-Name : + + + + Package location : + Paket Ort : + + + + Destination folder : + Zielordner : + + + + Unpack + Entpacken + + + + Cancel + Abbrechen + + + + Extract a catalog + Einen Katalog extrahieren + + + + Compresed library covers (*.clc) + Komprimierte Bibliothek Cover (*.clc) + + + + ImportWidget + + + stop + Stopp + + + + Some of the comics being added... + Einige der Comics werden hinzugefügt... + + + + Importing comics + Comics werden importiert + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary erstellt nun eine neue Bibliothek. </p><p>Es kann einige Minuten dauern, eine neue Bibliothek zu erstellen. Sie können den Prozess abbrechen und die Bibliothek später aktualisieren, um den Vorgang abzuschließen.</p> + + + + Updating the library + Aktualisierung der Bibliothek + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>Die aktuelle Bibliothek wird gerade aktualisiert. Für eine schnellere Aktualisierung, aktualisieren Sie die Bibliothek bitte regelmäßig.</p><p>Sie können den Prozess abbrechen und mit der Aktualisierung später fortfahren.<p> + + + + Upgrading the library + Upgrade der Bibliothek + + + + <p>The current library is being upgraded, please wait.</p> + Die aktuelle Bibliothek wird gerade upgegradet, bitte warten. + + + + Scanning the library + Durchsuchen der Bibliothek + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>Die aktuelle Bibliothek wird nach alten XML-Metadateninformationen durchsucht.</p><p>Dies ist nur einmal erforderlich und nur, wenn die Bibliothek mit YACReaderLibrary 9.8.2 oder früher erstellt wurde.</p> + + + + LibraryWindow + + + YACReader Library + YACReader Bibliothek + + + + + + comic + komisch + + + + + + manga + Manga + + + + + + western manga (left to right) + Western-Manga (von links nach rechts) + + + + + + web comic + Webcomic + + + + + + 4koma (top to botom) + 4koma (von oben nach unten) + + + + + + + Set type + Typ festlegen + + + + Library + Bibliothek + + + + Folder + Ordner + + + + Comic + Komisch + + + + Upgrade failed + Update gescheitert + + + + There were errors during library upgrade in: + Beim Upgrade der Bibliothek kam es zu Fehlern in: + + + + Update needed + Update benötigt + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Diese Bibliothek wurde mit einer älteren Version von YACReader erzeugt. Sie muss geupdated werden. Jetzt updaten? + + + + Download new version + Neue Version herunterladen + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Die Bibliothek wurde mit einer neueren Version von YACReader erstellt. Die neue Version jetzt herunterladen? + + + + Library not available + Bibliothek nicht verfügbar + + + + Library '%1' is no longer available. Do you want to remove it? + Bibliothek '%1' ist nicht mehr verfügbar. Wollen Sie sie entfernen? + + + + Old library + Alte Bibliothek + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Bibliothek '%1' wurde mit einer älteren Version von YACReader erstellt. Sie muss neu erzeugt werden. Wollen Sie die Bibliothek jetzt erzeugen? + + + + + Copying comics... + Kopieren von Comics... + + + + + Moving comics... + Verschieben von Comics... + + + + Add new folder + Neuen Ordner erstellen + + + + Folder name: + Ordnername + + + + No folder selected + Kein Ordner ausgewählt + + + + Please, select a folder first + Bitte wählen Sie zuerst einen Ordner aus + + + + Error in path + Fehler im Pfad + + + + There was an error accessing the folder's path + Beim Aufrufen des Ordnerpfades kam es zu einem Fehler + + + + Delete folder + Ordner löschen + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + Der ausgewählte Ordner und sein gesamter Inhalt wird von Ihrer Festplatte gelöscht. Sind Sie sicher? + + + + + Unable to delete + Löschen nicht möglich + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Beim Löschen des ausgewählten Ordners ist ein Problem aufgetreten. Bitte überprüfen Sie die Schreibrechte und stellen Sie sicher, dass keine Anwendung diese Ordner oder die darin enthaltenen Dateien verwendet. + + + + Add new reading lists + Neue Leseliste hinzufügen + + + + + List name: + Name der Liste + + + + Delete list/label + Ausgewählte/s Liste/Label löschen + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + Das ausgewählte Element wird gelöscht; Ihre Comics oder Ordner werden NICHT von Ihrer Festplatte gelöscht. Sind Sie sicher? + + + + Rename list name + Listenname ändern + + + + Open folder... + Öffne Ordner... + + + + Update folder + Ordner aktualisieren + + + + Rescan library for XML info + Durchsuchen Sie die Bibliothek erneut nach XML-Informationen + + + + Set as uncompleted + Als nicht gelesen markieren + + + + Set as completed + Als gelesen markieren + + + + Set as read + Als gelesen markieren + + + + + Set as unread + Als ungelesen markieren + + + + Set custom cover + Legen Sie ein benutzerdefiniertes Cover fest + + + + Delete custom cover + Benutzerdefiniertes Cover löschen + + + + Save covers + Titelbilder speichern + + + + You are adding too many libraries. + Sie fügen zu viele Bibliotheken hinzu. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Sie fügen zu viele Bibliotheken hinzu. + Wahrscheinlich brauchen Sie nur eine Bibliothek in Ihrem obersten Comic-Ordner, Sie können alle Unterordner mit Hilfe des Ordnerbereichs in der linken Seitenleiste durchsuchen. + +YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen, aber Sie sollten die Anzahl der Bibliotheken gering halten. + + + + + YACReader not found + YACReader nicht gefunden + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader nicht gefunden. YACReader muss im gleichen Ordner installiert sein wie YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader nicht gefunden. Eventuell besteht ein Problem mit Ihrer YACReader-Installation. + + + + Error + Fehler + + + + Error opening comic with third party reader. + Beim Öffnen des Comics mit dem Drittanbieter-Reader ist ein Fehler aufgetreten. + + + + Library not found + Bibliothek nicht gefunden + + + + The selected folder doesn't contain any library. + Der ausgewählte Ordner enthält keine Bibliothek. + + + + Are you sure? + Sind Sie sicher? + + + + Do you want remove + Möchten Sie entfernen + + + + library? + Bibliothek? + + + + Remove and delete metadata + Entferne und lösche Metadaten + + + + Library info + Informationen zur Bibliothek + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Es gab ein Problem beim Löschen der ausgewählten Comics. Überprüfen Sie bitte die Schreibberechtigung für die ausgewählten Dateien oder Ordner. + + + + Assign comics numbers + Comics Nummern zuweisen + + + + Assign numbers starting in: + Nummern zuweisen, beginnend mit: + + + + Invalid image + Ungültiges Bild + + + + The selected file is not a valid image. + Die ausgewählte Datei ist kein gültiges Bild. + + + + Error saving cover + Fehler beim Speichern des Covers + + + + There was an error saving the cover image. + Beim Speichern des Titelbildes ist ein Fehler aufgetreten. + + + + Error creating the library + Fehler beim Erstellen der Bibliothek + + + + Error updating the library + Fehler beim Updaten der Bibliothek + + + + Error opening the library + Fehler beim Öffnen der Bibliothek + + + + Delete comics + Comics löschen + + + + All the selected comics will be deleted from your disk. Are you sure? + Alle ausgewählten Comics werden von Ihrer Festplatte gelöscht. Sind Sie sicher? + + + + Remove comics + Comics löschen + + + + Comics will only be deleted from the current label/list. Are you sure? + Comics werden nur vom aktuellen Label/der aktuellen Liste gelöscht. Sind Sie sicher? + + + + Library name already exists + Bibliothek-Name bereits vorhanden + + + + There is another library with the name '%1'. + Es gibt bereits eine Bibliothek mit dem Namen '%1'. + + + + LibraryWindowActions + + + Create a new library + Neue Bibliothek erstellen + + + + Open an existing library + Eine vorhandede Bibliothek öffnen + + + + + Export comics info + Comicinfo exportieren + + + + + Import comics info + Importiere Comic-Info + + + + Pack covers + Titelbild-Paket erzeugen + + + + Pack the covers of the selected library + Packe die Titelbilder der ausgewählten Bibliothek in ein Paket + + + + Unpack covers + Titelbilder entpacken + + + + Unpack a catalog + Katalog entpacken + + + + Update library + Bibliothek updaten + + + + Update current library + Aktuelle Bibliothek updaten + + + + Rename library + Bibliothek umbenennen + + + + Rename current library + Aktuelle Bibliothek umbenennen + + + + Remove library + Bibliothek entfernen + + + + Remove current library from your collection + Aktuelle Bibliothek aus der Sammlung entfernen + + + + Rescan library for XML info + Durchsuchen Sie die Bibliothek erneut nach XML-Informationen + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Versucht, in Comic-Dateien eingebettete XML-Informationen zu finden. Sie müssen dies nur tun, wenn die Bibliothek mit 9.8.2 oder früheren Versionen erstellt wurde oder wenn Sie Software von Drittanbietern verwenden, um XML-Informationen in die Dateien einzubetten. + + + + Show library info + Bibliotheksinformationen anzeigen + + + + Show information about the current library + Informationen zur aktuellen Bibliothek anzeigen + + + + Open current comic + Aktuellen Comic öffnen + + + + Open current comic on YACReader + Aktuellen Comic mit YACReader öffnen + + + + Save selected covers to... + Ausgewählte Titelbilder speichern in... + + + + Save covers of the selected comics as JPG files + Titelbilder der ausgewählten Comics als JPG-Datei speichern + + + + + Set as read + Als gelesen markieren + + + + Set comic as read + Comic als gelesen markieren + + + + + Set as unread + Als ungelesen markieren + + + + Set comic as unread + Comic als ungelesen markieren + + + + + manga + Manga + + + + Set issue as manga + Ausgabe als Manga festlegen + + + + + comic + komisch + + + + Set issue as normal + Ausgabe als normal festlegen + + + + western manga + Western-Manga + + + + Set issue as western manga + Ausgabe als Western-Manga festlegen + + + + + web comic + Webcomic + + + + Set issue as web comic + Ausgabe als Webcomic festlegen + + + + + yonkoma + Yonkoma + + + + Set issue as yonkoma + Stellen Sie das Problem als Yonkoma ein + + + + Show/Hide marks + Zeige/Verberge Markierungen + + + + Show or hide read marks + Gelesen-Markierungen anzeigen oder verbergen + + + + Show/Hide recent indicator + Aktuelle Anzeige ein-/ausblenden + + + + Show or hide recent indicator + Aktuelle Anzeige anzeigen oder ausblenden + + + + + Fullscreen mode on/off + Vollbildmodus an/aus + + + + Help, About YACReader + Hilfe, über YACReader + + + + Add new folder + Neuen Ordner erstellen + + + + Add new folder to the current library + Neuen Ordner in der aktuellen Bibliothek erstellen + + + + Delete folder + Ordner löschen + + + + Delete current folder from disk + Aktuellen Ordner von der Festplatte löschen + + + + Select root node + Ursprungsordner auswählen + + + + Expand all nodes + Alle Unterordner anzeigen + + + + Collapse all nodes + Alle Unterordner einklappen + + + + Show options dialog + Zeige den Optionen-Dialog + + + + Show comics server options dialog + Zeige Comic-Server-Optionen-Dialog + + + + + Change between comics views + Zwischen Comic-Anzeigemodi wechseln + + + + Open folder... + Öffne Ordner... + + + + Set as uncompleted + Als nicht gelesen markieren + + + + Set as completed + Als gelesen markieren + + + + Set custom cover + Legen Sie ein benutzerdefiniertes Cover fest + + + + Delete custom cover + Benutzerdefiniertes Cover löschen + + + + western manga (left to right) + Western-Manga (von links nach rechts) + + + + Open containing folder... + Öffne aktuellen Ordner... + + + + Reset comic rating + Comic-Bewertung zurücksetzen + + + + Select all comics + Alle Comics auswählen + + + + Edit + Ändern + + + + Assign current order to comics + Aktuele Sortierung auf Comics anwenden + + + + Update cover + Titelbild updaten + + + + Delete selected comics + Ausgewählte Comics löschen + + + + Delete metadata from selected comics + Metadaten aus ausgewählten Comics löschen + + + + Download tags from Comic Vine + Tags von Comic Vine herunterladen + + + + Focus search line + Suchzeile fokussieren + + + + Focus comics view + Fokus-Comic-Ansicht + + + + Edit shortcuts + Kürzel ändern + + + + &Quit + &Schließen + + + + Update folder + Ordner aktualisieren + + + + Update current folder + Aktuellen Ordner aktualisieren + + + + Scan legacy XML metadata + Scannen Sie ältere XML-Metadaten + + + + Add new reading list + Neue Leseliste hinzufügen + + + + Add a new reading list to the current library + Neue Leseliste zur aktuellen Bibliothek hinzufügen + + + + Remove reading list + Leseliste entfernen + + + + Remove current reading list from the library + Aktuelle Leseliste von der Bibliothek entfernen + + + + Add new label + Neues Label hinzufügen + + + + Add a new label to this library + Neues Label zu dieser Bibliothek hinzufügen + + + + Rename selected list + Ausgewählte Liste umbenennen + + + + Rename any selected labels or lists + Ausgewählte Labels oder Listen umbenennen + + + + Add to... + Hinzufügen zu... + + + + Favorites + Favoriten + + + + Add selected comics to favorites list + Ausgewählte Comics zu Favoriten hinzufügen + + + + LocalComicListModel + + + file name + Dateiname + + + + NoLibrariesWidget + + + You don't have any libraries yet + Sie haben aktuell noch keine Bibliothek + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Sie können eine Bibliothek in jedem beliebigen Ordner erstellen, YACReaderLibrary wird alle Comics und Unterordner von diesem Ordner importieren. Wenn Sie bereits eine Bibliothek erstellt haben, können Sie sie öffnen.</p><p>Vergessen Sie nicht, dass Sie YACReader als eigentsändige Anwendung nutzen können, um Comics auf Ihrem Computer zu lesen.</p> + + + + create your first library + Erstellen Sie Ihre erste Bibliothek + + + + add an existing one + Existierende hinzufügen + + + + NoSearchResultsWidget + + + No results + Keine Ergebnisse + + + + OptionsDialog + + + + General + Allgemein + + + + + Libraries + Bibliotheken + + + + Comic Flow + Comic-Flow + + + + Grid view + Rasteransicht + + + + + Appearance + Aussehen + + + + + Options + Optionen + + + + + Language + Sprache + + + + + Application language + Anwendungssprache + + + + + System default + Systemstandard + + + + Tray icon settings (experimental) + Taskleisten-Einstellungen (experimentell) + + + + Close to tray + In Taskleiste schließen + + + + Start into the system tray + In die Taskleiste starten + + + + Edit Comic Vine API key + Comic Vine API-Schlüssel ändern + + + + Comic Vine API key + Comic Vine API Schlüssel + + + + ComicInfo.xml legacy support + ComicInfo.xml-Legacy-Unterstützung + + + + Import metadata from ComicInfo.xml when adding new comics + Importieren Sie Metadaten aus ComicInfo.xml, wenn Sie neue Comics hinzufügen + + + + Consider 'recent' items added or updated since X days ago + Berücksichtigen Sie „neue“ Elemente, die seit X Tagen hinzugefügt oder aktualisiert wurden + + + + Third party reader + Drittanbieter-Reader + + + + Write {comic_file_path} where the path should go in the command + Schreiben Sie {comic_file_path}, wohin der Pfad im Befehl gehen soll + + + + + Clear + Löschen + + + + Update libraries at startup + Aktualisieren Sie die Bibliotheken beim Start + + + + Try to detect changes automatically + Versuchen Sie, Änderungen automatisch zu erkennen + + + + Update libraries periodically + Aktualisieren Sie die Bibliotheken regelmäßig + + + + Interval: + Intervall: + + + + 30 minutes + 30 Minuten + + + + 1 hour + 1 Stunde + + + + 2 hours + 2 Stunden + + + + 4 hours + 4 Stunden + + + + 8 hours + 8 Stunden + + + + 12 hours + 12 Stunden + + + + daily + täglich + + + + Update libraries at certain time + Aktualisieren Sie Bibliotheken zu einem bestimmten Zeitpunkt + + + + Time: + Zeit: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + WARNUNG! Während Bibliotheksaktualisierungen sind Schreibvorgänge in die Datenbank deaktiviert! +Planen Sie keine Updates, während Sie die App möglicherweise aktiv nutzen. +Bei automatischen Updates blockiert die App einige Aktionen, bis das Update abgeschlossen ist. +Um eine automatische Aktualisierung zu stoppen, tippen Sie auf die Ladeanzeige neben dem Titel „Bibliotheken“. + + + + Modifications detection + Erkennung von Änderungen + + + + Compare the modified date of files when updating a library (not recommended) + Vergleichen Sie das Änderungsdatum von Dateien beim Aktualisieren einer Bibliothek (nicht empfohlen) + + + + Enable background image + Hintergrundbild aktivieren + + + + Opacity level + Deckkraft-Stufe + + + + Blur level + Unschärfe-Stufe + + + + Use selected comic cover as background + Den ausgewählten Comic als Hintergrund verwenden + + + + Restore defautls + Standardwerte wiederherstellen + + + + Background + Hintergrund + + + + Display continue reading banner + Weiterlesen-Banner anzeigen + + + + Display current comic banner + Aktuelles Comic-Banner anzeigen + + + + Continue reading + Weiterlesen + + + + My comics path + Meine Comics-Pfad + + + + Display + Anzeige + + + + Show time in current page information label + Zeit im Informationsetikett der aktuellen Seite anzeigen + + + + "Go to flow" size + "Go to flow" Größe + + + + Background color + Hintergrundfarbe + + + + Choose + Auswählen + + + + Scroll behaviour + Scrollverhalten + + + + Disable scroll animations and smooth scrolling + Scroll-Animationen und sanftes Scrollen deaktivieren + + + + Do not turn page using scroll + Blättern Sie nicht mit dem Scrollen um + + + + Use single scroll step to turn page + Verwenden Sie einen einzelnen Bildlaufschritt, um die Seite umzublättern + + + + Mouse mode + Mausmodus + + + + Only Back/Forward buttons can turn pages + Nur mit den Zurück-/Vorwärts-Tasten können Seiten umgeblättert werden + + + + Use the Left/Right buttons to turn pages. + Verwenden Sie die Links-/Rechts-Tasten, um Seiten umzublättern. + + + + Click left or right half of the screen to turn pages. + Klicken Sie auf die linke oder rechte Hälfte des Bildschirms, um die Seiten umzublättern. + + + + Quick Navigation Mode + Schnellnavigations-Modus + + + + Disable mouse over activation + Aktivierung durch Maus deaktivieren + + + + Brightness + Helligkeit + + + + Contrast + Kontrast + + + + Gamma + Gammawert + + + + Reset + Zurücksetzen + + + + Image options + Bilderoptionen + + + + Fit options + Anpassungsoptionen + + + + Enlarge images to fit width/height + Bilder vergrößern, um sie Breite/Höhe anzupassen + + + + Double Page options + Doppelseiten-Einstellungen + + + + Show covers as single page + Cover als eine Seite darstellen + + + + Scaling + Skalierung + + + + Scaling method + Skalierungsmethode + + + + Nearest (fast, low quality) + Am nächsten (schnell, niedrige Qualität) + + + + Bilinear + Bilinear-Filter + + + + Lanczos (better quality) + Lanczos (bessere Qualität) + + + + Page Flow + Seitenfluss + + + + Image adjustment + Bildanpassung + + + + + Restart is needed + Neustart erforderlich + + + + Comics directory + Comics-Verzeichnis + + + + PropertiesDialog + + + General info + Allgemeine Info + + + + Plot + Inhalt + + + + Authors + Autoren + + + + Publishing + Veröffentlichung + + + + Notes + Notizen + + + + Cover page + Titelbild + + + + Load previous page as cover + Vorherige Seite als Cover laden + + + + Load next page as cover + Nächste Seite als Cover laden + + + + Reset cover to the default image + Cover auf das Standardbild zurücksetzen + + + + Load custom cover image + Laden Sie ein benutzerdefiniertes Titelbild + + + + Series: + Serie: + + + + Title: + Titel: + + + + + + of: + von + + + + Issue number: + Ausgabennummer: + + + + Volume: + Band: + + + + Arc number: + Handlungsbogen Nummer: + + + + Story arc: + Handlung: + + + + alt. number: + alt. Nummer: + + + + Alternate series: + Alternative Serie: + + + + Series Group: + Seriengruppe: + + + + Genre: + Gattung: + + + + Size: + Größe: + + + + Writer(s): + Autor(en): + + + + Penciller(s): + Künstler(Bleistift): + + + + Inker(s): + Künstler(Tinte): + + + + Colorist(s): + Künstler(Farbe): + + + + Letterer(s): + Künstler(Schrift): + + + + Cover Artist(s): + Titelbild-Künstler: + + + + Editor(s): + Herausgeber(n): + + + + Imprint: + Impressum: + + + + Day: + Tag: + + + + Month: + Monat: + + + + Year: + Jahr: + + + + Publisher: + Verlag: + + + + Format: + Formatangabe: + + + + Color/BW: + Farbe/Schwarz-Weiß: + + + + Age rating: + Altersangabe: + + + + Type: + Typ: + + + + Language (ISO): + Sprache (ISO): + + + + Synopsis: + Zusammenfassung: + + + + Characters: + Charaktere: + + + + Teams: + Mannschaften: + + + + Locations: + Standorte: + + + + Main character or team: + Hauptfigur oder Team: + + + + Review: + Rezension: + + + + Notes: + Anmerkungen: + + + + Tags: + Schlagworte: + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine-Link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ansehen </a> + + + + Not found + Nicht gefunden + + + + Comic not found. You should update your library. + Comic nicht gefunden. Sie sollten Ihre Bibliothek updaten. + + + + Edit comic information + Comic-Informationen bearbeiten + + + + Edit selected comics information + Ausgewählte Comic-Informationen bearbeiten + + + + Invalid cover + Ungültiger Versicherungsschutz + + + + The image is invalid. + Das Bild ist ungültig. + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer ist die Headless-Version (keine GUI) von YACReaderLibrary. + +Diese Anwendung unterstützt dauerhafte Einstellungen. Um sie einzurichten, bearbeiten Sie diese Datei %1 +Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Dokumentation unter https://raw.githubusercontent.com/YACReader/yareader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject + + + Trace + Verfolgen + + + + Debug + Fehlersuche + + + + Info + Information + + + + Warning + Warnung + + + + Error + Fehler + + + + Fatal + Tödlich + + + + Select custom cover + Wählen Sie ein benutzerdefiniertes Cover + + + + Images (%1) + Bilder (%1) + + + + 7z lib not found + 7z-Verzeichnis nicht gefunden + + + + unable to load 7z lib from ./utils + 7z -erzeichnis kann von ./utils nicht geladen werden + + + + The file could not be read or is not valid JSON. + Die Datei konnte nicht gelesen werden oder ist kein gültiges JSON. + + + + This theme is for %1, not %2. + Dieses Thema ist für %1, nicht für %2. + + + + Libraries + Bibliotheken + + + + Folders + Ordner + + + + Reading Lists + Leselisten + + + + RenameLibraryDialog + + + New Library Name : + Neuer Bibliotheksname : + + + + Rename + Umbenennen + + + + Cancel + Abbrechen + + + + Rename current library + Aktuelle Bibliothek umbenennen + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + Anzahl der gefundenen Bände: %1 + + + + + page %1 of %2 + Seite %1 von %2 + + + + Number of %1 found : %2 + Anzahl von %1 gefunden : %2 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + Bitte stellen Sie weitere Informationen zur Verfügung. + + + + Series: + Serie: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Verwenden Sie die Suche nach exakten Übereinstimmungen. Deaktivieren Sie diese Option, wenn Sie Bände finden möchten, die mit einigen Wörtern im Namen übereinstimmen. + + + + SearchVolume + + + Please provide some additional information. + Bitte stellen Sie weitere Informationen zur Verfügung. + + + + Series: + Serie: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Verwenden Sie die Suche nach exakten Übereinstimmungen. Deaktivieren Sie diese Option, wenn Sie Bände finden möchten, die mit einigen Wörtern im Namen übereinstimmen. + + + + SelectComic + + + Please, select the right comic info. + Bitte wählen Sie die korrekte Comic-Information aus. + + + + comics + Comics + + + + loading cover + Titelbild wird geladen + + + + loading description + Beschreibung wird laden + + + + comic description unavailable + Comic-Beschreibung nicht verfügbar + + + + SelectVolume + + + Please, select the right series for your comic. + Bitte wählen Sie die korrekte Serie für Ihre Comics aus. + + + + Filter: + Filteroption: + + + + volumes + Bände + + + + Nothing found, clear the filter if any. + Nichts gefunden. Löschen Sie ggf. den Filter. + + + + loading cover + Titelbild wird geladen + + + + loading description + Beschreibung wird laden + + + + volume description unavailable + Bandbeschreibung nicht verfügbar + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + Sie versuchen, Informationen zu mehreren Comics gleichzeitig zu laden, sind diese Teil einer Serie? + + + + yes + Ja + + + + no + Nein + + + + ServerConfigDialog + + + set port + Anschluss wählen + + + + Server connectivity information + Serveranschluss-Information + + + + Scan it! + Durchsuchen! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader ist für iOS- und Android-Geräte verfügbar.<br/>Entdecken Sie es für <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> oder <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + + + + Choose an IP address + IP-Adresse auswählen + + + + Port + Anschluss + + + + enable the server + Server aktivieren + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + Sortieren Sie bitte die Comic-Informationen links, bis die Informationen mit den Comics übereinstimmen. + + + + sort comics to match comic information + Comics laut Comic-Information sortieren + + + + issues + Ausgaben + + + + remove selected comics + Ausgewählte Comics entfernen + + + + restore all removed comics + Alle entfernten Comics wiederherstellen + + + + ThemeEditorDialog + + + Theme Editor + Theme-Editor + + + + + + + + + + + - + - + + + + i + ich + + + + Expand all + Alles erweitern + + + + Collapse all + Alles einklappen + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Halten Sie gedrückt, um den ausgewählten Wert in der Benutzeroberfläche zu blinken (Magenta / umgeschaltet / 0↔10). Releases stellen das Original wieder her. + + + + Search… + Suchen… + + + + Light + Licht + + + + Dark + Dunkel + + + + ID: + AUSWEIS: + + + + Display name: + Anzeigename: + + + + Variant: + Variante: + + + + Theme info + Themeninfo + + + + Parameter + Parameterwert + + + + Value + Wert + + + + Save and apply + Speichern und bewerben + + + + Export to file... + In Datei exportieren... + + + + Load from file... + Aus Datei laden... + + + + Close + Schliessen + + + + Double-click to edit color + Doppelklicken Sie, um die Farbe zu bearbeiten + + + + + + + + + true + WAHR + + + + + + + false + FALSCH + + + + Double-click to toggle + Zum Umschalten doppelklicken + + + + Double-click to edit value + Doppelklicken Sie, um den Wert zu bearbeiten + + + + + + Edit: %1 + Bearbeiten: %1 + + + + Save theme + Thema speichern + + + + + JSON files (*.json);;All files (*) + JSON-Dateien (*.json);;Alle Dateien (*) + + + + Save failed + Speichern fehlgeschlagen + + + + Could not open file for writing: +%1 + Die Datei konnte nicht zum Schreiben geöffnet werden: +%1 + + + + Load theme + Theme laden + + + + + + Load failed + Das Laden ist fehlgeschlagen + + + + Could not open file: +%1 + Datei konnte nicht geöffnet werden: +%1 + + + + Invalid JSON: +%1 + Ungültiger JSON: +%1 + + + + Expected a JSON object. + Es wurde ein JSON-Objekt erwartet. + + + + TitleHeader + + + SEARCH + Suchen + + + + UpdateLibraryDialog + + + Updating.... + Aktualisierung.... + + + + Cancel + Abbrechen + + + + Update library + Bibliothek updaten + + + + Viewer + + + + Press 'O' to open comic. + 'O' drücken, um Comic zu öffnen. + + + + Not found + Nicht gefunden + + + + Comic not found + Comic nicht gefunden + + + + Error opening comic + Fehler beim Öffnen des Comics + + + + CRC Error + CRC Fehler + + + + Loading...please wait! + Ladevorgang... Bitte warten! + + + + Page not available! + Seite nicht verfügbar! + + + + Cover! + Titelseite! + + + + Last page! + Letzte Seite! + + + + VolumeComicsModel + + + title + Titel + + + + VolumesModel + + + year + Jahr + + + + issues + Ausgaben + + + + publisher + Herausgeber + + + + YACReader3DFlowConfigWidget + + + Presets: + Voreinstellungen: + + + + Classic look + Klassische Ansicht + + + + Stripe look + Streifen-Ansicht + + + + Overlapped Stripe look + Überlappende Streifen-Ansicht + + + + Modern look + Moderne Ansicht + + + + Roulette look + Zufalls-Ansicht + + + + Show advanced settings + Zeige erweiterte Einstellungen + + + + Custom: + Benutzerdefiniert: + + + + View angle + Anzeige-Winkel + + + + Position + Lage + + + + Cover gap + Titelbild-Abstand + + + + Central gap + Mittiger Abstand + + + + Zoom + Vergrößern + + + + Y offset + Y-Anpassung + + + + Z offset + Z-Anpassung + + + + Cover Angle + Titelbild Ansichtswinkel + + + + Visibility + Sichtbarkeit + + + + Light + Licht + + + + Max angle + Maximaler Winkel + + + + Low Performance + Niedrige Leistung + + + + High Performance + Hohe Leistung + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Benutze VSync (verbessert die Bildqualität im Vollanzeigemodus, schlechtere Leistung) + + + + Performance: + Leistung: + + + + YACReader::MainWindowViewer + + + &Open + &Öffnen + + + + Open a comic + Comic öffnen + + + + New instance + Neuer Fall + + + + Open Folder + Ordner öffnen + + + + Open image folder + Bilder-Ordner öffnen + + + + Open latest comic + Neuesten Comic öffnen + + + + Open the latest comic opened in the previous reading session + Öffne den neuesten Comic deiner letzten Sitzung + + + + Clear + Löschen + + + + Clear open recent list + Lösche Liste zuletzt geöffneter Elemente + + + + Save + Speichern + + + + + Save current page + Aktuelle Seite speichern + + + + Previous Comic + Voheriger Comic + + + + + + Open previous comic + Vorherigen Comic öffnen + + + + Next Comic + Nächster Comic + + + + + + Open next comic + Nächsten Comic öffnen + + + + &Previous + &Vorherige + + + + + + Go to previous page + Zur vorherigen Seite gehen + + + + &Next + &Nächstes + + + + + + Go to next page + Zur nächsten Seite gehen + + + + Fit Height + Höhe anpassen + + + + Fit image to height + Bild an Höhe anpassen + + + + Fit Width + Breite anpassen + + + + Fit image to width + Bildbreite anpassen + + + + Show full size + Vollansicht anzeigen + + + + Fit to page + An Seite anpassen + + + + Continuous scroll + Kontinuierliches Scrollen + + + + Switch to continuous scroll mode + Wechseln Sie in den kontinuierlichen Bildlaufmodus + + + + Reset zoom + Zoom zurücksetzen + + + + Show zoom slider + Zoomleiste anzeigen + + + + Zoom+ + Vergr??ern+ + + + + Zoom- + Verkleinern- + + + + Rotate image to the left + Bild nach links drehen + + + + Rotate image to the right + Bild nach rechts drehen + + + + Double page mode + Doppelseiten-Modus + + + + Switch to double page mode + Zum Doppelseiten-Modus wechseln + + + + Double page manga mode + Doppelseiten-Manga-Modus + + + + Reverse reading order in double page mode + Umgekehrte Lesereihenfolge im Doppelseiten-Modus + + + + Go To + Gehe zu + + + + Go to page ... + Gehe zu Seite ... + + + + Options + Optionen + + + + YACReader options + YACReader Optionen + + + + + Help + Hilfe + + + + Help, About YACReader + Hilfe, über YACReader + + + + Magnifying glass + Vergößerungsglas + + + + Switch Magnifying glass + Vergrößerungsglas wechseln + + + + Set bookmark + Lesezeichen setzen + + + + Set a bookmark on the current page + Lesezeichen auf dieser Seite setzen + + + + Show bookmarks + Lesezeichen anzeigen + + + + Show the bookmarks of the current comic + Lesezeichen für diesen Comic anzeigen + + + + Show keyboard shortcuts + Tastenkürzel anzeigen + + + + Show Info + Info anzeigen + + + + Close + Schliessen + + + + Show Dictionary + Wörterbuch anzeigen + + + + Show go to flow + "Go to Flow" anzeigen + + + + Edit shortcuts + Kürzel ändern + + + + &File + &Datei + + + + + Open recent + Kürzlich geöffnet + + + + File + Datei + + + + Edit + Ändern + + + + View + Anzeigen + + + + Go + Los + + + + Window + Fenster + + + + + + Open Comic + Comic öffnen + + + + + + Comic files + Comic-Dateien + + + + Open folder + Ordner öffnen + + + + page_%1.jpg + Seite_%1.jpg + + + + Image files (*.jpg) + Bildateien (*.jpg) + + + + + Comics + Comichefte + + + + + General + Allgemein + + + + + Magnifiying glass + Vergrößerungsglas + + + + + Page adjustement + Seitenanpassung + + + + + Reading + Lesend + + + + Toggle fullscreen mode + Vollbild-Modus umschalten + + + + Hide/show toolbar + Symbolleiste anzeigen/verstecken + + + + Size up magnifying glass + Vergrößerungsglas vergrößern + + + + Size down magnifying glass + Vergrößerungsglas verkleinern + + + + Zoom in magnifying glass + Vergrößerungsglas reinzoomen + + + + Zoom out magnifying glass + Vergrößerungsglas rauszoomen + + + + Reset magnifying glass + Lupe zurücksetzen + + + + Toggle between fit to width and fit to height + Zwischen Anpassung an Seite und Höhe wechseln + + + + Autoscroll down + Automatisches Runterscrollen + + + + Autoscroll up + Automatisches Raufscrollen + + + + Autoscroll forward, horizontal first + Automatisches Vorwärtsscrollen, horizontal zuerst + + + + Autoscroll backward, horizontal first + Automatisches Zurückscrollen, horizontal zuerst + + + + Autoscroll forward, vertical first + Automatisches Vorwärtsscrollen, vertikal zuerst + + + + Autoscroll backward, vertical first + Automatisches Zurückscrollen, vertikal zuerst + + + + Move down + Nach unten + + + + Move up + Nach oben + + + + Move left + Nach links + + + + Move right + Nach rechts + + + + Go to the first page + Zur ersten Seite gehen + + + + Go to the last page + Zur letzten Seite gehen + + + + Offset double page to the left + Doppelseite nach links versetzt + + + + Offset double page to the right + Doppelseite nach rechts versetzt + + + + There is a new version available + Neue Version verfügbar + + + + Do you want to download the new version? + Möchten Sie die neue Version herunterladen? + + + + Remind me in 14 days + In 14 Tagen erneut erinnern + + + + Not now + Nicht jetzt + + + + YACReader::TrayIconController + + + &Restore + &Wiederherstellen + + + + Systray + Taskleiste + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary wird im Hintergrund weiterlaufen. Um das Programm zu schließen, wählen Sie <b>Schließen</b> im Kontextmenü des Taskleisten-Symbols. + + + + YACReaderFieldEdit + + + + Click to overwrite + Anklicken, um zu überschreiben + + + + Restore to default + Ursprungszustand wiederherstellen + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + Anklicken, um zu überschreiben + + + + Restore to default + Ursprungszustand wiederherstellen + + + + YACReaderOptionsDialog + + + Save + Speichern + + + + Cancel + Abbrechen + + + + Edit shortcuts + Kürzel ändern + + + + Shortcuts + Kürzel + + + + YACReaderSearchLineEdit + + + type to search + tippen, um zu suchen + + + + YACReaderSlider + + + Reset + Zurücksetzen - QsLogging::Window + YACReaderTranslator - - &Pause - + + YACReader translator + YACReader Übersetzer - - &Resume - + + + Translation + Übersetzung - - Save log - + + clear + Löschen - - Log file (*.log) - + + Service not available + Service nicht verfügbar diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_es.ts b/YACReaderLibraryServer/yacreaderlibraryserver_es.ts index 747d30579..b4d17cb38 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_es.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_es.ts @@ -2,150 +2,3694 @@ - FileComic + ActionsShortcutsModel - - CRC error on page (%1): some of the pages will not be displayed correctly - + + None + Ninguno + + + AddLabelDialog - - Unknown error opening the file - + + Label name: + Nombre de la etiqueta: - - 7z not found - + + Choose a color: + Elige un color: - - Format not supported - + + accept + aceptar + + + + cancel + Cancelar - LogWindow + AddLibraryDialog + + + Comics folder : + Carpeta de cómics : + + + + Library name : + Nombre de la biblioteca : + - - Log window - + + Add + Añadir - - &Pause - + + Cancel + Cancelar - - &Save - + + Add an existing library + Añadir una biblioteca existente + + + ApiKeyDialog - - C&lear - + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Antes de que te puedas conectar a Comic Vine necesitas tu propia clave API. Por favor, obtén una gratis <a href="http://www.comicvine.com/api/">aquí</a> - - &Copy - + + Paste here your Comic Vine API key + Pega aquí tu clave API de Comic Vine - - Level: - + + Accept + Aceptar - - &Auto scroll - + + Cancel + Cancelar - QCoreApplication + AppearanceTabWidget - - -YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + + Color scheme + Esquema de color + + + + System + Sistema + + + + Light + Luz + + + + Dark + Oscuro + + + + Custom + Personalizado + + + + Remove + Eliminar + + + + Remove this user-imported theme + Eliminar este tema importado por el usuario + + + + Light: + Claro: + + + + Dark: + Oscuro: + + + + Custom: + Personalizado: + + + + Import theme... + Importar tema... + + + + Theme + Tema + + + + Theme editor + Editor de temas + + + + Open Theme Editor... + Abrir editor de temas... + + + + Theme editor error + Error del editor de temas + + + + The current theme JSON could not be loaded. + No se ha podido cargar el JSON del tema actual. + + + + Import theme + Importar tema + + + + JSON files (*.json);;All files (*) + Archivos JSON (*.json);;Todos los archivos (*) + + + + Could not import theme from: +%1 + No se pudo importar el tema desde:\n%1 + + + + Could not import theme from: +%1 -This appplication supports persistent settings, to set them up edit this file %1 -To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md - +%2 + No se pudo importar el tema desde:\n%1\n\n%2 + + + + Import failed + Error al importar - QObject + BookmarksDialog - - Trace - + + Lastest Page + Última página - - Debug - + + Close + Cerrar - - Info - + + Click on any image to go to the bookmark + Pulsa en cualquier imagen para ir al marcador - - Warning - + + + Loading... + Cargando... + + + ClassicComicsView - - Error - + + Hide comic flow + Ocultar cómic flow + + + ComicModel - - Fatal - + + yes + + + + + no + No + + + + Title + Título + + + + File Name + Nombre de archivo + + + + Pages + Páginas + + + + Size + Tamaño + + + + Read + Leído + + + + Current Page + Página Actual + + + + Publication Date + Fecha de publicación + + + + Rating + Nota + + + + Series + Serie + + + + Volume + Volumen + + + + Story Arc + Arco argumental + + + + ComicVineDialog + + + skip + omitir + + + + back + atrás + + + + next + siguiente + + + + search + buscar + + + + close + Cerrar + + + + + comic %1 of %2 - %3 + cómic %1 de %2 - %3 + + + + + + Looking for volume... + Buscando volumen... + + + + %1 comics selected + %1 cómics seleccionados + + + + Error connecting to ComicVine + Error conectando a ComicVine + + + + + Retrieving tags for : %1 + Recuperando etiquetas para : %1 + + + + Retrieving volume info... + Recuperando información del volumen... + + + + Looking for comic... + Buscando cómic... + + + + ContinuousPageWidget + + + Loading page %1 + Cargando página %1 + + + + CreateLibraryDialog + + + Comics folder : + Carpeta de cómics : + + + + Library Name : + Nombre de la biblioteca : + + + + Create + Crear + + + + Cancel + Cancelar + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Crear una biblioteca puede llevar varios minutos. Puedes parar el proceso en cualquier momento y completar la tarea más tarde. + + + + Create new library + Crear la nueva biblioteca + + + + Path not found + Ruta no encontrada + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + La ruta seleccionada no existe o no es válida. Asegúrate de que tienes privilegios de escritura en esta carpeta + + + + EditShortcutsDialog + + + Restore defaults + Restaurar los valores predeterminados + + + + To change a shortcut, double click in the key combination and type the new keys. + Para cambiar un atajo, haz doble clic en la combinación de teclas y escribe las nuevas teclas. + + + + Shortcuts settings + Configuración de accesos directos + + + + Shortcut in use + Accesos directos en uso + + + + The shortcut "%1" is already assigned to other function + El acceso directo "%1" ya está asignado a otra función + + + + EmptyFolderWidget + + + This folder doesn't contain comics yet + Esta carpeta aún no contiene cómics + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + Esta etiqueta aún no contiene ningún cómic + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + Esta lista de tectura aún no contiene ningún cómic + + + + EmptySpecialListWidget + + + No favorites + Ningún favorito + + + + You are not reading anything yet, come on!! + No estás leyendo nada aún, ¡vamos! + + + + There are no recent comics! + ¡No hay comics recientes! + + + + ExportComicsInfoDialog + + + Output file : + Archivo de salida : + + + + Create + Crear + + + + Cancel + Cancelar + + + + Export comics info + Exportar información de los cómics + + + + Destination database name + Nombre de la base de datos de destino + + + + Problem found while writing + Problema encontrado mientras se escribía + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + La ruta seleccionada para el archivo de salida no existe o no es una ruta válida. Asegúrate de que tienes permisos de escritura en esta carpeta + + + + ExportLibraryDialog + + + Output folder : + Carpeta de destino : + + + + Create + Crear + + + + Cancel + Cancelar + + + + Create covers package + Crear paquete de portadas + + + + Problem found while writing + Problema encontrado mientras se escribía + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + La ruta seleccionada para el archivo de salida no existe o no es una ruta válida. Asegúrate de que tienes permisos de escritura en esta carpeta + + + + Destination directory + Carpeta de destino + + + + FileComic + + + CRC error on page (%1): some of the pages will not be displayed correctly + Error CRC en la página (%1): algunas de las páginas no se mostrarán correctamente + + + + Unknown error opening the file + Error desconocido abriendo el archivo + + + + 7z not found + 7z no encontrado + + + + Format not supported + Formato no soportado + + + + GoToDialog + + + Page : + Página : + + + + Go To + Ir a + + + + Cancel + Cancelar + + + + + Total pages : + Páginas totales : + + + + Go to... + Ir a... + + + + GoToFlowToolBar + + + Page : + Página : + + + + GridComicsView + + + Show info + Mostrar información - QsLogging::LogWindowModel + HelpAboutDialog - - Time - + + About + Acerca de - - Level - + + Help + Ayuda - - Message - + + System info + Información de sistema + + + + ImportComicsInfoDialog + + + Import comics info + Importar información de cómics + + + + Info database location : + Ubicación de la base de datos de información : + + + + Import + Importar + + + + Cancel + Cancelar + + + + Comics info file (*.ydb) + Archivo de información de cómics (*.ydb) + + + + ImportLibraryDialog + + + Library Name : + Nombre de la biblioteca : + + + + Package location : + Ubicación del paquete : + + + + Destination folder : + Directorio de destino : + + + + Unpack + Desempaquetar + + + + Cancel + Cancelar + + + + Extract a catalog + Extraer un catálogo + + + + Compresed library covers (*.clc) + Portadas de biblioteca comprimidas (*.clc) + + + + ImportWidget + + + stop + parar + + + + Some of the comics being added... + Algunos de los cómics que estan siendo añadidos.... + + + + Importing comics + Importando cómics + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary está creando una nueva biblioteca.</p><p>Crear una biblioteca puede llevar varios minutos. Puedes parar el proceso en cualquier momento y actualizar la biblioteca más tarde para completar el proceso.</p> + + + + Updating the library + Actualizando la biblioteca + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>La biblioteca actual está siendo actualizada. Para actualizaciones más rápidas, por favor, actualiza tus bibliotecas frecuentemente.</p><p>Puedes parar el proceso y continunar la actualización más tarde.</p> + + + + Upgrading the library + Actualizando la biblioteca + + + + <p>The current library is being upgraded, please wait.</p> + <p>La biblioteca actual está siendo actualizadad, espera por favor.</p> + + + + Scanning the library + Escaneando la biblioteca + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>La biblioteca está siendo escaneada para encontrar metadatos en formato XML.</p><p>Sólo necesitas hacer esto una vez, y sólo si la biblioteca fue creada con YACReaderLibrary 9.8.2 o antes.</p> + + + + LibraryWindow + + + YACReader Library + Biblioteca YACReader + + + + + + comic + Cómic + + + + + + manga + historieta manga + + + + + + western manga (left to right) + manga occidental (izquierda a derecha) + + + + + + web comic + cómic web + + + + + + 4koma (top to botom) + 4koma (de arriba a abajo) + + + + + + + Set type + Establecer tipo + + + + Library + Librería + + + + Folder + Carpeta + + + + Comic + Cómic + + + + Upgrade failed + La actualización falló + + + + There were errors during library upgrade in: + Hubo errores durante la actualización de la biblioteca en: + + + + Update needed + Se necesita actualizar + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Esta biblioteca fue creada con una versión anterior de YACReaderLibrary. Es necesario que se actualice. ¿Deseas hacerlo ahora? + + + + Download new version + Descargar la nueva versión + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Esta biblioteca fue creada con una versión más nueva de YACReaderLibrary. ¿Deseas descargar la nueva versión ahora? + + + + Library not available + Biblioteca no disponible + + + + Library '%1' is no longer available. Do you want to remove it? + La biblioteca '%1' no está disponible. ¿Deseas eliminarla? + + + + Old library + Biblioteca antigua + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La biblioteca '%1' ha sido creada con una versión más antigua de YACReaderLibrary y debe ser creada de nuevo. ¿Deseas crear la biblioteca ahora? + + + + + Copying comics... + Copiando cómics... + + + + + Moving comics... + Moviendo cómics... + + + + Add new folder + Añadir carpeta + + + + Folder name: + Nombre de la carpeta: + + + + No folder selected + No has selecionado ninguna carpeta + + + + Please, select a folder first + Por favor, selecciona una carpeta primero + + + + Error in path + Error en la ruta + + + + There was an error accessing the folder's path + Hubo un error al acceder a la ruta de la carpeta + + + + Delete folder + Borrar carpeta + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + ¿Estás seguro de que deseas eliminar la carpeta seleccionada y todo su contenido de tu disco? + + + + + Unable to delete + No se ha podido borrar + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Se produjo un problema al intentar eliminar las carpetas seleccionadas. Por favor, verifica los permisos de escritura y asegúrate de que no haya aplicaciones usando estas carpetas o alguno de los archivos contenidos en ellas. + + + + Add new reading lists + Añadir nuevas listas de lectura + + + + + List name: + Nombre de la lista: + + + + Delete list/label + Eliminar lista/etiqueta + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + El elemento seleccionado se eliminará, tus cómics o carpetas NO se eliminarán de tu disco. ¿Estás seguro? + + + + Rename list name + Renombrar lista + + + + Open folder... + Abrir carpeta... + + + + Update folder + Actualizar carpeta + + + + Rescan library for XML info + Volver a escanear la biblioteca en busca de información XML + + + + Set as uncompleted + Marcar como incompleto + + + + Set as completed + Marcar como completo + + + + Set as read + Marcar como leído + + + + + Set as unread + Marcar como no leído + + + + Set custom cover + Establecer portada personalizada + + + + Delete custom cover + Eliminar portada personalizada + + + + Save covers + Guardar portadas + + + + You are adding too many libraries. + Estás añadiendo demasiadas bibliotecas. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Estás añadiendo demasiadas bibliotecas.\n\nProbablemente solo necesites una biblioteca en la carpeta principal de tus cómics, puedes explorar cualquier subcarpeta utilizando la sección de carpetas en la barra lateral izquierda.\n\nYACReaderLibrary no te detendrá de crear más bibliotecas, pero deberías mantener el número de bibliotecas bajo control. + + + + + YACReader not found + YACReader no encontrado + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader no encontrado. YACReader debería estar instalado en la misma carpeta que YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader no encontrado. Podría haber un problema con tu instalación de YACReader. + + + + Error + Fallo + + + + Error opening comic with third party reader. + Error al abrir el cómic con una aplicación de terceros. + + + + Library not found + Biblioteca no encontrada + + + + The selected folder doesn't contain any library. + La carpeta seleccionada no contiene ninguna biblioteca. + + + + Are you sure? + ¿Estás seguro? + + + + Do you want remove + ¿Deseas eliminar la biblioteca + + + + library? + ? + + + + Remove and delete metadata + Eliminar y borrar metadatos + + + + Library info + Información de la biblioteca + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Ha habido algún problema intentando borrar los cómics selecionados. Por favor, verifica los permisos de escritura en los arhicovs seleccionados o los directorios que los conienen. + + + + Assign comics numbers + Asignar números a los cómics + + + + Assign numbers starting in: + Asignar números comenzando en: + + + + Invalid image + Imagen inválida + + + + The selected file is not a valid image. + El archivo seleccionado no es una imagen válida. + + + + Error saving cover + Error guardando portada + + + + There was an error saving the cover image. + Hubo un error guardando la image de portada. + + + + Error creating the library + Errar creando la biblioteca + + + + Error updating the library + Error actualizando la biblioteca + + + + Error opening the library + Error abriendo la biblioteca + + + + Delete comics + Borrar cómics + + + + All the selected comics will be deleted from your disk. Are you sure? + Todos los cómics seleccionados serán borrados de tu disco. ¿Estás seguro? + + + + Remove comics + Eliminar cómics + + + + Comics will only be deleted from the current label/list. Are you sure? + Los cómics sólo se eliminarán de la etiqueta/lista actual. ¿Estás seguro? + + + + Library name already exists + Ya existe el nombre de la biblioteca + + + + There is another library with the name '%1'. + Hay otra biblioteca con el nombre '%1'. + + + + LibraryWindowActions + + + Create a new library + Crear una nueva biblioteca + + + + Open an existing library + Abrir una biblioteca existente + + + + + Export comics info + Exportar información de los cómics + + + + + Import comics info + Importar información de cómics + + + + Pack covers + Empaquetar portadas + + + + Pack the covers of the selected library + Empaquetar las portadas de la biblioteca seleccionada + + + + Unpack covers + Desempaquetar portadas + + + + Unpack a catalog + Desempaquetar un catálogo + + + + Update library + Actualizar biblioteca + + + + Update current library + Actualizar la biblioteca seleccionada + + + + Rename library + Renombrar biblioteca + + + + Rename current library + Renombrar la biblioteca seleccionada + + + + Remove library + Eliminar biblioteca + + + + Remove current library from your collection + Eliminar biblioteca de la colección + + + + Rescan library for XML info + Volver a escanear la biblioteca en busca de información XML + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Intenta encontrar información XML incrustada en los archivos de cómic. Solo necesitas hacer esto si la biblioteca fue creada con la versión 9.8.2 o versiones anteriores o si estás utilizando software de terceros para incrustar información XML en los archivos. + + + + Show library info + Mostrar información de la biblioteca + + + + Show information about the current library + Mostrar información de la biblioteca actual + + + + Open current comic + Abrir cómic actual + + + + Open current comic on YACReader + Abrir el cómic actual en YACReader + + + + Save selected covers to... + Guardar las portadas seleccionadas en... + + + + Save covers of the selected comics as JPG files + Guardar las portadas de los cómics seleccionados como archivos JPG + + + + + Set as read + Marcar como leído + + + + Set comic as read + Marcar cómic como leído + + + + + Set as unread + Marcar como no leído + + + + Set comic as unread + Marcar cómic como no leído + + + + + manga + historieta manga + + + + Set issue as manga + Marcar número como manga + + + + + comic + Cómic + + + + Set issue as normal + Marcar número como cómic + + + + western manga + manga occidental + + + + Set issue as western manga + Marcar número como manga occidental + + + + + web comic + cómic web + + + + Set issue as web comic + Marcar número como cómic web + + + + + yonkoma + tira yonkoma + + + + Set issue as yonkoma + Marcar número como yonkoma + + + + Show/Hide marks + Mostrar/Ocultar marcas + + + + Show or hide read marks + Mostrar u ocultar marcas + + + + Show/Hide recent indicator + Mostrar/Ocultar el indicador reciente + + + + Show or hide recent indicator + Mostrar o ocultar el indicador reciente + + + + + Fullscreen mode on/off + Modo a pantalla completa on/off + + + + Help, About YACReader + Ayuda, Sobre YACReader + + + + Add new folder + Añadir carpeta + + + + Add new folder to the current library + Añadir carpeta a la biblioteca actual + + + + Delete folder + Borrar carpeta + + + + Delete current folder from disk + Borrar carpeta actual del disco + + + + Select root node + Seleccionar el nodo raíz + + + + Expand all nodes + Expandir todos los nodos + + + + Collapse all nodes + Contraer todos los nodos + + + + Show options dialog + Mostrar opciones + + + + Show comics server options dialog + Mostrar el diálogo de opciones del servidor de cómics + + + + + Change between comics views + Cambiar entre vistas de cómics + + + + Open folder... + Abrir carpeta... + + + + Set as uncompleted + Marcar como incompleto + + + + Set as completed + Marcar como completo + + + + Set custom cover + Establecer portada personalizada + + + + Delete custom cover + Eliminar portada personalizada + + + + western manga (left to right) + manga occidental (izquierda a derecha) + + + + Open containing folder... + Abrir carpeta contenedora... + + + + Reset comic rating + Reseteal cómic rating + + + + Select all comics + Seleccionar todos los cómics + + + + Edit + Editar + + + + Assign current order to comics + Asignar el orden actual a los cómics + + + + Update cover + Actualizar portada + + + + Delete selected comics + Borrar los cómics seleccionados + + + + Delete metadata from selected comics + Borrar metadatos de los cómics seleccionados + + + + Download tags from Comic Vine + Descargar etiquetas de Comic Vine + + + + Focus search line + Selecionar el campo de búsqueda + + + + Focus comics view + Selecionar la vista de cómics + + + + Edit shortcuts + Editar accesos directos + + + + &Quit + &Salir + + + + Update folder + Actualizar carpeta + + + + Update current folder + Actualizar carpeta actual + + + + Scan legacy XML metadata + Escaneal metadatos XML + + + + Add new reading list + Añadir lista de lectura + + + + Add a new reading list to the current library + Añadir una nueva lista de lectura a la biblioteca actual + + + + Remove reading list + Eliminar lista de lectura + + + + Remove current reading list from the library + Eliminar la lista de lectura actual de la biblioteca + + + + Add new label + Añadir etiqueta + + + + Add a new label to this library + Añadir etiqueta a esta biblioteca + + + + Rename selected list + Renombrar la lista seleccionada + + + + Rename any selected labels or lists + Renombrar las etiquetas o listas seleccionadas + + + + Add to... + Añadir a... + + + + Favorites + Favoritos + + + + Add selected comics to favorites list + Añadir cómics seleccionados a la lista de favoritos + + + + LocalComicListModel + + + file name + Nombre de archivo + + + + NoLibrariesWidget + + + You don't have any libraries yet + Aún no tienes ninguna biblioteca + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Puedes crear una biblioteca en cualquier carpeta, YACReaderLibrary importará todos las carpetas y cómics de esa carpeta. Si has creado alguna biblioteca anteriormente, puedes abrirla sin volver a crearla.</p><p>No olvides que puedes usar YACReader como una aplicación independiente para leer los cómics en tu ordenador.</p> + + + + create your first library + crea tu primera biblioteca + + + + add an existing one + añade una existente + + + + NoSearchResultsWidget + + + No results + Sin resultados + + + + OptionsDialog + + + + General + Opciones generales + + + + + Libraries + Bibliotecas + + + + Comic Flow + Flujo cómico + + + + Grid view + Vista en cuadrícula + + + + + Appearance + Apariencia + + + + + Options + Opciones + + + + + Language + Idioma + + + + + Application language + Idioma de la aplicación + + + + + System default + Predeterminado del sistema + + + + Tray icon settings (experimental) + Opciones de bandeja de sistema (experimental) + + + + Close to tray + Cerrar a la bandeja + + + + Start into the system tray + Comenzar en la bandeja de sistema + + + + Edit Comic Vine API key + Editar la clave API de Comic Vine + + + + Comic Vine API key + Clave API de Comic Vine + + + + ComicInfo.xml legacy support + Soporte para ComicInfo.xml + + + + Import metadata from ComicInfo.xml when adding new comics + Importar metadatos desde ComicInfo.xml al añadir nuevos cómics + + + + Consider 'recent' items added or updated since X days ago + Considerar elementos 'recientes' añadidos o actualizados desde hace X días + + + + Third party reader + Lector externo + + + + Write {comic_file_path} where the path should go in the command + Escribe {comic_file_path} donde la ruta al cómic debería ir en el comando + + + + + Clear + Limpiar + + + + Update libraries at startup + Actualizar bibliotecas al inicio + + + + Try to detect changes automatically + Intentar detectar cambios automáticamente + + + + Update libraries periodically + Actualizar bibliotecas periódicamente + + + + Interval: + Intervalo: + + + + 30 minutes + 30 minutos + + + + 1 hour + 1 hora + + + + 2 hours + 2 horas + + + + 4 hours + 4 horas + + + + 8 hours + 8 horas + + + + 12 hours + 12 horas + + + + daily + dirariamente + + + + Update libraries at certain time + Actualizar bibliotecas en un momento determinado + + + + Time: + Hora: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + ¡ADVERTENCIA! Durante las actualizaciones de la biblioteca se desactivan las escrituras en la base de datos. No programes actualizaciones mientras puedas estar usando la aplicación activamente. Durante las actualizaciones automáticas, la aplicación bloqueará algunas de las acciones hasta que la actualización esté terminada. Para detener una actualización automática, toca en el indicador de carga junto al título de Bibliotecas. + + + + Modifications detection + Detección de modificaciones + + + + Compare the modified date of files when updating a library (not recommended) + Comparar la fecha de modificación de los archivos al actualizar una biblioteca (no recomendado) + + + + Enable background image + Activar imagen de fondo + + + + Opacity level + Nivel de opacidad + + + + Blur level + Nivel de desenfoque + + + + Use selected comic cover as background + Usar la portada del cómic seleccionado como fondo + + + + Restore defautls + Restaurar valores predeterminados + + + + Background + Fondo + + + + Display continue reading banner + Mostrar banner de "Continuar leyendo" + + + + Display current comic banner + Mostar el báner del cómic actual + + + + Continue reading + Continuar leyendo + + + + My comics path + Ruta a mis cómics + + + + Display + Visualización + + + + Show time in current page information label + Mostrar la hora en la etiqueta de información de la página actual + + + + "Go to flow" size + Tamaño de "Go to flow" + + + + Background color + Color de fondo + + + + Choose + Elegir + + + + Scroll behaviour + Comportamiento del scroll + + + + Disable scroll animations and smooth scrolling + Desactivar animaciones de desplazamiento y desplazamiento suave + + + + Do not turn page using scroll + No cambiar de página usando el scroll + + + + Use single scroll step to turn page + Usar un solo paso de desplazamiento para cambiar de página + + + + Mouse mode + Modo del ratón + + + + Only Back/Forward buttons can turn pages + Solo los botones Atrás/Adelante pueden cambiar de página + + + + Use the Left/Right buttons to turn pages. + Usar los botones Izquierda/Derecha para cambiar de página. + + + + Click left or right half of the screen to turn pages. + Hacer clic en la mitad izquierda o derecha de la pantalla para cambiar de página. + + + + Quick Navigation Mode + Modo de navegación rápida + + + + Disable mouse over activation + Desactivar activación al pasar el ratón + + + + Brightness + Brillo + + + + Contrast + Contraste + + + + Gamma + Gama + + + + Reset + Restablecer + + + + Image options + Opciones de imagen + + + + Fit options + Opciones de ajuste + + + + Enlarge images to fit width/height + Ampliar imágenes para ajustarse al ancho/alto + + + + Double Page options + Opciones de doble página + + + + Show covers as single page + Mostrar portadas como página única + + + + Scaling + Escalado + + + + Scaling method + Método de escalado + + + + Nearest (fast, low quality) + Vecino más cercano (rápido, baja calidad) + + + + Bilinear + Bilineal + + + + Lanczos (better quality) + Lanczos (mejor calidad) + + + + Page Flow + Flujo de página + + + + Image adjustment + Ajustes de imagen + + + + + Restart is needed + Es necesario reiniciar + + + + Comics directory + Directorio de cómics + + + + PropertiesDialog + + + General info + Información general + + + + Plot + Argumento + + + + Authors + Autores + + + + Publishing + Publicación + + + + Notes + Notas + + + + Cover page + Página de portada + + + + Load previous page as cover + Cargar página anterior como portada + + + + Load next page as cover + Cargar página siguiente como portada + + + + Reset cover to the default image + Restaurar la portada por defecto + + + + Load custom cover image + Cargar portada personalizada + + + + Series: + Serie: + + + + Title: + Título: + + + + + + of: + de: + + + + Issue number: + Número: + + + + Volume: + Volumen: + + + + Arc number: + Número de arco: + + + + Story arc: + Arco argumental: + + + + alt. number: + número alternativo: + + + + Alternate series: + Serie alternativa: + + + + Series Group: + Grupo de series: + + + + Genre: + Género: + + + + Size: + Tamaño: + + + + Writer(s): + Guionista(s): + + + + Penciller(s): + Dibujant(es): + + + + Inker(s): + Entintador(es): + + + + Colorist(s): + Color: + + + + Letterer(s): + Rotulista(s): + + + + Cover Artist(s): + Artista(s) portada: + + + + Editor(s): + Editor(es): + + + + Imprint: + Sello: + + + + Day: + Día: + + + + Month: + Mes: + + + + Year: + Año: + + + + Publisher: + Editorial: + + + + Format: + Formato: + + + + Color/BW: + Color/BN: + + + + Age rating: + Casificación edades: + + + + Type: + Tipo: + + + + Language (ISO): + Idioma (ISO): + + + + Synopsis: + Sinopsis: + + + + Characters: + Personajes: + + + + Teams: + Equipos: + + + + Locations: + Lugares: + + + + Main character or team: + Personaje o equipo principal: + + + + Review: + Reseña: + + + + Notes: + Notas: + + + + Tags: + Etiquetas: + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ver </a> + + + + Not found + No encontrado + + + + Comic not found. You should update your library. + Cómic no encontrado. Deberias actualizar tu biblioteca. + + + + Edit comic information + Editar la información del cócmic + + + + Edit selected comics information + Editar la información de los cómics seleccionados + + + + Invalid cover + Portada inválida + + + + The image is invalid. + La imagen no es válida. + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + \nYACReaderLibraryServer es la versión sin interfaz gráfica (headless) de YACReaderLibrary.\n\nEsta aplicación admite ajustes persistentes; para configurarlos, edita este archivo %1\nPara conocer los ajustes disponibles, consulta la documentación en https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject + + + Trace + Traza + + + + Debug + Depuración + + + + Info + Información + + + + Warning + Advertencia + + + + Error + Fallo + + + + Fatal + Cr?tico + + + + Select custom cover + Seleccionar portada personalizada + + + + Images (%1) + Imágenes (%1) + + + + 7z lib not found + 7z lib no encontrado + + + + unable to load 7z lib from ./utils + imposible cargar 7z lib de ./utils + + + + The file could not be read or is not valid JSON. + No se pudo leer el archivo o no es un JSON válido. + + + + This theme is for %1, not %2. + Este tema es para %1, no para %2. + + + + Libraries + Bibliotecas + + + + Folders + CARPETAS + + + + Reading Lists + Listas de lectura + + + + RenameLibraryDialog + + + New Library Name : + Nuevo nombre de la biblioteca : + + + + Rename + Renombrar + + + + Cancel + Cancelar + + + + Rename current library + Renombrar la biblioteca seleccionada + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + Número de volúmenes encontrados : %1 + + + + + page %1 of %2 + página %1 de %2 + + + + Number of %1 found : %2 + Número de %1 encontrados : %2 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + Por favor, proporciona alguna información adicional para éste cómic. + + + + Series: + Serie: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Usar búsqueda exacta. Desactívala si quieres encontrar volúmenes que coincidan con algunas palabras del nombre. + + + + SearchVolume + + + Please provide some additional information. + Por favor, proporciona alguna informacion adicional. + + + + Series: + Serie: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Usar búsqueda exacta. Desactívala si quieres encontrar volúmenes que coincidan con algunas palabras del nombre. + + + + SelectComic + + + Please, select the right comic info. + Por favor, selecciona la información correcta. + + + + comics + Cómics + + + + loading cover + cargando portada + + + + loading description + cargando descripción + + + + comic description unavailable + Descripción del cómic no disponible + + + + SelectVolume + + + Please, select the right series for your comic. + Por favor, seleciona la serie correcta para tu cómic. + + + + Filter: + Filtro: + + + + volumes + volúmenes + + + + Nothing found, clear the filter if any. + No se encontró nada, limpia el filtro si lo hubiera. + + + + loading cover + cargando portada + + + + loading description + cargando descripción + + + + volume description unavailable + Descripción del volumen no disponible + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + Estás intentando obtener información de varios cómics a la vez, ¿son parte de la misma serie? + + + + yes + + + + + no + No + + + + ServerConfigDialog + + + set port + fijar puerto + + + + Server connectivity information + Infomación de conexión del servidor + + + + Scan it! + ¡Escaneálo! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader está disponible para iOS y Android.<br/> Descúbrela para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a>o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + + + + Choose an IP address + Elige una dirección IP + + + + Port + Puerto + + + + enable the server + activar el servidor + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + Por favor, ordena la lista de cómics en la izquiera hasta que coincida con la información adecuada. + + + + sort comics to match comic information + ordena los cómics para coincidir con la información + + + + issues + números + + + + remove selected comics + eliminar cómics seleccionados + + + + restore all removed comics + restaurar todos los cómics eliminados + + + + ThemeEditorDialog + + + Theme Editor + Editor de temas + + + + + + + + + + + - + - + + + + i + ? + + + + Expand all + Expandir todo + + + + Collapse all + Contraer todo + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Mantén pulsado para resaltar temporalmente el valor seleccionado en la interfaz (magenta / alternado / 0↔10). Al soltar se restaura el original. + + + + Search… + Buscar… + + + + Light + Luz + + + + Dark + Oscuro + + + + ID: + IDENTIFICACIÓN: + + + + Display name: + Nombre para mostrar: + + + + Variant: + Variante: + + + + Theme info + Información del tema + + + + Parameter + Parámetro + + + + Value + Valor + + + + Save and apply + Guardar y aplicar + + + + Export to file... + Exportar a archivo... + + + + Load from file... + Cargar desde archivo... + + + + Close + Cerrar + + + + Double-click to edit color + Doble clic para editar el color + + + + + + + + + true + verdadero + + + + + + + false + falso + + + + Double-click to toggle + Doble clic para alternar + + + + Double-click to edit value + Doble clic para editar el valor + + + + + + Edit: %1 + Editar: %1 + + + + Save theme + Guardar tema + + + + + JSON files (*.json);;All files (*) + Archivos JSON (*.json);;Todos los archivos (*) + + + + Save failed + Error al guardar + + + + Could not open file for writing: +%1 + No se pudo abrir el archivo para escribir:\n%1 + + + + Load theme + Cargar tema + + + + + + Load failed + Error al cargar + + + + Could not open file: +%1 + No se pudo abrir el archivo:\n%1 + + + + Invalid JSON: +%1 + JSON no válido:\n%1 + + + + Expected a JSON object. + Se esperaba un objeto JSON. + + + + TitleHeader + + + SEARCH + buscar + + + + UpdateLibraryDialog + + + Updating.... + Actualizado... + + + + Cancel + Cancelar + + + + Update library + Actualizar biblioteca + + + + Viewer + + + + Press 'O' to open comic. + Pulsa 'O' para abrir un fichero. + + + + Not found + No encontrado + + + + Comic not found + Cómic no encontrado + + + + Error opening comic + Error abriendo cómic + + + + CRC Error + Error CRC + + + + Loading...please wait! + Cargando...espere, por favor! + + + + Page not available! + ¡Página no disponible! + + + + Cover! + ¡Portada! + + + + Last page! + ¡Última página! + + + + VolumeComicsModel + + + title + Título + + + + VolumesModel + + + year + año + + + + issues + números + + + + publisher + Editorial + + + + YACReader3DFlowConfigWidget + + + Presets: + Predefinidos: + + + + Classic look + Tipo clásico + + + + Stripe look + Tipo tira + + + + Overlapped Stripe look + Tipo tira solapada + + + + Modern look + Tipo moderno + + + + Roulette look + Tipo ruleta + + + + Show advanced settings + Opciones avanzadas + + + + Custom: + Personalizado: + + + + View angle + Ángulo de vista + + + + Position + Posición + + + + Cover gap + Hueco entre portadas + + + + Central gap + Hueco central + + + + Zoom + Ampliaci?n + + + + Y offset + Desplazamiento en Y + + + + Z offset + Desplazamiento en Z + + + + Cover Angle + Ángulo de las portadas + + + + Visibility + Visibilidad + + + + Light + Luz + + + + Max angle + Ángulo máximo + + + + Low Performance + Rendimiento bajo + + + + High Performance + Alto rendimiento + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Utilizar VSync (mejora la calidad de imagen en pantalla completa, peor rendimiento) + + + + Performance: + Rendimiento: + + + + YACReader::MainWindowViewer + + + &Open + &Abrir + + + + Open a comic + Abrir cómic + + + + New instance + Nueva instancia + + + + Open Folder + Abrir carpeta + + + + Open image folder + Abrir carpeta de imágenes + + + + Open latest comic + Abrir el cómic más reciente + + + + Open the latest comic opened in the previous reading session + Abrir el cómic más reciente abierto en la sesión de lectura anterior + + + + Clear + Limpiar + + + + Clear open recent list + Limpiar lista de abiertos recientemente + + + + Save + Guardar + + + + + Save current page + Guardar la página actual + + + + Previous Comic + Cómic anterior + + + + + + Open previous comic + Abrir cómic anterior + + + + Next Comic + Siguiente Cómic + + + + + + Open next comic + Abrir siguiente cómic + + + + &Previous + A&nterior + + + + + + Go to previous page + Ir a la página anterior + + + + &Next + Siguie&nte + + + + + + Go to next page + Ir a la página siguiente + + + + Fit Height + Ajustar altura + + + + Fit image to height + Ajustar página a lo alto + + + + Fit Width + Ajustar anchura + + + + Fit image to width + Ajustar página a lo ancho + + + + Show full size + Mostrar a tamaño original + + + + Fit to page + Ajustar a página + + + + Continuous scroll + Desplazamiento continuo + + + + Switch to continuous scroll mode + Cambiar al modo de desplazamiento continuo + + + + Reset zoom + Restablecer zoom + + + + Show zoom slider + Mostrar control deslizante de zoom + + + + Zoom+ + Ampliar+ + + + + Zoom- + Reducir + + + + Rotate image to the left + Rotar imagen a la izquierda + + + + Rotate image to the right + Rotar imagen a la derecha + + + + Double page mode + Modo a doble página + + + + Switch to double page mode + Cambiar a modo de doble página + + + + Double page manga mode + Modo de manga de página doble + + + + Reverse reading order in double page mode + Invertir el orden de lectura en modo de página doble + + + + Go To + Ir a + + + + Go to page ... + Ir a página... + + + + Options + Opciones + + + + YACReader options + Opciones de YACReader + + + + + Help + Ayuda + + + + Help, About YACReader + Ayuda, Sobre YACReader + + + + Magnifying glass + Lupa + + + + Switch Magnifying glass + Lupa On/Off + + + + Set bookmark + Añadir marcador + + + + Set a bookmark on the current page + Añadir un marcador en la página actual + + + + Show bookmarks + Mostrar marcadores + + + + Show the bookmarks of the current comic + Mostrar los marcadores del cómic actual + + + + Show keyboard shortcuts + Mostrar atajos de teclado + + + + Show Info + Mostrar información + + + + Close + Cerrar + + + + Show Dictionary + Mostrar diccionario + + + + Show go to flow + Mostrar flow ir a + + + + Edit shortcuts + Editar accesos directos + + + + &File + &Archivo + + + + + Open recent + Abrir reciente + + + + File + Archivo + + + + Edit + Editar + + + + View + Ver + + + + Go + Ir + + + + Window + Ventana + + + + + + Open Comic + Abrir cómic + + + + + + Comic files + Archivos de cómic + + + + Open folder + Abrir carpeta + + + + page_%1.jpg + página_%1.jpg + + + + Image files (*.jpg) + Archivos de imagen (*.jpg) + + + + + Comics + Cómics + + + + + General + Opciones generales + + + + + Magnifiying glass + Lupa + + + + + Page adjustement + Ajuste de página + + + + + Reading + Leyendo + + + + Toggle fullscreen mode + Alternar modo de pantalla completa + + + + Hide/show toolbar + Ocultar/mostrar barra de herramientas + + + + Size up magnifying glass + Aumentar tamaño de la lupa + + + + Size down magnifying glass + Disminuir tamaño de lupa + + + + Zoom in magnifying glass + Incrementar el aumento de la lupa + + + + Zoom out magnifying glass + Reducir el aumento de la lupa + + + + Reset magnifying glass + Resetear lupa + + + + Toggle between fit to width and fit to height + Alternar entre ajuste al ancho y ajuste al alto + + + + Autoscroll down + Desplazamiento automático hacia abajo + + + + Autoscroll up + Desplazamiento automático hacia arriba + + + + Autoscroll forward, horizontal first + Desplazamiento automático hacia adelante, primero horizontal + + + + Autoscroll backward, horizontal first + Desplazamiento automático hacia atrás, primero horizontal + + + + Autoscroll forward, vertical first + Desplazamiento automático hacia adelante, primero vertical + + + + Autoscroll backward, vertical first + Desplazamiento automático hacia atrás, primero vertical + + + + Move down + Mover abajo + + + + Move up + Mover arriba + + + + Move left + Mover a la izquierda + + + + Move right + Mover a la derecha + + + + Go to the first page + Ir a la primera página + + + + Go to the last page + Ir a la última página + + + + Offset double page to the left + Mover una página a la izquierda + + + + Offset double page to the right + Mover una página a la derecha + + + + There is a new version available + Hay una nueva versión disponible + + + + Do you want to download the new version? + ¿Desea descargar la nueva versión? + + + + Remind me in 14 days + Recordar en 14 días + + + + Not now + Ahora no + + + + YACReader::TrayIconController + + + &Restore + &Restaurar + + + + Systray + Bandeja del sistema + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary se continuará ejecutando en la bandeja del sistema. Para cerrar el programa elige <b>Cerrar</b> en el menú contextual del icono de la aplicación en la bandeja del sistema. + + + + YACReaderFieldEdit + + + + Click to overwrite + Clic para sobrescribir + + + + Restore to default + Restaurar valor por defecto + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + Clic para sobrescribir + + + + Restore to default + Restaurar valor por defecto + + + + YACReaderOptionsDialog + + + Save + Guardar + + + + Cancel + Cancelar + + + + Edit shortcuts + Editar accesos directos + + + + Shortcuts + Accesos directos + + + + YACReaderSearchLineEdit + + + type to search + escribe para buscar + + + + YACReaderSlider + + + Reset + Restablecer - QsLogging::Window + YACReaderTranslator - - &Pause - + + YACReader translator + Traductor YACReader - - &Resume - + + + Translation + Traducción - - Save log - + + clear + Limpiar - - Log file (*.log) - + + Service not available + Servicio no disponible diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_fr.ts b/YACReaderLibraryServer/yacreaderlibraryserver_fr.ts index 43ac18d56..f0aa9106d 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_fr.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_fr.ts @@ -2,150 +2,3712 @@ - FileComic + ActionsShortcutsModel - - CRC error on page (%1): some of the pages will not be displayed correctly - + + None + Rien + + + AddLabelDialog - - Unknown error opening the file - + + Label name: + Nom de l'étiquette : - - 7z not found - + + Choose a color: + Choisissez une couleur: - - Format not supported - + + accept + accepter + + + + cancel + Annuler - LogWindow + AddLibraryDialog + + + Comics folder : + Dossier des bandes dessinées : + + + + Library name : + Nom de la librairie : + - - Log window - + + Add + Ajouter - - &Pause - + + Cancel + Annuler - - &Save - + + Add an existing library + Ajouter une librairie existante + + + ApiKeyDialog - - C&lear - + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Avant de pouvoir vous connecter à Comic Vine, vous avez besoin de votre propre clé API. Veuillez en obtenir une gratuitement ici: <a href="http://www.comicvine.com/api/"></a> - - &Copy - + + Paste here your Comic Vine API key + Collez ici votre clé API Comic Vine - - Level: - + + Accept + Accepter - - &Auto scroll - + + Cancel + Annuler - QCoreApplication + AppearanceTabWidget - - -YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + + Color scheme + Jeu de couleurs + + + + System + Système + + + + Light + Lumière + + + + Dark + Sombre + + + + Custom + Coutume + + + + Remove + Retirer + + + + Remove this user-imported theme + Supprimer ce thème importé par l'utilisateur + + + + Light: + Lumière: + + + + Dark: + Sombre: + + + + Custom: + Personnalisation: + + + + Import theme... + Importer le thème... + + + + Theme + Thème + + + + Theme editor + Éditeur de thème + + + + Open Theme Editor... + Ouvrir l'éditeur de thème... + + + + Theme editor error + Erreur de l'éditeur de thème + + + + The current theme JSON could not be loaded. + Le thème actuel JSON n'a pas pu être chargé. + + + + Import theme + Importer un thème + + + + JSON files (*.json);;All files (*) + Fichiers JSON (*.json);;Tous les fichiers (*) + + + + Could not import theme from: +%1 + Impossible d'importer le thème depuis : +%1 + + + + Could not import theme from: +%1 -This appplication supports persistent settings, to set them up edit this file %1 -To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md - +%2 + Impossible d'importer le thème depuis : +%1 + +%2 + + + + Import failed + Échec de l'importation - QObject + BookmarksDialog - - Trace - + + Lastest Page + Aller à la dernière page - - Debug - + + Close + Fermer - - Info - + + Click on any image to go to the bookmark + Cliquez sur une image pour aller au marque-page - - Warning - + + + Loading... + Chargement... + + + ClassicComicsView - - Error - + + Hide comic flow + Cacher le flux de bande dessinée + + + + ComicModel + + + yes + oui - - Fatal - + + no + non + + + + Title + Titre + + + + File Name + Nom du fichier + + + + Pages + Feuilles + + + + Size + Taille + + + + Read + Lu + + + + Current Page + Page en cours + + + + Publication Date + Date de publication + + + + Rating + Note + + + + Series + Série + + + + Volume + Tome + + + + Story Arc + Arc d'histoire + + + + ComicVineDialog + + + skip + passer + + + + back + retour + + + + next + suivant + + + + search + chercher + + + + close + fermer + + + + + comic %1 of %2 - %3 + bande dessinée %1 sur %2 - %3 + + + + + + Looking for volume... + Vous cherchez du volume... + + + + %1 comics selected + %1 bande(s) dessinnée(s) sélectionnée(s) + + + + Error connecting to ComicVine + Erreur de connexion à Comic Vine + + + + + Retrieving tags for : %1 + Retrouver les infomartions de: %1 + + + + Retrieving volume info... + Récupération des informations sur le volume... + + + + Looking for comic... + Vous cherchez une bande dessinée ... + + + + ContinuousPageWidget + + + Loading page %1 + Chargement de la page %1 + + + + CreateLibraryDialog + + + Comics folder : + Dossier des bandes dessinées : + + + + Library Name : + Nom de la librairie : + + + + Create + Créer + + + + Cancel + Annuler + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et continuer plus tard. + + + + Create new library + Créer une nouvelle librairie + + + + Path not found + Chemin introuvable + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + Le chemin sélectionné n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + + + + EditShortcutsDialog + + + Restore defaults + Réinitialiser + + + + To change a shortcut, double click in the key combination and type the new keys. + Pour modifier un raccourci, double-cliquez sur la combinaison de touches et tapez les nouvelles clés. + + + + Shortcuts settings + Paramètres de raccourcis + + + + Shortcut in use + Raccourci en cours d'utilisation + + + + The shortcut "%1" is already assigned to other function + Le raccourci "%1" est déjà affecté à une autre fonction + + + + EmptyFolderWidget + + + This folder doesn't contain comics yet + Ce dossier ne contient pas encore de bandes dessinées + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + Ce dossier ne contient pas encore de bandes dessinées + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + Cette liste de lecture ne contient aucune bande dessinée + + + + EmptySpecialListWidget + + + No favorites + Pas de favoris + + + + You are not reading anything yet, come on!! + Vous ne lisez rien encore, allez !! + + + + There are no recent comics! + Il n'y a pas de BD récente ! + + + + ExportComicsInfoDialog + + + Output file : + Fichier de sortie : + + + + Create + Créer + + + + Cancel + Annuler + + + + Export comics info + Exporter les infos des bandes dessinées + + + + Destination database name + Nom de la base de données de destination + + + + Problem found while writing + Problème durant l'écriture + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + + + + ExportLibraryDialog + + + Output folder : + Dossier de sortie : + + + + Create + Créer + + + + Cancel + Annuler + + + + Create covers package + Créer un pack de couvertures + + + + Problem found while writing + Problème durant l'écriture + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + + + + Destination directory + Répertoire de destination + + + + FileComic + + + CRC error on page (%1): some of the pages will not be displayed correctly + Erreur CRC sur la page (%1): certaines pages ne s'afficheront pas correctement + + + + Unknown error opening the file + Erreur inconnue lors de l'ouverture du fichier + + + + 7z not found + 7z introuvable + + + + Format not supported + Format non supporté + + + + GoToDialog + + + Page : + Feuille : + + + + Go To + Aller à + + + + Cancel + Annuler + + + + + Total pages : + Nombre de pages : + + + + Go to... + Aller à... + + + + GoToFlowToolBar + + + Page : + Feuille : - QsLogging::LogWindowModel + GridComicsView - - Time - + + Show info + Afficher les informations + + + HelpAboutDialog - - Level - + + About + A propos - - Message - + + Help + Aide + + + + System info + Informations système + + + + ImportComicsInfoDialog + + + Import comics info + Importer les infos des bandes dessinées + + + + Info database location : + Emplacement des infos: + + + + Import + Importer + + + + Cancel + Annuler + + + + Comics info file (*.ydb) + Fichier infos BD (*.ydb) + + + + ImportLibraryDialog + + + Library Name : + Nom de la librairie : + + + + Package location : + Emplacement : + + + + Destination folder : + Dossier de destination : + + + + Unpack + Désarchiver + + + + Cancel + Annuler + + + + Extract a catalog + Extraire un catalogue + + + + Compresed library covers (*.clc) + Couvertures de bibliothèque compressées (*.clc) + + + + ImportWidget + + + stop + Arrêter + + + + Some of the comics being added... + Ajout de bande dessinée... + + + + Importing comics + Importation de bande dessinée + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary est en train de créer une nouvelle librairie.</p><p>La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et poursuivre plus tard.</p> + + + + Updating the library + Mise à jour de la librairie + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>Mise à jour de la librairie. Pour plus de rapidité lors de la mise à jour, veuillez effectuer cette dernière régulièrement.</p><p>Vous pouvez arrêter le processus et poursuivre plus tard.</p> + + + + Upgrading the library + Mise à niveau de la bibliothèque + + + + <p>The current library is being upgraded, please wait.</p> + <p>La bibliothèque actuelle est en cours de mise à niveau, veuillez patienter.</p> + + + + Scanning the library + Scanner la bibliothèque + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>La bibliothèque actuelle est en cours d'analyse pour rechercher des informations sur les métadonnées XML héritées.</p><p>Ceci n'est nécessaire qu'une seule fois, et uniquement si la bibliothèque a été créée avec YACReaderLibrary 9.8.2 ou une version antérieure.</p> + + + + LibraryWindow + + + YACReader Library + Librairie de YACReader + + + + + + comic + comique + + + + + + manga + mangas + + + + + + western manga (left to right) + manga occidental (de gauche à droite) + + + + + + web comic + bande dessinée Web + + + + + + 4koma (top to botom) + 4koma (de haut en bas) + + + + + + + Set type + Définir le type + + + + Library + Librairie + + + + Folder + Dossier + + + + Comic + Bande dessinée + + + + Upgrade failed + La mise à niveau a échoué + + + + There were errors during library upgrade in: + Des erreurs se sont produites lors de la mise à niveau de la bibliothèque dans : + + + + Update needed + Mise à jour requise + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Cette librairie a été créée avec une ancienne version de YACReaderLibrary. Mise à jour necessaire. Mettre à jour? + + + + Download new version + Téléchrger la nouvelle version + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Cette librairie a été créée avec une version plus récente de YACReaderLibrary. Télécharger la nouvelle version? + + + + Library not available + Librairie non disponible + + + + Library '%1' is no longer available. Do you want to remove it? + La librarie '%1' n'est plus disponible. Voulez-vous la supprimer? + + + + Old library + Ancienne librairie + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La librarie '%1' a été créée avec une ancienne version de YACReaderLibrary. Elle doit être re-créée. Voulez-vous créer la librairie? + + + + + Copying comics... + Copier la bande dessinée... + + + + + Moving comics... + Déplacer la bande dessinée... + + + + Add new folder + Ajouter un nouveau dossier + + + + Folder name: + Nom du dossier : + + + + No folder selected + Aucun dossier sélectionné + + + + Please, select a folder first + Veuillez d'abord sélectionner un dossier + + + + Error in path + Erreur dans le chemin + + + + There was an error accessing the folder's path + Une erreur s'est produite lors de l'accès au chemin du dossier + + + + Delete folder + Supprimer le dossier + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + Le dossier sélectionné et tout son contenu seront supprimés de votre disque. Es-tu sûr? + + + + + Unable to delete + Impossible de supprimer + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Un problème est survenu lors de la tentative de suppression des dossiers sélectionnés. Veuillez vérifier les autorisations d'écriture et assurez-vous que toutes les applications utilisent ces dossiers ou l'un des fichiers contenus. + + + + Add new reading lists + Ajouter de nouvelles listes de lecture + + + + + List name: + Nom de la liste : + + + + Delete list/label + Supprimer la liste/l'étiquette + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + L'élément sélectionné sera supprimé, vos bandes dessinées ou dossiers ne seront pas supprimés de votre disque. Êtes-vous sûr? + + + + Rename list name + Renommer le nom de la liste + + + + Open folder... + Ouvrir le dossier... + + + + Update folder + Mettre à jour le dossier + + + + Rescan library for XML info + Réanalyser la bibliothèque pour les informations XML + + + + Set as uncompleted + Marquer comme incomplet + + + + Set as completed + Marquer comme complet + + + + Set as read + Marquer comme lu + + + + + Set as unread + Marquer comme non-lu + + + + Set custom cover + Définir une couverture personnalisée + + + + Delete custom cover + Supprimer la couverture personnalisée + + + + Save covers + Enregistrer les couvertures + + + + You are adding too many libraries. + Vous ajoutez trop de bibliothèques. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Vous ajoutez trop de bibliothèques. + +Vous n'avez probablement besoin que d'une bibliothèque dans votre dossier BD de niveau supérieur, vous pouvez parcourir les sous-dossiers en utilisant la section des dossiers dans la barre latérale gauche. + +YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais vous devriez garder le nombre de bibliothèques bas. + + + + + YACReader not found + YACReader introuvable + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader introuvable. YACReader doit être installé dans le même dossier que YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader introuvable. Il se peut qu'il y ait un problème avec votre installation de YACReader. + + + + Error + Erreur + + + + Error opening comic with third party reader. + Erreur lors de l'ouverture de la bande dessinée avec un lecteur tiers. + + + + Library not found + Librairie introuvable + + + + The selected folder doesn't contain any library. + Le dossier sélectionné ne contient aucune librairie. + + + + Are you sure? + Êtes-vous sûr? + + + + Do you want remove + Voulez-vous supprimer + + + + library? + la librairie? + + + + Remove and delete metadata + Supprimer les métadata + + + + Library info + Informations sur la bibliothèque + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Un problème est survenu lors de la tentative de suppression des bandes dessinées sélectionnées. Veuillez vérifier les autorisations d'écriture dans les fichiers sélectionnés ou le dossier contenant. + + + + Assign comics numbers + Attribuer des numéros de bandes dessinées + + + + Assign numbers starting in: + Attribuez des numéros commençant par : + + + + Invalid image + Image invalide + + + + The selected file is not a valid image. + Le fichier sélectionné n'est pas une image valide. + + + + Error saving cover + Erreur lors de l'enregistrement de la couverture + + + + There was an error saving the cover image. + Une erreur s'est produite lors de l'enregistrement de l'image de couverture. + + + + Error creating the library + Erreur lors de la création de la librairie + + + + Error updating the library + Erreur lors de la mise à jour de la librairie + + + + Error opening the library + Erreur lors de l'ouverture de la librairie + + + + Delete comics + Supprimer les comics + + + + All the selected comics will be deleted from your disk. Are you sure? + Tous les comics sélectionnés vont être supprimés de votre disque. Êtes-vous sûr? + + + + Remove comics + Supprimer les bandes dessinées + + + + Comics will only be deleted from the current label/list. Are you sure? + Les bandes dessinées seront uniquement supprimées du label/liste actuelle. Es-tu sûr? + + + + Library name already exists + Le nom de la librairie existe déjà + + + + There is another library with the name '%1'. + Une autre librairie a le nom '%1'. + + + + LibraryWindowActions + + + Create a new library + Créer une nouvelle librairie + + + + Open an existing library + Ouvrir une librairie existante + + + + + Export comics info + Exporter les infos des bandes dessinées + + + + + Import comics info + Importer les infos des bandes dessinées + + + + Pack covers + Archiver les couvertures + + + + Pack the covers of the selected library + Archiver les couvertures de la librairie sélectionnée + + + + Unpack covers + Désarchiver les couvertures + + + + Unpack a catalog + Désarchiver un catalogue + + + + Update library + Mettre la librairie à jour + + + + Update current library + Mettre à jour la librairie actuelle + + + + Rename library + Renommer la librairie + + + + Rename current library + Renommer la librairie actuelle + + + + Remove library + Supprimer la librairie + + + + Remove current library from your collection + Enlever cette librairie de votre collection + + + + Rescan library for XML info + Réanalyser la bibliothèque pour les informations XML + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Essaie de trouver des informations XML intégrées dans des fichiers de bandes dessinées. Vous ne devez le faire que si la bibliothèque a été créée avec la version 9.8.2 ou des versions antérieures ou si vous utilisez un logiciel tiers pour intégrer des informations XML dans les fichiers. + + + + Show library info + Afficher les informations sur la bibliothèque + + + + Show information about the current library + Afficher des informations sur la bibliothèque actuelle + + + + Open current comic + Ouvrir cette bande dessinée + + + + Open current comic on YACReader + Ouvrir cette bande dessinée dans YACReader + + + + Save selected covers to... + Exporter la couverture vers... + + + + Save covers of the selected comics as JPG files + Enregistrer les couvertures des bandes dessinées sélectionnées en tant que fichiers JPG + + + + + Set as read + Marquer comme lu + + + + Set comic as read + Marquer cette bande dessinée comme lu + + + + + Set as unread + Marquer comme non-lu + + + + Set comic as unread + Marquer cette bande dessinée comme non-lu + + + + + manga + mangas + + + + Set issue as manga + Définir le problème comme manga + + + + + comic + comique + + + + Set issue as normal + Définir le problème comme d'habitude + + + + western manga + manga occidental + + + + Set issue as western manga + Définir le problème comme un manga occidental + + + + + web comic + bande dessinée Web + + + + Set issue as web comic + Définir le problème comme bande dessinée Web + + + + + yonkoma + Yonkoma + + + + Set issue as yonkoma + Définir le problème comme Yonkoma + + + + Show/Hide marks + Afficher/Cacher les marqueurs + + + + Show or hide read marks + Afficher ou masquer les marques de lecture + + + + Show/Hide recent indicator + Afficher/Masquer l'indicateur récent + + + + Show or hide recent indicator + Afficher ou masquer l'indicateur récent + + + + + Fullscreen mode on/off + Mode plein écran activé/désactivé + + + + Help, About YACReader + Aide, à propos de YACReader + + + + Add new folder + Ajouter un nouveau dossier + + + + Add new folder to the current library + Ajouter un nouveau dossier à la bibliothèque actuelle + + + + Delete folder + Supprimer le dossier + + + + Delete current folder from disk + Supprimer le dossier actuel du disque + + + + Select root node + Allerà la racine + + + + Expand all nodes + Afficher tous les noeuds + + + + Collapse all nodes + Réduire tous les nœuds + + + + Show options dialog + Ouvrir la boite de dialogue + + + + Show comics server options dialog + Ouvrir la boite de dialogue du serveur + + + + + Change between comics views + Changement entre les vues de bandes dessinées + + + + Open folder... + Ouvrir le dossier... + + + + Set as uncompleted + Marquer comme incomplet + + + + Set as completed + Marquer comme complet + + + + Set custom cover + Définir une couverture personnalisée + + + + Delete custom cover + Supprimer la couverture personnalisée + + + + western manga (left to right) + manga occidental (de gauche à droite) + + + + Open containing folder... + Ouvrir le dossier... + + + + Reset comic rating + Supprimer la note d'évaluation + + + + Select all comics + Sélectionner toutes les bandes dessinées + + + + Edit + Editer + + + + Assign current order to comics + Assigner l'ordre actuel aux bandes dessinées + + + + Update cover + Mise à jour des couvertures + + + + Delete selected comics + Supprimer la bande dessinée sélectionnée + + + + Delete metadata from selected comics + Supprimer les métadonnées des bandes dessinées sélectionnées + + + + Download tags from Comic Vine + Télécharger les informations de Comic Vine + + + + Focus search line + Ligne de recherche ciblée + + + + Focus comics view + Focus sur la vue des bandes dessinées + + + + Edit shortcuts + Modifier les raccourcis + + + + &Quit + &Quitter + + + + Update folder + Mettre à jour le dossier + + + + Update current folder + Mettre à jour ce dossier + + + + Scan legacy XML metadata + Analyser les métadonnées XML héritées + + + + Add new reading list + Ajouter une nouvelle liste de lecture + + + + Add a new reading list to the current library + Ajouter une nouvelle liste de lecture à la bibliothèque actuelle + + + + Remove reading list + Supprimer la liste de lecture + + + + Remove current reading list from the library + Supprimer la liste de lecture actuelle de la bibliothèque + + + + Add new label + Ajouter une nouvelle étiquette + + + + Add a new label to this library + Ajouter une nouvelle étiquette à cette bibliothèque + + + + Rename selected list + Renommer la liste sélectionnée + + + + Rename any selected labels or lists + Renommer toutes les étiquettes ou listes sélectionnées + + + + Add to... + Ajouter à... + + + + Favorites + Favoris + + + + Add selected comics to favorites list + Ajouter la bande dessinée sélectionnée à la liste des favoris + + + + LocalComicListModel + + + file name + nom de fichier + + + + NoLibrariesWidget + + + You don't have any libraries yet + Vous n'avez pas encore de librairie + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Vous pouvez creer une librairie dans n'importe quel dossierr, YACReaderLibrary importera les dossiers et les bandes dessinées contenus dans ce dossier. Si vous avez déjà crer des librairies, vous pouvez les ouvrir.</p><p>N'oubliez pas que vous pouvez utiliser YACReader en tant que stand alone pour lire vos bandes dessinées sur votre ordinateur.</p> + + + + create your first library + Créez votre première librairie + + + + add an existing one + Ajouter une librairie existante + + + + NoSearchResultsWidget + + + No results + Aucun résultat + + + + OptionsDialog + + + + General + Général + + + + + Libraries + Bibliothèques + + + + Comic Flow + Flux comique + + + + Grid view + Vue grille + + + + + Appearance + Apparence + + + + + Options + Possibilités + + + + + Language + Langue + + + + + Application language + Langue de l'application + + + + + System default + Par défaut du système + + + + Tray icon settings (experimental) + Paramètres de l'icône de la barre d'état (expérimental) + + + + Close to tray + Près du plateau + + + + Start into the system tray + Commencez dans la barre d'état système + + + + Edit Comic Vine API key + Modifier la clé API Comic Vine + + + + Comic Vine API key + Clé API Comic Vine + + + + ComicInfo.xml legacy support + Prise en charge héritée de ComicInfo.xml + + + + Import metadata from ComicInfo.xml when adding new comics + Importer des métadonnées depuis ComicInfo.xml lors de l'ajout de nouvelles bandes dessinées + + + + Consider 'recent' items added or updated since X days ago + Considérez les éléments « récents » ajoutés ou mis à jour depuis X jours + + + + Third party reader + Lecteur tiers + + + + Write {comic_file_path} where the path should go in the command + Écrivez {comic_file_path} où le chemin doit aller dans la commande + + + + + Clear + Clair + + + + Update libraries at startup + Mettre à jour les bibliothèques au démarrage + + + + Try to detect changes automatically + Essayez de détecter automatiquement les changements + + + + Update libraries periodically + Mettre à jour les bibliothèques périodiquement + + + + Interval: + Intervalle: + + + + 30 minutes + 30 min + + + + 1 hour + 1 heure + + + + 2 hours + 2 heures + + + + 4 hours + 4 heures + + + + 8 hours + 8 heures + + + + 12 hours + 12 heures + + + + daily + tous les jours + + + + Update libraries at certain time + Mettre à jour les bibliothèques à un certain moment + + + + Time: + Temps: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + AVERTISSEMENT! Lors des mises à jour de la bibliothèque, les écritures dans la base de données sont désactivées ! +Ne planifiez pas de mises à jour pendant que vous utilisez activement l'application. +Lors des mises à jour automatiques, l'application bloquera certaines actions jusqu'à ce que la mise à jour soit terminée. +Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de chargement à côté du titre Bibliothèques. + + + + Modifications detection + Détection des modifications + + + + Compare the modified date of files when updating a library (not recommended) + Comparer la date de modification des fichiers lors de la mise à jour d'une bibliothèque (déconseillé) + + + + Enable background image + Activer l'image d'arrière-plan + + + + Opacity level + Niveau d'opacité + + + + Blur level + Niveau de flou + + + + Use selected comic cover as background + Utiliser la couverture de bande dessinée sélectionnée comme arrière-plan + + + + Restore defautls + Restaurer les valeurs par défaut + + + + Background + Arrière-plan + + + + Display continue reading banner + Afficher la bannière de lecture continue + + + + Display current comic banner + Afficher la bannière de bande dessinée actuelle + + + + Continue reading + Continuer la lecture + + + + My comics path + Chemin de mes bandes dessinées + + + + Display + Afficher + + + + Show time in current page information label + Afficher l'heure dans l'étiquette d'information de la page actuelle + + + + "Go to flow" size + Taille du flux + + + + Background color + Couleur d'arrière plan + + + + Choose + Choisir + + + + Scroll behaviour + Comportement de défilement + + + + Disable scroll animations and smooth scrolling + Désactiver les animations de défilement et le défilement fluide + + + + Do not turn page using scroll + Ne tournez pas la page en utilisant le défilement + + + + Use single scroll step to turn page + Utilisez une seule étape de défilement pour tourner la page + + + + Mouse mode + Mode souris + + + + Only Back/Forward buttons can turn pages + Seuls les boutons Précédent/Avant peuvent tourner les pages + + + + Use the Left/Right buttons to turn pages. + Utilisez les boutons Gauche/Droite pour tourner les pages. + + + + Click left or right half of the screen to turn pages. + Cliquez sur la moitié gauche ou droite de l'écran pour tourner les pages. + + + + Quick Navigation Mode + Mode navigation rapide + + + + Disable mouse over activation + Désactiver la souris sur l'activation + + + + Brightness + Luminosité + + + + Contrast + Contraste + + + + Gamma + Valeur gamma + + + + Reset + Remise à zéro + + + + Image options + Option de l'image + + + + Fit options + Options d'ajustement + + + + Enlarge images to fit width/height + Agrandir les images pour les adapter à la largeur/hauteur + + + + Double Page options + Options de double page + + + + Show covers as single page + Afficher les couvertures sur une seule page + + + + Scaling + Mise à l'échelle + + + + Scaling method + Méthode de mise à l'échelle + + + + Nearest (fast, low quality) + Le plus proche (rapide, mauvaise qualité) + + + + Bilinear + Bilinéaire + + + + Lanczos (better quality) + Lanczos (meilleure qualité) + + + + Page Flow + Flux des pages + + + + Image adjustment + Ajustement de l'image + + + + + Restart is needed + Redémarrage nécessaire + + + + Comics directory + Répertoire des bandes dessinées + + + + PropertiesDialog + + + General info + Infos générales + + + + Plot + Intrigue + + + + Authors + Auteurs + + + + Publishing + Publication + + + + Notes + Remarques + + + + Cover page + Couverture + + + + Load previous page as cover + Charger la page précédente comme couverture + + + + Load next page as cover + Charger la page suivante comme couverture + + + + Reset cover to the default image + Réinitialiser la couverture à l'image par défaut + + + + Load custom cover image + Charger une image de couverture personnalisée + + + + Series: + Série: + + + + Title: + Titre: + + + + + + of: + sur: + + + + Issue number: + Numéro: + + + + Volume: + Tome : + + + + Arc number: + Arc numéro: + + + + Story arc: + Arc narratif: + + + + alt. number: + alt. nombre: + + + + Alternate series: + Série alternative : + + + + Series Group: + Groupe de séries : + + + + Genre: + Genre : + + + + Size: + Taille: + + + + Writer(s): + Scénariste(s): + + + + Penciller(s): + Dessinateur(s): + + + + Inker(s): + Encreur(s): + + + + Colorist(s): + Coloriste(s): + + + + Letterer(s): + Lettreur(s): + + + + Cover Artist(s): + Artiste(s) de couverture: + + + + Editor(s): + Editeur(s) : + + + + Imprint: + Imprimer: + + + + Day: + Jour: + + + + Month: + Mois: + + + + Year: + Année: + + + + Publisher: + Editeur: + + + + Format: + Format : + + + + Color/BW: + Couleur/Noir et blanc: + + + + Age rating: + Limite d'âge: + + + + Type: + Taper: + + + + Language (ISO): + Langue (ISO) : + + + + Synopsis: + Synopsis : + + + + Characters: + Personnages: + + + + Teams: + Équipes : + + + + Locations: + Emplacements : + + + + Main character or team: + Personnage principal ou équipe : + + + + Review: + Revoir: + + + + Notes: + Remarques : + + + + Tags: + Balises : + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Lien Comic Vine : <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> vue </a> + + + + Not found + Introuvable + + + + Comic not found. You should update your library. + Comic introuvable. Vous devriez mettre à jour votre librairie. + + + + Edit comic information + Editer les informations du comic + + + + Edit selected comics information + Editer les informations du comic sélectionné + + + + Invalid cover + Couverture invalide + + + + The image is invalid. + L'image n'est pas valide. + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer est la version sans tête (sans interface graphique) de YACReaderLibrary. + +Cette application prend en charge les paramètres persistants, pour les configurer, modifiez ce fichier %1 +Pour en savoir plus sur les paramètres disponibles, veuillez consulter la documentation sur https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject + + + Trace + Tracer + + + + Debug + Déboguer + + + + Info + Informations + + + + Warning + Avertissement + + + + Error + Erreur + + + + Fatal + Critique + + + + Select custom cover + Sélectionnez une couverture personnalisée + + + + Images (%1) + Illustrations (%1) + + + + 7z lib not found + lib 7z introuvable + + + + unable to load 7z lib from ./utils + impossible de charger 7z depuis ./utils + + + + The file could not be read or is not valid JSON. + Le fichier n'a pas pu être lu ou n'est pas un JSON valide. + + + + This theme is for %1, not %2. + Ce thème est pour %1, pas pour %2. + + + + Libraries + Bibliothèques + + + + Folders + Dossiers + + + + Reading Lists + Listes de lecture + + + + RenameLibraryDialog + + + New Library Name : + Nouveau nom de librairie: + + + + Rename + Renommer + + + + Cancel + Annuler + + + + Rename current library + Renommer la librairie actuelle + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + Nombre de volumes trouvés : %1 + + + + + page %1 of %2 + page %1 de %2 + + + + Number of %1 found : %2 + Nombre de %1 trouvés : %2 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + Veuillez fournir des informations supplémentaires pour cette bande dessinée. + + + + Series: + Série: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Utilisez la recherche de correspondance exacte. Désactivez-la si vous souhaitez rechercher des volumes correspondant à certains mots du nom. + + + + SearchVolume + + + Please provide some additional information. + Veuillez fournir quelques informations supplémentaires. + + + + Series: + Série: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Utilisez la recherche de correspondance exacte. Désactivez-la si vous souhaitez rechercher des volumes correspondant à certains mots du nom. + + + + SelectComic + + + Please, select the right comic info. + Veuillez sélectionner les bonnes informations sur la bande dessinée. + + + + comics + bandes dessinées + + + + loading cover + couvercle de chargement + + + + loading description + description du chargement + + + + comic description unavailable + description de la bande dessinée indisponible + + + + SelectVolume + + + Please, select the right series for your comic. + Veuillez sélectionner la bonne série pour votre bande dessinée. + + + + Filter: + Filtre: + + + + volumes + tomes + + + + Nothing found, clear the filter if any. + Rien trouvé, effacez le filtre le cas échéant. + + + + loading cover + couvercle de chargement + + + + loading description + description du chargement + + + + volume description unavailable + description du volume indisponible + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + Vous essayez d’obtenir des informations sur plusieurs bandes dessinées à la fois, font-elles partie de la même série ? + + + + yes + oui + + + + no + non + + + + ServerConfigDialog + + + set port + Configurer le port + + + + Server connectivity information + Informations sur la connectivité du serveur + + + + Scan it! + Scannez-le ! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader est disponible pour les appareils iOS et Android.<br/>Découvrez-le pour <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + + + + Choose an IP address + Choisissez une adresse IP + + + + Port + Port r?seau + + + + enable the server + Autoriser le serveur + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + Veuillez trier la liste des bandes dessinées sur la gauche jusqu'à ce qu'elle corresponde aux informations des bandes dessinées. + + + + sort comics to match comic information + trier les bandes dessinées pour qu'elles correspondent aux informations sur les bandes dessinées + + + + issues + problèmes + + + + remove selected comics + supprimer les bandes dessinées sélectionnées + + + + restore all removed comics + restaurer toutes les bandes dessinées supprimées + + + + ThemeEditorDialog + + + Theme Editor + Éditeur de thème + + + + + + + + + + + - + - + + + + i + je + + + + Expand all + Tout développer + + + + Collapse all + Tout réduire + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Maintenez enfoncé pour faire clignoter la valeur sélectionnée dans l'interface utilisateur (magenta / basculé / 0↔10). Les versions restaurent l'original. + + + + Search… + Rechercher… + + + + Light + Lumière + + + + Dark + Sombre + + + + ID: + IDENTIFIANT: + + + + Display name: + Nom d'affichage : + + + + Variant: + Variante: + + + + Theme info + Informations sur le thème + + + + Parameter + Paramètre + + + + Value + Valeur + + + + Save and apply + Enregistrer et postuler + + + + Export to file... + Exporter vers un fichier... + + + + Load from file... + Charger à partir du fichier... + + + + Close + Fermer + + + + Double-click to edit color + Double-cliquez pour modifier la couleur + + + + + + + + + true + vrai + + + + + + + false + FAUX + + + + Double-click to toggle + Double-cliquez pour basculer + + + + Double-click to edit value + Double-cliquez pour modifier la valeur + + + + + + Edit: %1 + Modifier : %1 + + + + Save theme + Enregistrer le thème + + + + + JSON files (*.json);;All files (*) + Fichiers JSON (*.json);;Tous les fichiers (*) + + + + Save failed + Échec de l'enregistrement + + + + Could not open file for writing: +%1 + Impossible d'ouvrir le fichier en écriture : +%1 + + + + Load theme + Charger le thème + + + + + + Load failed + Échec du chargement + + + + Could not open file: +%1 + Impossible d'ouvrir le fichier : +%1 + + + + Invalid JSON: +%1 + JSON invalide : +%1 + + + + Expected a JSON object. + Attendu un objet JSON. + + + + TitleHeader + + + SEARCH + RECHERCHE + + + + UpdateLibraryDialog + + + Updating.... + Mise à jour... + + + + Cancel + Annuler + + + + Update library + Mettre la librairie à jour + + + + Viewer + + + + Press 'O' to open comic. + Appuyez sur "O" pour ouvrir une bande dessinée. + + + + Not found + Introuvable + + + + Comic not found + Bande dessinée introuvable + + + + Error opening comic + Erreur d'ouverture de la bande dessinée + + + + CRC Error + Erreur CRC + + + + Loading...please wait! + Chargement... Patientez + + + + Page not available! + Page non disponible ! + + + + Cover! + Couverture! + + + + Last page! + Dernière page! + + + + VolumeComicsModel + + + title + titre + + + + VolumesModel + + + year + année + + + + issues + problèmes + + + + publisher + éditeur + + + + YACReader3DFlowConfigWidget + + + Presets: + Réglages: + + + + Classic look + Vue classique + + + + Stripe look + Vue alignée + + + + Overlapped Stripe look + Vue superposée + + + + Modern look + Vue moderne + + + + Roulette look + Vue roulette + + + + Show advanced settings + Voir les paramètres avancés + + + + Custom: + Personnalisation: + + + + View angle + Angle de vue + + + + Position + Positionnement + + + + Cover gap + Espace entre les couvertures + + + + Central gap + Espace couverture centrale + + + + Zoom + Agrandissement + + + + Y offset + Axe Y + + + + Z offset + Axe Z + + + + Cover Angle + Angle des couvertures + + + + Visibility + Visibilité + + + + Light + Lumière + + + + Max angle + Angle Maximum + + + + Low Performance + Faible performance + + + + High Performance + Haute performance + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Utiliser VSync (Améliore la qualité d'image en mode plein écran, ralentit la performance) + + + + Performance: + Performance : + + + + YACReader::MainWindowViewer + + + &Open + &Ouvrir + + + + Open a comic + Ouvrir une bande dessinée + + + + New instance + Nouvelle instance + + + + Open Folder + Ouvrir un dossier + + + + Open image folder + Ouvrir un dossier d'images + + + + Open latest comic + Ouvrir la dernière bande dessinée + + + + Open the latest comic opened in the previous reading session + Ouvrir la dernière bande dessinée ouverte lors de la session de lecture précédente + + + + Clear + Clair + + + + Clear open recent list + Vider la liste d'ouverture récente + + + + Save + Sauvegarder + + + + + Save current page + Sauvegarder la page actuelle + + + + Previous Comic + Bande dessinée précédente + + + + + + Open previous comic + Ouvrir la bande dessiné précédente + + + + Next Comic + Bande dessinée suivante + + + + + + Open next comic + Ouvrir la bande dessinée suivante + + + + &Previous + &Précédent + + + + + + Go to previous page + Aller à la page précédente + + + + &Next + &Suivant + + + + + + Go to next page + Aller à la page suivante + + + + Fit Height + Ajuster la hauteur + + + + Fit image to height + Ajuster l'image à la hauteur + + + + Fit Width + Ajuster la largeur + + + + Fit image to width + Ajuster l'image à la largeur + + + + Show full size + Plein écran + + + + Fit to page + Ajuster à la page + + + + Continuous scroll + Défilement continu + + + + Switch to continuous scroll mode + Passer en mode défilement continu + + + + Reset zoom + Réinitialiser le zoom + + + + Show zoom slider + Afficher le curseur de zoom + + + + Zoom+ + Agrandir + + + + Zoom- + R?duire + + + + Rotate image to the left + Rotation à gauche + + + + Rotate image to the right + Rotation à droite + + + + Double page mode + Mode double page + + + + Switch to double page mode + Passer en mode double page + + + + Double page manga mode + Mode manga en double page + + + + Reverse reading order in double page mode + Ordre de lecture inversée en mode double page + + + + Go To + Aller à + + + + Go to page ... + Aller à la page ... + + + + Options + Possibilités + + + + YACReader options + Options de YACReader + + + + + Help + Aide + + + + Help, About YACReader + Aide, à propos de YACReader + + + + Magnifying glass + Loupe + + + + Switch Magnifying glass + Utiliser la loupe + + + + Set bookmark + Placer un marque-page + + + + Set a bookmark on the current page + Placer un marque-page sur la page actuelle + + + + Show bookmarks + Voir les marque-pages + + + + Show the bookmarks of the current comic + Voir les marque-pages de cette bande dessinée + + + + Show keyboard shortcuts + Voir les raccourcis + + + + Show Info + Voir les infos + + + + Close + Fermer + + + + Show Dictionary + Dictionnaire + + + + Show go to flow + Afficher le flux + + + + Edit shortcuts + Modifier les raccourcis + + + + &File + &Fichier + + + + + Open recent + Ouvrir récent + + + + File + Fichier + + + + Edit + Editer + + + + View + Vue + + + + Go + Aller + + + + Window + Fenêtre + + + + + + Open Comic + Ouvrir la bande dessinée + + + + + + Comic files + Bande dessinée + + + + Open folder + Ouvirir le dossier + + + + page_%1.jpg + feuille_%1.jpg + + + + Image files (*.jpg) + Image(*.jpg) + + + + + Comics + Bandes dessinées + + + + + General + Général + + + + + Magnifiying glass + Loupe + + + + + Page adjustement + Ajustement de la page + + + + + Reading + Lecture + + + + Toggle fullscreen mode + Basculer en mode plein écran + + + + Hide/show toolbar + Masquer / afficher la barre d'outils + + + + Size up magnifying glass + Augmenter la taille de la loupe + + + + Size down magnifying glass + Réduire la taille de la loupe + + + + Zoom in magnifying glass + Zoomer + + + + Zoom out magnifying glass + Dézoomer + + + + Reset magnifying glass + Réinitialiser la loupe + + + + Toggle between fit to width and fit to height + Basculer entre adapter à la largeur et adapter à la hauteur + + + + Autoscroll down + Défilement automatique vers le bas + + + + Autoscroll up + Défilement automatique vers le haut + + + + Autoscroll forward, horizontal first + Défilement automatique en avant, horizontal + + + + Autoscroll backward, horizontal first + Défilement automatique en arrière horizontal + + + + Autoscroll forward, vertical first + Défilement automatique en avant, vertical + + + + Autoscroll backward, vertical first + Défilement automatique en arrière, verticak + + + + Move down + Descendre + + + + Move up + Monter + + + + Move left + Déplacer à gauche + + + + Move right + Déplacer à droite + + + + Go to the first page + Aller à la première page + + + + Go to the last page + Aller à la dernière page + + + + Offset double page to the left + Double page décalée vers la gauche + + + + Offset double page to the right + Double page décalée à droite + + + + There is a new version available + Une nouvelle version est disponible + + + + Do you want to download the new version? + Voulez-vous télécharger la nouvelle version? + + + + Remind me in 14 days + Rappelez-moi dans 14 jours + + + + Not now + Pas maintenant + + + + YACReader::TrayIconController + + + &Restore + &Restaurer + + + + Systray + Zone de notification + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quit</b> dans le menu contextuel de l'icône de la barre d'état système. + + + + YACReaderFieldEdit + + + + Click to overwrite + Cliquez pour remplacer + + + + Restore to default + Rétablir les paramètres par défaut + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + Cliquez pour remplacer + + + + Restore to default + Rétablir les paramètres par défaut + + + + YACReaderOptionsDialog + + + Save + Sauvegarder + + + + Cancel + Annuler + + + + Edit shortcuts + Modifier les raccourcis + + + + Shortcuts + Raccourcis + + + + YACReaderSearchLineEdit + + + type to search + tapez pour rechercher + + + + YACReaderSlider + + + Reset + Remise à zéro - QsLogging::Window + YACReaderTranslator - - &Pause - + + YACReader translator + Traducteur YACReader - - &Resume - + + + Translation + Traduction - - Save log - + + clear + effacer - - Log file (*.log) - + + Service not available + Service non disponible diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_nl.ts b/YACReaderLibraryServer/yacreaderlibraryserver_nl.ts index 67bca4f97..1367b2426 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_nl.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_nl.ts @@ -2,150 +2,3712 @@ - FileComic + ActionsShortcutsModel - - CRC error on page (%1): some of the pages will not be displayed correctly - + + None + Geen + + + AddLabelDialog - - Unknown error opening the file - + + Label name: + Labelnaam: - - 7z not found - + + Choose a color: + Kies een kleur: - - Format not supported - + + accept + accepteren + + + + cancel + annuleren - LogWindow + AddLibraryDialog + + + Comics folder : + Strips map: + + + + Library name : + Bibliotheek Naam : + - - Log window - + + Add + Toevoegen - - &Pause - + + Cancel + Annuleren - - &Save - + + Add an existing library + Voeg een bestaand bibliotheek toe + + + ApiKeyDialog - - C&lear - + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Voordat je verbinding kunt maken met Comic Vine, heb je een eigen API-sleutel nodig. Vraag er <a href="http://www.comicvine.com/api/">hier</a> één gratis aan - - &Copy - + + Paste here your Comic Vine API key + Plak hier uw Comic Vine API-sleutel - - Level: - + + Accept + Accepteren - - &Auto scroll - + + Cancel + Annuleren - QCoreApplication + AppearanceTabWidget - - -YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + + Color scheme + Kleurenschema + + + + System + Systeem + + + + Light + Licht + + + + Dark + Donker + + + + Custom + Aangepast + + + + Remove + Verwijderen + + + + Remove this user-imported theme + Verwijder dit door de gebruiker geïmporteerde thema + + + + Light: + Licht: + + + + Dark: + Donker: + + + + Custom: + Aangepast: + + + + Import theme... + Thema importeren... + + + + Theme + Thema + + + + Theme editor + Thema-editor + + + + Open Theme Editor... + Thema-editor openen... + + + + Theme editor error + Fout in de thema-editor + + + + The current theme JSON could not be loaded. + De huidige thema-JSON kan niet worden geladen. + + + + Import theme + Thema importeren + + + + JSON files (*.json);;All files (*) + JSON-bestanden (*.json);;Alle bestanden (*) + + + + Could not import theme from: +%1 + Kan thema niet importeren uit: +%1 + + + + Could not import theme from: +%1 -This appplication supports persistent settings, to set them up edit this file %1 -To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md - +%2 + Kan thema niet importeren uit: +%1 + +%2 + + + + Import failed + Importeren is mislukt - QObject + BookmarksDialog - - Trace - + + Lastest Page + Laatste Pagina - - Debug - + + Close + Sluiten - - Info - + + Click on any image to go to the bookmark + Klik op een afbeelding om naar de bladwijzer te gaan - - Warning - + + + Loading... + Inladen... + + + ClassicComicsView - - Error - + + Hide comic flow + Sluit de Omslagbrowser + + + + ComicModel + + + yes + Ja - - Fatal - + + no + neen + + + + Title + Titel + + + + File Name + Bestandsnaam + + + + Pages + Pagina's + + + + Size + Grootte(MB) + + + + Read + Gelezen + + + + Current Page + Huidige pagina + + + + Publication Date + Publicatiedatum + + + + Rating + Beoordeling + + + + Series + Serie + + + + Volume + Deel + + + + Story Arc + Verhaalboog + + + + ComicVineDialog + + + skip + overslaan + + + + back + rug + + + + next + volgende + + + + search + zoekopdracht + + + + close + dichtbij + + + + + comic %1 of %2 - %3 + strip %1 van %2 - %3 + + + + + + Looking for volume... + Op zoek naar volumes... + + + + %1 comics selected + %1 strips geselecteerd + + + + Error connecting to ComicVine + Fout bij verbinden met ComicVine + + + + + Retrieving tags for : %1 + Tags ophalen voor: %1 + + + + Retrieving volume info... + Volume-informatie ophalen... + + + + Looking for comic... + Op zoek naar komische... + + + + ContinuousPageWidget + + + Loading page %1 + Pagina laden %1 + + + + CreateLibraryDialog + + + Comics folder : + Strips map: + + + + Library Name : + Bibliotheek Naam : + + + + Create + Aanmaken + + + + Cancel + Annuleren + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Een bibliotheek aanmaken kan enkele minuten duren. U kunt het proces stoppen en de bibliotheek later voltooien. + + + + Create new library + Een nieuwe Bibliotheek aanmaken + + + + Path not found + Pad niet gevonden + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + De geselecteerde pad bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map + + + + EditShortcutsDialog + + + Restore defaults + Standaardwaarden herstellen + + + + To change a shortcut, double click in the key combination and type the new keys. + Om een ​​snelkoppeling te wijzigen, dubbelklikt u op de toetsencombinatie en typt u de nieuwe toetsen. + + + + Shortcuts settings + Instellingen voor snelkoppelingen + + + + Shortcut in use + Snelkoppeling in gebruik + + + + The shortcut "%1" is already assigned to other function + De sneltoets "%1" is al aan een andere functie toegewezen + + + + EmptyFolderWidget + + + This folder doesn't contain comics yet + Deze map bevat nog geen strips + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + Dit label bevat nog geen strips + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + Deze leeslijst bevat nog geen strips + + + + EmptySpecialListWidget + + + No favorites + Geen favorieten + + + + You are not reading anything yet, come on!! + Je leest nog niets, kom op!! + + + + There are no recent comics! + Er zijn geen recente strips! + + + + ExportComicsInfoDialog + + + Output file : + Uitvoerbestand: + + + + Create + Aanmaken + + + + Cancel + Annuleren + + + + Export comics info + Strip info exporteren + + + + Destination database name + Bestemmingsdatabase naam + + + + Problem found while writing + Probleem bij het schrijven + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Het gekozen pad voor het uitvoerbestand bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map + + + + ExportLibraryDialog + + + Output folder : + Uitvoermap : + + + + Create + Aanmaken + + + + Cancel + Annuleren + + + + Create covers package + Aanmaken omslag pakket + + + + Problem found while writing + Probleem bij het schrijven + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Het gekozen pad voor het uitvoerbestand bestaat niet of is geen geldig pad. Controleer of u schrijftoegang hebt tot deze map + + + + Destination directory + Doeldirectory + + + + FileComic + + + CRC error on page (%1): some of the pages will not be displayed correctly + CRC-fout op pagina (%1): sommige pagina's worden niet correct weergegeven + + + + Unknown error opening the file + Onbekende fout bij het openen van het bestand + + + + 7z not found + 7Z Archiefbestand niet gevonden + + + + Format not supported + Formaat niet ondersteund + + + + GoToDialog + + + Page : + Pagina : + + + + Go To + Ga Naar + + + + Cancel + Annuleren + + + + + Total pages : + Totaal aantal pagina's : + + + + Go to... + Ga naar... + + + + GoToFlowToolBar + + + Page : + Pagina : - QsLogging::LogWindowModel + GridComicsView - - Time - + + Show info + Toon informatie + + + HelpAboutDialog - - Level - + + About + Over - - Message - + + Help + Hulp + + + + System info + Systeeminformatie + + + + ImportComicsInfoDialog + + + Import comics info + Strip info Importeren + + + + Info database location : + Info database locatie : + + + + Import + Importeren + + + + Cancel + Annuleren + + + + Comics info file (*.ydb) + Strips info bestand ( * .ydb) + + + + ImportLibraryDialog + + + Library Name : + Bibliotheek Naam : + + + + Package location : + Arrangement locatie : + + + + Destination folder : + Doelmap: + + + + Unpack + Uitpakken + + + + Cancel + Annuleren + + + + Extract a catalog + Een catalogus uitpakken + + + + Compresed library covers (*.clc) + Compresed omslag- bibliotheek ( * .clc) + + + + ImportWidget + + + stop + Stoppen + + + + Some of the comics being added... + Enkele strips zijn toegevoegd ... + + + + Importing comics + Strips importeren + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <P>YACReaderLibrary maak nu een nieuwe bibliotheek. < /p> <p>Een bibliotheek aanmaken kan enkele minuten duren. U kunt het proces stoppen en de bibliotheek later voltooien. < /p> + + + + Updating the library + Actualisering van de bibliotheek + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <P>De huidige bibliotheek wordt bijgewerkt. Voor snellere updates, update uw bibliotheken regelmatig. < /p> <p>u kunt het proces stoppen om later bij te werken. < /p> + + + + Upgrading the library + Het upgraden van de bibliotheek + + + + <p>The current library is being upgraded, please wait.</p> + <p>De huidige bibliotheek wordt geüpgraded. Een ogenblik geduld.</p> + + + + Scanning the library + De bibliotheek scannen + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>De huidige bibliotheek wordt gescand op oudere XML-metadata-informatie.</p><p>Dit is slechts één keer nodig en alleen als de bibliotheek is ingepakt met YACReaderLibrary 9.8.2 of eerder.</p> + + + + LibraryWindow + + + YACReader Library + YACReader Bibliotheek + + + + + + comic + grappig + + + + + + manga + Manga + + + + + + western manga (left to right) + westerse manga (van links naar rechts) + + + + + + web comic + web-strip + + + + + + 4koma (top to botom) + 4koma (van boven naar beneden) + + + + + + + Set type + Soort instellen + + + + Library + Bibliotheek + + + + Folder + Map + + + + Comic + Grappig + + + + Upgrade failed + Upgrade mislukt + + + + There were errors during library upgrade in: + Er zijn fouten opgetreden tijdens de bibliotheekupgrade in: + + + + Update needed + Bijwerken is nodig + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Deze bibliotheek is gemaakt met een vorige versie van YACReaderLibrary. Het moet worden bijgewerkt. Nu bijwerken? + + + + Download new version + Nieuwe versie ophalen + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Deze bibliotheek is gemaakt met een nieuwere versie van YACReaderLibrary. Download de nieuwe versie? + + + + Library not available + Bibliotheek niet beschikbaar + + + + Library '%1' is no longer available. Do you want to remove it? + Bibliotheek ' %1' is niet langer beschikbaar. Wilt u het verwijderen? + + + + Old library + Oude Bibliotheek + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Bibliotheek ' %1' is gemaakt met een oudere versie van YACReaderLibrary. Zij moet opnieuw worden aangemaakt. Wilt u de bibliotheek nu aanmaken? + + + + + Copying comics... + Strips kopiëren... + + + + + Moving comics... + Strips verplaatsen... + + + + Add new folder + Nieuwe map toevoegen + + + + Folder name: + Mapnaam: + + + + No folder selected + Geen map geselecteerd + + + + Please, select a folder first + Selecteer eerst een map + + + + Error in path + Fout in pad + + + + There was an error accessing the folder's path + Er is een fout opgetreden bij het verkrijgen van toegang tot het pad van de map + + + + Delete folder + Map verwijderen + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + De geselecteerde map en de volledige inhoud ervan worden van uw schijf verwijderd. Weet je het zeker? + + + + + Unable to delete + Kan niet verwijderen + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Er is een probleem opgetreden bij het verwijderen van de geselecteerde mappen. Controleer of er schrijfrechten zijn en zorg ervoor dat alle toepassingen deze mappen of een van de daarin opgenomen bestanden gebruiken. + + + + Add new reading lists + Voeg nieuwe leeslijsten toe + + + + + List name: + Lijstnaam: + + + + Delete list/label + Lijst/label verwijderen + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + Het geselecteerde item wordt verwijderd, uw strips of mappen worden NIET van uw schijf verwijderd. Weet je het zeker? + + + + Rename list name + Hernoem de lijstnaam + + + + Open folder... + Map openen ... + + + + Update folder + Map bijwerken + + + + Rescan library for XML info + Bibliotheek opnieuw scannen op XML-info + + + + Set as uncompleted + Ingesteld als onvoltooid + + + + Set as completed + Instellen als voltooid + + + + Set as read + Instellen als gelezen + + + + + Set as unread + Instellen als ongelezen + + + + Set custom cover + Aangepaste omslag instellen + + + + Delete custom cover + Aangepaste omslag verwijderen + + + + Save covers + Bewaar hoesjes + + + + You are adding too many libraries. + U voegt te veel bibliotheken toe. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + U voegt te veel bibliotheken toe. + +Je hebt waarschijnlijk maar één bibliotheek nodig in je stripmap op het hoogste niveau. Je kunt door alle submappen bladeren met behulp van het mappengedeelte in de linkerzijbalk. + +YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, maar u moet het aantal bibliotheken laag houden. + + + + + YACReader not found + YACReader niet gevonden + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader niet gevonden. YACReader moet in dezelfde map worden geïnstalleerd als YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader niet gevonden. Er is mogelijk een probleem met uw YACReader-installatie. + + + + Error + Fout + + + + Error opening comic with third party reader. + Fout bij het openen van een strip met een lezer van een derde partij. + + + + Library not found + Bibliotheek niet gevonden + + + + The selected folder doesn't contain any library. + De geselecteerde map bevat geen bibliotheek. + + + + Are you sure? + Weet u het zeker? + + + + Do you want remove + Wilt u verwijderen + + + + library? + Bibliotheek? + + + + Remove and delete metadata + Verwijder metagegevens + + + + Library info + Bibliotheekinformatie + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Er is een probleem opgetreden bij het verwijderen van de geselecteerde strips. Controleer of er schrijfrechten zijn voor de geselecteerde bestanden of de map waarin deze zich bevinden. + + + + Assign comics numbers + Wijs stripnummers toe + + + + Assign numbers starting in: + Nummers toewijzen beginnend met: + + + + Invalid image + Ongeldige afbeelding + + + + The selected file is not a valid image. + Het geselecteerde bestand is geen geldige afbeelding. + + + + Error saving cover + Fout bij opslaan van dekking + + + + There was an error saving the cover image. + Er is een fout opgetreden bij het opslaan van de omslagafbeelding. + + + + Error creating the library + Fout bij aanmaken Bibliotheek + + + + Error updating the library + Fout bij bijwerken Bibliotheek + + + + Error opening the library + Fout bij openen Bibliotheek + + + + Delete comics + Strips verwijderen + + + + All the selected comics will be deleted from your disk. Are you sure? + Alle geselecteerde strips worden verwijderd van uw schijf. Weet u het zeker? + + + + Remove comics + Verwijder strips + + + + Comics will only be deleted from the current label/list. Are you sure? + Strips worden alleen verwijderd van het huidige label/de huidige lijst. Weet je het zeker? + + + + Library name already exists + Bibliotheek naam bestaat al + + + + There is another library with the name '%1'. + Er is al een bibliotheek met de naam ' %1 '. + + + + LibraryWindowActions + + + Create a new library + Maak een nieuwe Bibliotheek + + + + Open an existing library + Open een bestaande Bibliotheek + + + + + Export comics info + Strip info exporteren + + + + + Import comics info + Strip info Importeren + + + + Pack covers + Inpakken strip voorbladen + + + + Pack the covers of the selected library + Inpakken alle strip voorbladen van de geselecteerde Bibliotheek + + + + Unpack covers + Uitpakken voorbladen + + + + Unpack a catalog + Uitpaken van een catalogus + + + + Update library + Bibliotheek bijwerken + + + + Update current library + Huidige Bibliotheek bijwerken + + + + Rename library + Bibliotheek hernoemen + + + + Rename current library + Huidige Bibliotheek hernoemen + + + + Remove library + Bibliotheek verwijderen + + + + Remove current library from your collection + De huidige Bibliotheek verwijderen uit uw verzameling + + + + Rescan library for XML info + Bibliotheek opnieuw scannen op XML-info + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Probeert XML-informatie te vinden die is ingebed in stripbestanden. U hoeft dit alleen te doen als de bibliotheek is gemaakt met versie 9.8.2 of eerdere versies of als u software van derden gebruikt om XML-informatie in de bestanden in te sluiten. + + + + Show library info + Bibliotheekinfo tonen + + + + Show information about the current library + Toon informatie over de huidige bibliotheek + + + + Open current comic + Huidige strip openen + + + + Open current comic on YACReader + Huidige strip openen in YACReader + + + + Save selected covers to... + Geselecteerde omslagen opslaan in... + + + + Save covers of the selected comics as JPG files + Sla covers van de geselecteerde strips op als JPG-bestanden + + + + + Set as read + Instellen als gelezen + + + + Set comic as read + Strip Instellen als gelezen + + + + + Set as unread + Instellen als ongelezen + + + + Set comic as unread + Strip Instellen als ongelezen + + + + + manga + Manga + + + + Set issue as manga + Stel het probleem in als manga + + + + + comic + grappig + + + + Set issue as normal + Stel het probleem in als normaal + + + + western manga + westerse manga + + + + Set issue as western manga + Stel het probleem in als westerse manga + + + + + web comic + web-strip + + + + Set issue as web comic + Stel het probleem in als webstrip + + + + + yonkoma + yokoma + + + + Set issue as yonkoma + Stel het probleem in als yonkoma + + + + Show/Hide marks + Toon/Verberg markeringen + + + + Show or hide read marks + Toon of verberg leesmarkeringen + + + + Show/Hide recent indicator + Recente indicator tonen/verbergen + + + + Show or hide recent indicator + Toon of verberg recente indicator + + + + + Fullscreen mode on/off + Volledig scherm modus aan/of + + + + Help, About YACReader + Help, Over YACReader + + + + Add new folder + Nieuwe map toevoegen + + + + Add new folder to the current library + Voeg een nieuwe map toe aan de huidige bibliotheek + + + + Delete folder + Map verwijderen + + + + Delete current folder from disk + Verwijder de huidige map van schijf + + + + Select root node + Selecteer de hoofd categorie + + + + Expand all nodes + Alle categorieën uitklappen + + + + Collapse all nodes + Vouw alle knooppunten samen + + + + Show options dialog + Toon opties dialoog + + + + Show comics server options dialog + Toon strips-server opties dialoog + + + + + Change between comics views + Wisselen tussen stripweergaven + + + + Open folder... + Map openen ... + + + + Set as uncompleted + Ingesteld als onvoltooid + + + + Set as completed + Instellen als voltooid + + + + Set custom cover + Aangepaste omslag instellen + + + + Delete custom cover + Aangepaste omslag verwijderen + + + + western manga (left to right) + westerse manga (van links naar rechts) + + + + Open containing folder... + Open map ... + + + + Reset comic rating + Stripbeoordeling opnieuw instellen + + + + Select all comics + Selecteer alle strips + + + + Edit + Bewerken + + + + Assign current order to comics + Wijs de huidige volgorde toe aan strips + + + + Update cover + Strip omslagen bijwerken + + + + Delete selected comics + Geselecteerde strips verwijderen + + + + Delete metadata from selected comics + Verwijder metadata uit geselecteerde strips + + + + Download tags from Comic Vine + Tags downloaden van Comic Vine + + + + Focus search line + Focus zoeklijn + + + + Focus comics view + Focus stripweergave + + + + Edit shortcuts + Snelkoppelingen bewerken + + + + &Quit + &Afsluiten + + + + Update folder + Map bijwerken + + + + Update current folder + Werk de huidige map bij + + + + Scan legacy XML metadata + Scan oudere XML-metagegevens + + + + Add new reading list + Nieuwe leeslijst toevoegen + + + + Add a new reading list to the current library + Voeg een nieuwe leeslijst toe aan de huidige bibliotheek + + + + Remove reading list + Leeslijst verwijderen + + + + Remove current reading list from the library + Verwijder de huidige leeslijst uit de bibliotheek + + + + Add new label + Nieuw etiket toevoegen + + + + Add a new label to this library + Voeg een nieuw label toe aan deze bibliotheek + + + + Rename selected list + Hernoem de geselecteerde lijst + + + + Rename any selected labels or lists + Hernoem alle geselecteerde labels of lijsten + + + + Add to... + Toevoegen aan... + + + + Favorites + Favorieten + + + + Add selected comics to favorites list + Voeg geselecteerde strips toe aan de favorietenlijst + + + + LocalComicListModel + + + file name + bestandsnaam + + + + NoLibrariesWidget + + + You don't have any libraries yet + Je hebt geen nog libraries + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <P>u kunt een bibliotheek maken in een willekeurige map, YACReaderLibrary importeert alle strips en mappen uit deze map. Alle bibliotheek aangemaakt in het verleden kan je openen. < /p> <p>vergeet niet dat u YACReader kan gebruiken als stand-alone applicatie voor het lezen van de strips op de computer. < /p> + + + + create your first library + Maak uw eerste bibliotheek + + + + add an existing one + voeg een bestaande bibliotheek toe + + + + NoSearchResultsWidget + + + No results + Geen resultaten + + + + OptionsDialog + + + + General + Algemeen + + + + + Libraries + Bibliotheken + + + + Comic Flow + Komische stroom + + + + Grid view + Rasterweergave + + + + + Appearance + Verschijning + + + + + Options + Opties + + + + + Language + Taal + + + + + Application language + Applicatietaal + + + + + System default + Standaard van het systeem + + + + Tray icon settings (experimental) + Instellingen voor ladepictogram (experimenteel) + + + + Close to tray + Dicht bij lade + + + + Start into the system tray + Begin in het systeemvak + + + + Edit Comic Vine API key + Bewerk de Comic Vine API-sleutel + + + + Comic Vine API key + Comic Vine API-sleutel + + + + ComicInfo.xml legacy support + ComicInfo.xml verouderde ondersteuning + + + + Import metadata from ComicInfo.xml when adding new comics + Importeer metagegevens uit ComicInfo.xml wanneer u nieuwe strips toevoegt + + + + Consider 'recent' items added or updated since X days ago + Overweeg 'recente' items die sinds X dagen geleden zijn toegevoegd of bijgewerkt + + + + Third party reader + Lezer van derden + + + + Write {comic_file_path} where the path should go in the command + Schrijf {comic_file_path} waar het pad naartoe moet in de opdracht + + + + + Clear + Duidelijk + + + + Update libraries at startup + Update bibliotheken bij het opstarten + + + + Try to detect changes automatically + Probeer wijzigingen automatisch te detecteren + + + + Update libraries periodically + Update bibliotheken regelmatig + + + + Interval: + Tijdsinterval: + + + + 30 minutes + 30 minuten + + + + 1 hour + 1 uur + + + + 2 hours + 2 uur + + + + 4 hours + 4 uur + + + + 8 hours + 8 uur + + + + 12 hours + 12 uur + + + + daily + dagelijks + + + + Update libraries at certain time + Update bibliotheken op een bepaald tijdstip + + + + Time: + Tijd: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + WAARSCHUWING! Tijdens bibliotheekupdates is schrijven naar de database uitgeschakeld! +Plan geen updates terwijl u de app mogelijk actief gebruikt. +During automatic updates the app will block some of the actions until the update is finished. +Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de titel van Bibliotheken. + + + + Modifications detection + Detectie van wijzigingen + + + + Compare the modified date of files when updating a library (not recommended) + Vergelijk de wijzigingsdatum van bestanden bij het updaten van een bibliotheek (niet aanbevolen) + + + + Enable background image + Achtergrondafbeelding inschakelen + + + + Opacity level + Dekkingsniveau + + + + Blur level + Vervagingsniveau + + + + Use selected comic cover as background + Gebruik geselecteerde stripomslag als achtergrond + + + + Restore defautls + Standaardwaarden herstellen + + + + Background + Achtergrond + + + + Display continue reading banner + Toon de banner voor verder lezen + + + + Display current comic banner + Toon huidige stripbanner + + + + Continue reading + Lees verder + + + + My comics path + Pad naar mijn strips + + + + Display + Weergave + + + + Show time in current page information label + Toon de tijd in het informatielabel van de huidige pagina + + + + "Go to flow" size + "Naar Omslagbrowser" afmetingen + + + + Background color + Achtergrondkleur + + + + Choose + Kies + + + + Scroll behaviour + Scrollgedrag + + + + Disable scroll animations and smooth scrolling + Schakel scrollanimaties en soepel scrollen uit + + + + Do not turn page using scroll + Sla de pagina niet om met scrollen + + + + Use single scroll step to turn page + Gebruik een enkele scrollstap om de pagina om te slaan + + + + Mouse mode + Muismodus + + + + Only Back/Forward buttons can turn pages + Alleen de knoppen Terug/Vooruit kunnen pagina's omslaan + + + + Use the Left/Right buttons to turn pages. + Gebruik de knoppen Links/Rechts om pagina's om te slaan. + + + + Click left or right half of the screen to turn pages. + Klik op de linker- of rechterhelft van het scherm om pagina's om te slaan. + + + + Quick Navigation Mode + Snelle navigatiemodus + + + + Disable mouse over activation + Schakel muis-over-activering uit + + + + Brightness + Helderheid + + + + Contrast + Contrastwaarde + + + + Gamma + Gammawaarde + + + + Reset + Standaardwaarden terugzetten + + + + Image options + Afbeelding opties + + + + Fit options + Pas opties + + + + Enlarge images to fit width/height + Vergroot afbeeldingen zodat ze in de breedte/hoogte passen + + + + Double Page options + Opties voor dubbele pagina's + + + + Show covers as single page + Toon omslagen als enkele pagina + + + + Scaling + Schalen + + + + Scaling method + Schaalmethode + + + + Nearest (fast, low quality) + Dichtstbijzijnde (snel, lage kwaliteit) + + + + Bilinear + Bilineair + + + + Lanczos (better quality) + Lanczos (betere kwaliteit) + + + + Page Flow + Omslagbrowser + + + + Image adjustment + Beeldaanpassing + + + + + Restart is needed + Herstart is nodig + + + + Comics directory + Strips map + + + + PropertiesDialog + + + General info + Algemene Info + + + + Plot + Verhaal + + + + Authors + Auteurs + + + + Publishing + Uitgever + + + + Notes + Opmerkingen + + + + Cover page + Omslag + + + + Load previous page as cover + Laad de vorige pagina als omslag + + + + Load next page as cover + Laad de volgende pagina als omslag + + + + Reset cover to the default image + Zet de omslag terug naar de standaardafbeelding + + + + Load custom cover image + Aangepaste omslagafbeelding laden + + + + Series: + Serie: + + + + Title: + Titel: + + + + + + of: + van: + + + + Issue number: + Ids: + + + + Volume: + Inhoud: + + + + Arc number: + Boognummer: + + + + Story arc: + Verhaallijn: + + + + alt. number: + alt. nummer: + + + + Alternate series: + Alternatieve serie: + + + + Series Group: + Seriegroep: + + + + Genre: + Genretype: + + + + Size: + Grootte(MB): + + + + Writer(s): + Schrijver(s): + + + + Penciller(s): + Tekenaar(s): + + + + Inker(s): + Inkt(en): + + + + Colorist(s): + Inkleurder(s): + + + + Letterer(s): + Letterzetter(s): + + + + Cover Artist(s): + Omslag ontwikkelaar(s): + + + + Editor(s): + Redacteur(en): + + + + Imprint: + Opdruk: + + + + Day: + Dag: + + + + Month: + Maand: + + + + Year: + Jaar: + + + + Publisher: + Uitgever: + + + + Format: + Formaat: + + + + Color/BW: + Kleur/ZW: + + + + Age rating: + Leeftijdsbeperking: + + + + Type: + Soort: + + + + Language (ISO): + Taal (ISO): + + + + Synopsis: + Samenvatting: + + + + Characters: + Personages: + + + + Teams: + Ploegen: + + + + Locations: + Locaties: + + + + Main character or team: + Hoofdpersoon of team: + + + + Review: + Beoordeling: + + + + Notes: + Opmerkingen: + + + + Tags: + Labels: + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine-link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> bekijken </a> + + + + Not found + Niet gevonden + + + + Comic not found. You should update your library. + Strip niet gevonden. U moet uw bibliotheek.bijwerken. + + + + Edit comic information + Strip informatie bijwerken + + + + Edit selected comics information + Geselecteerde strip informatie bijwerken + + + + Invalid cover + Ongeldige dekking + + + + The image is invalid. + De afbeelding is ongeldig. + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer is de headless (geen gui) versie van YACReaderLibrary. + +Deze applicatie ondersteunt permanente instellingen. Om ze in te stellen, bewerk dit bestand %1 +Voor meer informatie over de beschikbare instellingen kunt u de documentatie raadplegen op https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject + + + Trace + Spoor + + + + Debug + Foutopsporing + + + + Info + Informatie + + + + Warning + Waarschuwing + + + + Error + Fout + + + + Fatal + Fataal + + + + Select custom cover + Selecteer een aangepaste omslag + + + + Images (%1) + Afbeeldingen (%1) + + + + 7z lib not found + 7z-lib niet gevonden + + + + unable to load 7z lib from ./utils + kan 7z lib niet laden vanuit ./utils + + + + The file could not be read or is not valid JSON. + Het bestand kan niet worden gelezen of is geen geldige JSON. + + + + This theme is for %1, not %2. + Dit thema is voor %1, niet voor %2. + + + + Libraries + Bibliotheken + + + + Folders + Mappen + + + + Reading Lists + Leeslijsten + + + + RenameLibraryDialog + + + New Library Name : + Nieuwe Bibliotheek Naam : + + + + Rename + Hernoem + + + + Cancel + Annuleren + + + + Rename current library + Huidige Bibliotheek hernoemen + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + Aantal gevonden volumes: %1 + + + + + page %1 of %2 + pagina %1 van %2 + + + + Number of %1 found : %2 + Aantal %1 gevonden: %2 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + Geef wat aanvullende informatie op voor deze strip. + + + + Series: + Serie: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Gebruik exacte matchzoekopdrachten. Schakel dit uit als u volumes wilt vinden die overeenkomen met enkele woorden in de naam. + + + + SearchVolume + + + Please provide some additional information. + Geef alstublieft wat aanvullende informatie op. + + + + Series: + Serie: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Gebruik exacte matchzoekopdrachten. Schakel dit uit als u volumes wilt vinden die overeenkomen met enkele woorden in de naam. + + + + SelectComic + + + Please, select the right comic info. + Selecteer de juiste stripinformatie. + + + + comics + strips + + + + loading cover + laaddeksel + + + + loading description + beschrijving laden + + + + comic description unavailable + komische beschrijving niet beschikbaar + + + + SelectVolume + + + Please, select the right series for your comic. + Selecteer de juiste serie voor jouw strip. + + + + Filter: + Selectiefilter: + + + + volumes + delen + + + + Nothing found, clear the filter if any. + Niets gevonden. Wis eventueel het filter. + + + + loading cover + laaddeksel + + + + loading description + beschrijving laden + + + + volume description unavailable + volumebeschrijving niet beschikbaar + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + Je probeert informatie voor verschillende strips tegelijk te krijgen. Maken ze deel uit van dezelfde serie? + + + + yes + Ja + + + + no + neen + + + + ServerConfigDialog + + + set port + Poort instellen + + + + Server connectivity information + Informatie over serverconnectiviteit + + + + Scan it! + Scan het! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is beschikbaar voor iOS- en Android-apparaten.<br/>Ontdek het voor <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> of <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + + + + Choose an IP address + Kies een IP-adres + + + + Port + Poort + + + + enable the server + De server instellen + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + Sorteer de lijst met strips aan de linkerkant totdat deze overeenkomt met de informatie over de strips. + + + + sort comics to match comic information + sorteer strips zodat ze overeenkomen met stripinformatie + + + + issues + problemen + + + + remove selected comics + verwijder geselecteerde strips + + + + restore all removed comics + herstel alle verwijderde strips + + + + ThemeEditorDialog + + + Theme Editor + Thema-editor + + + + + + + + + + + - + - + + + + i + ? + + + + Expand all + Alles uitvouwen + + + + Collapse all + Alles samenvouwen + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Houd ingedrukt om de geselecteerde waarde in de gebruikersinterface te laten knipperen (magenta / geschakeld / 0↔10). Releases herstellen het origineel. + + + + Search… + Zoekopdracht… + + + + Light + Licht + + + + Dark + Donker + + + + ID: + Identiteitskaart: + + + + Display name: + Weergavenaam: + + + + Variant: + Variatie: + + + + Theme info + Thema-informatie + + + + Parameter + Instelwaarde + + + + Value + Waarde + + + + Save and apply + Opslaan en toepassen + + + + Export to file... + Exporteren naar bestand... + + + + Load from file... + Laden uit bestand... + + + + Close + Sluiten + + + + Double-click to edit color + Dubbelklik om de kleur te bewerken + + + + + + + + + true + WAAR + + + + + + + false + vals + + + + Double-click to toggle + Dubbelklik om te schakelen + + + + Double-click to edit value + Dubbelklik om de waarde te bewerken + + + + + + Edit: %1 + Bewerken: %1 + + + + Save theme + Thema opslaan + + + + + JSON files (*.json);;All files (*) + JSON-bestanden (*.json);;Alle bestanden (*) + + + + Save failed + Opslaan mislukt + + + + Could not open file for writing: +%1 + Kan bestand niet openen om te schrijven: +%1 + + + + Load theme + Thema laden + + + + + + Load failed + Laden mislukt + + + + Could not open file: +%1 + Kan bestand niet openen: +%1 + + + + Invalid JSON: +%1 + Ongeldige JSON: +%1 + + + + Expected a JSON object. + Er werd een JSON-object verwacht. + + + + TitleHeader + + + SEARCH + ZOEKOPDRACHT + + + + UpdateLibraryDialog + + + Updating.... + Bijwerken.... + + + + Cancel + Annuleren + + + + Update library + Bibliotheek bijwerken + + + + Viewer + + + + Press 'O' to open comic. + Druk 'O' om een strip te openen. + + + + Not found + Niet gevonden + + + + Comic not found + Strip niet gevonden + + + + Error opening comic + Fout bij openen strip + + + + CRC Error + CRC-fout + + + + Loading...please wait! + Inladen...even wachten! + + + + Page not available! + Pagina niet beschikbaar! + + + + Cover! + Omslag! + + + + Last page! + Laatste pagina! + + + + VolumeComicsModel + + + title + titel + + + + VolumesModel + + + year + jaar + + + + issues + problemen + + + + publisher + uitgever + + + + YACReader3DFlowConfigWidget + + + Presets: + Voorinstellingen: + + + + Classic look + Klassiek + + + + Stripe look + Brede band + + + + Overlapped Stripe look + Overlappende band + + + + Modern look + Modern + + + + Roulette look + Roulette + + + + Show advanced settings + Toon geavanceerde instellingen + + + + Custom: + Aangepast: + + + + View angle + Kijkhoek + + + + Position + Positie + + + + Cover gap + Ruimte tss Omslag + + + + Central gap + Centrale ruimte + + + + Zoom + Vergroting + + + + Y offset + Y-positie + + + + Z offset + Z- positie + + + + Cover Angle + Omslag hoek + + + + Visibility + Zichtbaarheid + + + + Light + Licht + + + + Max angle + Maximale hoek + + + + Low Performance + Lage Prestaties + + + + High Performance + Hoge Prestaties + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Gebruik VSync (verbetering van de beeldkwaliteit in de modus volledig scherm, slechtere prestatie) + + + + Performance: + Prestatie: + + + + YACReader::MainWindowViewer + + + &Open + &Openen + + + + Open a comic + Open een strip + + + + New instance + Nieuw exemplaar + + + + Open Folder + Map Openen + + + + Open image folder + Open afbeeldings map + + + + Open latest comic + Open de nieuwste strip + + + + Open the latest comic opened in the previous reading session + Open de nieuwste strip die in de vorige leessessie is geopend + + + + Clear + Duidelijk + + + + Clear open recent list + Wis geopende recente lijst + + + + Save + Bewaar + + + + + Save current page + Bewaren huidige pagina + + + + Previous Comic + Vorige Strip + + + + + + Open previous comic + Open de vorige strip + + + + Next Comic + Volgende Strip + + + + + + Open next comic + Open volgende strip + + + + &Previous + &Vorige + + + + + + Go to previous page + Ga naar de vorige pagina + + + + &Next + &Volgende + + + + + + Go to next page + Ga naar de volgende pagina + + + + Fit Height + Geschikte hoogte + + + + Fit image to height + Afbeelding aanpassen aan hoogte + + + + Fit Width + Vensterbreedte aanpassen + + + + Fit image to width + Afbeelding aanpassen aan breedte + + + + Show full size + Volledig Scherm + + + + Fit to page + Aanpassen aan pagina + + + + Continuous scroll + Continu scrollen + + + + Switch to continuous scroll mode + Schakel over naar de continue scrollmodus + + + + Reset zoom + Zoom opnieuw instellen + + + + Show zoom slider + Zoomschuifregelaar tonen + + + + Zoom+ + Inzoomen + + + + Zoom- + Uitzoomen + + + + Rotate image to the left + Links omdraaien + + + + Rotate image to the right + Rechts omdraaien + + + + Double page mode + Dubbele bladzijde modus + + + + Switch to double page mode + Naar dubbele bladzijde modus + + + + Double page manga mode + Manga-modus met dubbele pagina + + + + Reverse reading order in double page mode + Omgekeerde leesvolgorde in dubbele paginamodus + + + + Go To + Ga Naar + + + + Go to page ... + Ga naar bladzijde ... + + + + Options + Opties + + + + YACReader options + YACReader opties + + + + + Help + Hulp + + + + Help, About YACReader + Help, Over YACReader + + + + Magnifying glass + Vergrootglas + + + + Switch Magnifying glass + Overschakelen naar Vergrootglas + + + + Set bookmark + Bladwijzer instellen + + + + Set a bookmark on the current page + Een bladwijzer toevoegen aan de huidige pagina + + + + Show bookmarks + Bladwijzers weergeven + + + + Show the bookmarks of the current comic + Toon de bladwijzers van de huidige strip + + + + Show keyboard shortcuts + Toon de sneltoetsen + + + + Show Info + Info tonen + + + + Close + Sluiten + + + + Show Dictionary + Woordenlijst weergeven + + + + Show go to flow + Toon ga naar de Omslagbrowser + + + + Edit shortcuts + Snelkoppelingen bewerken + + + + &File + &Bestand + + + + + Open recent + Recent geopend + + + + File + Bestand + + + + Edit + Bewerken + + + + View + Weergave + + + + Go + Gaan + + + + Window + Raam + + + + + + Open Comic + Open een Strip + + + + + + Comic files + Strip bestanden + + + + Open folder + Open een Map + + + + page_%1.jpg + pagina_%1.jpg + + + + Image files (*.jpg) + Afbeelding bestanden (*.jpg) + + + + + Comics + Strips + + + + + General + Algemeen + + + + + Magnifiying glass + Vergrootglas + + + + + Page adjustement + Pagina-aanpassing + + + + + Reading + Lezing + + + + Toggle fullscreen mode + Schakel de modus Volledig scherm in + + + + Hide/show toolbar + Werkbalk verbergen/tonen + + + + Size up magnifying glass + Vergrootglas vergroten + + + + Size down magnifying glass + Vergrootglas kleiner maken + + + + Zoom in magnifying glass + Zoom in vergrootglas + + + + Zoom out magnifying glass + Uitzoomen vergrootglas + + + + Reset magnifying glass + Vergrootglas opnieuw instellen + + + + Toggle between fit to width and fit to height + Schakel tussen Aanpassen aan breedte en Aanpassen aan hoogte + + + + Autoscroll down + Automatisch naar beneden scrollen + + + + Autoscroll up + Automatisch omhoog scrollen + + + + Autoscroll forward, horizontal first + Automatisch vooruit scrollen, eerst horizontaal + + + + Autoscroll backward, horizontal first + Automatisch achteruit scrollen, eerst horizontaal + + + + Autoscroll forward, vertical first + Automatisch vooruit scrollen, eerst verticaal + + + + Autoscroll backward, vertical first + Automatisch achteruit scrollen, eerst verticaal + + + + Move down + Ga naar beneden + + + + Move up + Ga omhoog + + + + Move left + Ga naar links + + + + Move right + Ga naar rechts + + + + Go to the first page + Ga naar de eerste pagina + + + + Go to the last page + Ga naar de laatste pagina + + + + Offset double page to the left + Dubbele pagina naar links verschoven + + + + Offset double page to the right + Offset dubbele pagina naar rechts + + + + There is a new version available + Er is een nieuwe versie beschikbaar + + + + Do you want to download the new version? + Wilt u de nieuwe versie downloaden? + + + + Remind me in 14 days + Herinner mij er over 14 dagen aan + + + + Not now + Niet nu + + + + YACReader::TrayIconController + + + &Restore + &Herstellen + + + + Systray + Systeemvak + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary blijft actief in het systeemvak. Om het programma te beëindigen, kiest u <b>Quit</b> in het contextmenu van het systeemvakpictogram. + + + + YACReaderFieldEdit + + + + Click to overwrite + Klik hier om te overschrijven + + + + Restore to default + Standaardwaarden herstellen + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + Klik hier om te overschrijven + + + + Restore to default + Standaardwaarden herstellen + + + + YACReaderOptionsDialog + + + Save + Bewaar + + + + Cancel + Annuleren + + + + Edit shortcuts + Snelkoppelingen bewerken + + + + Shortcuts + Snelkoppelingen + + + + YACReaderSearchLineEdit + + + type to search + typ om te zoeken + + + + YACReaderSlider + + + Reset + Standaardwaarden terugzetten - QsLogging::Window + YACReaderTranslator - - &Pause - + + YACReader translator + YACReader-vertaler - - &Resume - + + + Translation + Vertaling - - Save log - + + clear + duidelijk - - Log file (*.log) - + + Service not available + Dienst niet beschikbaar diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_pt.ts b/YACReaderLibraryServer/yacreaderlibraryserver_pt.ts index a506a2a66..c62cc90e7 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_pt.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_pt.ts @@ -2,150 +2,3712 @@ - FileComic + ActionsShortcutsModel - - CRC error on page (%1): some of the pages will not be displayed correctly - + + None + Nenhum + + + AddLabelDialog - - Unknown error opening the file - + + Label name: + Nome da etiqueta: - - 7z not found - + + Choose a color: + Escolha uma cor: - - Format not supported - + + accept + aceitar + + + + cancel + cancelar - LogWindow + AddLibraryDialog + + + Comics folder : + Pasta dos quadrinhos : + + + + Library name : + Nome da Biblioteca : + - - Log window - + + Add + Adicionar - - &Pause - + + Cancel + Cancelar - - &Save - + + Add an existing library + Adicionar uma biblioteca existente + + + ApiKeyDialog - - C&lear - + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Antes de se conectar ao Comic Vine, você precisa de sua própria chave de API. Por favor, ganhe um <a href="http://www.comicvine.com/api/">aqui</a> grátis - - &Copy - + + Paste here your Comic Vine API key + Cole aqui sua chave API do Comic Vine - - Level: - + + Accept + Aceitar - - &Auto scroll - + + Cancel + Cancelar - QCoreApplication + AppearanceTabWidget - - -YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + + Color scheme + Esquema de cores + + + + System + Sistema + + + + Light + Luz + + + + Dark + Escuro + + + + Custom + Personalizado + + + + Remove + Remover + + + + Remove this user-imported theme + Remova este tema importado pelo usuário + + + + Light: + Luz: + + + + Dark: + Escuro: + + + + Custom: + Personalizado: + + + + Import theme... + Importar tema... + + + + Theme + Tema + + + + Theme editor + Editor de tema + + + + Open Theme Editor... + Abra o Editor de Tema... + + + + Theme editor error + Erro no editor de tema + + + + The current theme JSON could not be loaded. + O tema atual JSON não pôde ser carregado. + + + + Import theme + Importar tema + + + + JSON files (*.json);;All files (*) + Arquivos JSON (*.json);;Todos os arquivos (*) + + + + Could not import theme from: +%1 + Não foi possível importar o tema de: +%1 + + + + Could not import theme from: +%1 -This appplication supports persistent settings, to set them up edit this file %1 -To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md - +%2 + Não foi possível importar o tema de: +%1 + +%2 + + + + Import failed + Falha na importação - QObject + BookmarksDialog - - Trace - + + Lastest Page + Última Página - - Debug - + + Close + Fechar - - Info - + + Click on any image to go to the bookmark + Clique em qualquer imagem para ir para o marcador - - Warning - + + + Loading... + Carregando... + + + ClassicComicsView - - Error - + + Hide comic flow + Ocultar fluxo de quadrinhos + + + + ComicModel + + + yes + sim - - Fatal - + + no + não + + + + Title + Título + + + + File Name + Nome do arquivo + + + + Pages + Páginas + + + + Size + Tamanho + + + + Read + Ler + + + + Current Page + Página atual + + + + Publication Date + Data de publicação + + + + Rating + Avaliação + + + + Series + Série + + + + Volume + Tomo + + + + Story Arc + Arco de história + + + + ComicVineDialog + + + skip + pular + + + + back + voltar + + + + next + próximo + + + + search + procurar + + + + close + fechar + + + + + comic %1 of %2 - %3 + história em quadrinhos %1 de %2 - %3 + + + + + + Looking for volume... + Procurando volume... + + + + %1 comics selected + %1 quadrinhos selecionados + + + + Error connecting to ComicVine + Erro ao conectar-se ao ComicVine + + + + + Retrieving tags for : %1 + Recuperando tags para: %1 + + + + Retrieving volume info... + Recuperando informações de volume... + + + + Looking for comic... + Procurando quadrinhos... + + + + ContinuousPageWidget + + + Loading page %1 + Carregando página %1 + + + + CreateLibraryDialog + + + Comics folder : + Pasta dos quadrinhos : + + + + Library Name : + Nome da Biblioteca : + + + + Create + Criar + + + + Cancel + Cancelar + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Criar uma biblioteca pode levar vários minutos. Você pode interromper o processo e atualizar a biblioteca posteriormente para concluir a tarefa. + + + + Create new library + Criar uma nova biblioteca + + + + Path not found + Caminho não encontrado + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + O caminho selecionado não existe ou não é um caminho válido. Certifique-se de ter acesso de gravação a esta pasta + + + + EditShortcutsDialog + + + Restore defaults + Restaurar padrões + + + + To change a shortcut, double click in the key combination and type the new keys. + Para alterar um atalho, clique duas vezes na combinação de teclas e digite as novas teclas. + + + + Shortcuts settings + Configurações de atalhos + + + + Shortcut in use + Atalho em uso + + + + The shortcut "%1" is already assigned to other function + O atalho "%1" já está atribuído a outra função + + + + EmptyFolderWidget + + + This folder doesn't contain comics yet + Esta pasta ainda não contém quadrinhos + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + Este rótulo ainda não contém quadrinhos + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + Esta lista de leitura ainda não contém quadrinhos + + + + EmptySpecialListWidget + + + No favorites + Sem favoritos + + + + You are not reading anything yet, come on!! + Você ainda não está lendo nada, vamos lá!! + + + + There are no recent comics! + Não há quadrinhos recentes! + + + + ExportComicsInfoDialog + + + Output file : + Arquivo de saída: + + + + Create + Criar + + + + Cancel + Cancelar + + + + Export comics info + Exportar informações de quadrinhos + + + + Destination database name + Nome do banco de dados de destino + + + + Problem found while writing + Problema encontrado ao escrever + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + O caminho selecionado para o arquivo de saída não existe ou não é um caminho válido. Certifique-se de ter acesso de gravação a esta pasta + + + + ExportLibraryDialog + + + Output folder : + Pasta de saída : + + + + Create + Criar + + + + Cancel + Cancelar + + + + Create covers package + Criar pacote de capas + + + + Problem found while writing + Problema encontrado ao escrever + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + O caminho selecionado para o arquivo de saída não existe ou não é um caminho válido. Certifique-se de ter acesso de gravação a esta pasta + + + + Destination directory + Diretório de destino + + + + FileComic + + + CRC error on page (%1): some of the pages will not be displayed correctly + Erro CRC na página (%1): algumas páginas não serão exibidas corretamente + + + + Unknown error opening the file + Erro desconhecido ao abrir o arquivo + + + + 7z not found + 7z não encontrado + + + + Format not supported + Formato não suportado + + + + GoToDialog + + + Page : + Página : + + + + Go To + Ir Para + + + + Cancel + Cancelar + + + + + Total pages : + Total de páginas : + + + + Go to... + Ir para... + + + + GoToFlowToolBar + + + Page : + Página : - QsLogging::LogWindowModel + GridComicsView - - Time - + + Show info + Mostrar informações + + + HelpAboutDialog - - Level - + + About + Sobre - - Message - + + Help + Ajuda + + + + System info + Informações do sistema + + + + ImportComicsInfoDialog + + + Import comics info + Importar informações de quadrinhos + + + + Info database location : + Localização do banco de dados de informações: + + + + Import + Importar + + + + Cancel + Cancelar + + + + Comics info file (*.ydb) + Arquivo de informações de quadrinhos (*.ydb) + + + + ImportLibraryDialog + + + Library Name : + Nome da Biblioteca : + + + + Package location : + Local do pacote : + + + + Destination folder : + Pasta de destino : + + + + Unpack + Desempacotar + + + + Cancel + Cancelar + + + + Extract a catalog + Extrair um catálogo + + + + Compresed library covers (*.clc) + Capas da biblioteca compactada (*.clc) + + + + ImportWidget + + + stop + parar + + + + Some of the comics being added... + Alguns dos quadrinhos sendo adicionados... + + + + Importing comics + Importando quadrinhos + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary está criando uma nova biblioteca.</p><p>A criação de uma biblioteca pode levar vários minutos. Você pode interromper o processo e atualizar a biblioteca posteriormente para concluir a tarefa.</p> + + + + Updating the library + Atualizando a biblioteca + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>A biblioteca atual está sendo atualizada. Para atualizações mais rápidas, atualize suas bibliotecas com frequência.</p><p>Você pode interromper o processo e continuar atualizando esta biblioteca mais tarde.</p> + + + + Upgrading the library + Atualizando a biblioteca + + + + <p>The current library is being upgraded, please wait.</p> + <p>A biblioteca atual está sendo atualizada. Aguarde.</p> + + + + Scanning the library + Digitalizando a biblioteca + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>A biblioteca atual está sendo verificada em busca de informações de metadados XML legados.</p><p>Isso só será necessário uma vez e somente se a biblioteca tiver sido criada com YACReaderLibrary 9.8.2 ou anterior.</p> + + + + LibraryWindow + + + YACReader Library + Biblioteca YACReader + + + + + + comic + cômico + + + + + + manga + mangá + + + + + + western manga (left to right) + mangá ocidental (da esquerda para a direita) + + + + + + web comic + quadrinhos da web + + + + + + 4koma (top to botom) + 4koma (de cima para baixo) + + + + + + + Set type + Definir tipo + + + + Library + Biblioteca + + + + Folder + Pasta + + + + Comic + Quadrinhos + + + + Upgrade failed + Falha na atualização + + + + There were errors during library upgrade in: + Ocorreram erros durante a atualização da biblioteca em: + + + + Update needed + Atualização necessária + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Esta biblioteca foi criada com uma versão anterior do YACReaderLibrary. Ele precisa ser atualizado. Atualizar agora? + + + + Download new version + Baixe a nova versão + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Esta biblioteca foi criada com uma versão mais recente do YACReaderLibrary. Baixe a nova versão agora? + + + + Library not available + Biblioteca não disponível + + + + Library '%1' is no longer available. Do you want to remove it? + A biblioteca '%1' não está mais disponível. Você quer removê-lo? + + + + Old library + Biblioteca antiga + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + A biblioteca '%1' foi criada com uma versão mais antiga do YACReaderLibrary. Deve ser criado novamente. Deseja criar a biblioteca agora? + + + + + Copying comics... + Copiando quadrinhos... + + + + + Moving comics... + Quadrinhos em movimento... + + + + Add new folder + Adicionar nova pasta + + + + Folder name: + Nome da pasta: + + + + No folder selected + Nenhuma pasta selecionada + + + + Please, select a folder first + Por favor, selecione uma pasta primeiro + + + + Error in path + Erro no caminho + + + + There was an error accessing the folder's path + Ocorreu um erro ao acessar o caminho da pasta + + + + Delete folder + Excluir pasta + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + A pasta selecionada e todo o seu conteúdo serão excluídos do disco. Tem certeza? + + + + + Unable to delete + Não foi possível excluir + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Ocorreu um problema ao tentar excluir as pastas selecionadas. Por favor, verifique as permissões de gravação e certifique-se de que algum aplicativo esteja usando essas pastas ou qualquer um dos arquivos contidos. + + + + Add new reading lists + Adicione novas listas de leitura + + + + + List name: + Nome da lista: + + + + Delete list/label + Excluir lista/rótulo + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + O item selecionado será excluído, seus quadrinhos ou pastas NÃO serão excluídos do disco. Tem certeza? + + + + Rename list name + Renomear nome da lista + + + + Open folder... + Abrir pasta... + + + + Update folder + Atualizar pasta + + + + Rescan library for XML info + Digitalizar novamente a biblioteca em busca de informações XML + + + + Set as uncompleted + Definir como incompleto + + + + Set as completed + Definir como concluído + + + + Set as read + Definir como lido + + + + + Set as unread + Definir como não lido + + + + Set custom cover + Definir capa personalizada + + + + Delete custom cover + Excluir capa personalizada + + + + Save covers + Salvar capas + + + + You are adding too many libraries. + Você está adicionando muitas bibliotecas. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Você está adicionando muitas bibliotecas. + +Você provavelmente só precisa de uma biblioteca em sua pasta de quadrinhos de nível superior. Você pode navegar em qualquer subpasta usando a seção de pastas na barra lateral esquerda. + +YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve manter o número de bibliotecas baixo. + + + + + YACReader not found + YACReader não encontrado + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader não encontrado. YACReader deve ser instalado na mesma pasta que YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader não encontrado. Pode haver um problema com a instalação do YACReader. + + + + Error + Erro + + + + Error opening comic with third party reader. + Erro ao abrir o quadrinho com leitor de terceiros. + + + + Library not found + Biblioteca não encontrada + + + + The selected folder doesn't contain any library. + A pasta selecionada não contém nenhuma biblioteca. + + + + Are you sure? + Você tem certeza? + + + + Do you want remove + Você deseja remover + + + + library? + biblioteca? + + + + Remove and delete metadata + Remover e excluir metadados + + + + Library info + Informações da biblioteca + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Ocorreu um problema ao tentar excluir os quadrinhos selecionados. Por favor, verifique as permissões de gravação nos arquivos selecionados ou na pasta que os contém. + + + + Assign comics numbers + Atribuir números de quadrinhos + + + + Assign numbers starting in: + Atribua números começando em: + + + + Invalid image + Imagem inválida + + + + The selected file is not a valid image. + O arquivo selecionado não é uma imagem válida. + + + + Error saving cover + Erro ao salvar a capa + + + + There was an error saving the cover image. + Ocorreu um erro ao salvar a imagem da capa. + + + + Error creating the library + Erro ao criar a biblioteca + + + + Error updating the library + Erro ao atualizar a biblioteca + + + + Error opening the library + Erro ao abrir a biblioteca + + + + Delete comics + Excluir quadrinhos + + + + All the selected comics will be deleted from your disk. Are you sure? + Todos os quadrinhos selecionados serão excluídos do seu disco. Tem certeza? + + + + Remove comics + Remover quadrinhos + + + + Comics will only be deleted from the current label/list. Are you sure? + Os quadrinhos serão excluídos apenas do rótulo/lista atual. Tem certeza? + + + + Library name already exists + O nome da biblioteca já existe + + + + There is another library with the name '%1'. + Existe outra biblioteca com o nome '%1'. + + + + LibraryWindowActions + + + Create a new library + Criar uma nova biblioteca + + + + Open an existing library + Abrir uma biblioteca existente + + + + + Export comics info + Exportar informações de quadrinhos + + + + + Import comics info + Importar informações de quadrinhos + + + + Pack covers + Capas de pacote + + + + Pack the covers of the selected library + Pacote de capas da biblioteca selecionada + + + + Unpack covers + Desembale as capas + + + + Unpack a catalog + Desempacotar um catálogo + + + + Update library + Atualizar biblioteca + + + + Update current library + Atualizar biblioteca atual + + + + Rename library + Renomear biblioteca + + + + Rename current library + Renomear biblioteca atual + + + + Remove library + Remover biblioteca + + + + Remove current library from your collection + Remover biblioteca atual da sua coleção + + + + Rescan library for XML info + Digitalizar novamente a biblioteca em busca de informações XML + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Tenta encontrar informações XML incorporadas em arquivos de quadrinhos. Você só precisa fazer isso se a biblioteca foi criada com versões 9.8.2 ou anteriores ou se você estiver usando software de terceiros para incorporar informações XML nos arquivos. + + + + Show library info + Mostrar informações da biblioteca + + + + Show information about the current library + Mostrar informações sobre a biblioteca atual + + + + Open current comic + Abrir quadrinho atual + + + + Open current comic on YACReader + Abrir quadrinho atual no YACReader + + + + Save selected covers to... + Salvar capas selecionadas em... + + + + Save covers of the selected comics as JPG files + Salve as capas dos quadrinhos selecionados como arquivos JPG + + + + + Set as read + Definir como lido + + + + Set comic as read + Definir quadrinhos como lidos + + + + + Set as unread + Definir como não lido + + + + Set comic as unread + Definir quadrinhos como não lidos + + + + + manga + mangá + + + + Set issue as manga + Definir problema como mangá + + + + + comic + cômico + + + + Set issue as normal + Defina o problema como normal + + + + western manga + mangá ocidental + + + + Set issue as western manga + Definir problema como mangá ocidental + + + + + web comic + quadrinhos da web + + + + Set issue as web comic + Definir o problema como web comic + + + + + yonkoma + tira yonkoma + + + + Set issue as yonkoma + Definir problema como yonkoma + + + + Show/Hide marks + Mostrar/ocultar marcas + + + + Show or hide read marks + Mostrar ou ocultar marcas de leitura + + + + Show/Hide recent indicator + Mostrar/ocultar indicador recente + + + + Show or hide recent indicator + Mostrar ou ocultar indicador recente + + + + + Fullscreen mode on/off + Modo tela cheia ativado/desativado + + + + Help, About YACReader + Ajuda, Sobre o YACReader + + + + Add new folder + Adicionar nova pasta + + + + Add new folder to the current library + Adicionar nova pasta à biblioteca atual + + + + Delete folder + Excluir pasta + + + + Delete current folder from disk + Exclua a pasta atual do disco + + + + Select root node + Selecionar raiz + + + + Expand all nodes + Expandir todos + + + + Collapse all nodes + Recolher todos os nós + + + + Show options dialog + Mostrar opções + + + + Show comics server options dialog + Mostrar caixa de diálogo de opções do servidor de quadrinhos + + + + + Change between comics views + Alterar entre visualizações de quadrinhos + + + + Open folder... + Abrir pasta... + + + + Set as uncompleted + Definir como incompleto + + + + Set as completed + Definir como concluído + + + + Set custom cover + Definir capa personalizada + + + + Delete custom cover + Excluir capa personalizada + + + + western manga (left to right) + mangá ocidental (da esquerda para a direita) + + + + Open containing folder... + Abrir a pasta contendo... + + + + Reset comic rating + Redefinir classificação de quadrinhos + + + + Select all comics + Selecione todos os quadrinhos + + + + Edit + Editar + + + + Assign current order to comics + Atribuir ordem atual aos quadrinhos + + + + Update cover + Atualizar capa + + + + Delete selected comics + Excluir quadrinhos selecionados + + + + Delete metadata from selected comics + Excluir metadados dos quadrinhos selecionados + + + + Download tags from Comic Vine + Baixe tags do Comic Vine + + + + Focus search line + Linha de pesquisa de foco + + + + Focus comics view + Visualização de quadrinhos em foco + + + + Edit shortcuts + Editar atalhos + + + + &Quit + &Qfato + + + + Update folder + Atualizar pasta + + + + Update current folder + Atualizar pasta atual + + + + Scan legacy XML metadata + Digitalize metadados XML legados + + + + Add new reading list + Adicionar nova lista de leitura + + + + Add a new reading list to the current library + Adicione uma nova lista de leitura à biblioteca atual + + + + Remove reading list + Remover lista de leitura + + + + Remove current reading list from the library + Remover lista de leitura atual da biblioteca + + + + Add new label + Adicionar novo rótulo + + + + Add a new label to this library + Adicione um novo rótulo a esta biblioteca + + + + Rename selected list + Renomear lista selecionada + + + + Rename any selected labels or lists + Renomeie quaisquer rótulos ou listas selecionados + + + + Add to... + Adicionar à... + + + + Favorites + Favoritos + + + + Add selected comics to favorites list + Adicione quadrinhos selecionados à lista de favoritos + + + + LocalComicListModel + + + file name + nome do arquivo + + + + NoLibrariesWidget + + + You don't have any libraries yet + Você ainda não tem nenhuma biblioteca + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Você pode criar uma biblioteca em qualquer pasta, YACReaderLibrary importará todos os quadrinhos e pastas desta pasta. Se você já criou alguma biblioteca, poderá abri-la.</p><p>Não se esqueça de que você pode usar o YACReader como um aplicativo independente para ler quadrinhos em seu computador.</p> + + + + create your first library + crie sua primeira biblioteca + + + + add an existing one + adicione um existente + + + + NoSearchResultsWidget + + + No results + Nenhum resultado + + + + OptionsDialog + + + + General + Em geral + + + + + Libraries + Bibliotecas + + + + Comic Flow + Fluxo de quadrinhos + + + + Grid view + Visualização em grade + + + + + Appearance + Aparência + + + + + Options + Opções + + + + + Language + Idioma + + + + + Application language + Idioma do aplicativo + + + + + System default + Padrão do sistema + + + + Tray icon settings (experimental) + Configurações do ícone da bandeja (experimental) + + + + Close to tray + Perto da bandeja + + + + Start into the system tray + Comece na bandeja do sistema + + + + Edit Comic Vine API key + Editar chave da API Comic Vine + + + + Comic Vine API key + Chave de API do Comic Vine + + + + ComicInfo.xml legacy support + Suporte legado ComicInfo.xml + + + + Import metadata from ComicInfo.xml when adding new comics + Importe metadados de ComicInfo.xml ao adicionar novos quadrinhos + + + + Consider 'recent' items added or updated since X days ago + Considere itens 'recentes' adicionados ou atualizados há X dias + + + + Third party reader + Leitor de terceiros + + + + Write {comic_file_path} where the path should go in the command + Escreva {comic_file_path} onde o caminho deve ir no comando + + + + + Clear + Claro + + + + Update libraries at startup + Atualizar bibliotecas na inicialização + + + + Try to detect changes automatically + Tente detectar alterações automaticamente + + + + Update libraries periodically + Atualize bibliotecas periodicamente + + + + Interval: + Intervalo: + + + + 30 minutes + 30 minutos + + + + 1 hour + 1 hora + + + + 2 hours + 2 horas + + + + 4 hours + 4 horas + + + + 8 hours + 8 horas + + + + 12 hours + 12 horas + + + + daily + diário + + + + Update libraries at certain time + Atualizar bibliotecas em determinado momento + + + + Time: + Tempo: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + AVISO! Durante as atualizações da biblioteca, as gravações no banco de dados são desativadas! +Não agende atualizações enquanto estiver usando o aplicativo ativamente. +Durante as atualizações automáticas, o aplicativo bloqueará algumas ações até que a atualização seja concluída. +Para interromper uma atualização automática, toque no indicador de carregamento próximo ao título Bibliotecas. + + + + Modifications detection + Detecção de modificações + + + + Compare the modified date of files when updating a library (not recommended) + Compare a data de modificação dos arquivos ao atualizar uma biblioteca (não recomendado) + + + + Enable background image + Ativar imagem de fundo + + + + Opacity level + Nível de opacidade + + + + Blur level + Nível de desfoque + + + + Use selected comic cover as background + Use a capa de quadrinhos selecionada como plano de fundo + + + + Restore defautls + Restaurar padrões + + + + Background + Fundo + + + + Display continue reading banner + Exibir banner para continuar lendo + + + + Display current comic banner + Exibir banner de quadrinhos atual + + + + Continue reading + Continuar lendo + + + + My comics path + Meu caminho de quadrinhos + + + + Display + Mostrar + + + + Show time in current page information label + Mostrar hora no rótulo de informações da página atual + + + + "Go to flow" size + Tamanho do "Ir para cheia" + + + + Background color + Cor de fundo + + + + Choose + Escolher + + + + Scroll behaviour + Comportamento de rolagem + + + + Disable scroll animations and smooth scrolling + Desative animações de rolagem e rolagem suave + + + + Do not turn page using scroll + Não vire a página usando scroll + + + + Use single scroll step to turn page + Use uma única etapa de rolagem para virar a página + + + + Mouse mode + Modo mouse + + + + Only Back/Forward buttons can turn pages + Apenas os botões Voltar/Avançar podem virar páginas + + + + Use the Left/Right buttons to turn pages. + Use os botões Esquerda/Direita para virar as páginas. + + + + Click left or right half of the screen to turn pages. + Clique na metade esquerda ou direita da tela para virar as páginas. + + + + Quick Navigation Mode + Modo de navegação rápida + + + + Disable mouse over activation + Desativar ativação do mouse sobre + + + + Brightness + Brilho + + + + Contrast + Contraste + + + + Gamma + Gama + + + + Reset + Reiniciar + + + + Image options + Opções de imagem + + + + Fit options + Opções de ajuste + + + + Enlarge images to fit width/height + Amplie as imagens para caber na largura/altura + + + + Double Page options + Opções de página dupla + + + + Show covers as single page + Mostrar capas como página única + + + + Scaling + Dimensionamento + + + + Scaling method + Método de dimensionamento + + + + Nearest (fast, low quality) + Mais próximo (rápido, baixa qualidade) + + + + Bilinear + Interpola??o bilinear + + + + Lanczos (better quality) + Lanczos (melhor qualidade) + + + + Page Flow + Fluxo de página + + + + Image adjustment + Ajuste de imagem + + + + + Restart is needed + Reiniciar é necessário + + + + Comics directory + Diretório de quadrinhos + + + + PropertiesDialog + + + General info + Informações gerais + + + + Plot + Trama + + + + Authors + Autores + + + + Publishing + Publicação + + + + Notes + Notas + + + + Cover page + Página de rosto + + + + Load previous page as cover + Carregar página anterior como capa + + + + Load next page as cover + Carregar a próxima página como capa + + + + Reset cover to the default image + Redefinir a capa para a imagem padrão + + + + Load custom cover image + Carregar imagem de capa personalizada + + + + Series: + Série: + + + + Title: + Título: + + + + + + of: + de: + + + + Issue number: + Número de emissão: + + + + Volume: + Tomo: + + + + Arc number: + Número do arco: + + + + Story arc: + Arco da história: + + + + alt. number: + alt. número: + + + + Alternate series: + Série alternativa: + + + + Series Group: + Grupo de séries: + + + + Genre: + Gênero: + + + + Size: + Tamanho: + + + + Writer(s): + Escritor(es): + + + + Penciller(s): + Desenhador(es): + + + + Inker(s): + Tinteiro(s): + + + + Colorist(s): + Colorista(s): + + + + Letterer(s): + Letrista(s): + + + + Cover Artist(s): + Artista(s) da capa: + + + + Editor(s): + Editor(es): + + + + Imprint: + Imprimir: + + + + Day: + Dia: + + + + Month: + Mês: + + + + Year: + Ano: + + + + Publisher: + Editor: + + + + Format: + Formatar: + + + + Color/BW: + Cor/PB: + + + + Age rating: + Classificação etária: + + + + Type: + Tipo: + + + + Language (ISO): + Idioma (ISO): + + + + Synopsis: + Sinopse: + + + + Characters: + Personagens: + + + + Teams: + Equipes: + + + + Locations: + Locais: + + + + Main character or team: + Personagem principal ou equipe: + + + + Review: + Análise: + + + + Notes: + Notas: + + + + Tags: + Etiquetas: + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Link do Comic Vine: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> visualizar </a> + + + + Not found + Não encontrado + + + + Comic not found. You should update your library. + Quadrinho não encontrado. Você deve atualizar sua biblioteca. + + + + Edit comic information + Editar informações dos quadrinhos + + + + Edit selected comics information + Edite as informações dos quadrinhos selecionados + + + + Invalid cover + Capa inválida + + + + The image is invalid. + A imagem é inválida. + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer é a versão sem cabeça (sem interface gráfica) do YACReaderLibrary. + +Este aplicativo suporta configurações persistentes, para configurá-las edite este arquivo %1 +Para saber mais sobre as configurações disponíveis, verifique a documentação em https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject + + + Trace + Rastreamento + + + + Debug + Depurar + + + + Info + Informações + + + + Warning + Aviso + + + + Error + Erro + + + + Fatal + Cr?tico + + + + Select custom cover + Selecione a capa personalizada + + + + Images (%1) + Imagens (%1) + + + + 7z lib not found + Biblioteca 7z não encontrada + + + + unable to load 7z lib from ./utils + não é possível carregar 7z lib de ./utils + + + + The file could not be read or is not valid JSON. + O arquivo não pôde ser lido ou não é JSON válido. + + + + This theme is for %1, not %2. + Este tema é para %1, não %2. + + + + Libraries + Bibliotecas + + + + Folders + Pastas + + + + Reading Lists + Listas de leitura + + + + RenameLibraryDialog + + + New Library Name : + Novo nome da biblioteca : + + + + Rename + Renomear + + + + Cancel + Cancelar + + + + Rename current library + Renomear biblioteca atual + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + Número de volumes encontrados: %1 + + + + + page %1 of %2 + página %1 de %2 + + + + Number of %1 found : %2 + Número de %1 encontrado: %2 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + Forneça algumas informações adicionais para esta história em quadrinhos. + + + + Series: + Série: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Use a pesquisa de correspondência exata. Desative se quiser encontrar volumes que correspondam a algumas das palavras do nome. + + + + SearchVolume + + + Please provide some additional information. + Forneça algumas informações adicionais. + + + + Series: + Série: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Use a pesquisa de correspondência exata. Desative se quiser encontrar volumes que correspondam a algumas das palavras do nome. + + + + SelectComic + + + Please, select the right comic info. + Por favor, selecione as informações corretas dos quadrinhos. + + + + comics + quadrinhos + + + + loading cover + tampa de carregamento + + + + loading description + descrição de carregamento + + + + comic description unavailable + descrição do quadrinho indisponível + + + + SelectVolume + + + Please, select the right series for your comic. + Por favor, selecione a série certa para o seu quadrinho. + + + + Filter: + Filtro: + + + + volumes + tomos + + + + Nothing found, clear the filter if any. + Nada encontrado, limpe o filtro, se houver. + + + + loading cover + tampa de carregamento + + + + loading description + descrição de carregamento + + + + volume description unavailable + descrição do volume indisponível + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + Você está tentando obter informações sobre vários quadrinhos ao mesmo tempo. Eles fazem parte da mesma série? + + + + yes + sim + + + + no + não + + + + ServerConfigDialog + + + set port + definir porta + + + + Server connectivity information + Informações de conectividade do servidor + + + + Scan it! + Digitalize! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + O YACReader está disponível para dispositivos iOS e Android.<br/>Descubra-o para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + + + + Choose an IP address + Escolha um endereço IP + + + + Port + Porta + + + + enable the server + habilitar o servidor + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + Por favor, classifique a lista de quadrinhos à esquerda até que corresponda às informações dos quadrinhos. + + + + sort comics to match comic information + classifique os quadrinhos para corresponder às informações dos quadrinhos + + + + issues + problemas + + + + remove selected comics + remover quadrinhos selecionados + + + + restore all removed comics + restaurar todos os quadrinhos removidos + + + + ThemeEditorDialog + + + Theme Editor + Editor de Tema + + + + + + + + + + + - + - + + + + i + eu + + + + Expand all + Expandir tudo + + + + Collapse all + Recolher tudo + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Segure para piscar o valor selecionado na UI (magenta/alternado/0↔10). Os lançamentos restauram o original. + + + + Search… + Procurar… + + + + Light + Luz + + + + Dark + Escuro + + + + ID: + EU IA: + + + + Display name: + Nome de exibição: + + + + Variant: + Variante: + + + + Theme info + Informações do tema + + + + Parameter + Parâmetro + + + + Value + Valor + + + + Save and apply + Salvar e aplicar + + + + Export to file... + Exportar para arquivo... + + + + Load from file... + Carregar do arquivo... + + + + Close + Fechar + + + + Double-click to edit color + Clique duas vezes para editar a cor + + + + + + + + + true + verdadeiro + + + + + + + false + falso + + + + Double-click to toggle + Clique duas vezes para alternar + + + + Double-click to edit value + Clique duas vezes para editar o valor + + + + + + Edit: %1 + Editar: %1 + + + + Save theme + Salvar tema + + + + + JSON files (*.json);;All files (*) + Arquivos JSON (*.json);;Todos os arquivos (*) + + + + Save failed + Falha ao salvar + + + + Could not open file for writing: +%1 + Não foi possível abrir o arquivo para gravação: +%1 + + + + Load theme + Carregar tema + + + + + + Load failed + Falha no carregamento + + + + Could not open file: +%1 + Não foi possível abrir o arquivo: +%1 + + + + Invalid JSON: +%1 + JSON inválido: +%1 + + + + Expected a JSON object. + Esperava um objeto JSON. + + + + TitleHeader + + + SEARCH + PROCURAR + + + + UpdateLibraryDialog + + + Updating.... + Atualizando.... + + + + Cancel + Cancelar + + + + Update library + Atualizar biblioteca + + + + Viewer + + + + Press 'O' to open comic. + Pressione 'O' para abrir um quadrinho. + + + + Not found + Não encontrado + + + + Comic not found + Quadrinho não encontrado + + + + Error opening comic + Erro ao abrir quadrinho + + + + CRC Error + Erro CRC + + + + Loading...please wait! + Carregando... por favor, aguarde! + + + + Page not available! + Página não disponível! + + + + Cover! + Cobrir! + + + + Last page! + Última página! + + + + VolumeComicsModel + + + title + título + + + + VolumesModel + + + year + ano + + + + issues + problemas + + + + publisher + editor + + + + YACReader3DFlowConfigWidget + + + Presets: + Predefinições: + + + + Classic look + Aparência clássica + + + + Stripe look + Olhar lista + + + + Overlapped Stripe look + Olhar lista sobreposta + + + + Modern look + Aparência moderna + + + + Roulette look + Aparência de roleta + + + + Show advanced settings + Mostrar configurações avançadas + + + + Custom: + Personalizado: + + + + View angle + Ângulo de visão + + + + Position + Posição + + + + Cover gap + Cubra a lacuna + + + + Central gap + Lacuna central + + + + Zoom + Amplia??o + + + + Y offset + Deslocamento Y + + + + Z offset + Deslocamento Z + + + + Cover Angle + Ângulo de cobertura + + + + Visibility + Visibilidade + + + + Light + Luz + + + + Max angle + Ângulo máximo + + + + Low Performance + Baixo desempenho + + + + High Performance + Alto desempenho + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Use VSync (melhora a qualidade da imagem em modo tela cheia, pior desempenho) + + + + Performance: + Desempenho: + + + + YACReader::MainWindowViewer + + + &Open + &Abrir + + + + Open a comic + Abrir um quadrinho + + + + New instance + Nova instância + + + + Open Folder + Abrir Pasta + + + + Open image folder + Abra a pasta de imagens + + + + Open latest comic + Abra o último quadrinho + + + + Open the latest comic opened in the previous reading session + Abra o último quadrinho aberto na sessão de leitura anterior + + + + Clear + Claro + + + + Clear open recent list + Limpar lista recente aberta + + + + Save + Salvar + + + + + Save current page + Salvar página atual + + + + Previous Comic + Quadrinho Anterior + + + + + + Open previous comic + Abrir quadrinho anterior + + + + Next Comic + Próximo Quadrinho + + + + + + Open next comic + Abrir próximo quadrinho + + + + &Previous + A&nterior + + + + + + Go to previous page + Ir para a página anterior + + + + &Next + &Próxima + + + + + + Go to next page + Ir para a próxima página + + + + Fit Height + Ajustar Altura + + + + Fit image to height + Ajustar imagem à altura + + + + Fit Width + Ajustar à Largura + + + + Fit image to width + Ajustar imagem à largura + + + + Show full size + Mostrar tamanho grande + + + + Fit to page + Ajustar à página + + + + Continuous scroll + Rolagem contínua + + + + Switch to continuous scroll mode + Mudar para o modo de rolagem contínua + + + + Reset zoom + Redefinir zoom + + + + Show zoom slider + Mostrar controle deslizante de zoom + + + + Zoom+ + Ampliar + + + + Zoom- + Reduzir + + + + Rotate image to the left + Girar imagem à esquerda + + + + Rotate image to the right + Girar imagem à direita + + + + Double page mode + Modo dupla página + + + + Switch to double page mode + Alternar para o modo dupla página + + + + Double page manga mode + Modo mangá de página dupla + + + + Reverse reading order in double page mode + Ordem de leitura inversa no modo de página dupla + + + + Go To + Ir Para + + + + Go to page ... + Ir para a página... + + + + Options + Opções + + + + YACReader options + Opções do YACReader + + + + + Help + Ajuda + + + + Help, About YACReader + Ajuda, Sobre o YACReader + + + + Magnifying glass + Lupa + + + + Switch Magnifying glass + Alternar Lupa + + + + Set bookmark + Definir marcador + + + + Set a bookmark on the current page + Definir um marcador na página atual + + + + Show bookmarks + Mostrar marcadores + + + + Show the bookmarks of the current comic + Mostrar os marcadores do quadrinho atual + + + + Show keyboard shortcuts + Mostrar teclas de atalhos + + + + Show Info + Mostrar Informações + + + + Close + Fechar + + + + Show Dictionary + Mostrar dicionário + + + + Show go to flow + Mostrar ir para o fluxo + + + + Edit shortcuts + Editar atalhos + + + + &File + &Arquivo + + + + + Open recent + Abrir recente + + + + File + Arquivo + + + + Edit + Editar + + + + View + Visualizar + + + + Go + Ir + + + + Window + Janela + + + + + + Open Comic + Abrir Quadrinho + + + + + + Comic files + Arquivos de quadrinhos + + + + Open folder + Abrir pasta + + + + page_%1.jpg + página_%1.jpg + + + + Image files (*.jpg) + Arquivos de imagem (*.jpg) + + + + + Comics + Quadrinhos + + + + + General + Em geral + + + + + Magnifiying glass + Lupa + + + + + Page adjustement + Ajuste de página + + + + + Reading + Leitura + + + + Toggle fullscreen mode + Alternar modo de tela cheia + + + + Hide/show toolbar + Ocultar/mostrar barra de ferramentas + + + + Size up magnifying glass + Dimensione a lupa + + + + Size down magnifying glass + Diminuir o tamanho da lupa + + + + Zoom in magnifying glass + Zoom na lupa + + + + Zoom out magnifying glass + Diminuir o zoom da lupa + + + + Reset magnifying glass + Redefinir lupa + + + + Toggle between fit to width and fit to height + Alternar entre ajustar à largura e ajustar à altura + + + + Autoscroll down + Rolagem automática para baixo + + + + Autoscroll up + Rolagem automática para cima + + + + Autoscroll forward, horizontal first + Rolagem automática para frente, horizontal primeiro + + + + Autoscroll backward, horizontal first + Rolagem automática para trás, horizontal primeiro + + + + Autoscroll forward, vertical first + Rolagem automática para frente, vertical primeiro + + + + Autoscroll backward, vertical first + Rolagem automática para trás, vertical primeiro + + + + Move down + Mover para baixo + + + + Move up + Subir + + + + Move left + Mover para a esquerda + + + + Move right + Mover para a direita + + + + Go to the first page + Vá para a primeira página + + + + Go to the last page + Ir para a última página + + + + Offset double page to the left + Deslocar página dupla para a esquerda + + + + Offset double page to the right + Deslocar página dupla para a direita + + + + There is a new version available + Há uma nova versão disponível + + + + Do you want to download the new version? + Você deseja baixar a nova versão? + + + + Remind me in 14 days + Lembre-me em 14 dias + + + + Not now + Agora não + + + + YACReader::TrayIconController + + + &Restore + &Rloja + + + + Systray + Bandeja do sistema + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary continuará em execução na bandeja do sistema. Para encerrar o programa, escolha <b>Quit</b> no menu de contexto do ícone da bandeja do sistema. + + + + YACReaderFieldEdit + + + + Click to overwrite + Clique para substituir + + + + Restore to default + Restaurar para o padrão + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + Clique para substituir + + + + Restore to default + Restaurar para o padrão + + + + YACReaderOptionsDialog + + + Save + Salvar + + + + Cancel + Cancelar + + + + Edit shortcuts + Editar atalhos + + + + Shortcuts + Atalhos + + + + YACReaderSearchLineEdit + + + type to search + digite para pesquisar + + + + YACReaderSlider + + + Reset + Reiniciar - QsLogging::Window + YACReaderTranslator - - &Pause - + + YACReader translator + Tradutor YACReader - - &Resume - + + + Translation + Tradução - - Save log - + + clear + claro - - Log file (*.log) - + + Service not available + Serviço não disponível diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_ru.ts b/YACReaderLibraryServer/yacreaderlibraryserver_ru.ts index fc4f9988b..05e5aea42 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_ru.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_ru.ts @@ -2,150 +2,3712 @@ - FileComic + ActionsShortcutsModel - - CRC error on page (%1): some of the pages will not be displayed correctly - + + None + Никто + + + AddLabelDialog - - Unknown error opening the file - + + Label name: + Название ярлыка: - - 7z not found - + + Choose a color: + Выбрать цвет: - - Format not supported - + + accept + добавить + + + + cancel + отменить - LogWindow + AddLibraryDialog + + + Comics folder : + Папка комиксов : + + + + Library name : + Имя библиотеки : + - - Log window - + + Add + Добавить - - &Pause - + + Cancel + Отмена - - &Save - + + Add an existing library + Добавить в существующую библиотеку + + + ApiKeyDialog - - C&lear - + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Для подключения к Comic Vine вам потребуется ваш личный API ключ. Приобретите его бесплатно вот <a href="http://www.comicvine.com/api/">здесь</a> - - &Copy - + + Paste here your Comic Vine API key + Вставьте сюда ваш Comic Vine API ключ - - Level: - + + Accept + Принять - - &Auto scroll - + + Cancel + Отмена - QCoreApplication + AppearanceTabWidget - - -YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + + Color scheme + Цветовая гамма + + + + System + Система + + + + Light + Осветить + + + + Dark + Темный + + + + Custom + Обычай + + + + Remove + Удалять + + + + Remove this user-imported theme + Удалить эту импортированную пользователем тему + + + + Light: + Свет: + + + + Dark: + Темный: + + + + Custom: + Пользовательский: + + + + Import theme... + Импортировать тему... + + + + Theme + Тема + + + + Theme editor + Редактор тем + + + + Open Theme Editor... + Открыть редактор тем... + + + + Theme editor error + Ошибка редактора темы + + + + The current theme JSON could not be loaded. + Не удалось загрузить JSON текущей темы. + + + + Import theme + Импортировать тему + + + + JSON files (*.json);;All files (*) + Файлы JSON (*.json);;Все файлы (*) + + + + Could not import theme from: +%1 + Не удалось импортировать тему из: +%1 + + + + Could not import theme from: +%1 -This appplication supports persistent settings, to set them up edit this file %1 -To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md - +%2 + Не удалось импортировать тему из: +%1 + +%2 + + + + Import failed + Импорт не удался - QObject + BookmarksDialog - - Trace - + + Lastest Page + Последняя страница - - Debug - + + Close + Закрыть - - Info - + + Click on any image to go to the bookmark + Нажмите на любое изображение чтобы перейти к закладке - - Warning - + + + Loading... + Загрузка... + + + ClassicComicsView - - Error - + + Hide comic flow + Показать/скрыть поток комиксов + + + + ComicModel + + + yes + да - - Fatal - + + no + нет + + + + Title + Заголовок + + + + File Name + Имя файла + + + + Pages + Всего страниц + + + + Size + Размер + + + + Read + Прочитано + + + + Current Page + Текущая страница + + + + Publication Date + Дата публикации + + + + Rating + Рейтинг + + + + Series + Ряд + + + + Volume + Объем + + + + Story Arc + Сюжетная арка + + + + ComicVineDialog + + + skip + пропустить + + + + back + назад + + + + next + дальше + + + + search + искать + + + + close + закрыть + + + + + comic %1 of %2 - %3 + комикс %1 of %2 - %3 + + + + + + Looking for volume... + Поиск информации... + + + + %1 comics selected + %1 было выбрано + + + + Error connecting to ComicVine + Ошибка поключения к ComicVine + + + + + Retrieving tags for : %1 + Получение тегов для : %1 + + + + Retrieving volume info... + Получение информации... + + + + Looking for comic... + Поиск комикса... + + + + ContinuousPageWidget + + + Loading page %1 + Загрузка страницы %1 + + + + CreateLibraryDialog + + + Comics folder : + Папка комиксов : + + + + Library Name : + Имя библиотеки: + + + + Create + Создать + + + + Cancel + Отмена + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Создание библиотеки может занять несколько минут. Вы можете остановить процесс и обновить библиотеку позже для завершения задачи. + + + + Create new library + Создать новую библиотеку + + + + Path not found + Путь не найден + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + Выбранный путь отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке + + + + EditShortcutsDialog + + + Restore defaults + Восстановить значения по умолчанию + + + + To change a shortcut, double click in the key combination and type the new keys. + Чтобы изменить горячую клавишу дважды щелкните по выбранной комбинации клавиш и введите новые сочетания клавиш. + + + + Shortcuts settings + Горячие клавиши + + + + Shortcut in use + Горячая клавиша уже занята + + + + The shortcut "%1" is already assigned to other function + Сочетание клавиш "%1" уже назначено для другой функции + + + + EmptyFolderWidget + + + This folder doesn't contain comics yet + В этой папке еще нет комиксов + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + Этот ярлык пока ничего не содержит + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + Этот список чтения пока ничего не содержит + + + + EmptySpecialListWidget + + + No favorites + Нет избранного + + + + You are not reading anything yet, come on!! + Вы пока ничего не читаете. Может самое время почитать? + + + + There are no recent comics! + Свежих комиксов нет! + + + + ExportComicsInfoDialog + + + Output file : + Выходной файл (*.ydb) : + + + + Create + Создать + + + + Cancel + Отмена + + + + Export comics info + Экспортировать информацию комикса + + + + Destination database name + Имя этой базы данных + + + + Problem found while writing + Обнаружена Ошибка записи + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Выбранный путь для импортируемого файла отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке + + + + ExportLibraryDialog + + + Output folder : + Папка вывода : + + + + Create + Создать + + + + Cancel + Отмена + + + + Create covers package + Создать комплект обложек + + + + Problem found while writing + Обнаружена Ошибка записи + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Выбранный путь для импортируемого файла отсутствует, либо неверен. Убедитесь , что у вас есть доступ к этой папке + + + + Destination directory + Назначенная директория + + + + FileComic + + + CRC error on page (%1): some of the pages will not be displayed correctly + Ошибка контрольной суммы CRC на странице (%1): некоторые страницы будут отображаться неправильно + + + + Unknown error opening the file + Неизвестная ошибка при открытии файла + + + + 7z not found + 7z не найден + + + + Format not supported + Формат не поддерживается + + + + GoToDialog + + + Page : + Страница : + + + + Go To + Перейти к странице... + + + + Cancel + Отмена + + + + + Total pages : + Общее количество страниц : + + + + Go to... + Перейти к странице... + + + + GoToFlowToolBar + + + Page : + Страница : - QsLogging::LogWindowModel + GridComicsView - - Time - + + Show info + Показать информацию + + + HelpAboutDialog - - Level - + + About + О программе - - Message - + + Help + Справка + + + + System info + Информация о системе + + + + ImportComicsInfoDialog + + + Import comics info + Импортировать информацию комикса + + + + Info database location : + Путь к файлу (*.ydb) : + + + + Import + Импортировать + + + + Cancel + Отмена + + + + Comics info file (*.ydb) + Инфо файл комикса (*.ydb) + + + + ImportLibraryDialog + + + Library Name : + Имя библиотеки: + + + + Package location : + Местоположение комплекта : + + + + Destination folder : + Папка назначения : + + + + Unpack + Распаковать + + + + Cancel + Отмена + + + + Extract a catalog + Извлечь каталог + + + + Compresed library covers (*.clc) + Сжатая библиотека обложек (*.clc) + + + + ImportWidget + + + stop + Остановить + + + + Some of the comics being added... + Поиск новых комиксов... + + + + Importing comics + Импорт комиксов + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary сейчас создает библиотеку.</p><p> Создание библиотеки может занять несколько минут. Вы можете остановить процесс и обновить библиотеку позже для завершения задачи.</p> + + + + Updating the library + Обновление библиотеки + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>Текущая библиотека обновляется. Для более быстрого обновления в дальнейшем старайтесь почаще обновлять вашу библиотеку после добавления новых комиксов.</p><p>Вы можете остановить этот процесс и продолжить обновление этой библиотеки позже.</p> + + + + Upgrading the library + Обновление библиотеки + + + + <p>The current library is being upgraded, please wait.</p> + <p>Текущая библиотека обновляется, подождите.</p> + + + + Scanning the library + Сканирование библиотеки + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>Текущая библиотека сканируется на предмет устаревших метаданных XML.</p><p>Это необходимо только один раз и только в том случае, если библиотека была создана с помощью YACReaderLibrary 9.8.2 или более ранней версии.</p> + + + + LibraryWindow + + + YACReader Library + Библиотека YACReader + + + + + + comic + комикс + + + + + + manga + манга + + + + + + western manga (left to right) + западная манга (слева направо) + + + + + + web comic + веб-комикс + + + + + + 4koma (top to botom) + 4кома (сверху вниз) + + + + + + + Set type + Тип установки + + + + Library + Библиотека + + + + Folder + Папка + + + + Comic + Комикс + + + + Upgrade failed + Обновление не удалось + + + + There were errors during library upgrade in: + При обновлении библиотеки возникли ошибки: + + + + Update needed + Необходимо обновление + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Эта библиотека была создана с предыдущей версией YACReaderLibrary. Она должна быть обновлена. Обновить сейчас? + + + + Download new version + Загрузить новую версию + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Эта библиотека была создана новой версией YACReaderLibrary. Скачать новую версию сейчас? + + + + Library not available + Библиотека не доступна + + + + Library '%1' is no longer available. Do you want to remove it? + Библиотека '%1' больше не доступна. Вы хотите удалить ее? + + + + Old library + Библиотека из старой версии YACreader + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Библиотека '%1' была создана старой версией YACReaderLibrary. Она должна быть вновь создана. Вы хотите создать библиотеку сейчас? + + + + + Copying comics... + Скопировать комиксы... + + + + + Moving comics... + Переместить комиксы... + + + + Add new folder + Добавить новую папку + + + + Folder name: + Имя папки: + + + + No folder selected + Ни одна папка не была выбрана + + + + Please, select a folder first + Пожалуйста, сначала выберите папку + + + + Error in path + Ошибка в пути + + + + There was an error accessing the folder's path + Ошибка доступа к пути папки + + + + Delete folder + Удалить папку + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + Выбранная папка и все ее содержимое будет удалено с вашего жёсткого диска. Вы уверены? + + + + + Unable to delete + Не удалось удалить + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Возникла проблема при удалении выбранных папок. Пожалуйста, проверьте права на запись и убедитесь что другие приложения не используют эти папки или файлы. + + + + Add new reading lists + Добавить новый список чтения + + + + + List name: + Имя списка: + + + + Delete list/label + Удалить список/ярлык + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + Выбранные элементы будут удалены, ваши комиксы или папки НЕ БУДУТ удалены с вашего жёсткого диска. Вы уверены? + + + + Rename list name + Изменить имя списка + + + + Open folder... + Открыть папку... + + + + Update folder + Обновить папку + + + + Rescan library for XML info + Повторное сканирование библиотеки для получения информации XML + + + + Set as uncompleted + Отметить как не завершено + + + + Set as completed + Отметить как завершено + + + + Set as read + Отметить как прочитано + + + + + Set as unread + Отметить как не прочитано + + + + Set custom cover + Установить собственную обложку + + + + Delete custom cover + Удалить пользовательскую обложку + + + + Save covers + Сохранить обложки + + + + You are adding too many libraries. + Вы добавляете слишком много библиотек. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Вы добавляете слишком много библиотек. + +Вероятно, вам нужна только одна библиотека в папке комиксов верхнего уровня, вы можете просматривать любые подпапки, используя раздел папок на левой боковой панели. + +YACReaderLibrary не помешает вам создать больше библиотек, но вы должны иметь не большое количество библиотек. + + + + + YACReader not found + YACReader не найден + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader не найден. YACReader должен быть установлен в ту же папку, что и YACReaderLibrary. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader не найден. Возможно, возникла проблема с установкой YACReader. + + + + Error + Ошибка + + + + Error opening comic with third party reader. + Ошибка при открытии комикса с помощью сторонней программы чтения. + + + + Library not found + Библиотека не найдена + + + + The selected folder doesn't contain any library. + Выбранная папка не содержит ни одной библиотеки. + + + + Are you sure? + Вы уверены? + + + + Do you want remove + Вы хотите удалить библиотеку + + + + library? + ? + + + + Remove and delete metadata + Удаление метаданных + + + + Library info + Информация о библиотеке + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Возникла проблема при удалении выбранных комиксов. Пожалуйста, проверьте права на запись для выбранных файлов или содержащую их папку. + + + + Assign comics numbers + Порядковый номер + + + + Assign numbers starting in: + Назначить порядковый номер начиная с: + + + + Invalid image + Неверное изображение + + + + The selected file is not a valid image. + Выбранный файл не является допустимым изображением. + + + + Error saving cover + Не удалось сохранить обложку. + + + + There was an error saving the cover image. + Не удалось сохранить изображение обложки. + + + + Error creating the library + Ошибка создания библиотеки + + + + Error updating the library + Ошибка обновления библиотеки + + + + Error opening the library + Ошибка открытия библиотеки + + + + Delete comics + Удалить комиксы + + + + All the selected comics will be deleted from your disk. Are you sure? + Все выбранные комиксы будут удалены с вашего жёсткого диска. Вы уверены? + + + + Remove comics + Убрать комиксы + + + + Comics will only be deleted from the current label/list. Are you sure? + Комиксы будут удалены только из выбранного списка/ярлыка. Вы уверены? + + + + Library name already exists + Имя папки уже используется + + + + There is another library with the name '%1'. + Уже существует другая папка с именем '%1'. + + + + LibraryWindowActions + + + Create a new library + Создать новую библиотеку + + + + Open an existing library + Открыть существующую библиотеку + + + + + Export comics info + Экспортировать информацию комикса + + + + + Import comics info + Импортировать информацию комикса + + + + Pack covers + Запаковать обложки + + + + Pack the covers of the selected library + Запаковать обложки выбранной библиотеки + + + + Unpack covers + Распаковать обложки + + + + Unpack a catalog + Распаковать каталог + + + + Update library + Обновить библиотеку + + + + Update current library + Обновить эту библиотеку + + + + Rename library + Переименовать библиотеку + + + + Rename current library + Переименовать эту библиотеку + + + + Remove library + Удалить библиотеку + + + + Remove current library from your collection + Удалить эту библиотеку из своей коллекции + + + + Rescan library for XML info + Повторное сканирование библиотеки для получения информации XML + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Пытается найти информацию XML, встроенную в файлы комиксов. Это необходимо делать только в том случае, если библиотека была создана с помощью версии 9.8.2 или более ранней, или если вы используете стороннее программное обеспечение для встраивания информации XML в файлы. + + + + Show library info + Показать информацию о библиотеке + + + + Show information about the current library + Показать информацию о текущей библиотеке + + + + Open current comic + Открыть выбранный комикс + + + + Open current comic on YACReader + Открыть комикс в YACReader + + + + Save selected covers to... + Сохранить выбранные обложки в... + + + + Save covers of the selected comics as JPG files + Сохранить обложки выбранных комиксов как JPG файлы + + + + + Set as read + Отметить как прочитано + + + + Set comic as read + Отметить комикс как прочитано + + + + + Set as unread + Отметить как не прочитано + + + + Set comic as unread + Отметить комикс как не прочитано + + + + + manga + манга + + + + Set issue as manga + Установить выпуск как мангу + + + + + comic + комикс + + + + Set issue as normal + Установите проблему как обычно + + + + western manga + вестерн манга + + + + Set issue as western manga + Установить выпуск как западную мангу + + + + + web comic + веб-комикс + + + + Set issue as web comic + Установить выпуск как веб-комикс + + + + + yonkoma + йонкома + + + + Set issue as yonkoma + Установить проблему как йонкома + + + + Show/Hide marks + Показать/Спрятать пометки + + + + Show or hide read marks + Показать или спрятать отметку прочтено + + + + Show/Hide recent indicator + Показать/скрыть индикатор последних событий + + + + Show or hide recent indicator + Показать или скрыть недавний индикатор + + + + + Fullscreen mode on/off + Полноэкранный режим включить/выключить + + + + Help, About YACReader + Справка + + + + Add new folder + Добавить новую папку + + + + Add new folder to the current library + Добавить новую папку в текущую библиотеку + + + + Delete folder + Удалить папку + + + + Delete current folder from disk + Удалить выбранную папку с жёсткого диска + + + + Select root node + Домашняя папка + + + + Expand all nodes + Раскрыть все папки + + + + Collapse all nodes + Свернуть все папки + + + + Show options dialog + Настройки + + + + Show comics server options dialog + Настройки сервера YACReader + + + + + Change between comics views + Изменение внешнего вида потока комиксов + + + + Open folder... + Открыть папку... + + + + Set as uncompleted + Отметить как не завершено + + + + Set as completed + Отметить как завершено + + + + Set custom cover + Установить собственную обложку + + + + Delete custom cover + Удалить пользовательскую обложку + + + + western manga (left to right) + западная манга (слева направо) + + + + Open containing folder... + Открыть выбранную папку... + + + + Reset comic rating + Сбросить рейтинг комикса + + + + Select all comics + Выбрать все комиксы + + + + Edit + Редактировать + + + + Assign current order to comics + Назначить порядковый номер + + + + Update cover + Обновить обложки + + + + Delete selected comics + Удалить выбранное + + + + Delete metadata from selected comics + Удалить метаданные из выбранных комиксов + + + + Download tags from Comic Vine + Скачать теги из Comic Vine + + + + Focus search line + Строка поиска фокуса + + + + Focus comics view + Просмотр комиксов в фокусе + + + + Edit shortcuts + Редактировать горячие клавиши + + + + &Quit + &Qкостюм + + + + Update folder + Обновить папку + + + + Update current folder + Обновить выбранную папку + + + + Scan legacy XML metadata + Сканировать устаревшие метаданные XML + + + + Add new reading list + Создать новый список чтения + + + + Add a new reading list to the current library + Создать новый список чтения + + + + Remove reading list + Удалить список чтения + + + + Remove current reading list from the library + Удалить выбранный ярлык/список чтения + + + + Add new label + Создать новый ярлык + + + + Add a new label to this library + Создать новый ярлык + + + + Rename selected list + Переименовать выбранный список + + + + Rename any selected labels or lists + Переименовать выбранный ярлык/список чтения + + + + Add to... + Добавить в... + + + + Favorites + Избранное + + + + Add selected comics to favorites list + Добавить выбранные комиксы в список избранного + + + + LocalComicListModel + + + file name + имя файла + + + + NoLibrariesWidget + + + You don't have any libraries yet + У вас нет ни одной библиотеки + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Вы можете создать библиотеку в любой папке, YACReaderLibrary будет импортировать все комиксы и папки из этой папки. Если вы уже ранее создавали библиотеки, их можно будет открыть.< / p > <p>Не забывайте, что Вы можете использовать YACReader в качестве отдельного приложения для чтения комиксов на вашем компьютере.</п> + + + + create your first library + создайте свою первую библиотеку + + + + add an existing one + добавить уже существующую + + + + NoSearchResultsWidget + + + No results + Нет результатов + + + + OptionsDialog + + + + General + Общие + + + + + Libraries + Библиотеки + + + + Comic Flow + Поток комиксов + + + + Grid view + Фоновое изображение + + + + + Appearance + Появление + + + + + Options + Настройки + + + + + Language + Язык + + + + + Application language + Язык приложения + + + + + System default + Системный по умолчанию + + + + Tray icon settings (experimental) + Настройки значков в трее (экспериментально) + + + + Close to tray + Рядом с лотком + + + + Start into the system tray + Запустите в системном трее + + + + Edit Comic Vine API key + Редактировать Comic Vine API ключ + + + + Comic Vine API key + Comic Vine API ключ + + + + ComicInfo.xml legacy support + Поддержка устаревших версий ComicInfo.xml + + + + Import metadata from ComicInfo.xml when adding new comics + Импортируйте метаданные из ComicInfo.xml при добавлении новых комиксов. + + + + Consider 'recent' items added or updated since X days ago + Учитывайте «недавние» элементы, добавленные или обновленные X дней назад. + + + + Third party reader + Сторонний читатель + + + + Write {comic_file_path} where the path should go in the command + Напишите {comic_file_path}, где должен идти путь в команде. + + + + + Clear + Очистить + + + + Update libraries at startup + Обновлять библиотеки при запуске + + + + Try to detect changes automatically + Попробуйте обнаружить изменения автоматически + + + + Update libraries periodically + Периодически обновляйте библиотеки + + + + Interval: + Интервал: + + + + 30 minutes + 30 минут + + + + 1 hour + 1 час + + + + 2 hours + 2 часа + + + + 4 hours + 4 часа + + + + 8 hours + 8 часов + + + + 12 hours + 12 часов + + + + daily + ежедневно + + + + Update libraries at certain time + Обновлять библиотеки в определенное время + + + + Time: + Время: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + ПРЕДУПРЕЖДЕНИЕ! Во время обновления библиотеки запись в базу данных отключена! +Не планируйте обновления, пока вы активно используете приложение. +Во время автоматического обновления приложение будет блокировать некоторые действия до завершения обновления. +Чтобы остановить автоматическое обновление, нажмите на индикатор загрузки рядом с названием «Библиотеки». + + + + Modifications detection + Обнаружение модификаций + + + + Compare the modified date of files when updating a library (not recommended) + Сравните дату изменения файлов при обновлении библиотеки (не рекомендуется) + + + + Enable background image + Включить фоновое изображение + + + + Opacity level + Уровень непрозрачности + + + + Blur level + Уровень размытия + + + + Use selected comic cover as background + Обложка комикса фоновое изображение + + + + Restore defautls + Вернуть к первоначальным значениям + + + + Background + Фоновое изображение + + + + Display continue reading banner + Отображение баннера продолжения чтения + + + + Display current comic banner + Отображать текущий комикс-баннер + + + + Continue reading + Продолжить чтение + + + + My comics path + Папка комиксов + + + + Display + Отображать + + + + Show time in current page information label + Показывать время в информационной метке текущей страницы + + + + "Go to flow" size + Размер потока страниц + + + + Background color + Фоновый цвет + + + + Choose + Выбрать + + + + Scroll behaviour + Поведение прокрутки + + + + Disable scroll animations and smooth scrolling + Отключить анимацию прокрутки и плавную прокрутку + + + + Do not turn page using scroll + Не переворачивайте страницу с помощью прокрутки + + + + Use single scroll step to turn page + Используйте один шаг прокрутки, чтобы перевернуть страницу + + + + Mouse mode + Режим мыши + + + + Only Back/Forward buttons can turn pages + Только кнопки «Назад/Вперед» могут перелистывать страницы. + + + + Use the Left/Right buttons to turn pages. + Используйте кнопки «Влево/Вправо», чтобы перелистывать страницы. + + + + Click left or right half of the screen to turn pages. + Нажмите левую или правую половину экрана, чтобы перелистывать страницы. + + + + Quick Navigation Mode + Ползунок для быстрой навигации по страницам + + + + Disable mouse over activation + Отключить активацию потока при наведении мыши + + + + Brightness + Яркость + + + + Contrast + Контраст + + + + Gamma + Гамма + + + + Reset + Вернуть к первоначальным значениям + + + + Image options + Настройки изображения + + + + Fit options + Варианты подгонки + + + + Enlarge images to fit width/height + Увеличьте изображения по ширине/высоте + + + + Double Page options + Параметры двойной страницы + + + + Show covers as single page + Показывать обложки на одной странице + + + + Scaling + Масштабирование + + + + Scaling method + Метод масштабирования + + + + Nearest (fast, low quality) + Ближайший (быстро, низкое качество) + + + + Bilinear + Билинейный + + + + Lanczos (better quality) + Ланцос (лучшее качество) + + + + Page Flow + Поток Страниц + + + + Image adjustment + Настройка изображения + + + + + Restart is needed + Требуется перезагрузка + + + + Comics directory + Папка комиксов + + + + PropertiesDialog + + + General info + Общая информация + + + + Plot + Сюжет + + + + Authors + Авторы + + + + Publishing + Издатели + + + + Notes + Примечания + + + + Cover page + Страница обложки + + + + Load previous page as cover + Загрузить предыдущую страницу в качестве обложки + + + + Load next page as cover + Загрузить следующую страницу в качестве обложки + + + + Reset cover to the default image + Сбросить обложку к изображению по умолчанию + + + + Load custom cover image + Загрузить собственное изображение обложки + + + + Series: + Серия: + + + + Title: + Заголовок: + + + + + + of: + из: + + + + Issue number: + Номер выпуска + + + + Volume: + Объём : + + + + Arc number: + Номер дуги: + + + + Story arc: + Сюжетная арка: + + + + alt. number: + альт. число: + + + + Alternate series: + Альтернативный сериал: + + + + Series Group: + Группа серий: + + + + Genre: + Жанр: + + + + Size: + Размер: + + + + Writer(s): + Писатель(и): + + + + Penciller(s): + Художник(и): + + + + Inker(s): + Контуровщик(и): + + + + Colorist(s): + Колорист(ы): + + + + Letterer(s): + Гравёр-шрифтовик(и): + + + + Cover Artist(s): + Художник(и) Обложки: + + + + Editor(s): + Редактор(ы): + + + + Imprint: + Выходные данные: + + + + Day: + День: + + + + Month: + Месяц: + + + + Year: + Год: + + + + Publisher: + Издатель: + + + + Format: + Формат: + + + + Color/BW: + Цвет/BW: + + + + Age rating: + Возрастной рейтинг: + + + + Type: + Тип: + + + + Language (ISO): + Язык (ISO): + + + + Synopsis: + Описание: + + + + Characters: + Персонажи: + + + + Teams: + Команды: + + + + Locations: + Местоположение: + + + + Main character or team: + Главный герой или команда: + + + + Review: + Обзор: + + + + Notes: + Заметки: + + + + Tags: + Теги: + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + <a style='color: ##666666; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Открыть страницу этого комикса на сайте Comic Vine </a> + + + + Not found + Не найдено + + + + Comic not found. You should update your library. + Комикс не найден. Обновите вашу библиотеку. + + + + Edit comic information + Редактировать информацию комикса + + + + Edit selected comics information + Редактировать информацию выбранного комикса + + + + Invalid cover + Неверное покрытие + + + + The image is invalid. + Изображение недействительно. + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer — это безголовая (без графического интерфейса) версия YACReaderLibrary. + +Это приложение поддерживает постоянные настройки. Чтобы настроить их, отредактируйте этот файл %1. +Чтобы узнать о доступных настройках, ознакомьтесь с документацией по адресу https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md. + + + + QObject + + + Trace + След + + + + Debug + Отлаживать + + + + Info + Информация + + + + Warning + Предупреждение + + + + Error + Ошибка + + + + Fatal + Фатальный + + + + Select custom cover + Выбрать индивидуальную обложку + + + + Images (%1) + Изображения (%1) + + + + 7z lib not found + Библиотека распаковщика 7z не найдена + + + + unable to load 7z lib from ./utils + не удается загрузить 7z lib из ./ utils + + + + The file could not be read or is not valid JSON. + Файл не может быть прочитан или имеет недопустимый формат JSON. + + + + This theme is for %1, not %2. + Эта тема предназначена для %1, а не для %2. + + + + Libraries + Библиотеки + + + + Folders + Папки + + + + Reading Lists + Списки чтения + + + + RenameLibraryDialog + + + New Library Name : + Новое имя библиотеки: + + + + Rename + Переименовать + + + + Cancel + Отмена + + + + Rename current library + Переименовать эту библиотеку + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + Количество найденных томов : %1 + + + + + page %1 of %2 + страница %1 из %2 + + + + Number of %1 found : %2 + Количество из %1 найдено : %2 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + Пожалуйста, введите инфомарцию для поиска. + + + + Series: + Серия: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Используйте поиск по точному совпадению. Отключите, если хотите найти тома, соответствующие некоторым словам в названии. + + + + SearchVolume + + + Please provide some additional information. + Пожалуйста, введите инфомарцию для поиска. + + + + Series: + Серия: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Используйте поиск по точному совпадению. Отключите, если хотите найти тома, соответствующие некоторым словам в названии. + + + + SelectComic + + + Please, select the right comic info. + Пожалуйста, выберите правильную информацию об комиксе. + + + + comics + комиксы + + + + loading cover + загрузка обложки + + + + loading description + загрузка описания + + + + comic description unavailable + Описание комикса недоступно + + + + SelectVolume + + + Please, select the right series for your comic. + Пожалуйста, выберите правильную серию для вашего комикса. + + + + Filter: + Фильтр: + + + + volumes + тома + + + + Nothing found, clear the filter if any. + Ничего не найдено, очистите фильтр, если есть. + + + + loading cover + загрузка обложки + + + + loading description + загрузка описания + + + + volume description unavailable + описание тома недоступно + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + Вы пытаетесь получить информацию для нескольких комиксов одновременно, являются ли они все частью одной серии? + + + + yes + да + + + + no + нет + + + + ServerConfigDialog + + + set port + указать порт + + + + Server connectivity information + Информация о подключении + + + + Scan it! + Сканируйте! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader доступен для устройств iOS и Android.<br/>Найдите его для <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> или <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + + + + Choose an IP address + Выбрать IP адрес + + + + Port + Порт + + + + enable the server + активировать сервер + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + Пожалуйста, отсортируйте список комиксов слева, пока он не будет соответствовать информации комикса. + + + + sort comics to match comic information + сортировать комиксы, чтобы соответствовать информации комиксов + + + + issues + выпуск + + + + remove selected comics + удалить выбранные комиксы + + + + restore all removed comics + восстановить все удаленные комиксы + + + + ThemeEditorDialog + + + Theme Editor + Редактор тем + + + + + + + + + + + - + - + + + + i + я + + + + Expand all + Развернуть все + + + + Collapse all + Свернуть все + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Удерживайте, чтобы выбранное значение мигало в пользовательском интерфейсе (пурпурный / переключено / 0↔10). Релизы восстанавливают оригинал. + + + + Search… + Поиск… + + + + Light + Осветить + + + + Dark + Темный + + + + ID: + ИДЕНТИФИКАТОР: + + + + Display name: + Отображаемое имя: + + + + Variant: + Вариант: + + + + Theme info + Информация о теме + + + + Parameter + Параметр + + + + Value + Ценить + + + + Save and apply + Сохраните и примените + + + + Export to file... + Экспортировать в файл... + + + + Load from file... + Загрузить из файла... + + + + Close + Закрыть + + + + Double-click to edit color + Дважды щелкните, чтобы изменить цвет + + + + + + + + + true + истинный + + + + + + + false + ЛОЖЬ + + + + Double-click to toggle + Дважды щелкните, чтобы переключиться + + + + Double-click to edit value + Дважды щелкните, чтобы изменить значение + + + + + + Edit: %1 + Изменить: %1 + + + + Save theme + Сохранить тему + + + + + JSON files (*.json);;All files (*) + Файлы JSON (*.json);;Все файлы (*) + + + + Save failed + Сохранить не удалось + + + + Could not open file for writing: +%1 + Не удалось открыть файл для записи: +%1 + + + + Load theme + Загрузить тему + + + + + + Load failed + Загрузка не удалась + + + + Could not open file: +%1 + Не удалось открыть файл: +%1 + + + + Invalid JSON: +%1 + Неверный JSON: +%1 + + + + Expected a JSON object. + Ожидается объект JSON. + + + + TitleHeader + + + SEARCH + ПОИСК + + + + UpdateLibraryDialog + + + Updating.... + Обновление... + + + + Cancel + Отмена + + + + Update library + Обновить библиотеку + + + + Viewer + + + + Press 'O' to open comic. + Нажмите "O" чтобы открыть комикс. + + + + Not found + Не найдено + + + + Comic not found + Комикс не найден + + + + Error opening comic + Ошибка открытия комикса + + + + CRC Error + Ошибка CRC + + + + Loading...please wait! + Загрузка... Пожалуйста подождите! + + + + Page not available! + Страница недоступна! + + + + Cover! + Начало! + + + + Last page! + Конец! + + + + VolumeComicsModel + + + title + название + + + + VolumesModel + + + year + год + + + + issues + выпуск + + + + publisher + издатель + + + + YACReader3DFlowConfigWidget + + + Presets: + Предустановки: + + + + Classic look + Классический вид + + + + Stripe look + Вид полосами + + + + Overlapped Stripe look + Вид перекрывающимися полосами + + + + Modern look + Современный вид + + + + Roulette look + Вид рулеткой + + + + Show advanced settings + Показать дополнительные настройки + + + + Custom: + Пользовательский: + + + + View angle + Угол зрения + + + + Position + Позиция + + + + Cover gap + Осветить разрыв + + + + Central gap + Сфокусировать разрыв + + + + Zoom + Масштабировать + + + + Y offset + Смещение по Y + + + + Z offset + Смещение по Z + + + + Cover Angle + Охватить угол + + + + Visibility + Прозрачность + + + + Light + Осветить + + + + Max angle + Максимальный угол + + + + Low Performance + Минимальная производительность + + + + High Performance + Максимальная производительность + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + Использовать VSync (повысить формат изображения в полноэкранном режиме , хуже производительность) + + + + Performance: + Производительность: + + + + YACReader::MainWindowViewer + + + &Open + &Открыть + + + + Open a comic + Открыть комикс + + + + New instance + Новый экземпляр + + + + Open Folder + Открыть папку + + + + Open image folder + Открыть папку с изображениями + + + + Open latest comic + Открыть последний комикс + + + + Open the latest comic opened in the previous reading session + Открыть комикс открытый в предыдущем сеансе чтения + + + + Clear + Очистить + + + + Clear open recent list + Очистить список недавно открытых файлов + + + + Save + Сохранить + + + + + Save current page + Сохранить текущию страницу + + + + Previous Comic + Предыдущий комикс + + + + + + Open previous comic + Открыть предыдуший комикс + + + + Next Comic + Следующий комикс + + + + + + Open next comic + Открыть следующий комикс + + + + &Previous + &Предыдущий + + + + + + Go to previous page + Перейти к предыдущей странице + + + + &Next + &Следующий + + + + + + Go to next page + Перейти к следующей странице + + + + Fit Height + Подогнать по высоте + + + + Fit image to height + Подогнать по высоте + + + + Fit Width + Подогнать по ширине + + + + Fit image to width + Подогнать по ширине + + + + Show full size + Показать в полном размере + + + + Fit to page + Подогнать под размер страницы + + + + Continuous scroll + Непрерывная прокрутка + + + + Switch to continuous scroll mode + Переключиться в режим непрерывной прокрутки + + + + Reset zoom + Сбросить масштаб + + + + Show zoom slider + Показать ползунок масштабирования + + + + Zoom+ + Увеличить масштаб + + + + Zoom- + Уменьшить масштаб + + + + Rotate image to the left + Повернуть изображение против часовой стрелки + + + + Rotate image to the right + Повернуть изображение по часовой стрелке + + + + Double page mode + Двухстраничный режим + + + + Switch to double page mode + Двухстраничный режим + + + + Double page manga mode + Двухстраничный режим манги + + + + Reverse reading order in double page mode + Двухстраничный режим манги + + + + Go To + Перейти к странице... + + + + Go to page ... + Перейти к странице... + + + + Options + Настройки + + + + YACReader options + Настройки + + + + + Help + Справка + + + + Help, About YACReader + Справка + + + + Magnifying glass + Увеличительное стекло + + + + Switch Magnifying glass + Увеличительное стекло + + + + Set bookmark + Установить закладку + + + + Set a bookmark on the current page + Установить закладку на текущей странице + + + + Show bookmarks + Показать закладки + + + + Show the bookmarks of the current comic + Показать закладки в текущем комиксе + + + + Show keyboard shortcuts + Показать горячие клавиши + + + + Show Info + Показать/скрыть номер страницы и текущее время + + + + Close + Закрыть + + + + Show Dictionary + Переводчик YACreader + + + + Show go to flow + Показать поток страниц + + + + Edit shortcuts + Редактировать горячие клавиши + + + + &File + &Отображать панель инструментов + + + + + Open recent + Открыть недавние + + + + File + Файл + + + + Edit + Редактировать + + + + View + Посмотреть + + + + Go + Перейти + + + + Window + Окно + + + + + + Open Comic + Открыть комикс + + + + + + Comic files + Файлы комикса + + + + Open folder + Открыть папку + + + + page_%1.jpg + страница_%1.jpg + + + + Image files (*.jpg) + Файлы изображений (*.jpg) + + + + + Comics + Комикс + + + + + General + Общие + + + + + Magnifiying glass + Увеличительное стекло + + + + + Page adjustement + Настройка страницы + + + + + Reading + Чтение + + + + Toggle fullscreen mode + Полноэкранный режим включить/выключить + + + + Hide/show toolbar + Показать/скрыть панель инструментов + + + + Size up magnifying glass + Увеличение размера окошка увеличительного стекла + + + + Size down magnifying glass + Уменьшение размера окошка увеличительного стекла + + + + Zoom in magnifying glass + Увеличить + + + + Zoom out magnifying glass + Уменьшить + + + + Reset magnifying glass + Сбросить увеличительное стекло + + + + Toggle between fit to width and fit to height + Переключение режима подгонки страницы по ширине/высоте + + + + Autoscroll down + Автопрокрутка вниз + + + + Autoscroll up + Автопрокрутка вверх + + + + Autoscroll forward, horizontal first + Автопрокрутка вперед, горизонтальная + + + + Autoscroll backward, horizontal first + Автопрокрутка назад, горизонтальная + + + + Autoscroll forward, vertical first + Автопрокрутка вперед, вертикальная + + + + Autoscroll backward, vertical first + Автопрокрутка назад, вертикальная + + + + Move down + Переместить вниз + + + + Move up + Переместить вверх + + + + Move left + Переместить влево + + + + Move right + Переместить вправо + + + + Go to the first page + Перейти к первой странице + + + + Go to the last page + Перейти к последней странице + + + + Offset double page to the left + Смещение разворота влево + + + + Offset double page to the right + Смещение разворота вправо + + + + There is a new version available + Доступна новая версия + + + + Do you want to download the new version? + Хотите загрузить новую версию ? + + + + Remind me in 14 days + Напомнить через 14 дней + + + + Not now + Не сейчас + + + + YACReader::TrayIconController + + + &Restore + &Rмагазин + + + + Systray + Систрей + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary продолжит работать в системном трее. Чтобы завершить работу программы, выберите <b>Quit</b> в контекстном меню значка на панели задач. + + + + YACReaderFieldEdit + + + + Click to overwrite + Изменить + + + + Restore to default + Восстановить значения по умолчанию + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + Изменить + + + + Restore to default + Восстановить значения по умолчанию + + + + YACReaderOptionsDialog + + + Save + Сохранить + + + + Cancel + Отмена + + + + Edit shortcuts + Редактировать горячие клавиши + + + + Shortcuts + Горячие клавиши + + + + YACReaderSearchLineEdit + + + type to search + Начать поиск + + + + YACReaderSlider + + + Reset + Вернуть к первоначальным значениям - QsLogging::Window + YACReaderTranslator - - &Pause - + + YACReader translator + Переводчик YACReader - - &Resume - + + + Translation + Перевод - - Save log - + + clear + очистить - - Log file (*.log) - + + Service not available + Сервис недоступен diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_tr.ts b/YACReaderLibraryServer/yacreaderlibraryserver_tr.ts index f83835c4f..9e8582c4c 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_tr.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_tr.ts @@ -2,150 +2,3713 @@ - FileComic + ActionsShortcutsModel - - CRC error on page (%1): some of the pages will not be displayed correctly - + + None + Hiçbiri + + + AddLabelDialog - - Unknown error opening the file - + + Label name: + Etiket adı: - - 7z not found - + + Choose a color: + Renk seçiniz: - - Format not supported - + + accept + kabul et + + + + cancel + vazgeç - LogWindow + AddLibraryDialog + + + Comics folder : + Çizgi roman klasörü : + + + + Library name : + Kütüphane adı : + - - Log window - + + Add + Ekle - - &Pause - + + Cancel + Vazgeç - - &Save - + + Add an existing library + Kütüphaneye ekle + + + ApiKeyDialog - - C&lear - + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Comic Vine'a bağlanmadan önce kendi API anahtarınıza ihtiyacınız var. Lütfen <a href="http://www.comicvine.com/api/">buradan</a> ücretsiz bir tane edinin - - &Copy - + + Paste here your Comic Vine API key + Comic Vine API anahtarınızı buraya yapıştırın - - Level: - + + Accept + Kabul et - - &Auto scroll - + + Cancel + Vazgeç - QCoreApplication + AppearanceTabWidget - - -YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + + Color scheme + Renk şeması + + + + System + Sistem + + + + Light + Işık + + + + Dark + Karanlık + + + + Custom + Gelenek + + + + Remove + Kaldırmak + + + + Remove this user-imported theme + Kullanıcı tarafından içe aktarılan bu temayı kaldır + + + + Light: + Işık: + + + + Dark: + Karanlık: + + + + Custom: + Kişisel: + + + + Import theme... + Temayı içe aktar... + + + + Theme + Tema + + + + Theme editor + Tema düzenleyici + + + + Open Theme Editor... + Tema Düzenleyiciyi Aç... + + + + Theme editor error + Tema düzenleyici hatası + + + + The current theme JSON could not be loaded. + Geçerli tema JSON yüklenemedi. + + + + Import theme + Temayı içe aktar + + + + JSON files (*.json);;All files (*) + JSON dosyaları (*.json);;Tüm dosyalar (*) + + + + Could not import theme from: +%1 + Tema şu kaynaktan içe aktarılamadı: +%1 + + + + Could not import theme from: +%1 -This appplication supports persistent settings, to set them up edit this file %1 -To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md - +%2 + Tema şu kaynaktan içe aktarılamadı: +%1 + +%2 + + + + Import failed + İçe aktarma başarısız oldu - QObject + BookmarksDialog - - Trace - + + Lastest Page + Son Sayfa - - Debug - + + Close + Kapat - - Info - + + Click on any image to go to the bookmark + Yer imine git - - Warning - + + + Loading... + Yükleniyor... + + + ClassicComicsView - - Error - + + Hide comic flow + Çizgi roman akışını gizle + + + + ComicModel + + + yes + evet - - Fatal - + + no + hayır + + + + Title + Başlık + + + + File Name + Dosya Adı + + + + Pages + Sayfalar + + + + Size + Boyut + + + + Read + Oku + + + + Current Page + Geçreli Sayfa + + + + Publication Date + Yayın Tarihi + + + + Rating + Reyting + + + + Series + Seri + + + + Volume + Hacim + + + + Story Arc + Hikaye Arkı + + + + ComicVineDialog + + + skip + geç + + + + back + geri + + + + next + sonraki + + + + search + ara + + + + close + kapat + + + + + comic %1 of %2 - %3 + çizgi roman %1 / %2 - %3 + + + + + + Looking for volume... + Sayılar aranıyor... + + + + %1 comics selected + %1 çizgi roman seçildi + + + + Error connecting to ComicVine + ComicVine sitesine bağlanılırken hata + + + + + Retrieving tags for : %1 + %1 için etiketler alınıyor + + + + Retrieving volume info... + Sayı bilgileri alınıyor... + + + + Looking for comic... + Çizgi romanlar aranıyor... + + + + ContinuousPageWidget + + + Loading page %1 + %1 sayfası yükleniyor + + + + CreateLibraryDialog + + + Comics folder : + Çizgi roman klasörü : + + + + Library Name : + Kütüphane Adı : + + + + Create + Oluştur + + + + Cancel + Vazgeç + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + Yeni kütüphanenin oluşturulması birkaç dakika sürecek. + + + + Create new library + Yeni kütüphane oluştur + + + + Path not found + Dizin bulunamadı + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + Seçilen dizine yazma iznimiz yok yazma izni olduğundan emin ol + + + + EditShortcutsDialog + + + Restore defaults + Varsayılarları geri yükle + + + + To change a shortcut, double click in the key combination and type the new keys. + Bir kısayolu değiştirmek için tuş kombinasyonuna çift tıklayın ve yeni tuşları girin. + + + + Shortcuts settings + Kısayol oyarları + + + + Shortcut in use + Kısayol kullanımda + + + + The shortcut "%1" is already assigned to other function + "%1" kısayolu bir başka işleve zaten atanmış + + + + EmptyFolderWidget + + + This folder doesn't contain comics yet + Bu klasör henüz çizgi roman içermiyor + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + Bu etiket henüz çizgi roman içermiyor + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + Bu okuma listesi henüz çizgi roman içermiyor + + + + EmptySpecialListWidget + + + No favorites + Favoriler boş + + + + You are not reading anything yet, come on!! + Henüz bir şey okumuyorsun, hadi ama! + + + + There are no recent comics! + Yeni çizgi roman yok! + + + + ExportComicsInfoDialog + + + Output file : + Çıkış dosyası : + + + + Create + Oluştur + + + + Cancel + Vazgeç + + + + Export comics info + Çizgi roman bilgilerini göster + + + + Destination database name + Hedef adı + + + + Problem found while writing + Yazma sırasında bir problem oldu + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Seçilen dizine yazma iznimiz yok yazma izni olduğundan emin ol + + + + ExportLibraryDialog + + + Output folder : + Çıktı klasörü : + + + + Create + Oluştur + + + + Cancel + Vazgeç + + + + Create covers package + Kapak paketi oluştur + + + + Problem found while writing + Yazma sırasında bir problem oldu + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + Seçilen dizine yazma iznimiz yok yazma izni olduğundan emin ol + + + + Destination directory + Hedef dizin + + + + FileComic + + + CRC error on page (%1): some of the pages will not be displayed correctly + (%1). sayfada CRC hatası : bazı sayfalar düzgün görüntülenmeyecek + + + + Unknown error opening the file + Dosya açılırken bilinmeyen hata + + + + 7z not found + 7z bulunamadı + + + + Format not supported + Biçim desteklenmiyor + + + + GoToDialog + + + Page : + Sayfa : + + + + Go To + Git + + + + Cancel + Vazgeç + + + + + Total pages : + Toplam sayfa: + + + + Go to... + Git... + + + + GoToFlowToolBar + + + Page : + Sayfa : - QsLogging::LogWindowModel + GridComicsView - - Time - + + Show info + Bilgi göster + + + HelpAboutDialog - - Level - + + About + Hakkında - - Message - + + Help + Yardım + + + + System info + Sistem bilgisi + + + + ImportComicsInfoDialog + + + Import comics info + Çizgi roman bilgilerini çıkart + + + + Info database location : + Bilgi veritabanı konumu : + + + + Import + Çıkart + + + + Cancel + Vazgeç + + + + Comics info file (*.ydb) + Çizgi roman bilgi dosyası (*.ydb) + + + + ImportLibraryDialog + + + Library Name : + Kütüphane Adı : + + + + Package location : + Paket konumu : + + + + Destination folder : + Hedef klasör : + + + + Unpack + Paketten çıkar + + + + Cancel + Vazgeç + + + + Extract a catalog + Katalog ayıkla + + + + Compresed library covers (*.clc) + Sıkıştırılmış kütüphane kapakları (*.clc) + + + + ImportWidget + + + stop + dur + + + + Some of the comics being added... + Bazı çizgi romanlar önceden eklenmiş... + + + + Importing comics + önemli çizgi romanlar + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderKütüphane şu anda yeni bir kütüphane oluşturuyor</p><p>Kütüphanenin oluşturulması birkaç dakika alacak.</p> + + + + Updating the library + Kütüphaneyi güncelle + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>Kütüphane güncelleniyor</p><p>Güncellemeyi daha sonra iptal edebilirsin.</p> + + + + Upgrading the library + Kütüphane güncelleniyor + + + + <p>The current library is being upgraded, please wait.</p> + <p>Mevcut kütüphane güncelleniyor, lütfen bekleyin.</p> + + + + Scanning the library + Kütüphaneyi taramak + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>Geçerli kitaplık, eski XML meta veri bilgileri için taranıyor.</p><p>Bu yalnızca bir kez gereklidir ve yalnızca kitaplığın YACReaderLibrary 9.8.2 veya daha eski bir sürümle oluşturulmuş olması durumunda gereklidir.</p> + + + + LibraryWindow + + + YACReader Library + YACReader Kütüphane + + + + + + comic + komik + + + + + + manga + manga t?r? + + + + + + western manga (left to right) + Batı mangası (soldan sağa) + + + + + + web comic + web çizgi romanı + + + + + + 4koma (top to botom) + 4koma (yukarıdan aşağıya) + + + + + + + Set type + Türü ayarla + + + + Library + Kütüphane + + + + Folder + Klasör + + + + Comic + Çizgi roman + + + + Upgrade failed + Yükseltme başarısız oldu + + + + There were errors during library upgrade in: + Kütüphane yükseltmesi sırasında hatalar oluştu: + + + + Update needed + Güncelleme gerekli + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + Bu kütüphane YACReaderKütüphabenin bir önceki versiyonun oluşturulmuş, güncellemeye ihtiyacın var. Şimdi güncellemek ister misin ? + + + + Download new version + Yeni versiyonu indir + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + Bu kütüphane YACRKütüphanenin üst bir versiyonunda oluşturulmu. Yeni versiyonu indirmek ister misiniz ? + + + + + Library not available + Kütüphane ulaşılabilir değil + + + + Library '%1' is no longer available. Do you want to remove it? + Kütüphane '%1'ulaşılabilir değil. Kaldırmak ister misin? + + + + Old library + Eski kütüphane + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Kütüphane '%1 YACRKütüphanenin eski bir sürümünde oluşturulmuş, Kütüphaneyi yeniden oluşturmak ister misin? + + + + + Copying comics... + Çizgi romanlar kopyalanıyor... + + + + + Moving comics... + Çizgi romanlar taşınıyor... + + + + Add new folder + Yeni klasör ekle + + + + Folder name: + Klasör adı: + + + + No folder selected + Hiçbir klasör seçilmedi + + + + Please, select a folder first + Lütfen, önce bir klasör seçiniz + + + + Error in path + Yolda hata + + + + There was an error accessing the folder's path + Klasörün yoluna erişilirken hata oluştu + + + + Delete folder + Klasörü sil + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + Seçilen klasör ve tüm içeriği diskinizden silinecek. Emin misin? + + + + + Unable to delete + Silinemedi + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + Seçili klasörleri silmeye çalışırken bir sorun oluştu. Lütfen yazma izinlerini kontrol edin ve herhangi bir uygulamanın bu klasörleri veya içerdiği dosyalardan herhangi birini kullandığından emin olun. + + + + Add new reading lists + Yeni okuma listeleri ekle + + + + + List name: + Liste adı: + + + + Delete list/label + Listeyi/Etiketi sil + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + Seçilen öğe silinecek, çizgi romanlarınız veya klasörleriniz diskinizden SİLİNMEYECEKTİR. Emin misin? + + + + Rename list name + Listeyi yeniden adlandır + + + + Open folder... + Dosyayı aç... + + + + Update folder + Klasörü güncelle + + + + Rescan library for XML info + XML bilgisi için kitaplığı yeniden tarayın + + + + Set as uncompleted + Tamamlanmamış olarak ayarla + + + + Set as completed + Tamamlanmış olarak ayarla + + + + Set as read + Okundu olarak işaretle + + + + + Set as unread + Hepsini okunmadı işaretle + + + + Set custom cover + Özel kapak ayarla + + + + Delete custom cover + Özel kapağı sil + + + + Save covers + Kapakları kaydet + + + + You are adding too many libraries. + Çok fazla kütüphane ekliyorsunuz. + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + Çok fazla kütüphane ekliyorsunuz. + +Muhtemelen üst düzey çizgi roman klasörünüzde yalnızca bir kütüphaneye ihtiyacınız vardır, sol kenar çubuğundaki klasörler bölümünü kullanarak herhangi bir alt klasöre göz atabilirsiniz. + +YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütüphane sayısını düşük tutmalısınız. + + + + + YACReader not found + YACReader bulunamadı + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + YACReader bulunamadı. YACReader, YACReaderLibrary ile aynı klasöre kurulmalıdır. + + + + YACReader not found. There might be a problem with your YACReader installation. + YACReader bulunamadı. YACReader kurulumunuzda bir sorun olabilir. + + + + Error + Hata + + + + Error opening comic with third party reader. + Çizgi roman üçüncü taraf okuyucuyla açılırken hata oluştu. + + + + Library not found + Kütüphane bulunamadı + + + + The selected folder doesn't contain any library. + Seçilen dosya kütüphanede yok. + + + + Are you sure? + Emin misin? + + + + Do you want remove + Kaldırmak ister misin + + + + library? + kütüphane? + + + + Remove and delete metadata + Metadata'yı kaldır ve sil + + + + Library info + Kütüphane bilgisi + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + Seçilen çizgi romanlar silinmeye çalışılırken bir sorun oluştu. Lütfen seçilen dosyalarda veya klasörleri içeren yazma izinlerini kontrol edin. + + + + Assign comics numbers + Çizgi roman numaraları ata + + + + Assign numbers starting in: + Şunlardan başlayarak numaralar ata: + + + + Invalid image + Geçersiz resim + + + + The selected file is not a valid image. + Seçilen dosya geçerli bir resim değil. + + + + Error saving cover + Kapak kaydedilirken hata oluştu + + + + There was an error saving the cover image. + Kapak resmi kaydedilirken bir hata oluştu. + + + + Error creating the library + Kütüphane oluşturma sorunu + + + + Error updating the library + Kütüphane güncelleme sorunu + + + + Error opening the library + Haa kütüphanesini aç + + + + Delete comics + Çizgi romanları sil + + + + All the selected comics will be deleted from your disk. Are you sure? + Seçilen tüm çizgi romanlar diskten silinecek emin misin ? + + + + Remove comics + Çizgi romanları kaldır + + + + Comics will only be deleted from the current label/list. Are you sure? + Çizgi romanlar yalnızca mevcut etiketten/listeden silinecektir. Emin misin? + + + + Library name already exists + Kütüphane ismi zaten alınmış + + + + There is another library with the name '%1'. + Bu başka bir kütüphanenin adı '%1'. + + + + LibraryWindowActions + + + Create a new library + Yeni kütüphane oluştur + + + + Open an existing library + Çıkış kütüphanesini aç + + + + + Export comics info + Çizgi roman bilgilerini göster + + + + + Import comics info + Çizgi roman bilgilerini çıkart + + + + Pack covers + Paket kapakları + + + + Pack the covers of the selected library + Kütüphanede ki kapakları paketle + + + + Unpack covers + Kapakları aç + + + + Unpack a catalog + Kataloğu çkart + + + + Update library + Kütüphaneyi güncelle + + + + Update current library + Kütüphaneyi güncelle + + + + Rename library + Kütüphaneyi yeniden adlandır + + + + Rename current library + Kütüphaneyi adlandır + + + + Remove library + Kütüphaneyi sil + + + + Remove current library from your collection + Kütüphaneyi koleksiyonundan kaldır + + + + Rescan library for XML info + XML bilgisi için kitaplığı yeniden tarayın + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + Komik dosyalara gömülü XML bilgilerini bulmaya çalışır. Bunu yalnızca kitaplık 9.8.2 veya önceki sürümlerle oluşturulmuşsa veya XML bilgilerini dosyalara eklemek için üçüncü taraf yazılım kullanıyorsanız yapmanız gerekir. + + + + Show library info + Kitaplık bilgilerini göster + + + + Show information about the current library + Geçerli kitaplık hakkındaki bilgileri göster + + + + Open current comic + Seçili çizgi romanı aç + + + + Open current comic on YACReader + YACReader'ı geçerli çizgi roman okuyucsu seç + + + + Save selected covers to... + Seçilen kapakları şuraya kaydet... + + + + Save covers of the selected comics as JPG files + Seçilen çizgi romanların kapaklarını JPG dosyaları olarak kaydet + + + + + Set as read + Okundu olarak işaretle + + + + Set comic as read + Çizgi romanı okundu olarak işaretle + + + + + Set as unread + Hepsini okunmadı işaretle + + + + Set comic as unread + Çizgi Romanı okunmadı olarak seç + + + + + manga + manga t?r? + + + + Set issue as manga + Sayıyı manga olarak ayarla + + + + + comic + komik + + + + Set issue as normal + Sayıyı normal olarak ayarla + + + + western manga + batı mangası + + + + Set issue as western manga + Konuyu western mangası olarak ayarla + + + + + web comic + web çizgi romanı + + + + Set issue as web comic + Sorunu web çizgi romanı olarak ayarla + + + + + yonkoma + d?rt panelli + + + + Set issue as yonkoma + Sorunu yonkoma olarak ayarla + + + + Show/Hide marks + Altçizgileri aç/kapa + + + + Show or hide read marks + Okundu işaretlerini göster yada gizle + + + + Show/Hide recent indicator + Son göstergeyi Göster/Gizle + + + + Show or hide recent indicator + Son göstergeyi göster veya gizle + + + + + Fullscreen mode on/off + Tam ekran modu açık/kapalı + + + + Help, About YACReader + YACReader hakkında yardım ve bilgi + + + + Add new folder + Yeni klasör ekle + + + + Add new folder to the current library + Geçerli kitaplığa yeni klasör ekle + + + + Delete folder + Klasörü sil + + + + Delete current folder from disk + Geçerli klasörü diskten sil + + + + Select root node + Kökü seçin + + + + Expand all nodes + Tüm düğümleri büyüt + + + + Collapse all nodes + Tüm düğümleri kapat + + + + Show options dialog + Ayarları göster + + + + Show comics server options dialog + Çizgi romanların server ayarlarını göster + + + + + Change between comics views + Çizgi roman görünümleri arasında değiştir + + + + Open folder... + Dosyayı aç... + + + + Set as uncompleted + Tamamlanmamış olarak ayarla + + + + Set as completed + Tamamlanmış olarak ayarla + + + + Set custom cover + Özel kapak ayarla + + + + Delete custom cover + Özel kapağı sil + + + + western manga (left to right) + Batı mangası (soldan sağa) + + + + Open containing folder... + Klasör açılıyor... + + + + Reset comic rating + Çizgi roman reytingini sıfırla + + + + Select all comics + Tüm çizgi romanları seç + + + + Edit + Düzen + + + + Assign current order to comics + Geçerli sırayı çizgi romanlara ata + + + + Update cover + Kapağı güncelle + + + + Delete selected comics + Seçili çizgi romanları sil + + + + Delete metadata from selected comics + Seçilen çizgi romanlardan meta verileri sil + + + + Download tags from Comic Vine + Etiketleri Comic Vine sitesinden indir + + + + Focus search line + Arama satırına odaklan + + + + Focus comics view + Çizgi roman görünümüne odaklanın + + + + Edit shortcuts + Kısayolları düzenle + + + + &Quit + &Çıkış + + + + Update folder + Klasörü güncelle + + + + Update current folder + Geçerli klasörü güncelle + + + + Scan legacy XML metadata + Eski XML meta verilerini tarayın + + + + Add new reading list + Yeni okuma listesi ekle + + + + Add a new reading list to the current library + Geçerli kitaplığa yeni bir okuma listesi ekle + + + + Remove reading list + Okuma listesini kaldır + + + + Remove current reading list from the library + Geçerli okuma listesini kütüphaneden kaldır + + + + Add new label + Yeni etiket ekle + + + + Add a new label to this library + Bu kitaplığa yeni bir etiket ekle + + + + Rename selected list + Seçilen listeyi yeniden adlandır + + + + Rename any selected labels or lists + Seçilen etiketleri ya da listeleri yeniden adlandır + + + + Add to... + Şuraya ekle... + + + + Favorites + Favoriler + + + + Add selected comics to favorites list + Seçilen çizgi romanları favoriler listesine ekle + + + + LocalComicListModel + + + file name + dosya adı + + + + NoLibrariesWidget + + + You don't have any libraries yet + Henüz bir kütüphaneye sahip değilsin + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Yeni bir kütüphane oluşturabilmeniçin kütüphane</p><p>No olvides que puedes usar YACReader como una aplicación independiente para leer los cómics en tu ordenador.</p> + + + + create your first library + İlk kütüphaneni oluştur + + + + add an existing one + Var olan bir tane ekle + + + + NoSearchResultsWidget + + + No results + Sonuç yok + + + + OptionsDialog + + + + General + Genel + + + + + Libraries + Kütüphaneler + + + + Comic Flow + Çizgi Roman Akışı + + + + Grid view + Izgara görünümü + + + + + Appearance + Dış görünüş + + + + + Options + Ayarlar + + + + + Language + Dil + + + + + Application language + Uygulama dili + + + + + System default + Sistem varsayılanı + + + + Tray icon settings (experimental) + Tepsi simgesi ayarları (deneysel) + + + + Close to tray + Tepsiyi kapat + + + + Start into the system tray + Sistem tepsisinde başlat + + + + Edit Comic Vine API key + Comic Vine API anahtarını düzenle + + + + Comic Vine API key + Comic Vine API anahtarı + + + + ComicInfo.xml legacy support + ComicInfo.xml eski desteği + + + + Import metadata from ComicInfo.xml when adding new comics + Yeni çizgi roman eklerken meta verileri ComicInfo.xml'den içe aktarın + + + + Consider 'recent' items added or updated since X days ago + X gün öncesinden bu yana eklenen veya güncellenen 'en son' öğeleri göz önünde bulundurun + + + + Third party reader + Üçüncü taraf okuyucu + + + + Write {comic_file_path} where the path should go in the command + Komutta yolun gitmesi gereken yere {comic_file_path} yazın + + + + + Clear + Temizle + + + + Update libraries at startup + Başlangıçta kitaplıkları güncelleyin + + + + Try to detect changes automatically + Değişiklikleri otomatik olarak algılamayı deneyin + + + + Update libraries periodically + Kitaplıkları düzenli aralıklarla güncelleyin + + + + Interval: + Aralık: + + + + 30 minutes + 30 dakika + + + + 1 hour + 1 saat + + + + 2 hours + 2 saat + + + + 4 hours + 4 saat + + + + 8 hours + 8 saat + + + + 12 hours + 12 saat + + + + daily + günlük + + + + Update libraries at certain time + Kitaplıkları belirli bir zamanda güncelle + + + + Time: + Zaman: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + UYARI! Kütüphane güncellemeleri sırasında veritabanına yazma işlemi devre dışı bırakılır! +Uygulamayı aktif olarak kullanırken güncelleme planlamayın. +Otomatik güncellemeler sırasında uygulama, güncelleme bitene kadar bazı eylemleri engelleyecektir. +Otomatik güncellemeyi durdurmak için Kitaplıklar başlığının yanındaki yükleme göstergesine dokunun. + + + + Modifications detection + Değişiklik tespiti + + + + Compare the modified date of files when updating a library (not recommended) + Kitaplığı güncellerken dosyaların değiştirilme tarihini karşılaştırın (önerilmez) + + + + Enable background image + Arka plan resmini etkinleştir + + + + Opacity level + Matlık düzeyi + + + + Blur level + Bulanıklık düzeyi + + + + Use selected comic cover as background + Seçilen çizgi roman kapanığı arka plan olarak kullan + + + + Restore defautls + Varsayılanları geri yükle + + + + Background + Arka plan + + + + Display continue reading banner + Okuma devam et bannerını göster + + + + Display current comic banner + Mevcut çizgi roman banner'ını görüntüle + + + + Continue reading + Okumaya devam et + + + + My comics path + Çizgi Romanlarım + + + + Display + Görüntülemek + + + + Show time in current page information label + Geçerli sayfa bilgisi etiketinde zamanı göster + + + + "Go to flow" size + Akış görünümüne git + + + + Background color + Arka plan rengi + + + + Choose + Seç + + + + Scroll behaviour + Kaydırma davranışı + + + + Disable scroll animations and smooth scrolling + Kaydırma animasyonlarını ve düzgün kaydırmayı devre dışı bırakın + + + + Do not turn page using scroll + Kaydırmayı kullanarak sayfayı çevirmeyin + + + + Use single scroll step to turn page + Sayfayı çevirmek için tek kaydırma adımını kullanın + + + + Mouse mode + Fare modu + + + + Only Back/Forward buttons can turn pages + Yalnızca Geri/İleri düğmeleri sayfaları çevirebilir + + + + Use the Left/Right buttons to turn pages. + Sayfaları çevirmek için Sol/Sağ tuşlarını kullanın. + + + + Click left or right half of the screen to turn pages. + Sayfaları çevirmek için ekranın sol veya sağ yarısına tıklayın. + + + + Quick Navigation Mode + Hızlı Gezinti Kipi + + + + Disable mouse over activation + Etkinleştirme üzerinde fareyi devre dışı bırak + + + + Brightness + Parlaklık + + + + Contrast + Kontrast + + + + Gamma + Gama + + + + Reset + Yeniden başlat + + + + Image options + Sayfa ayarları + + + + Fit options + Sığdırma seçenekleri + + + + Enlarge images to fit width/height + Genişliğe/yüksekliği sığmaları için resimleri genişlet + + + + Double Page options + Çift Sayfa seçenekleri + + + + Show covers as single page + Kapakları tek sayfa olarak göster + + + + Scaling + Ölçeklendirme + + + + Scaling method + Ölçeklendirme yöntemi + + + + Nearest (fast, low quality) + En yakın (hızlı, düşük kalite) + + + + Bilinear + Çift doğrusal + + + + Lanczos (better quality) + Lanczos (daha kaliteli) + + + + Page Flow + Sayfa akışı + + + + Image adjustment + Resim ayarları + + + + + Restart is needed + Yeniden başlatılmalı + + + + Comics directory + Çizgi roman konumu + + + + PropertiesDialog + + + General info + Genel bilgi + + + + Plot + Argumento + + + + Authors + Yazarlar + + + + Publishing + Yayın + + + + Notes + Notlar + + + + Cover page + Kapak sayfası + + + + Load previous page as cover + Önceki sayfayı kapak olarak yükle + + + + Load next page as cover + Sonraki sayfayı kapak olarak yükle + + + + Reset cover to the default image + Kapağı varsayılan görüntüye sıfırla + + + + Load custom cover image + Özel kapak resmini yükle + + + + Series: + Seriler: + + + + Title: + Başlık: + + + + + + of: + ile ilgili: + + + + Issue number: + Yayın numarası: + + + + Volume: + Cilt: + + + + Arc number: + Ark numarası: + + + + Story arc: + Hiakye: + + + + alt. number: + alternatif sayı: + + + + Alternate series: + Alternatif seri: + + + + Series Group: + Seri Grubu: + + + + Genre: + Tür: + + + + Size: + Boyut: + + + + Writer(s): + Yazarlar: + + + + Penciller(s): + Çizenler: + + + + Inker(s): + Mürekkep(ler): + + + + Colorist(s): + Renklendiren: + + + + Letterer(s): + Mesaj(lar): + + + + Cover Artist(s): + Kapak artisti: + + + + Editor(s): + Editör(ler): + + + + Imprint: + Künye: + + + + Day: + Gün: + + + + Month: + Ay: + + + + Year: + Yıl: + + + + Publisher: + Yayıncı: + + + + Format: + Formato: + + + + Color/BW: + Renk/BW: + + + + Age rating: + Yaş sınırı: + + + + Type: + Tip: + + + + Language (ISO): + Dil (ISO): + + + + Synopsis: + Özet: + + + + Characters: + Karakterler: + + + + Teams: + Takımlar: + + + + Locations: + Konumlar: + + + + Main character or team: + Ana karakter veya takım: + + + + Review: + Gözden geçirmek: + + + + Notes: + Notlar: + + + + Tags: + Etiketler: + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine bağlantısı: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> görüntüle </a> + + + + Not found + Bulunamadı + + + + Comic not found. You should update your library. + Çizgi roman bulunamadı. Kütüphaneyi güncellemelisin. + + + + Edit comic information + Çizgi roman bilgisini düzenle + + + + Edit selected comics information + Seçilen çizgi roman bilgilerini düzenle + + + + Invalid cover + Geçersiz kapak + + + + The image is invalid. + Resim geçersiz. + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer, YACReaderLibrary'nin başsız (gui yok) sürümüdür. + +Bu uygulama kalıcı ayarları destekler, bunları ayarlamak için bu dosyayı düzenleyin %1 +Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md adresindeki belgelere bakın. + + + + QObject + + + Trace + İz + + + + Debug + Hata ayıkla + + + + Info + Bilgi + + + + Warning + Uyarı + + + + Error + Hata + + + + Fatal + Ölümcül + + + + Select custom cover + Özel kapak seçin + + + + Images (%1) + Resimler (%1) + + + + 7z lib not found + 7z lib bulunamadı + + + + unable to load 7z lib from ./utils + ./utils içinden 7z lib yüklenemedi + + + + The file could not be read or is not valid JSON. + Dosya okunamadı veya geçerli bir JSON değil. + + + + This theme is for %1, not %2. + Bu tema %2 için değil, %1 içindir. + + + + Libraries + Kütüphaneler + + + + Folders + Klasör + + + + Reading Lists + Okuma Listeleri + + + + RenameLibraryDialog + + + New Library Name : + Yeni Kütüphane Adı : + + + + Rename + Yeniden adlandır + + + + Cancel + Vazgeç + + + + Rename current library + Kütüphaneyi adlandır + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + Bulunan bölüm sayısı: %1 + + + + + page %1 of %2 + sayfa %1 / %2 + + + + Number of %1 found : %2 + Sayı %1, bulunan : %2 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + Lütfen bazı ek bilgiler sağlayın. + + + + Series: + Seriler: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Tam eşleme aramasını kullanın. Addaki bazı sözcüklerle eşleşen ciltleri bulmak istiyorsanız devre dışı bırakın. + + + + SearchVolume + + + Please provide some additional information. + Lütfen bazı ek bilgiler sağlayın. + + + + Series: + Seriler: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + Tam eşleme aramasını kullanın. Addaki bazı sözcüklerle eşleşen ciltleri bulmak istiyorsanız devre dışı bırakın. + + + + SelectComic + + + Please, select the right comic info. + Lütfen, doğru çizgi roman bilgisini seçin. + + + + comics + çizgi roman + + + + loading cover + kapak yükleniyor + + + + loading description + açıklama yükleniyor + + + + comic description unavailable + çizgi roman açıklaması mevcut değil + + + + SelectVolume + + + Please, select the right series for your comic. + Çizgi romanınız için doğru seriyi seçin. + + + + Filter: + Filtre: + + + + volumes + sayı + + + + Nothing found, clear the filter if any. + Hiçbir şey bulunamadı, varsa filtreyi temizleyin. + + + + loading cover + kapak yükleniyor + + + + loading description + açıklama yükleniyor + + + + volume description unavailable + cilt açıklaması kullanılamıyor + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + Aynı anda çeşitli çizgi romanlar için bilgi almaya çalışıyorsunuz, bunlar aynı serinin parçası mı? + + + + yes + evet + + + + no + hayır + + + + ServerConfigDialog + + + set port + Port Ayarla + + + + Server connectivity information + Sunucu bağlantı bilgileri + + + + Scan it! + Tara! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader, iOS ve Android cihazlarda kullanılabilir.<br/>Bunu <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> veya <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a> için keşfedin. + + + + Choose an IP address + IP adresi seçin + + + + Port + Liman + + + + enable the server + erişilebilir server + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + Lütfen, çizgi romanların bilgileriyle eşleşene kadar soldaki çizgi roman listesini sıralayın. + + + + sort comics to match comic information + çizgi roman bilgilerini eşleştirmek için çizgi romanları sıralayın + + + + issues + sayı + + + + remove selected comics + seçilen çizgi romanları kaldır + + + + restore all removed comics + tüm seçilen çizgi romanları geri yükle + + + + ThemeEditorDialog + + + Theme Editor + Tema Düzenleyici + + + + + + + + + + + - + - + + + + i + Ben + + + + Expand all + Tümünü genişlet + + + + Collapse all + Tümünü daralt + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + Kullanıcı arayüzünde seçilen değeri (macenta / geçişli / 0↔10) yanıp sönmek için basılı tutun. Sürümler orijinali geri yükler. + + + + Search… + Aramak… + + + + Light + Işık + + + + Dark + Karanlık + + + + ID: + İD: + + + + Display name: + Ekran adı: + + + + Variant: + Varyant: + + + + Theme info + Tema bilgisi + + + + Parameter + Parametre + + + + Value + Değer + + + + Save and apply + Kaydet ve uygula + + + + Export to file... + Dosyaya aktar... + + + + Load from file... + Dosyadan yükle... + + + + Close + Kapat + + + + Double-click to edit color + Rengi düzenlemek için çift tıklayın + + + + + + + + + true + doğru + + + + + + + false + YANLIŞ + + + + Double-click to toggle + Geçiş yapmak için çift tıklayın + + + + Double-click to edit value + Değeri düzenlemek için çift tıklayın + + + + + + Edit: %1 + Düzenleme: %1 + + + + Save theme + Temayı kaydet + + + + + JSON files (*.json);;All files (*) + JSON dosyaları (*.json);;Tüm dosyalar (*) + + + + Save failed + Kaydetme başarısız oldu + + + + Could not open file for writing: +%1 + Dosya yazmak için açılamadı: +%1 + + + + Load theme + Temayı yükle + + + + + + Load failed + Yükleme başarısız oldu + + + + Could not open file: +%1 + Dosya açılamadı: +%1 + + + + Invalid JSON: +%1 + Geçersiz JSON: +%1 + + + + Expected a JSON object. + Bir JSON nesnesi bekleniyordu. + + + + TitleHeader + + + SEARCH + ARA + + + + UpdateLibraryDialog + + + Updating.... + Güncelleniyor... + + + + Cancel + Vazgeç + + + + Update library + Kütüphaneyi güncelle + + + + Viewer + + + + Press 'O' to open comic. + 'O'ya basarak aç. + + + + Not found + Bulunamadı + + + + Comic not found + Çizgi roman bulunamadı + + + + Error opening comic + Çizgi roman açılırken hata + + + + CRC Error + CRC Hatası + + + + Loading...please wait! + Yükleniyor... lütfen bekleyin! + + + + Page not available! + Sayfa bulunamadı! + + + + Cover! + Kapak! + + + + Last page! + Son sayfa! + + + + VolumeComicsModel + + + title + başlık + + + + VolumesModel + + + year + yıl + + + + issues + sayı + + + + publisher + yayıncı + + + + YACReader3DFlowConfigWidget + + + Presets: + Hazırlayan: + + + + Classic look + Klasik görünüm + + + + Stripe look + Şerit görünüm + + + + Overlapped Stripe look + Çakışan şerit görünüm + + + + Modern look + Modern görünüm + + + + Roulette look + Rulet görünüm + + + + Show advanced settings + Daha fazla ayar göster + + + + Custom: + Kişisel: + + + + View angle + Bakış açısı + + + + Position + Pozisyon + + + + Cover gap + Kapak boşluğu + + + + Central gap + Boş merkaz + + + + Zoom + Yakınlaş + + + + Y offset + Y dengesi + + + + Z offset + Z dengesi + + + + Cover Angle + Kapak Açısı + + + + Visibility + Görünülebilirlik + + + + Light + Işık + + + + Max angle + Maksimum açı + + + + Low Performance + Düşük Performans + + + + High Performance + Yüksek performans + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + VSync kullan + + + + Performance: + Performans: + + + + YACReader::MainWindowViewer + + + &Open + &Aç + + + + Open a comic + Çizgi romanı aç + + + + New instance + Yeni örnek + + + + Open Folder + Dosyayı Aç + + + + Open image folder + Resim dosyasınıaç + + + + Open latest comic + En son çizgi romanı aç + + + + Open the latest comic opened in the previous reading session + Önceki okuma oturumunda açılan en son çizgi romanı aç + + + + Clear + Temizle + + + + Clear open recent list + Son açılanlar listesini temizle + + + + Save + Kaydet + + + + + Save current page + Geçerli sayfayı kaydet + + + + Previous Comic + Önce ki çizgi roman + + + + + + Open previous comic + Önceki çizgi romanı aç + + + + Next Comic + Sırada ki çizgi roman + + + + + + Open next comic + Sıradaki çizgi romanı aç + + + + &Previous + &Geri + + + + + + Go to previous page + Önceki sayfaya dön + + + + &Next + &İleri + + + + + + Go to next page + Sonra ki sayfaya geç + + + + Fit Height + Yüksekliğe Sığdır + + + + Fit image to height + Uygun yüksekliğe getir + + + + Fit Width + Uygun Genişlik + + + + Fit image to width + Görüntüyü sığdır + + + + Show full size + Tam erken + + + + Fit to page + Sayfaya sığdır + + + + Continuous scroll + Sürekli kaydırma + + + + Switch to continuous scroll mode + Sürekli kaydırma moduna geç + + + + Reset zoom + Yakınlaştırmayı sıfırla + + + + Show zoom slider + Yakınlaştırma çubuğunu göster + + + + Zoom+ + Yakınlaştır + + + + Zoom- + Uzaklaştır + + + + Rotate image to the left + Sayfayı sola yatır + + + + Rotate image to the right + Sayfayı sağa yator + + + + Double page mode + Çift sayfa modu + + + + Switch to double page mode + Çift sayfa moduna geç + + + + Double page manga mode + Çift sayfa manga kipi + + + + Reverse reading order in double page mode + Çift sayfa kipinde ters okuma sırası + + + + Go To + Git + + + + Go to page ... + Sayfata git... + + + + Options + Ayarlar + + + + YACReader options + YACReader ayarları + + + + + Help + Yardım + + + + Help, About YACReader + YACReader hakkında yardım ve bilgi + + + + Magnifying glass + Büyüteç + + + + Switch Magnifying glass + Büyüteç + + + + Set bookmark + Yer imi yap + + + + Set a bookmark on the current page + Sayfayı yer imi olarak ayarla + + + + Show bookmarks + Yer imlerini göster + + + + Show the bookmarks of the current comic + Bu çizgi romanın yer imlerini göster + + + + Show keyboard shortcuts + Klavye kısayollarını göster + + + + Show Info + Bilgiyi göster + + + + Close + Kapat + + + + Show Dictionary + Sözlüğü göster + + + + Show go to flow + Akışı göster + + + + Edit shortcuts + Kısayolları düzenle + + + + &File + &Dosya + + + + + Open recent + Son dosyaları aç + + + + File + Dosya + + + + Edit + Düzen + + + + View + Görünüm + + + + Go + Git + + + + Window + Pencere + + + + + + Open Comic + Çizgi Romanı Aç + + + + + + Comic files + Çizgi Roman Dosyaları + + + + Open folder + Dosyayı aç + + + + page_%1.jpg + sayfa_%1.jpg + + + + Image files (*.jpg) + Resim dosyaları (*.jpg) + + + + + Comics + Çizgi Roman + + + + + General + Genel + + + + + Magnifiying glass + Büyüteç + + + + + Page adjustement + Sayfa ayarı + + + + + Reading + Okuma + + + + Toggle fullscreen mode + Tam ekran kipini aç/kapat + + + + Hide/show toolbar + Araç çubuğunu göster/gizle + + + + Size up magnifying glass + Büyüteci büyüt + + + + Size down magnifying glass + Büyüteci küçült + + + + Zoom in magnifying glass + Büyüteci yakınlaştır + + + + Zoom out magnifying glass + Büyüteci uzaklaştır + + + + Reset magnifying glass + Büyüteci sıfırla + + + + Toggle between fit to width and fit to height + Genişliğe sığdır ile yüksekliğe sığdır arasında geçiş yap + + + + Autoscroll down + Otomatik aşağı kaydır + + + + Autoscroll up + Otomatik yukarı kaydır + + + + Autoscroll forward, horizontal first + Otomatik ileri kaydır, önce yatay + + + + Autoscroll backward, horizontal first + Otomatik geri kaydır, önce yatay + + + + Autoscroll forward, vertical first + Otomatik ileri kaydır, önce dikey + + + + Autoscroll backward, vertical first + Otomatik geri kaydır, önce dikey + + + + Move down + Aşağı git + + + + Move up + Yukarı git + + + + Move left + Sola git + + + + Move right + Sağa git + + + + Go to the first page + İlk sayfaya git + + + + Go to the last page + En son sayfaya git + + + + Offset double page to the left + Çift sayfayı sola kaydır + + + + Offset double page to the right + Çift sayfayı sağa kaydır + + + + There is a new version available + Yeni versiyon mevcut + + + + Do you want to download the new version? + Yeni versiyonu indirmek ister misin ? + + + + Remind me in 14 days + 14 gün içinde hatırlat + + + + Not now + Şimdi değil + + + + YACReader::TrayIconController + + + &Restore + &Geri Yükle + + + + Systray + Sistem tepsisi + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary sistem tepsisinde çalışmaya devam edecektir. Programı sonlandırmak için sistem tepsisi simgesinin bağlam menüsünden <b>Çık</b>'ı seçin. + + + + YACReaderFieldEdit + + + + Click to overwrite + Üzerine yazmak için tıkla + + + + Restore to default + Varsayılana ayarla + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + Üzerine yazmak için tıkla + + + + Restore to default + Varsayılana ayarla + + + + YACReaderOptionsDialog + + + Save + Kaydet + + + + Cancel + Vazgeç + + + + Edit shortcuts + Kısayolları düzenle + + + + Shortcuts + Kısayollar + + + + YACReaderSearchLineEdit + + + type to search + aramak için yazınız + + + + YACReaderSlider + + + Reset + Yeniden başlat - QsLogging::Window + YACReaderTranslator - - &Pause - + + YACReader translator + YACReader çevirmeni - - &Resume - + + + Translation + Çeviri - - Save log - + + clear + temizle - - Log file (*.log) - + + Service not available + Servis kullanılamıyor diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_zh_CN.ts b/YACReaderLibraryServer/yacreaderlibraryserver_zh_CN.ts index 45baf7bd7..9c36ddbde 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_zh_CN.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_zh_CN.ts @@ -2,150 +2,3712 @@ - FileComic + ActionsShortcutsModel - - CRC error on page (%1): some of the pages will not be displayed correctly - + + None + + + + AddLabelDialog - - Unknown error opening the file - + + Label name: + 标签名称: - - 7z not found - + + Choose a color: + 选择标签颜色: - - Format not supported - + + accept + 接受 + + + + cancel + 取消 - LogWindow + AddLibraryDialog + + + Comics folder : + 漫画文件夹: + + + + Library name : + 库名: + - - Log window - + + Add + 添加 - - &Pause - + + Cancel + 取消 - - &Save - + + Add an existing library + 添加一个现有库 + + + ApiKeyDialog - - C&lear - + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要拥有自己的API密钥才能够连接Comic Vine. 你可以通过这个链接获得一个免费的<a href="http://www.comicvine.com/api/">API</a>密钥 - - &Copy - + + Paste here your Comic Vine API key + 在此粘贴你的Comic Vine API - - Level: - + + Accept + 接受 - - &Auto scroll - + + Cancel + 取消 - QCoreApplication + AppearanceTabWidget - - -YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + + Color scheme + 配色方案 + + + + System + 系统 + + + + Light + 亮度 + + + + Dark + 黑暗的 + + + + Custom + 风俗 + + + + Remove + 消除 + + + + Remove this user-imported theme + 删除此用户导入的主题 + + + + Light: + 光: + + + + Dark: + 黑暗的: + + + + Custom: + 自定义: + + + + Import theme... + 导入主题... + + + + Theme + 主题 + + + + Theme editor + 主题编辑器 + + + + Open Theme Editor... + 打开主题编辑器... + + + + Theme editor error + 主题编辑器错误 + + + + The current theme JSON could not be loaded. + 无法加载当前主题 JSON。 + + + + Import theme + 导入主题 + + + + JSON files (*.json);;All files (*) + JSON 文件 (*.json);;所有文件 (*) + + + + Could not import theme from: +%1 + 无法从以下位置导入主题: +%1 + + + + Could not import theme from: +%1 -This appplication supports persistent settings, to set them up edit this file %1 -To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md - +%2 + 无法从以下位置导入主题: +%1 + +%2 + + + + Import failed + 导入失败 - QObject + BookmarksDialog - - Trace - + + Lastest Page + 尾页 - - Debug - + + Close + 关闭 - - Info - + + Click on any image to go to the bookmark + 点击任意图片以跳转至相应书签位置 - - Warning - + + + Loading... + 载入中... + + + ClassicComicsView - - Error - + + Hide comic flow + 隐藏漫画流 + + + + ComicModel + + + yes + - - Fatal - + + no + + + + + Title + 标题 + + + + File Name + 文件名 + + + + Pages + 页数 + + + + Size + 大小 + + + + Read + 阅读 + + + + Current Page + 当前页 + + + + Publication Date + 出版日期 + + + + Rating + 评分 + + + + Series + 系列 + + + + Volume + + + + + Story Arc + 故事线 + + + + ComicVineDialog + + + skip + 忽略 + + + + back + 返回 + + + + next + 下一步 + + + + search + 搜索 + + + + close + 关闭 + + + + + comic %1 of %2 - %3 + 第 %1 本 共 %2 本 - %3 + + + + + + Looking for volume... + 搜索卷... + + + + %1 comics selected + 已选择 %1 本漫画 + + + + Error connecting to ComicVine + ComicVine 连接时出错 + + + + + Retrieving tags for : %1 + 正在检索标签: %1 + + + + Retrieving volume info... + 正在接收卷信息... + + + + Looking for comic... + 搜索漫画中... + + + + ContinuousPageWidget + + + Loading page %1 + 正在加载页面 %1 + + + + CreateLibraryDialog + + + Comics folder : + 漫画文件夹: + + + + Library Name : + 库名: + + + + Create + 创建 + + + + Cancel + 取消 + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + 创建一个新的库可能需要几分钟时间,您可以先停止该进程,稍后可以通过更新库选项来更新数据。 + + + + Create new library + 创建新的漫画库 + + + + Path not found + 未找到路径 + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + 所选路径不存在或不是有效路径. 确保您具有此文件夹的写入权限 + + + + EditShortcutsDialog + + + Restore defaults + 恢复默认 + + + + To change a shortcut, double click in the key combination and type the new keys. + 更改快捷键: 双击按键组合并输入新的映射. + + + + Shortcuts settings + 快捷键设置 + + + + Shortcut in use + 快捷键被占用 + + + + The shortcut "%1" is already assigned to other function + 快捷键 "%1" 已被映射至其他功能 + + + + EmptyFolderWidget + + + This folder doesn't contain comics yet + 该文件夹还没有漫画 + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + 此标签尚未包含漫画 + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + 此阅读列表尚未包含任何漫画 + + + + EmptySpecialListWidget + + + No favorites + 没有收藏 + + + + You are not reading anything yet, come on!! + 你还没有阅读任何东西,加油!! + + + + There are no recent comics! + 没有最近的漫画! + + + + ExportComicsInfoDialog + + + Output file : + 输出文件: + + + + Create + 创建 + + + + Cancel + 取消 + + + + Export comics info + 导出漫画信息 + + + + Destination database name + 目标数据库名称 + + + + Problem found while writing + 写入时出现问题 + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 选定的输出文件路径不存在或路径无效. 确保您具有此文件夹的写入权限 + + + + ExportLibraryDialog + + + Output folder : + 输出文件夹: + + + + Create + 创建 + + + + Cancel + 取消 + + + + Create covers package + 创建封面包 + + + + Problem found while writing + 写入时出现问题 + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 选定的输出文件路径不存在或路径无效. 确保您具有此文件夹的写入权限 + + + + Destination directory + 目标目录 + + + + FileComic + + + CRC error on page (%1): some of the pages will not be displayed correctly + 第 %1 页 CRC 校验失败: 部分页面将无法正确显示 + + + + Unknown error opening the file + 打开文件时出现未知错误 + + + + 7z not found + 未找到 7z + + + + Format not supported + 不支持的文件格式 + + + + GoToDialog + + + Page : + 页码 : + + + + Go To + 跳转 + + + + Cancel + 取消 + + + + + Total pages : + 总页数: + + + + Go to... + 跳转至 ... + + + + GoToFlowToolBar + + + Page : + 页码 : - QsLogging::LogWindowModel + GridComicsView - - Time - + + Show info + 显示信息 + + + HelpAboutDialog - - Level - + + About + 关于 - - Message - + + Help + 帮助 + + + + System info + 系统信息 + + + + ImportComicsInfoDialog + + + Import comics info + 导入漫画信息 + + + + Info database location : + 数据库地址: + + + + Import + 导入 + + + + Cancel + 取消 + + + + Comics info file (*.ydb) + 漫画信息文件(*.ydb) + + + + ImportLibraryDialog + + + Library Name : + 库名: + + + + Package location : + 打包地址: + + + + Destination folder : + 目标文件夹: + + + + Unpack + 解压 + + + + Cancel + 取消 + + + + Extract a catalog + 提取目录 + + + + Compresed library covers (*.clc) + 已压缩的库封面 (*.clc) + + + + ImportWidget + + + stop + 停止 + + + + Some of the comics being added... + 正在添加漫画... + + + + Importing comics + 正在导入漫画 + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary现在正在创建一个新库。</p><p>这可能需要几分钟时间,您可以先停止该进程,稍后可以通过更新库选项来更新数据。</p> + + + + Updating the library + 正在更新库 + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>正在更新当前库。要获得更快的更新,请经常更新您的库。</p><p>您可以停止该进程,稍后继续更新操作。</p> + + + + Upgrading the library + 正在更新库 + + + + <p>The current library is being upgraded, please wait.</p> + <p>正在更新当前漫画库, 请稍候.</p> + + + + Scanning the library + 正在扫描库 + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>正在扫描当前库的旧版 XML metadata 信息。</p><p>这只需要执行一次,且只有当创建库的 YACReaderLibrary 版本低于 9.8.2 时。</p> + + + + LibraryWindow + + + YACReader Library + YACReader 库 + + + + + + comic + 漫画 + + + + + + manga + 日本漫画 + + + + + + western manga (left to right) + 欧美漫画(从左到右) + + + + + + web comic + 网络漫画 + + + + + + 4koma (top to botom) + 四格漫画(从上到下) + + + + + + + Set type + 设置类型 + + + + Library + + + + + Folder + 文件夹 + + + + Comic + 漫画 + + + + Upgrade failed + 更新失败 + + + + There were errors during library upgrade in: + 漫画库更新时出现错误: + + + + Update needed + 需要更新 + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + 此库是使用旧版本的YACReaderLibrary创建的. 它需要更新. 现在更新? + + + + Download new version + 下载新版本 + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + 此库是使用较新版本的YACReaderLibrary创建的。 立即下载新版本? + + + + Library not available + 库不可用 + + + + Library '%1' is no longer available. Do you want to remove it? + 库 '%1' 不再可用。 你想删除它吗? + + + + Old library + 旧的库 + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 库 '%1' 是通过旧版本的YACReaderLibrary创建的。 必须再次创建。 你想现在创建吗? + + + + + Copying comics... + 复制漫画中... + + + + + Moving comics... + 移动漫画中... + + + + Add new folder + 添加新的文件夹 + + + + Folder name: + 文件夹名称: + + + + No folder selected + 没有选中的文件夹 + + + + Please, select a folder first + 请先选择一个文件夹 + + + + Error in path + 路径错误 + + + + There was an error accessing the folder's path + 访问文件夹的路径时出错 + + + + Delete folder + 删除文件夹 + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + 所选文件夹及其所有内容将从磁盘中删除。 你确定吗? + + + + + Unable to delete + 无法删除 + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + 尝试删除所选文件夹时出现问题。 请检查写入权限,并确保没有其他应用程序在使用这些文件夹或文件。 + + + + Add new reading lists + 添加新的阅读列表 + + + + + List name: + 列表名称: + + + + Delete list/label + 删除 列表/标签 + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + 所选项目将被删除,您的漫画或文件夹将不会从您的磁盘中删除。 你确定吗? + + + + Rename list name + 重命名列表 + + + + Open folder... + 打开文件夹... + + + + Update folder + 更新文件夹 + + + + Rescan library for XML info + 重新扫描库的 XML 信息 + + + + Set as uncompleted + 设为未完成 + + + + Set as completed + 设为已完成 + + + + Set as read + 设为已读 + + + + + Set as unread + 设为未读 + + + + Set custom cover + 设置自定义封面 + + + + Delete custom cover + 删除自定义封面 + + + + Save covers + 保存封面 + + + + You are adding too many libraries. + 您添加的库太多了。 + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + 您添加的库太多了。 + +一般情况只需要一个顶级的库,您可以使用左侧边栏中的文件夹功能来进行分类管理。 + +YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低的库数量来提升性能。 + + + + + YACReader not found + YACReader 未找到 + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + 未找到YACReader. YACReader应安装在与YACReaderLibrary相同的文件夹中. + + + + YACReader not found. There might be a problem with your YACReader installation. + 未找到YACReader. YACReader的安装可能有问题. + + + + Error + 错误 + + + + Error opening comic with third party reader. + 使用第三方阅读器打开漫画时出错。 + + + + Library not found + 未找到库 + + + + The selected folder doesn't contain any library. + 所选文件夹不包含任何库。 + + + + Are you sure? + 你确定吗? + + + + Do you want remove + 你想要删除 + + + + library? + 库? + + + + Remove and delete metadata + 移除并删除元数据 + + + + Library info + 图书馆信息 + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + 尝试删除所选漫画时出现问题。 请检查所选文件或包含文件夹中的写入权限。 + + + + Assign comics numbers + 分配漫画编号 + + + + Assign numbers starting in: + 从以下位置开始分配编号: + + + + Invalid image + 图片无效 + + + + The selected file is not a valid image. + 所选文件不是有效图像。 + + + + Error saving cover + 保存封面时出错 + + + + There was an error saving the cover image. + 保存封面图像时出错。 + + + + Error creating the library + 创建库时出错 + + + + Error updating the library + 更新库时出错 + + + + Error opening the library + 打开库时出错 + + + + Delete comics + 删除漫画 + + + + All the selected comics will be deleted from your disk. Are you sure? + 所有选定的漫画都将从您的磁盘中删除。你确定吗? + + + + Remove comics + 移除漫画 + + + + Comics will only be deleted from the current label/list. Are you sure? + 漫画只会从当前标签/列表中删除。 你确定吗? + + + + Library name already exists + 库名已存在 + + + + There is another library with the name '%1'. + 已存在另一个名为'%1'的库。 + + + + LibraryWindowActions + + + Create a new library + 创建一个新的库 + + + + Open an existing library + 打开现有的库 + + + + + Export comics info + 导出漫画信息 + + + + + Import comics info + 导入漫画信息 + + + + Pack covers + 打包封面 + + + + Pack the covers of the selected library + 打包所选库的封面 + + + + Unpack covers + 解压封面 + + + + Unpack a catalog + 解压目录 + + + + Update library + 更新库 + + + + Update current library + 更新当前库 + + + + Rename library + 重命名库 + + + + Rename current library + 重命名当前库 + + + + Remove library + 移除库 + + + + Remove current library from your collection + 从您的集合中移除当前库 + + + + Rescan library for XML info + 重新扫描库的 XML 信息 + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + 尝试查找漫画文件内嵌的 XML 信息。只有当创建库的 YACReaderLibrary 版本低于 9.8.2 或者使用第三方软件嵌入 XML 信息时,才需要执行该操作。 + + + + Show library info + 显示图书馆信息 + + + + Show information about the current library + 显示当前库的信息 + + + + Open current comic + 打开当前漫画 + + + + Open current comic on YACReader + 用YACReader打开漫画 + + + + Save selected covers to... + 选中的封面保存到... + + + + Save covers of the selected comics as JPG files + 保存所选的封面为jpg + + + + + Set as read + 设为已读 + + + + Set comic as read + 漫画设为已读 + + + + + Set as unread + 设为未读 + + + + Set comic as unread + 漫画设为未读 + + + + + manga + 日本漫画 + + + + Set issue as manga + 将问题设置为漫画 + + + + + comic + 漫画 + + + + Set issue as normal + 设置漫画为 + + + + western manga + 欧美漫画 + + + + Set issue as western manga + 设置为欧美漫画 + + + + + web comic + 网络漫画 + + + + Set issue as web comic + 设置为网络漫画 + + + + + yonkoma + 四格漫画 + + + + Set issue as yonkoma + 设置为四格漫画 + + + + Show/Hide marks + 显示/隐藏标记 + + + + Show or hide read marks + 显示或隐藏阅读标记 + + + + Show/Hide recent indicator + 显示/隐藏最近的指示标志 + + + + Show or hide recent indicator + 显示或隐藏最近的指示标志 + + + + + Fullscreen mode on/off + 全屏模式 开/关 + + + + Help, About YACReader + 帮助, 关于 YACReader + + + + Add new folder + 添加新的文件夹 + + + + Add new folder to the current library + 在当前库下添加新的文件夹 + + + + Delete folder + 删除文件夹 + + + + Delete current folder from disk + 从磁盘上删除当前文件夹 + + + + Select root node + 选择根节点 + + + + Expand all nodes + 展开所有节点 + + + + Collapse all nodes + 折叠所有节点 + + + + Show options dialog + 显示选项对话框 + + + + Show comics server options dialog + 显示漫画服务器选项对话框 + + + + + Change between comics views + 漫画视图之间的变化 + + + + Open folder... + 打开文件夹... + + + + Set as uncompleted + 设为未完成 + + + + Set as completed + 设为已完成 + + + + Set custom cover + 设置自定义封面 + + + + Delete custom cover + 删除自定义封面 + + + + western manga (left to right) + 欧美漫画(从左到右) + + + + Open containing folder... + 打开包含文件夹... + + + + Reset comic rating + 重置漫画评分 + + + + Select all comics + 全选漫画 + + + + Edit + 编辑 + + + + Assign current order to comics + 将当前序号分配给漫画 + + + + Update cover + 更新封面 + + + + Delete selected comics + 删除所选的漫画 + + + + Delete metadata from selected comics + 从选定的漫画中删除元数据 + + + + Download tags from Comic Vine + 从 Comic Vine 下载标签 + + + + Focus search line + 聚焦于搜索行 + + + + Focus comics view + 聚焦于漫画视图 + + + + Edit shortcuts + 编辑快捷键 + + + + &Quit + 退出(&Q) + + + + Update folder + 更新文件夹 + + + + Update current folder + 更新当前文件夹 + + + + Scan legacy XML metadata + 扫描旧版 XML 元数据 + + + + Add new reading list + 添加新的阅读列表 + + + + Add a new reading list to the current library + 在当前库添加新的阅读列表 + + + + Remove reading list + 移除阅读列表 + + + + Remove current reading list from the library + 从当前库移除阅读列表 + + + + Add new label + 添加新标签 + + + + Add a new label to this library + 在当前库添加标签 + + + + Rename selected list + 重命名列表 + + + + Rename any selected labels or lists + 重命名任何选定的标签或列表 + + + + Add to... + 添加到... + + + + Favorites + 收藏夹 + + + + Add selected comics to favorites list + 将所选漫画添加到收藏夹列表 + + + + LocalComicListModel + + + file name + 文件名 + + + + NoLibrariesWidget + + + You don't have any libraries yet + 你还没有库 + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>您可以在任何文件夹中创建库,YACReaderLibrary将导入此文件夹中的所有漫画和文件夹。如果已有库,则可以打开它们。</p><p>您可以把YACReader当成独立应用来阅读电脑上的漫画。</p> + + + + create your first library + 创建你的第一个库 + + + + add an existing one + 添加一个现有库 + + + + NoSearchResultsWidget + + + No results + 没有结果 + + + + OptionsDialog + + + + General + 常规 + + + + + Libraries + + + + + Comic Flow + 漫画流 + + + + Grid view + 网格视图 + + + + + Appearance + 外貌 + + + + + Options + 选项 + + + + + Language + 语言 + + + + + Application language + 应用程序语言 + + + + + System default + 系统默认 + + + + Tray icon settings (experimental) + 托盘图标设置 (实验特性) + + + + Close to tray + 关闭至托盘 + + + + Start into the system tray + 启动至系统托盘 + + + + Edit Comic Vine API key + 编辑Comic Vine API 密匙 + + + + Comic Vine API key + Comic Vine API 密匙 + + + + ComicInfo.xml legacy support + ComicInfo.xml 旧版支持 + + + + Import metadata from ComicInfo.xml when adding new comics + 添加新漫画时从 ComicInfo.xml 导入元数据 + + + + Consider 'recent' items added or updated since X days ago + 参考自 X 天前添加或更新的“最近”项目 + + + + Third party reader + 第三方阅读器 + + + + Write {comic_file_path} where the path should go in the command + 在命令中应将路径写入 {comic_file_path} + + + + + Clear + 清空 + + + + Update libraries at startup + 启动时更新库 + + + + Try to detect changes automatically + 尝试自动检测变化 + + + + Update libraries periodically + 定期更新库 + + + + Interval: + 间隔: + + + + 30 minutes + 30分钟 + + + + 1 hour + 1小时 + + + + 2 hours + 2小时 + + + + 4 hours + 4小时 + + + + 8 hours + 8小时 + + + + 12 hours + 12小时 + + + + daily + 每天 + + + + Update libraries at certain time + 定时更新库 + + + + Time: + 时间: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + 警告! 在库更新期间,将禁用对数据库的写入! +当您可能正在积极使用该应用程序时,请勿安排更新。 +在自动更新期间,应用程序将阻止某些操作,直到更新完成。 +要停止自动更新,请点击库标题旁边的加载指示器。 + + + + Modifications detection + 修改检测 + + + + Compare the modified date of files when updating a library (not recommended) + 更新库时比较文件的修改日期(不推荐) + + + + Enable background image + 启用背景图片 + + + + Opacity level + 透明度 + + + + Blur level + 模糊 + + + + Use selected comic cover as background + 使用选定的漫画封面做背景 + + + + Restore defautls + 恢复默认值 + + + + Background + 背景 + + + + Display continue reading banner + 显示继续阅读横幅 + + + + Display current comic banner + 显示当前漫画横幅 + + + + Continue reading + 继续阅读 + + + + My comics path + 我的漫画路径 + + + + Display + 展示 + + + + Show time in current page information label + 在当前页面信息标签中显示时间 + + + + "Go to flow" size + 页面流尺寸 + + + + Background color + 背景颜色 + + + + Choose + 选择 + + + + Scroll behaviour + 滚动效果 + + + + Disable scroll animations and smooth scrolling + 禁用滚动动画和平滑滚动 + + + + Do not turn page using scroll + 滚动时不翻页 + + + + Use single scroll step to turn page + 使用单滚动步骤翻页 + + + + Mouse mode + 鼠标模式 + + + + Only Back/Forward buttons can turn pages + 只有后退/前进按钮可以翻页 + + + + Use the Left/Right buttons to turn pages. + 使用向左/向右按钮翻页。 + + + + Click left or right half of the screen to turn pages. + 单击屏幕的左半部分或右半部分即可翻页。 + + + + Quick Navigation Mode + 快速导航模式 + + + + Disable mouse over activation + 禁用鼠标激活 + + + + Brightness + 亮度 + + + + Contrast + 对比度 + + + + Gamma + Gamma值 + + + + Reset + 重置 + + + + Image options + 图片选项 + + + + Fit options + 适应项 + + + + Enlarge images to fit width/height + 放大图片以适应宽度/高度 + + + + Double Page options + 双页选项 + + + + Show covers as single page + 显示封面为单页 + + + + Scaling + 缩放 + + + + Scaling method + 缩放方法 + + + + Nearest (fast, low quality) + 最近(快速,低质量) + + + + Bilinear + 双线性 + + + + Lanczos (better quality) + Lanczos(质量更好) + + + + Page Flow + 页面流 + + + + Image adjustment + 图像调整 + + + + + Restart is needed + 需要重启 + + + + Comics directory + 漫画目录 + + + + PropertiesDialog + + + General info + 基本信息 + + + + Plot + 情节 + + + + Authors + 作者 + + + + Publishing + 出版 + + + + Notes + 笔记 + + + + Cover page + 封面 + + + + Load previous page as cover + 加载上一页作为封面 + + + + Load next page as cover + 加载下一页作为封面 + + + + Reset cover to the default image + 将封面重置为默认图像 + + + + Load custom cover image + 加载自定义封面图片 + + + + Series: + 系列: + + + + Title: + 标题: + + + + + + of: + 的: + + + + Issue number: + 发行刊号: + + + + Volume: + 卷: + + + + Arc number: + 世界线数量: + + + + Story arc: + 故事线: + + + + alt. number: + 备选编号: + + + + Alternate series: + 备用系列: + + + + Series Group: + 系列组: + + + + Genre: + 类型: + + + + Size: + 大小: + + + + Writer(s): + 作者: + + + + Penciller(s): + 线稿师: + + + + Inker(s): + 上墨师: + + + + Colorist(s): + 上色师: + + + + Letterer(s): + 嵌字师: + + + + Cover Artist(s): + 封面设计: + + + + Editor(s): + 编辑: + + + + Imprint: + 印记: + + + + Day: + 日: + + + + Month: + 月: + + + + Year: + 年: + + + + Publisher: + 出版商: + + + + Format: + 格式: + + + + Color/BW: + 彩色/黑白: + + + + Age rating: + 年龄分级: + + + + Type: + 类型: + + + + Language (ISO): + 语言(ISO): + + + + Synopsis: + 简介: + + + + Characters: + 角色: + + + + Teams: + 团队: + + + + Locations: + 地点: + + + + Main character or team: + 主要角色或团队: + + + + Review: + 审查: + + + + Notes: + 笔记: + + + + Tags: + 标签: + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 连接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + + + + Not found + 未找到 + + + + Comic not found. You should update your library. + 未找到漫画,请先更新您的库. + + + + Edit comic information + 编辑漫画信息 + + + + Edit selected comics information + 编辑选中的漫画信息 + + + + Invalid cover + 封面无效 + + + + The image is invalid. + 该图像无效。 + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 + +此应用程序支持持久设置,要设置它们,请编辑此文件 %1 +要了解可用设置,请查看文档:https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject + + + Trace + 追踪 + + + + Debug + 除错 + + + + Info + 信息 + + + + Warning + 警告 + + + + Error + 错误 + + + + Fatal + 严重错误 + + + + Select custom cover + 选择自定义封面 + + + + Images (%1) + 图片 (%1) + + + + 7z lib not found + 未找到 7z 库文件 + + + + unable to load 7z lib from ./utils + 无法从 ./utils 载入 7z 库文件 + + + + The file could not be read or is not valid JSON. + 无法读取该文件或者该文件不是有效的 JSON。 + + + + This theme is for %1, not %2. + 此主题适用于 %1,而不是 %2。 + + + + Libraries + + + + + Folders + 文件夹 + + + + Reading Lists + 阅读列表 + + + + RenameLibraryDialog + + + New Library Name : + 新库名: + + + + Rename + 重命名 + + + + Cancel + 取消 + + + + Rename current library + 重命名当前库 + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + 搜索结果: %1 + + + + + page %1 of %2 + 第 %1 页 共 %2 页 + + + + Number of %1 found : %2 + 第 %1 页 共: %2 条 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + 请提供附加信息. + + + + Series: + 系列: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + 使用精确匹配搜索。如果您想要查找与名称中某些单词匹配的卷,请禁用。 + + + + SearchVolume + + + Please provide some additional information. + 请提供附加信息. + + + + Series: + 系列: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + 使用精确匹配搜索。如果您想要查找与名称中某些单词匹配的卷,请禁用。 + + + + SelectComic + + + Please, select the right comic info. + 请正确选择漫画信息. + + + + comics + 漫画 + + + + loading cover + 加载封面 + + + + loading description + 加载描述 + + + + comic description unavailable + 漫画描述不可用 + + + + SelectVolume + + + Please, select the right series for your comic. + 请选择正确的漫画系列。 + + + + Filter: + 筛选: + + + + volumes + + + + + Nothing found, clear the filter if any. + 未找到任何内容,如果有,请清除筛选器。 + + + + loading cover + 加载封面 + + + + loading description + 加载描述 + + + + volume description unavailable + 卷描述不可用 + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + 您正在尝试同时获取各种漫画的信息,它们是同一系列的吗? + + + + yes + + + + + no + + + + + ServerConfigDialog + + + set port + 设置端口 + + + + Server connectivity information + 服务器连接信息 + + + + Scan it! + 扫一扫! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 适用于 iOS 和 Android 设备。<br/>搜索 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + + + + Choose an IP address + 选择IP地址 + + + + Port + 端口 + + + + enable the server + 启用服务器 + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + 请在左侧对漫画列表进行排序,直到它与漫画的信息相符。 + + + + sort comics to match comic information + 排序漫画以匹配漫画信息 + + + + issues + 发行 + + + + remove selected comics + 移除所选漫画 + + + + restore all removed comics + 恢复所有移除的漫画 + + + + ThemeEditorDialog + + + Theme Editor + 主题编辑器 + + + + + + + + + + + - + - + + + + i + + + + + Expand all + 全部展开 + + + + Collapse all + 全部折叠 + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + 按住可在 UI 中闪烁所选值(洋红色/切换/0↔10)。发布后恢复原样。 + + + + Search… + 搜索… + + + + Light + 亮度 + + + + Dark + 黑暗的 + + + + ID: + ID: + + + + Display name: + 显示名称: + + + + Variant: + 变体: + + + + Theme info + 主题信息 + + + + Parameter + 范围 + + + + Value + 价值 + + + + Save and apply + 保存并应用 + + + + Export to file... + 导出到文件... + + + + Load from file... + 从文件加载... + + + + Close + 关闭 + + + + Double-click to edit color + 双击编辑颜色 + + + + + + + + + true + 真的 + + + + + + + false + 错误的 + + + + Double-click to toggle + 双击切换 + + + + Double-click to edit value + 双击编辑值 + + + + + + Edit: %1 + 编辑:%1 + + + + Save theme + 保存主题 + + + + + JSON files (*.json);;All files (*) + JSON 文件 (*.json);;所有文件 (*) + + + + Save failed + 保存失败 + + + + Could not open file for writing: +%1 + 无法打开文件进行写入: +%1 + + + + Load theme + 加载主题 + + + + + + Load failed + 加载失败 + + + + Could not open file: +%1 + 无法打开文件: +%1 + + + + Invalid JSON: +%1 + 无效的 JSON: +%1 + + + + Expected a JSON object. + 需要一个 JSON 对象。 + + + + TitleHeader + + + SEARCH + 搜索 + + + + UpdateLibraryDialog + + + Updating.... + 更新中... + + + + Cancel + 取消 + + + + Update library + 更新库 + + + + Viewer + + + + Press 'O' to open comic. + 按下 'O' 以打开漫画. + + + + Not found + 未找到 + + + + Comic not found + 未找到漫画 + + + + Error opening comic + 打开漫画时发生错误 + + + + CRC Error + CRC 校验失败 + + + + Loading...please wait! + 载入中... 请稍候! + + + + Page not available! + 页面不可用! + + + + Cover! + 封面! + + + + Last page! + 尾页! + + + + VolumeComicsModel + + + title + 标题 + + + + VolumesModel + + + year + + + + + issues + 发行 + + + + publisher + 出版者 + + + + YACReader3DFlowConfigWidget + + + Presets: + 预设: + + + + Classic look + 经典 + + + + Stripe look + 条状 + + + + Overlapped Stripe look + 重叠条状 + + + + Modern look + 现代 + + + + Roulette look + 轮盘 + + + + Show advanced settings + 显示高级选项 + + + + Custom: + 自定义: + + + + View angle + 视角 + + + + Position + 位置 + + + + Cover gap + 封面间距 + + + + Central gap + 中心间距 + + + + Zoom + 缩放 + + + + Y offset + Y位移 + + + + Z offset + Z位移 + + + + Cover Angle + 封面角度 + + + + Visibility + 透明度 + + + + Light + 亮度 + + + + Max angle + 最大角度 + + + + Low Performance + 低性能 + + + + High Performance + 高性能 + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + 使用VSync (在全屏模式下提高图像质量, 性能更差) + + + + Performance: + 性能: + + + + YACReader::MainWindowViewer + + + &Open + 打开(&O) + + + + Open a comic + 打开漫画 + + + + New instance + 新建实例 + + + + Open Folder + 打开文件夹 + + + + Open image folder + 打开图片文件夹 + + + + Open latest comic + 打开最近的漫画 + + + + Open the latest comic opened in the previous reading session + 打开最近阅读漫画 + + + + Clear + 清空 + + + + Clear open recent list + 清空最近访问列表 + + + + Save + 保存 + + + + + Save current page + 保存当前页面 + + + + Previous Comic + 上一个漫画 + + + + + + Open previous comic + 打开上一个漫画 + + + + Next Comic + 下一个漫画 + + + + + + Open next comic + 打开下一个漫画 + + + + &Previous + 上一页(&P) + + + + + + Go to previous page + 转至上一页 + + + + &Next + 下一页(&N) + + + + + + Go to next page + 转至下一页 + + + + Fit Height + 适应高度 + + + + Fit image to height + 缩放图片以适应高度 + + + + Fit Width + 适合宽度 + + + + Fit image to width + 缩放图片以适应宽度 + + + + Show full size + 显示全尺寸 + + + + Fit to page + 适应页面 + + + + Continuous scroll + 连续滚动 + + + + Switch to continuous scroll mode + 切换到连续滚动模式 + + + + Reset zoom + 重置缩放 + + + + Show zoom slider + 显示缩放滑块 + + + + Zoom+ + 放大 + + + + Zoom- + 缩小 + + + + Rotate image to the left + 向左旋转图片 + + + + Rotate image to the right + 向右旋转图片 + + + + Double page mode + 双页模式 + + + + Switch to double page mode + 切换至双页模式 + + + + Double page manga mode + 双页漫画模式 + + + + Reverse reading order in double page mode + 双页模式 (逆序阅读) + + + + Go To + 跳转 + + + + Go to page ... + 跳转至页面 ... + + + + Options + 选项 + + + + YACReader options + YACReader 选项 + + + + + Help + 帮助 + + + + Help, About YACReader + 帮助, 关于 YACReader + + + + Magnifying glass + 放大镜 + + + + Switch Magnifying glass + 切换放大镜 + + + + Set bookmark + 设置书签 + + + + Set a bookmark on the current page + 在当前页面设置书签 + + + + Show bookmarks + 显示书签 + + + + Show the bookmarks of the current comic + 显示当前漫画的书签 + + + + Show keyboard shortcuts + 显示键盘快捷键 + + + + Show Info + 显示信息 + + + + Close + 关闭 + + + + Show Dictionary + 显示字典 + + + + Show go to flow + 显示页面流 + + + + Edit shortcuts + 编辑快捷键 + + + + &File + 文件(&F) + + + + + Open recent + 最近打开的文件 + + + + File + 文件 + + + + Edit + 编辑 + + + + View + 查看 + + + + Go + 转到 + + + + Window + 窗口 + + + + + + Open Comic + 打开漫画 + + + + + + Comic files + 漫画文件 + + + + Open folder + 打开文件夹 + + + + page_%1.jpg + 页_%1.jpg + + + + Image files (*.jpg) + 图像文件 (*.jpg) + + + + + Comics + 漫画 + + + + + General + 常规 + + + + + Magnifiying glass + 放大镜 + + + + + Page adjustement + 页面调整 + + + + + Reading + 阅读 + + + + Toggle fullscreen mode + 切换全屏模式 + + + + Hide/show toolbar + 隐藏/显示 工具栏 + + + + Size up magnifying glass + 增大放大镜尺寸 + + + + Size down magnifying glass + 减小放大镜尺寸 + + + + Zoom in magnifying glass + 增大缩放级别 + + + + Zoom out magnifying glass + 减小缩放级别 + + + + Reset magnifying glass + 重置放大镜 + + + + Toggle between fit to width and fit to height + 切换显示为"适应宽度"或"适应高度" + + + + Autoscroll down + 向下自动滚动 + + + + Autoscroll up + 向上自动滚动 + + + + Autoscroll forward, horizontal first + 向前自动滚动,水平优先 + + + + Autoscroll backward, horizontal first + 向后自动滚动,水平优先 + + + + Autoscroll forward, vertical first + 向前自动滚动,垂直优先 + + + + Autoscroll backward, vertical first + 向后自动滚动,垂直优先 + + + + Move down + 向下移动 + + + + Move up + 向上移动 + + + + Move left + 向左移动 + + + + Move right + 向右移动 + + + + Go to the first page + 转到第一页 + + + + Go to the last page + 转到最后一页 + + + + Offset double page to the left + 双页向左偏移 + + + + Offset double page to the right + 双页向右偏移 + + + + There is a new version available + 有新版本可用 + + + + Do you want to download the new version? + 你要下载新版本吗? + + + + Remind me in 14 days + 14天后提醒我 + + + + Not now + 现在不 + + + + YACReader::TrayIconController + + + &Restore + 复位(&R) + + + + Systray + 系统托盘 + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary 将继续在系统托盘中运行. 想要终止程序, 请在系统托盘图标的上下文菜单中选择<b>退出</b>. + + + + YACReaderFieldEdit + + + + Click to overwrite + 点击以覆盖 + + + + Restore to default + 恢复默认 + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + 点击以覆盖 + + + + Restore to default + 恢复默认 + + + + YACReaderOptionsDialog + + + Save + 保存 + + + + Cancel + 取消 + + + + Edit shortcuts + 编辑快捷键 + + + + Shortcuts + 快捷键 + + + + YACReaderSearchLineEdit + + + type to search + 搜索类型 + + + + YACReaderSlider + + + Reset + 重置 - QsLogging::Window + YACReaderTranslator - - &Pause - + + YACReader translator + YACReader 翻译 - - &Resume - + + + Translation + 翻译 - - Save log - + + clear + 清空 - - Log file (*.log) - + + Service not available + 服务不可用 diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_zh_HK.ts b/YACReaderLibraryServer/yacreaderlibraryserver_zh_HK.ts index bf29a6a1b..1f5e317e5 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_zh_HK.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_zh_HK.ts @@ -2,150 +2,3712 @@ - FileComic + ActionsShortcutsModel - - CRC error on page (%1): some of the pages will not be displayed correctly - + + None + + + + AddLabelDialog - - Unknown error opening the file - + + Label name: + 標籤名稱: - - 7z not found - + + Choose a color: + 選擇標籤顏色: - - Format not supported - + + accept + 接受 + + + + cancel + 取消 - LogWindow + AddLibraryDialog + + + Comics folder : + 漫畫檔夾: + + + + Library name : + 庫名: + - - Log window - + + Add + 添加 - - &Pause - + + Cancel + 取消 - - &Save - + + Add an existing library + 添加一個現有庫 + + + ApiKeyDialog - - C&lear - + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 - - &Copy - + + Paste here your Comic Vine API key + 在此粘貼你的Comic Vine API - - Level: - + + Accept + 接受 - - &Auto scroll - + + Cancel + 取消 - QCoreApplication + AppearanceTabWidget - - -YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + + Color scheme + 配色方案 + + + + System + 系統 + + + + Light + 亮度 + + + + Dark + 黑暗的 + + + + Custom + 風俗 + + + + Remove + 消除 + + + + Remove this user-imported theme + 刪除此使用者匯入的主題 + + + + Light: + 光: + + + + Dark: + 黑暗的: + + + + Custom: + 自定義: + + + + Import theme... + 導入主題... + + + + Theme + 主題 + + + + Theme editor + 主題編輯器 + + + + Open Theme Editor... + 開啟主題編輯器... + + + + Theme editor error + 主題編輯器錯誤 + + + + The current theme JSON could not be loaded. + 無法載入目前主題 JSON。 + + + + Import theme + 導入主題 + + + + JSON files (*.json);;All files (*) + JSON 檔案 (*.json);;所有檔案 (*) + + + + Could not import theme from: +%1 + 無法從以下位置匯入主題: +%1 + + + + Could not import theme from: +%1 -This appplication supports persistent settings, to set them up edit this file %1 -To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md - +%2 + 無法從以下位置匯入主題: +%1 + +%2 + + + + Import failed + 導入失敗 - QObject + BookmarksDialog - - Trace - + + Lastest Page + 尾頁 - - Debug - + + Close + 關閉 - - Info - + + Click on any image to go to the bookmark + 點擊任意圖片以跳轉至相應書簽位置 - - Warning - + + + Loading... + 載入中... + + + ClassicComicsView - - Error - + + Hide comic flow + 隱藏漫畫流 + + + + ComicModel + + + yes + - - Fatal - + + no + + + + + Title + 標題 + + + + File Name + 檔案名 + + + + Pages + 頁數 + + + + Size + 大小 + + + + Read + 閱讀 + + + + Current Page + 當前頁 + + + + Publication Date + 發行日期 + + + + Rating + 評分 + + + + Series + 系列 + + + + Volume + 體積 + + + + Story Arc + 故事線 + + + + ComicVineDialog + + + skip + 忽略 + + + + back + 返回 + + + + next + 下一步 + + + + search + 搜索 + + + + close + 關閉 + + + + + comic %1 of %2 - %3 + 第 %1 本 共 %2 本 - %3 + + + + + + Looking for volume... + 搜索卷... + + + + %1 comics selected + 已選擇 %1 本漫畫 + + + + Error connecting to ComicVine + ComicVine 連接時出錯 + + + + + Retrieving tags for : %1 + 正在檢索標籤: %1 + + + + Retrieving volume info... + 正在接收卷資訊... + + + + Looking for comic... + 搜索漫畫中... + + + + ContinuousPageWidget + + + Loading page %1 + 正在載入頁面 %1 + + + + CreateLibraryDialog + + + Comics folder : + 漫畫檔夾: + + + + Library Name : + 庫名: + + + + Create + 創建 + + + + Cancel + 取消 + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + 創建一個新的庫可能需要幾分鐘時間,您可以先停止該進程,稍後可以通過更新庫選項來更新數據。 + + + + Create new library + 創建新的漫畫庫 + + + + Path not found + 未找到路徑 + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + 所選路徑不存在或不是有效路徑. 確保您具有此檔夾的寫入許可權 + + + + EditShortcutsDialog + + + Restore defaults + 恢復默認 + + + + To change a shortcut, double click in the key combination and type the new keys. + 更改快捷鍵: 雙擊按鍵組合並輸入新的映射. + + + + Shortcuts settings + 快捷鍵設置 + + + + Shortcut in use + 快捷鍵被佔用 + + + + The shortcut "%1" is already assigned to other function + 快捷鍵 "%1" 已被映射至其他功能 + + + + EmptyFolderWidget + + + This folder doesn't contain comics yet + 該資料夾還沒有漫畫 + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + 此標籤尚未包含漫畫 + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + 此閱讀列表尚未包含任何漫畫 + + + + EmptySpecialListWidget + + + No favorites + 沒有收藏 + + + + You are not reading anything yet, come on!! + 你還沒有閱讀任何東西,加油!! + + + + There are no recent comics! + 沒有最近的漫畫! + + + + ExportComicsInfoDialog + + + Output file : + 輸出檔: + + + + Create + 創建 + + + + Cancel + 取消 + + + + Export comics info + 導出漫畫資訊 + + + + Destination database name + 目標資料庫名稱 + + + + Problem found while writing + 寫入時出現問題 + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 選定的輸出檔路徑不存在或路徑無效. 確保您具有此檔夾的寫入許可權 + + + + ExportLibraryDialog + + + Output folder : + 輸出檔夾: + + + + Create + 創建 + + + + Cancel + 取消 + + + + Create covers package + 創建封面包 + + + + Problem found while writing + 寫入時出現問題 + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 選定的輸出檔路徑不存在或路徑無效. 確保您具有此檔夾的寫入許可權 + + + + Destination directory + 目標目錄 + + + + FileComic + + + CRC error on page (%1): some of the pages will not be displayed correctly + 第 %1 頁 CRC 校驗失敗: 部分頁面將無法正確顯示 + + + + Unknown error opening the file + 打開檔時出現未知錯誤 + + + + 7z not found + 未找到 7z + + + + Format not supported + 不支持的檔格式 + + + + GoToDialog + + + Page : + 頁碼 : + + + + Go To + 跳轉 + + + + Cancel + 取消 + + + + + Total pages : + 總頁數: + + + + Go to... + 跳轉至 ... + + + + GoToFlowToolBar + + + Page : + 頁碼 : - QsLogging::LogWindowModel + GridComicsView - - Time - + + Show info + 顯示資訊 + + + HelpAboutDialog - - Level - + + About + 關於 - - Message - + + Help + 幫助 + + + + System info + 系統資訊 + + + + ImportComicsInfoDialog + + + Import comics info + 導入漫畫資訊 + + + + Info database location : + 資料庫地址: + + + + Import + 導入 + + + + Cancel + 取消 + + + + Comics info file (*.ydb) + 漫畫資訊檔(*.ydb) + + + + ImportLibraryDialog + + + Library Name : + 庫名: + + + + Package location : + 打包地址: + + + + Destination folder : + 目標檔夾: + + + + Unpack + 解壓 + + + + Cancel + 取消 + + + + Extract a catalog + 提取目錄 + + + + Compresed library covers (*.clc) + 已壓縮的庫封面 (*.clc) + + + + ImportWidget + + + stop + 停止 + + + + Some of the comics being added... + 正在添加漫畫... + + + + Importing comics + 正在導入漫畫 + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary現在正在創建一個新庫。</p><p>這可能需要幾分鐘時間,您可以先停止該進程,稍後可以通過更新庫選項來更新數據。</p> + + + + Updating the library + 正在更新庫 + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>正在更新當前庫。要獲得更快的更新,請經常更新您的庫。</p><p>您可以停止該進程,稍後繼續更新操作。</p> + + + + Upgrading the library + 正在更新庫 + + + + <p>The current library is being upgraded, please wait.</p> + <p>正在更新當前漫畫庫, 請稍候.</p> + + + + Scanning the library + 正在掃描庫 + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>正在掃描當前庫的舊版 XML metadata 資訊。</p><p>這只需要執行一次,且只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 時。</p> + + + + LibraryWindow + + + YACReader Library + YACReader 庫 + + + + + + comic + 漫畫 + + + + + + manga + 漫畫 + + + + + + western manga (left to right) + 西方漫畫(從左到右) + + + + + + web comic + 網路漫畫 + + + + + + 4koma (top to botom) + 4koma(由上至下) + + + + + + + Set type + 套裝類型 + + + + Library + + + + + Folder + 檔夾 + + + + Comic + 漫畫 + + + + Upgrade failed + 更新失敗 + + + + There were errors during library upgrade in: + 漫畫庫更新時出現錯誤: + + + + Update needed + 需要更新 + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + 此庫是使用舊版本的YACReaderLibrary創建的. 它需要更新. 現在更新? + + + + Download new version + 下載新版本 + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + 此庫是使用較新版本的YACReaderLibrary創建的。 立即下載新版本? + + + + Library not available + 庫不可用 + + + + Library '%1' is no longer available. Do you want to remove it? + 庫 '%1' 不再可用。 你想刪除它嗎? + + + + Old library + 舊的庫 + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? + + + + + Copying comics... + 複製漫畫中... + + + + + Moving comics... + 移動漫畫中... + + + + Add new folder + 添加新的檔夾 + + + + Folder name: + 檔夾名稱: + + + + No folder selected + 沒有選中的檔夾 + + + + Please, select a folder first + 請先選擇一個檔夾 + + + + Error in path + 路徑錯誤 + + + + There was an error accessing the folder's path + 訪問檔夾的路徑時出錯 + + + + Delete folder + 刪除檔夾 + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + 所選檔夾及其所有內容將從磁片中刪除。 你確定嗎? + + + + + Unable to delete + 無法刪除 + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + 嘗試刪除所選檔夾時出現問題。 請檢查寫入許可權,並確保沒有其他應用程式在使用這些檔夾或檔。 + + + + Add new reading lists + 添加新的閱讀列表 + + + + + List name: + 列表名稱: + + + + Delete list/label + 刪除 列表/標籤 + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + 所選項目將被刪除,您的漫畫或檔夾將不會從您的磁片中刪除。 你確定嗎? + + + + Rename list name + 重命名列表 + + + + Open folder... + 打開檔夾... + + + + Update folder + 更新檔夾 + + + + Rescan library for XML info + 重新掃描庫的 XML 資訊 + + + + Set as uncompleted + 設為未完成 + + + + Set as completed + 設為已完成 + + + + Set as read + 設為已讀 + + + + + Set as unread + 設為未讀 + + + + Set custom cover + 設定自訂封面 + + + + Delete custom cover + 刪除自訂封面 + + + + Save covers + 保存封面 + + + + You are adding too many libraries. + 您添加的庫太多了。 + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + 您添加的庫太多了。 + +一般情況只需要一個頂級的庫,您可以使用左側邊欄中的檔夾功能來進行分類管理。 + +YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低的庫數量來提升性能。 + + + + + YACReader not found + YACReader 未找到 + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + 未找到YACReader. YACReader應安裝在與YACReaderLibrary相同的檔夾中. + + + + YACReader not found. There might be a problem with your YACReader installation. + 未找到YACReader. YACReader的安裝可能有問題. + + + + Error + 錯誤 + + + + Error opening comic with third party reader. + 使用第三方閱讀器開啟漫畫時出錯。 + + + + Library not found + 未找到庫 + + + + The selected folder doesn't contain any library. + 所選檔夾不包含任何庫。 + + + + Are you sure? + 你確定嗎? + + + + Do you want remove + 你想要刪除 + + + + library? + 庫? + + + + Remove and delete metadata + 移除並刪除元數據 + + + + Library info + 圖書館資訊 + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + 嘗試刪除所選漫畫時出現問題。 請檢查所選檔或包含檔夾中的寫入許可權。 + + + + Assign comics numbers + 分配漫畫編號 + + + + Assign numbers starting in: + 從以下位置開始分配編號: + + + + Invalid image + 圖片無效 + + + + The selected file is not a valid image. + 所選檔案不是有效影像。 + + + + Error saving cover + 儲存封面時發生錯誤 + + + + There was an error saving the cover image. + 儲存封面圖片時發生錯誤。 + + + + Error creating the library + 創建庫時出錯 + + + + Error updating the library + 更新庫時出錯 + + + + Error opening the library + 打開庫時出錯 + + + + Delete comics + 刪除漫畫 + + + + All the selected comics will be deleted from your disk. Are you sure? + 所有選定的漫畫都將從您的磁片中刪除。你確定嗎? + + + + Remove comics + 移除漫畫 + + + + Comics will only be deleted from the current label/list. Are you sure? + 漫畫只會從當前標籤/列表中刪除。 你確定嗎? + + + + Library name already exists + 庫名已存在 + + + + There is another library with the name '%1'. + 已存在另一個名為'%1'的庫。 + + + + LibraryWindowActions + + + Create a new library + 創建一個新的庫 + + + + Open an existing library + 打開現有的庫 + + + + + Export comics info + 導出漫畫資訊 + + + + + Import comics info + 導入漫畫資訊 + + + + Pack covers + 打包封面 + + + + Pack the covers of the selected library + 打包所選庫的封面 + + + + Unpack covers + 解壓封面 + + + + Unpack a catalog + 解壓目錄 + + + + Update library + 更新庫 + + + + Update current library + 更新當前庫 + + + + Rename library + 重命名庫 + + + + Rename current library + 重命名當前庫 + + + + Remove library + 移除庫 + + + + Remove current library from your collection + 從您的集合中移除當前庫 + + + + Rescan library for XML info + 重新掃描庫的 XML 資訊 + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + 嘗試查找漫畫檔內嵌的 XML 資訊。只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 或者使用第三方軟體嵌入 XML 資訊時,才需要執行該操作。 + + + + Show library info + 顯示圖書館資訊 + + + + Show information about the current library + 顯示當前庫的信息 + + + + Open current comic + 打開當前漫畫 + + + + Open current comic on YACReader + 用YACReader打開漫畫 + + + + Save selected covers to... + 選中的封面保存到... + + + + Save covers of the selected comics as JPG files + 保存所選的封面為jpg + + + + + Set as read + 設為已讀 + + + + Set comic as read + 漫畫設為已讀 + + + + + Set as unread + 設為未讀 + + + + Set comic as unread + 漫畫設為未讀 + + + + + manga + 漫畫 + + + + Set issue as manga + 將問題設定為漫畫 + + + + + comic + 漫畫 + + + + Set issue as normal + 設置發行狀態為正常發行 + + + + western manga + 西方漫畫 + + + + Set issue as western manga + 將問題設定為西方漫畫 + + + + + web comic + 網路漫畫 + + + + Set issue as web comic + 將問題設定為網路漫畫 + + + + + yonkoma + 四科馬 + + + + Set issue as yonkoma + 將問題設定為 yonkoma + + + + Show/Hide marks + 顯示/隱藏標記 + + + + Show or hide read marks + 顯示或隱藏閱讀標記 + + + + Show/Hide recent indicator + 顯示/隱藏最近的指標 + + + + Show or hide recent indicator + 顯示或隱藏最近的指示器 + + + + + Fullscreen mode on/off + 全屏模式 開/關 + + + + Help, About YACReader + 幫助, 關於 YACReader + + + + Add new folder + 添加新的檔夾 + + + + Add new folder to the current library + 在當前庫下添加新的檔夾 + + + + Delete folder + 刪除檔夾 + + + + Delete current folder from disk + 從磁片上刪除當前檔夾 + + + + Select root node + 選擇根節點 + + + + Expand all nodes + 展開所有節點 + + + + Collapse all nodes + 折疊所有節點 + + + + Show options dialog + 顯示選項對話框 + + + + Show comics server options dialog + 顯示漫畫伺服器選項對話框 + + + + + Change between comics views + 漫畫視圖之間的變化 + + + + Open folder... + 打開檔夾... + + + + Set as uncompleted + 設為未完成 + + + + Set as completed + 設為已完成 + + + + Set custom cover + 設定自訂封面 + + + + Delete custom cover + 刪除自訂封面 + + + + western manga (left to right) + 西方漫畫(從左到右) + + + + Open containing folder... + 打開包含檔夾... + + + + Reset comic rating + 重置漫畫評分 + + + + Select all comics + 全選漫畫 + + + + Edit + 編輯 + + + + Assign current order to comics + 將當前序號分配給漫畫 + + + + Update cover + 更新封面 + + + + Delete selected comics + 刪除所選的漫畫 + + + + Delete metadata from selected comics + 從選定的漫畫中刪除元數據 + + + + Download tags from Comic Vine + 從 Comic Vine 下載標籤 + + + + Focus search line + 聚焦於搜索行 + + + + Focus comics view + 聚焦於漫畫視圖 + + + + Edit shortcuts + 編輯快捷鍵 + + + + &Quit + 退出(&Q) + + + + Update folder + 更新檔夾 + + + + Update current folder + 更新當前檔夾 + + + + Scan legacy XML metadata + 掃描舊版 XML 元數據 + + + + Add new reading list + 添加新的閱讀列表 + + + + Add a new reading list to the current library + 在當前庫添加新的閱讀列表 + + + + Remove reading list + 移除閱讀列表 + + + + Remove current reading list from the library + 從當前庫移除閱讀列表 + + + + Add new label + 添加新標籤 + + + + Add a new label to this library + 在當前庫添加標籤 + + + + Rename selected list + 重命名列表 + + + + Rename any selected labels or lists + 重命名任何選定的標籤或列表 + + + + Add to... + 添加到... + + + + Favorites + 收藏夾 + + + + Add selected comics to favorites list + 將所選漫畫添加到收藏夾列表 + + + + LocalComicListModel + + + file name + 檔案名 + + + + NoLibrariesWidget + + + You don't have any libraries yet + 你還沒有庫 + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>您可以在任何檔夾中創建庫,YACReaderLibrary將導入此檔夾中的所有漫畫和文件夾。如果已有庫,則可以打開它們。</p><p>您可以把YACReader當成獨立應用來閱讀電腦上的漫畫。</p> + + + + create your first library + 創建你的第一個庫 + + + + add an existing one + 添加一個現有庫 + + + + NoSearchResultsWidget + + + No results + 沒有結果 + + + + OptionsDialog + + + + General + 常規 + + + + + Libraries + + + + + Comic Flow + 漫畫流 + + + + Grid view + 網格視圖 + + + + + Appearance + 外貌 + + + + + Options + 選項 + + + + + Language + 語言 + + + + + Application language + 應用程式語言 + + + + + System default + 系統預設 + + + + Tray icon settings (experimental) + 託盤圖示設置 (實驗特性) + + + + Close to tray + 關閉至託盤 + + + + Start into the system tray + 啟動至系統託盤 + + + + Edit Comic Vine API key + 編輯Comic Vine API 密匙 + + + + Comic Vine API key + Comic Vine API 密匙 + + + + ComicInfo.xml legacy support + ComicInfo.xml 遺留支持 + + + + Import metadata from ComicInfo.xml when adding new comics + 新增漫畫時從 ComicInfo.xml 匯入元數據 + + + + Consider 'recent' items added or updated since X days ago + 考慮自 X 天前新增或更新的「最近」項目 + + + + Third party reader + 第三方閱讀器 + + + + Write {comic_file_path} where the path should go in the command + 在命令中應將路徑寫入 {comic_file_path} + + + + + Clear + 清空 + + + + Update libraries at startup + 啟動時更新庫 + + + + Try to detect changes automatically + 嘗試自動偵測變化 + + + + Update libraries periodically + 定期更新庫 + + + + Interval: + 間隔: + + + + 30 minutes + 30分鐘 + + + + 1 hour + 1小時 + + + + 2 hours + 2小時 + + + + 4 hours + 4小時 + + + + 8 hours + 8小時 + + + + 12 hours + 12小時 + + + + daily + 日常的 + + + + Update libraries at certain time + 定時更新庫 + + + + Time: + 時間: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + 警告!在庫更新期間,將停用對資料庫的寫入! +當您可能正在積極使用應用程式時,請勿安排更新。 +在自動更新期間,應用程式將阻止某些操作,直到更新完成。 +若要停止自動更新,請點選庫標題旁的載入指示器。 + + + + Modifications detection + 修改檢測 + + + + Compare the modified date of files when updating a library (not recommended) + 更新庫時比較文件的修改日期(不建議) + + + + Enable background image + 啟用背景圖片 + + + + Opacity level + 透明度 + + + + Blur level + 模糊 + + + + Use selected comic cover as background + 使用選定的漫畫封面做背景 + + + + Restore defautls + 恢復默認值 + + + + Background + 背景 + + + + Display continue reading banner + 顯示繼續閱讀橫幅 + + + + Display current comic banner + 顯示目前漫畫橫幅 + + + + Continue reading + 繼續閱讀 + + + + My comics path + 我的漫畫路徑 + + + + Display + 展示 + + + + Show time in current page information label + 在目前頁面資訊標籤中顯示時間 + + + + "Go to flow" size + 頁面流尺寸 + + + + Background color + 背景顏色 + + + + Choose + 選擇 + + + + Scroll behaviour + 滾動效果 + + + + Disable scroll animations and smooth scrolling + 停用滾動動畫和平滑滾動 + + + + Do not turn page using scroll + 滾動時不翻頁 + + + + Use single scroll step to turn page + 使用單滾動步驟翻頁 + + + + Mouse mode + 滑鼠模式 + + + + Only Back/Forward buttons can turn pages + 只有後退/前進按鈕可以翻頁 + + + + Use the Left/Right buttons to turn pages. + 使用向左/向右按鈕翻頁。 + + + + Click left or right half of the screen to turn pages. + 點擊螢幕的左半部或右半部即可翻頁。 + + + + Quick Navigation Mode + 快速導航模式 + + + + Disable mouse over activation + 禁用滑鼠啟動 + + + + Brightness + 亮度 + + + + Contrast + 對比度 + + + + Gamma + Gamma值 + + + + Reset + 重置 + + + + Image options + 圖片選項 + + + + Fit options + 適應項 + + + + Enlarge images to fit width/height + 放大圖片以適應寬度/高度 + + + + Double Page options + 雙頁選項 + + + + Show covers as single page + 顯示封面為單頁 + + + + Scaling + 縮放 + + + + Scaling method + 縮放方法 + + + + Nearest (fast, low quality) + 最近(快速,低品質) + + + + Bilinear + 雙線性 + + + + Lanczos (better quality) + Lanczos(品質更好) + + + + Page Flow + 頁面流 + + + + Image adjustment + 圖像調整 + + + + + Restart is needed + 需要重啟 + + + + Comics directory + 漫畫目錄 + + + + PropertiesDialog + + + General info + 基本資訊 + + + + Plot + 情節 + + + + Authors + 作者 + + + + Publishing + 出版 + + + + Notes + 筆記 + + + + Cover page + 封面 + + + + Load previous page as cover + 載入上一頁作為封面 + + + + Load next page as cover + 載入下一頁作為封面 + + + + Reset cover to the default image + 將封面重設為預設圖片 + + + + Load custom cover image + 載入自訂封面圖片 + + + + Series: + 系列: + + + + Title: + 標題: + + + + + + of: + 的: + + + + Issue number: + 發行數量: + + + + Volume: + 卷: + + + + Arc number: + 世界線數量: + + + + Story arc: + 故事線: + + + + alt. number: + 替代。數字: + + + + Alternate series: + 替代系列: + + + + Series Group: + 系列組: + + + + Genre: + 類型: + + + + Size: + 大小: + + + + Writer(s): + 作者: + + + + Penciller(s): + 線稿: + + + + Inker(s): + 墨稿: + + + + Colorist(s): + 上色: + + + + Letterer(s): + 文本: + + + + Cover Artist(s): + 封面設計: + + + + Editor(s): + 編輯: + + + + Imprint: + 印記: + + + + Day: + 日: + + + + Month: + 月: + + + + Year: + 年: + + + + Publisher: + 出版者: + + + + Format: + 格式: + + + + Color/BW: + 彩色/黑白: + + + + Age rating: + 年齡等級: + + + + Type: + 類型: + + + + Language (ISO): + 語言(ISO): + + + + Synopsis: + 概要: + + + + Characters: + 角色: + + + + Teams: + 團隊: + + + + Locations: + 地點: + + + + Main character or team: + 主要角色或團隊: + + + + Review: + 審查: + + + + Notes: + 筆記: + + + + Tags: + 標籤: + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + + + + Not found + 未找到 + + + + Comic not found. You should update your library. + 未找到漫畫,請先更新您的庫. + + + + Edit comic information + 編輯漫畫資訊 + + + + Edit selected comics information + 編輯選中的漫畫資訊 + + + + Invalid cover + 封面無效 + + + + The image is invalid. + 該圖像無效。 + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 + +此應用程式支援持久性設置,要設定它們,請編輯此文件 %1 +若要了解可用設置,請查看文件:https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject + + + Trace + 追蹤 + + + + Debug + 除錯 + + + + Info + 資訊 + + + + Warning + 警告 + + + + Error + 錯誤 + + + + Fatal + 嚴重錯誤 + + + + Select custom cover + 選擇自訂封面 + + + + Images (%1) + 圖片 (%1) + + + + 7z lib not found + 未找到 7z 庫檔 + + + + unable to load 7z lib from ./utils + 無法從 ./utils 載入 7z 庫檔 + + + + The file could not be read or is not valid JSON. + 無法讀取該檔案或該檔案不是有效的 JSON。 + + + + This theme is for %1, not %2. + 此主題適用於 %1,而不是 %2。 + + + + Libraries + + + + + Folders + 檔夾 + + + + Reading Lists + 閱讀列表 + + + + RenameLibraryDialog + + + New Library Name : + 新庫名: + + + + Rename + 重命名 + + + + Cancel + 取消 + + + + Rename current library + 重命名當前庫 + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + 搜索結果: %1 + + + + + page %1 of %2 + 第 %1 頁 共 %2 頁 + + + + Number of %1 found : %2 + 第 %1 頁 共: %2 條 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + 請提供附加資訊. + + + + Series: + 系列: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + 使用精確匹配搜尋。如果您想要尋找與名稱中某些單字相符的捲,請停用。 + + + + SearchVolume + + + Please provide some additional information. + 請提供附加資訊. + + + + Series: + 系列: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + 使用精確匹配搜尋。如果您想要尋找與名稱中某些單字相符的捲,請停用。 + + + + SelectComic + + + Please, select the right comic info. + 請正確選擇漫畫資訊. + + + + comics + 漫畫 + + + + loading cover + 加載封面 + + + + loading description + 加載描述 + + + + comic description unavailable + 漫畫描述不可用 + + + + SelectVolume + + + Please, select the right series for your comic. + 請選擇正確的漫畫系列。 + + + + Filter: + 篩選: + + + + volumes + + + + + Nothing found, clear the filter if any. + 未找到任何內容,如果有,請清除過濾器。 + + + + loading cover + 加載封面 + + + + loading description + 加載描述 + + + + volume description unavailable + 卷描述不可用 + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + 您正在嘗試同時獲取各種漫畫的資訊,它們是同一系列的嗎? + + + + yes + + + + + no + + + + + ServerConfigDialog + + + set port + 設置端口 + + + + Server connectivity information + 伺服器連接資訊 + + + + Scan it! + 掃一掃! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 + + + + Choose an IP address + 選擇IP地址 + + + + Port + 端口 + + + + enable the server + 啟用伺服器 + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + 請在左側對漫畫列表進行排序,直到它與漫畫的資訊相符。 + + + + sort comics to match comic information + 排序漫畫以匹配漫畫資訊 + + + + issues + 發行 + + + + remove selected comics + 移除所選漫畫 + + + + restore all removed comics + 恢復所有移除的漫畫 + + + + ThemeEditorDialog + + + Theme Editor + 主題編輯器 + + + + + + + + + + + - + - + + + + i + + + + + Expand all + 全部展開 + + + + Collapse all + 全部折疊 + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + 按住可在 UI 中閃爍所選值(洋紅色/切換/0↔10)。發布後恢復原樣。 + + + + Search… + 搜尋… + + + + Light + 亮度 + + + + Dark + 黑暗的 + + + + ID: + ID: + + + + Display name: + 顯示名稱: + + + + Variant: + 變體: + + + + Theme info + 主題訊息 + + + + Parameter + 範圍 + + + + Value + 價值 + + + + Save and apply + 儲存並應用 + + + + Export to file... + 匯出到文件... + + + + Load from file... + 從檔案載入... + + + + Close + 關閉 + + + + Double-click to edit color + 雙擊編輯顏色 + + + + + + + + + true + 真的 + + + + + + + false + 錯誤的 + + + + Double-click to toggle + 按兩下切換 + + + + Double-click to edit value + 雙擊編輯值 + + + + + + Edit: %1 + 編輯:%1 + + + + Save theme + 儲存主題 + + + + + JSON files (*.json);;All files (*) + JSON 檔案 (*.json);;所有檔案 (*) + + + + Save failed + 保存失敗 + + + + Could not open file for writing: +%1 + 無法開啟文件進行寫入: +%1 + + + + Load theme + 載入主題 + + + + + + Load failed + 載入失敗 + + + + Could not open file: +%1 + 無法開啟檔案: +%1 + + + + Invalid JSON: +%1 + 無效的 JSON: +%1 + + + + Expected a JSON object. + 需要一個 JSON 物件。 + + + + TitleHeader + + + SEARCH + 搜索 + + + + UpdateLibraryDialog + + + Updating.... + 更新中... + + + + Cancel + 取消 + + + + Update library + 更新庫 + + + + Viewer + + + + Press 'O' to open comic. + 按下 'O' 以打開漫畫. + + + + Not found + 未找到 + + + + Comic not found + 未找到漫畫 + + + + Error opening comic + 打開漫畫時發生錯誤 + + + + CRC Error + CRC 校驗失敗 + + + + Loading...please wait! + 載入中... 請稍候! + + + + Page not available! + 頁面不可用! + + + + Cover! + 封面! + + + + Last page! + 尾頁! + + + + VolumeComicsModel + + + title + 標題 + + + + VolumesModel + + + year + + + + + issues + 發行 + + + + publisher + 出版者 + + + + YACReader3DFlowConfigWidget + + + Presets: + 預設: + + + + Classic look + 經典 + + + + Stripe look + 條狀 + + + + Overlapped Stripe look + 重疊條狀 + + + + Modern look + 現代 + + + + Roulette look + 輪盤 + + + + Show advanced settings + 顯示高級選項 + + + + Custom: + 自定義: + + + + View angle + 視角 + + + + Position + 位置 + + + + Cover gap + 封面間距 + + + + Central gap + 中心間距 + + + + Zoom + 縮放 + + + + Y offset + Y位移 + + + + Z offset + Z位移 + + + + Cover Angle + 封面角度 + + + + Visibility + 透明度 + + + + Light + 亮度 + + + + Max angle + 最大角度 + + + + Low Performance + 低性能 + + + + High Performance + 高性能 + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + 使用VSync (在全屏模式下提高圖像品質, 性能更差) + + + + Performance: + 性能: + + + + YACReader::MainWindowViewer + + + &Open + 打開(&O) + + + + Open a comic + 打開漫畫 + + + + New instance + 新建實例 + + + + Open Folder + 打開檔夾 + + + + Open image folder + 打開圖片檔夾 + + + + Open latest comic + 打開最近的漫畫 + + + + Open the latest comic opened in the previous reading session + 打開最近閱讀漫畫 + + + + Clear + 清空 + + + + Clear open recent list + 清空最近訪問列表 + + + + Save + 保存 + + + + + Save current page + 保存當前頁面 + + + + Previous Comic + 上一個漫畫 + + + + + + Open previous comic + 打開上一個漫畫 + + + + Next Comic + 下一個漫畫 + + + + + + Open next comic + 打開下一個漫畫 + + + + &Previous + 上一頁(&P) + + + + + + Go to previous page + 轉至上一頁 + + + + &Next + 下一頁(&N) + + + + + + Go to next page + 轉至下一頁 + + + + Fit Height + 適應高度 + + + + Fit image to height + 縮放圖片以適應高度 + + + + Fit Width + 適合寬度 + + + + Fit image to width + 縮放圖片以適應寬度 + + + + Show full size + 顯示全尺寸 + + + + Fit to page + 適應頁面 + + + + Continuous scroll + 連續滾動 + + + + Switch to continuous scroll mode + 切換到連續滾動模式 + + + + Reset zoom + 重置縮放 + + + + Show zoom slider + 顯示縮放滑塊 + + + + Zoom+ + 放大 + + + + Zoom- + 縮小 + + + + Rotate image to the left + 向左旋轉圖片 + + + + Rotate image to the right + 向右旋轉圖片 + + + + Double page mode + 雙頁模式 + + + + Switch to double page mode + 切換至雙頁模式 + + + + Double page manga mode + 雙頁漫畫模式 + + + + Reverse reading order in double page mode + 雙頁模式 (逆序閱讀) + + + + Go To + 跳轉 + + + + Go to page ... + 跳轉至頁面 ... + + + + Options + 選項 + + + + YACReader options + YACReader 選項 + + + + + Help + 幫助 + + + + Help, About YACReader + 幫助, 關於 YACReader + + + + Magnifying glass + 放大鏡 + + + + Switch Magnifying glass + 切換放大鏡 + + + + Set bookmark + 設置書簽 + + + + Set a bookmark on the current page + 在當前頁面設置書簽 + + + + Show bookmarks + 顯示書簽 + + + + Show the bookmarks of the current comic + 顯示當前漫畫的書簽 + + + + Show keyboard shortcuts + 顯示鍵盤快捷鍵 + + + + Show Info + 顯示資訊 + + + + Close + 關閉 + + + + Show Dictionary + 顯示字典 + + + + Show go to flow + 顯示頁面流 + + + + Edit shortcuts + 編輯快捷鍵 + + + + &File + 檔(&F) + + + + + Open recent + 最近打開的檔 + + + + File + + + + + Edit + 編輯 + + + + View + 查看 + + + + Go + 轉到 + + + + Window + 窗口 + + + + + + Open Comic + 打開漫畫 + + + + + + Comic files + 漫畫檔 + + + + Open folder + 打開檔夾 + + + + page_%1.jpg + 頁_%1.jpg + + + + Image files (*.jpg) + 圖像檔 (*.jpg) + + + + + Comics + 漫畫 + + + + + General + 常規 + + + + + Magnifiying glass + 放大鏡 + + + + + Page adjustement + 頁面調整 + + + + + Reading + 閱讀 + + + + Toggle fullscreen mode + 切換全屏模式 + + + + Hide/show toolbar + 隱藏/顯示 工具欄 + + + + Size up magnifying glass + 增大放大鏡尺寸 + + + + Size down magnifying glass + 減小放大鏡尺寸 + + + + Zoom in magnifying glass + 增大縮放級別 + + + + Zoom out magnifying glass + 減小縮放級別 + + + + Reset magnifying glass + 重置放大鏡 + + + + Toggle between fit to width and fit to height + 切換顯示為"適應寬度"或"適應高度" + + + + Autoscroll down + 向下自動滾動 + + + + Autoscroll up + 向上自動滾動 + + + + Autoscroll forward, horizontal first + 向前自動滾動,水準優先 + + + + Autoscroll backward, horizontal first + 向後自動滾動,水準優先 + + + + Autoscroll forward, vertical first + 向前自動滾動,垂直優先 + + + + Autoscroll backward, vertical first + 向後自動滾動,垂直優先 + + + + Move down + 向下移動 + + + + Move up + 向上移動 + + + + Move left + 向左移動 + + + + Move right + 向右移動 + + + + Go to the first page + 轉到第一頁 + + + + Go to the last page + 轉到最後一頁 + + + + Offset double page to the left + 雙頁向左偏移 + + + + Offset double page to the right + 雙頁向右偏移 + + + + There is a new version available + 有新版本可用 + + + + Do you want to download the new version? + 你要下載新版本嗎? + + + + Remind me in 14 days + 14天後提醒我 + + + + Not now + 現在不 + + + + YACReader::TrayIconController + + + &Restore + 複位(&R) + + + + Systray + 系統託盤 + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary 將繼續在系統託盤中運行. 想要終止程式, 請在系統託盤圖示的上下文菜單中選擇<b>退出</b>. + + + + YACReaderFieldEdit + + + + Click to overwrite + 點擊以覆蓋 + + + + Restore to default + 恢復默認 + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + 點擊以覆蓋 + + + + Restore to default + 恢復默認 + + + + YACReaderOptionsDialog + + + Save + 保存 + + + + Cancel + 取消 + + + + Edit shortcuts + 編輯快捷鍵 + + + + Shortcuts + 快捷鍵 + + + + YACReaderSearchLineEdit + + + type to search + 搜索類型 + + + + YACReaderSlider + + + Reset + 重置 - QsLogging::Window + YACReaderTranslator - - &Pause - + + YACReader translator + YACReader 翻譯 - - &Resume - + + + Translation + 翻譯 - - Save log - + + clear + 清空 - - Log file (*.log) - + + Service not available + 服務不可用 diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_zh_TW.ts b/YACReaderLibraryServer/yacreaderlibraryserver_zh_TW.ts index 04214c28b..7d47fa5c5 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_zh_TW.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_zh_TW.ts @@ -2,150 +2,3712 @@ - FileComic + ActionsShortcutsModel - - CRC error on page (%1): some of the pages will not be displayed correctly - + + None + + + + AddLabelDialog - - Unknown error opening the file - + + Label name: + 標籤名稱: - - 7z not found - + + Choose a color: + 選擇標籤顏色: - - Format not supported - + + accept + 接受 + + + + cancel + 取消 - LogWindow + AddLibraryDialog + + + Comics folder : + 漫畫檔夾: + + + + Library name : + 庫名: + - - Log window - + + Add + 添加 - - &Pause - + + Cancel + 取消 - - &Save - + + Add an existing library + 添加一個現有庫 + + + ApiKeyDialog - - C&lear - + + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 - - &Copy - + + Paste here your Comic Vine API key + 在此粘貼你的Comic Vine API - - Level: - + + Accept + 接受 - - &Auto scroll - + + Cancel + 取消 - QCoreApplication + AppearanceTabWidget - - -YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + + Color scheme + 配色方案 + + + + System + 系統 + + + + Light + 亮度 + + + + Dark + 黑暗的 + + + + Custom + 風俗 + + + + Remove + 消除 + + + + Remove this user-imported theme + 刪除此使用者匯入的主題 + + + + Light: + 光: + + + + Dark: + 黑暗的: + + + + Custom: + 自定義: + + + + Import theme... + 導入主題... + + + + Theme + 主題 + + + + Theme editor + 主題編輯器 + + + + Open Theme Editor... + 開啟主題編輯器... + + + + Theme editor error + 主題編輯器錯誤 + + + + The current theme JSON could not be loaded. + 無法載入目前主題 JSON。 + + + + Import theme + 導入主題 + + + + JSON files (*.json);;All files (*) + JSON 檔案 (*.json);;所有檔案 (*) + + + + Could not import theme from: +%1 + 無法從以下位置匯入主題: +%1 + + + + Could not import theme from: +%1 -This appplication supports persistent settings, to set them up edit this file %1 -To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md - +%2 + 無法從以下位置匯入主題: +%1 + +%2 + + + + Import failed + 導入失敗 - QObject + BookmarksDialog - - Trace - + + Lastest Page + 尾頁 - - Debug - + + Close + 關閉 - - Info - + + Click on any image to go to the bookmark + 點擊任意圖片以跳轉至相應書簽位置 - - Warning - + + + Loading... + 載入中... + + + ClassicComicsView - - Error - + + Hide comic flow + 隱藏漫畫流 + + + + ComicModel + + + yes + - - Fatal - + + no + + + + + Title + 標題 + + + + File Name + 檔案名 + + + + Pages + 頁數 + + + + Size + 大小 + + + + Read + 閱讀 + + + + Current Page + 當前頁 + + + + Publication Date + 發行日期 + + + + Rating + 評分 + + + + Series + 系列 + + + + Volume + 體積 + + + + Story Arc + 故事線 + + + + ComicVineDialog + + + skip + 忽略 + + + + back + 返回 + + + + next + 下一步 + + + + search + 搜索 + + + + close + 關閉 + + + + + comic %1 of %2 - %3 + 第 %1 本 共 %2 本 - %3 + + + + + + Looking for volume... + 搜索卷... + + + + %1 comics selected + 已選擇 %1 本漫畫 + + + + Error connecting to ComicVine + ComicVine 連接時出錯 + + + + + Retrieving tags for : %1 + 正在檢索標籤: %1 + + + + Retrieving volume info... + 正在接收卷資訊... + + + + Looking for comic... + 搜索漫畫中... + + + + ContinuousPageWidget + + + Loading page %1 + 正在載入頁面 %1 + + + + CreateLibraryDialog + + + Comics folder : + 漫畫檔夾: + + + + Library Name : + 庫名: + + + + Create + 創建 + + + + Cancel + 取消 + + + + Create a library could take several minutes. You can stop the process and update the library later for completing the task. + 創建一個新的庫可能需要幾分鐘時間,您可以先停止該進程,稍後可以通過更新庫選項來更新數據。 + + + + Create new library + 創建新的漫畫庫 + + + + Path not found + 未找到路徑 + + + + The selected path does not exist or is not a valid path. Be sure that you have write access to this folder + 所選路徑不存在或不是有效路徑. 確保您具有此檔夾的寫入許可權 + + + + EditShortcutsDialog + + + Restore defaults + 恢復默認 + + + + To change a shortcut, double click in the key combination and type the new keys. + 更改快捷鍵: 雙擊按鍵組合並輸入新的映射. + + + + Shortcuts settings + 快捷鍵設置 + + + + Shortcut in use + 快捷鍵被佔用 + + + + The shortcut "%1" is already assigned to other function + 快捷鍵 "%1" 已被映射至其他功能 + + + + EmptyFolderWidget + + + This folder doesn't contain comics yet + 該資料夾還沒有漫畫 + + + + EmptyLabelWidget + + + This label doesn't contain comics yet + 此標籤尚未包含漫畫 + + + + EmptyReadingListWidget + + + This reading list does not contain any comics yet + 此閱讀列表尚未包含任何漫畫 + + + + EmptySpecialListWidget + + + No favorites + 沒有收藏 + + + + You are not reading anything yet, come on!! + 你還沒有閱讀任何東西,加油!! + + + + There are no recent comics! + 沒有最近的漫畫! + + + + ExportComicsInfoDialog + + + Output file : + 輸出檔: + + + + Create + 創建 + + + + Cancel + 取消 + + + + Export comics info + 導出漫畫資訊 + + + + Destination database name + 目標資料庫名稱 + + + + Problem found while writing + 寫入時出現問題 + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 選定的輸出檔路徑不存在或路徑無效. 確保您具有此檔夾的寫入許可權 + + + + ExportLibraryDialog + + + Output folder : + 輸出檔夾: + + + + Create + 創建 + + + + Cancel + 取消 + + + + Create covers package + 創建封面包 + + + + Problem found while writing + 寫入時出現問題 + + + + The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder + 選定的輸出檔路徑不存在或路徑無效. 確保您具有此檔夾的寫入許可權 + + + + Destination directory + 目標目錄 + + + + FileComic + + + CRC error on page (%1): some of the pages will not be displayed correctly + 第 %1 頁 CRC 校驗失敗: 部分頁面將無法正確顯示 + + + + Unknown error opening the file + 打開檔時出現未知錯誤 + + + + 7z not found + 未找到 7z + + + + Format not supported + 不支持的檔格式 + + + + GoToDialog + + + Page : + 頁碼 : + + + + Go To + 跳轉 + + + + Cancel + 取消 + + + + + Total pages : + 總頁數: + + + + Go to... + 跳轉至 ... + + + + GoToFlowToolBar + + + Page : + 頁碼 : - QsLogging::LogWindowModel + GridComicsView - - Time - + + Show info + 顯示資訊 + + + HelpAboutDialog - - Level - + + About + 關於 - - Message - + + Help + 幫助 + + + + System info + 系統資訊 + + + + ImportComicsInfoDialog + + + Import comics info + 導入漫畫資訊 + + + + Info database location : + 資料庫地址: + + + + Import + 導入 + + + + Cancel + 取消 + + + + Comics info file (*.ydb) + 漫畫資訊檔(*.ydb) + + + + ImportLibraryDialog + + + Library Name : + 庫名: + + + + Package location : + 打包地址: + + + + Destination folder : + 目標檔夾: + + + + Unpack + 解壓 + + + + Cancel + 取消 + + + + Extract a catalog + 提取目錄 + + + + Compresed library covers (*.clc) + 已壓縮的庫封面 (*.clc) + + + + ImportWidget + + + stop + 停止 + + + + Some of the comics being added... + 正在添加漫畫... + + + + Importing comics + 正在導入漫畫 + + + + <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> + <p>YACReaderLibrary現在正在創建一個新庫。</p><p>這可能需要幾分鐘時間,您可以先停止該進程,稍後可以通過更新庫選項來更新數據。</p> + + + + Updating the library + 正在更新庫 + + + + <p>The current library is being updated. For faster updates, please, update your libraries frequently.</p><p>You can stop the process and continue updating this library later.</p> + <p>正在更新當前庫。要獲得更快的更新,請經常更新您的庫。</p><p>您可以停止該進程,稍後繼續更新操作。</p> + + + + Upgrading the library + 正在更新庫 + + + + <p>The current library is being upgraded, please wait.</p> + <p>正在更新當前漫畫庫, 請稍候.</p> + + + + Scanning the library + 正在掃描庫 + + + + <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> + <p>正在掃描當前庫的舊版 XML metadata 資訊。</p><p>這只需要執行一次,且只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 時。</p> + + + + LibraryWindow + + + YACReader Library + YACReader 庫 + + + + + + comic + 漫畫 + + + + + + manga + 漫畫 + + + + + + western manga (left to right) + 西方漫畫(從左到右) + + + + + + web comic + 網路漫畫 + + + + + + 4koma (top to botom) + 4koma(由上至下) + + + + + + + Set type + 套裝類型 + + + + Library + + + + + Folder + 檔夾 + + + + Comic + 漫畫 + + + + Upgrade failed + 更新失敗 + + + + There were errors during library upgrade in: + 漫畫庫更新時出現錯誤: + + + + Update needed + 需要更新 + + + + This library was created with a previous version of YACReaderLibrary. It needs to be updated. Update now? + 此庫是使用舊版本的YACReaderLibrary創建的. 它需要更新. 現在更新? + + + + Download new version + 下載新版本 + + + + This library was created with a newer version of YACReaderLibrary. Download the new version now? + 此庫是使用較新版本的YACReaderLibrary創建的。 立即下載新版本? + + + + Library not available + 庫不可用 + + + + Library '%1' is no longer available. Do you want to remove it? + 庫 '%1' 不再可用。 你想刪除它嗎? + + + + Old library + 舊的庫 + + + + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? + + + + + Copying comics... + 複製漫畫中... + + + + + Moving comics... + 移動漫畫中... + + + + Add new folder + 添加新的檔夾 + + + + Folder name: + 檔夾名稱: + + + + No folder selected + 沒有選中的檔夾 + + + + Please, select a folder first + 請先選擇一個檔夾 + + + + Error in path + 路徑錯誤 + + + + There was an error accessing the folder's path + 訪問檔夾的路徑時出錯 + + + + Delete folder + 刪除檔夾 + + + + The selected folder and all its contents will be deleted from your disk. Are you sure? + 所選檔夾及其所有內容將從磁片中刪除。 你確定嗎? + + + + + Unable to delete + 無法刪除 + + + + There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. + 嘗試刪除所選檔夾時出現問題。 請檢查寫入許可權,並確保沒有其他應用程式在使用這些檔夾或檔。 + + + + Add new reading lists + 添加新的閱讀列表 + + + + + List name: + 列表名稱: + + + + Delete list/label + 刪除 列表/標籤 + + + + The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? + 所選項目將被刪除,您的漫畫或檔夾將不會從您的磁片中刪除。 你確定嗎? + + + + Rename list name + 重命名列表 + + + + Open folder... + 打開檔夾... + + + + Update folder + 更新檔夾 + + + + Rescan library for XML info + 重新掃描庫的 XML 資訊 + + + + Set as uncompleted + 設為未完成 + + + + Set as completed + 設為已完成 + + + + Set as read + 設為已讀 + + + + + Set as unread + 設為未讀 + + + + Set custom cover + 設定自訂封面 + + + + Delete custom cover + 刪除自訂封面 + + + + Save covers + 保存封面 + + + + You are adding too many libraries. + 您添加的庫太多了。 + + + + You are adding too many libraries. + +You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. + +YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. + 您添加的庫太多了。 + +一般情況只需要一個頂級的庫,您可以使用左側邊欄中的檔夾功能來進行分類管理。 + +YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低的庫數量來提升性能。 + + + + + YACReader not found + YACReader 未找到 + + + + YACReader not found. YACReader should be installed in the same folder as YACReaderLibrary. + 未找到YACReader. YACReader應安裝在與YACReaderLibrary相同的檔夾中. + + + + YACReader not found. There might be a problem with your YACReader installation. + 未找到YACReader. YACReader的安裝可能有問題. + + + + Error + 錯誤 + + + + Error opening comic with third party reader. + 使用第三方閱讀器開啟漫畫時出錯。 + + + + Library not found + 未找到庫 + + + + The selected folder doesn't contain any library. + 所選檔夾不包含任何庫。 + + + + Are you sure? + 你確定嗎? + + + + Do you want remove + 你想要刪除 + + + + library? + 庫? + + + + Remove and delete metadata + 移除並刪除元數據 + + + + Library info + 圖書館資訊 + + + + There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. + 嘗試刪除所選漫畫時出現問題。 請檢查所選檔或包含檔夾中的寫入許可權。 + + + + Assign comics numbers + 分配漫畫編號 + + + + Assign numbers starting in: + 從以下位置開始分配編號: + + + + Invalid image + 圖片無效 + + + + The selected file is not a valid image. + 所選檔案不是有效影像。 + + + + Error saving cover + 儲存封面時發生錯誤 + + + + There was an error saving the cover image. + 儲存封面圖片時發生錯誤。 + + + + Error creating the library + 創建庫時出錯 + + + + Error updating the library + 更新庫時出錯 + + + + Error opening the library + 打開庫時出錯 + + + + Delete comics + 刪除漫畫 + + + + All the selected comics will be deleted from your disk. Are you sure? + 所有選定的漫畫都將從您的磁片中刪除。你確定嗎? + + + + Remove comics + 移除漫畫 + + + + Comics will only be deleted from the current label/list. Are you sure? + 漫畫只會從當前標籤/列表中刪除。 你確定嗎? + + + + Library name already exists + 庫名已存在 + + + + There is another library with the name '%1'. + 已存在另一個名為'%1'的庫。 + + + + LibraryWindowActions + + + Create a new library + 創建一個新的庫 + + + + Open an existing library + 打開現有的庫 + + + + + Export comics info + 導出漫畫資訊 + + + + + Import comics info + 導入漫畫資訊 + + + + Pack covers + 打包封面 + + + + Pack the covers of the selected library + 打包所選庫的封面 + + + + Unpack covers + 解壓封面 + + + + Unpack a catalog + 解壓目錄 + + + + Update library + 更新庫 + + + + Update current library + 更新當前庫 + + + + Rename library + 重命名庫 + + + + Rename current library + 重命名當前庫 + + + + Remove library + 移除庫 + + + + Remove current library from your collection + 從您的集合中移除當前庫 + + + + Rescan library for XML info + 重新掃描庫的 XML 資訊 + + + + Tries to find XML info embedded in comic files. You only need to do this if the library was created with 9.8.2 or earlier versions or if you are using third party software to embed XML info in the files. + 嘗試查找漫畫檔內嵌的 XML 資訊。只有當創建庫的 YACReaderLibrary 版本低於 9.8.2 或者使用第三方軟體嵌入 XML 資訊時,才需要執行該操作。 + + + + Show library info + 顯示圖書館資訊 + + + + Show information about the current library + 顯示當前庫的信息 + + + + Open current comic + 打開當前漫畫 + + + + Open current comic on YACReader + 用YACReader打開漫畫 + + + + Save selected covers to... + 選中的封面保存到... + + + + Save covers of the selected comics as JPG files + 保存所選的封面為jpg + + + + + Set as read + 設為已讀 + + + + Set comic as read + 漫畫設為已讀 + + + + + Set as unread + 設為未讀 + + + + Set comic as unread + 漫畫設為未讀 + + + + + manga + 漫畫 + + + + Set issue as manga + 將問題設定為漫畫 + + + + + comic + 漫畫 + + + + Set issue as normal + 設置發行狀態為正常發行 + + + + western manga + 西方漫畫 + + + + Set issue as western manga + 將問題設定為西方漫畫 + + + + + web comic + 網路漫畫 + + + + Set issue as web comic + 將問題設定為網路漫畫 + + + + + yonkoma + 四科馬 + + + + Set issue as yonkoma + 將問題設定為 yonkoma + + + + Show/Hide marks + 顯示/隱藏標記 + + + + Show or hide read marks + 顯示或隱藏閱讀標記 + + + + Show/Hide recent indicator + 顯示/隱藏最近的指標 + + + + Show or hide recent indicator + 顯示或隱藏最近的指示器 + + + + + Fullscreen mode on/off + 全屏模式 開/關 + + + + Help, About YACReader + 幫助, 關於 YACReader + + + + Add new folder + 添加新的檔夾 + + + + Add new folder to the current library + 在當前庫下添加新的檔夾 + + + + Delete folder + 刪除檔夾 + + + + Delete current folder from disk + 從磁片上刪除當前檔夾 + + + + Select root node + 選擇根節點 + + + + Expand all nodes + 展開所有節點 + + + + Collapse all nodes + 折疊所有節點 + + + + Show options dialog + 顯示選項對話框 + + + + Show comics server options dialog + 顯示漫畫伺服器選項對話框 + + + + + Change between comics views + 漫畫視圖之間的變化 + + + + Open folder... + 打開檔夾... + + + + Set as uncompleted + 設為未完成 + + + + Set as completed + 設為已完成 + + + + Set custom cover + 設定自訂封面 + + + + Delete custom cover + 刪除自訂封面 + + + + western manga (left to right) + 西方漫畫(從左到右) + + + + Open containing folder... + 打開包含檔夾... + + + + Reset comic rating + 重置漫畫評分 + + + + Select all comics + 全選漫畫 + + + + Edit + 編輯 + + + + Assign current order to comics + 將當前序號分配給漫畫 + + + + Update cover + 更新封面 + + + + Delete selected comics + 刪除所選的漫畫 + + + + Delete metadata from selected comics + 從選定的漫畫中刪除元數據 + + + + Download tags from Comic Vine + 從 Comic Vine 下載標籤 + + + + Focus search line + 聚焦於搜索行 + + + + Focus comics view + 聚焦於漫畫視圖 + + + + Edit shortcuts + 編輯快捷鍵 + + + + &Quit + 退出(&Q) + + + + Update folder + 更新檔夾 + + + + Update current folder + 更新當前檔夾 + + + + Scan legacy XML metadata + 掃描舊版 XML 元數據 + + + + Add new reading list + 添加新的閱讀列表 + + + + Add a new reading list to the current library + 在當前庫添加新的閱讀列表 + + + + Remove reading list + 移除閱讀列表 + + + + Remove current reading list from the library + 從當前庫移除閱讀列表 + + + + Add new label + 添加新標籤 + + + + Add a new label to this library + 在當前庫添加標籤 + + + + Rename selected list + 重命名列表 + + + + Rename any selected labels or lists + 重命名任何選定的標籤或列表 + + + + Add to... + 添加到... + + + + Favorites + 收藏夾 + + + + Add selected comics to favorites list + 將所選漫畫添加到收藏夾列表 + + + + LocalComicListModel + + + file name + 檔案名 + + + + NoLibrariesWidget + + + You don't have any libraries yet + 你還沒有庫 + + + + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>您可以在任何檔夾中創建庫,YACReaderLibrary將導入此檔夾中的所有漫畫和文件夾。如果已有庫,則可以打開它們。</p><p>您可以把YACReader當成獨立應用來閱讀電腦上的漫畫。</p> + + + + create your first library + 創建你的第一個庫 + + + + add an existing one + 添加一個現有庫 + + + + NoSearchResultsWidget + + + No results + 沒有結果 + + + + OptionsDialog + + + + General + 常規 + + + + + Libraries + + + + + Comic Flow + 漫畫流 + + + + Grid view + 網格視圖 + + + + + Appearance + 外貌 + + + + + Options + 選項 + + + + + Language + 語言 + + + + + Application language + 應用程式語言 + + + + + System default + 系統預設 + + + + Tray icon settings (experimental) + 託盤圖示設置 (實驗特性) + + + + Close to tray + 關閉至託盤 + + + + Start into the system tray + 啟動至系統託盤 + + + + Edit Comic Vine API key + 編輯Comic Vine API 密匙 + + + + Comic Vine API key + Comic Vine API 密匙 + + + + ComicInfo.xml legacy support + ComicInfo.xml 遺留支持 + + + + Import metadata from ComicInfo.xml when adding new comics + 新增漫畫時從 ComicInfo.xml 匯入元數據 + + + + Consider 'recent' items added or updated since X days ago + 考慮自 X 天前新增或更新的「最近」項目 + + + + Third party reader + 第三方閱讀器 + + + + Write {comic_file_path} where the path should go in the command + 在命令中應將路徑寫入 {comic_file_path} + + + + + Clear + 清空 + + + + Update libraries at startup + 啟動時更新庫 + + + + Try to detect changes automatically + 嘗試自動偵測變化 + + + + Update libraries periodically + 定期更新庫 + + + + Interval: + 間隔: + + + + 30 minutes + 30分鐘 + + + + 1 hour + 1小時 + + + + 2 hours + 2小時 + + + + 4 hours + 4小時 + + + + 8 hours + 8小時 + + + + 12 hours + 12小時 + + + + daily + 日常的 + + + + Update libraries at certain time + 定時更新庫 + + + + Time: + 時間: + + + + WARNING! During library updates writes to the database are disabled! +Don't schedule updates while you may be using the app actively. +During automatic updates the app will block some of the actions until the update is finished. +To stop an automatic update tap on the loading indicator next to the Libraries title. + 警告!在庫更新期間,將停用對資料庫的寫入! +當您可能正在積極使用應用程式時,請勿安排更新。 +在自動更新期間,應用程式將阻止某些操作,直到更新完成。 +若要停止自動更新,請點選庫標題旁的載入指示器。 + + + + Modifications detection + 修改檢測 + + + + Compare the modified date of files when updating a library (not recommended) + 更新庫時比較文件的修改日期(不建議) + + + + Enable background image + 啟用背景圖片 + + + + Opacity level + 透明度 + + + + Blur level + 模糊 + + + + Use selected comic cover as background + 使用選定的漫畫封面做背景 + + + + Restore defautls + 恢復默認值 + + + + Background + 背景 + + + + Display continue reading banner + 顯示繼續閱讀橫幅 + + + + Display current comic banner + 顯示目前漫畫橫幅 + + + + Continue reading + 繼續閱讀 + + + + My comics path + 我的漫畫路徑 + + + + Display + 展示 + + + + Show time in current page information label + 在目前頁面資訊標籤中顯示時間 + + + + "Go to flow" size + 頁面流尺寸 + + + + Background color + 背景顏色 + + + + Choose + 選擇 + + + + Scroll behaviour + 滾動效果 + + + + Disable scroll animations and smooth scrolling + 停用滾動動畫和平滑滾動 + + + + Do not turn page using scroll + 滾動時不翻頁 + + + + Use single scroll step to turn page + 使用單滾動步驟翻頁 + + + + Mouse mode + 滑鼠模式 + + + + Only Back/Forward buttons can turn pages + 只有後退/前進按鈕可以翻頁 + + + + Use the Left/Right buttons to turn pages. + 使用向左/向右按鈕翻頁。 + + + + Click left or right half of the screen to turn pages. + 點擊螢幕的左半部或右半部即可翻頁。 + + + + Quick Navigation Mode + 快速導航模式 + + + + Disable mouse over activation + 禁用滑鼠啟動 + + + + Brightness + 亮度 + + + + Contrast + 對比度 + + + + Gamma + Gamma值 + + + + Reset + 重置 + + + + Image options + 圖片選項 + + + + Fit options + 適應項 + + + + Enlarge images to fit width/height + 放大圖片以適應寬度/高度 + + + + Double Page options + 雙頁選項 + + + + Show covers as single page + 顯示封面為單頁 + + + + Scaling + 縮放 + + + + Scaling method + 縮放方法 + + + + Nearest (fast, low quality) + 最近(快速,低品質) + + + + Bilinear + 雙線性 + + + + Lanczos (better quality) + Lanczos(品質更好) + + + + Page Flow + 頁面流 + + + + Image adjustment + 圖像調整 + + + + + Restart is needed + 需要重啟 + + + + Comics directory + 漫畫目錄 + + + + PropertiesDialog + + + General info + 基本資訊 + + + + Plot + 情節 + + + + Authors + 作者 + + + + Publishing + 出版 + + + + Notes + 筆記 + + + + Cover page + 封面 + + + + Load previous page as cover + 載入上一頁作為封面 + + + + Load next page as cover + 載入下一頁作為封面 + + + + Reset cover to the default image + 將封面重設為預設圖片 + + + + Load custom cover image + 載入自訂封面圖片 + + + + Series: + 系列: + + + + Title: + 標題: + + + + + + of: + 的: + + + + Issue number: + 發行數量: + + + + Volume: + 卷: + + + + Arc number: + 世界線數量: + + + + Story arc: + 故事線: + + + + alt. number: + 替代。數字: + + + + Alternate series: + 替代系列: + + + + Series Group: + 系列組: + + + + Genre: + 類型: + + + + Size: + 大小: + + + + Writer(s): + 作者: + + + + Penciller(s): + 線稿: + + + + Inker(s): + 墨稿: + + + + Colorist(s): + 上色: + + + + Letterer(s): + 文本: + + + + Cover Artist(s): + 封面設計: + + + + Editor(s): + 編輯: + + + + Imprint: + 印記: + + + + Day: + 日: + + + + Month: + 月: + + + + Year: + 年: + + + + Publisher: + 出版者: + + + + Format: + 格式: + + + + Color/BW: + 彩色/黑白: + + + + Age rating: + 年齡等級: + + + + Type: + 類型: + + + + Language (ISO): + 語言(ISO): + + + + Synopsis: + 概要: + + + + Characters: + 角色: + + + + Teams: + 團隊: + + + + Locations: + 地點: + + + + Main character or team: + 主要角色或團隊: + + + + Review: + 審查: + + + + Notes: + 筆記: + + + + Tags: + 標籤: + + + + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + + + + Not found + 未找到 + + + + Comic not found. You should update your library. + 未找到漫畫,請先更新您的庫. + + + + Edit comic information + 編輯漫畫資訊 + + + + Edit selected comics information + 編輯選中的漫畫資訊 + + + + Invalid cover + 封面無效 + + + + The image is invalid. + 該圖像無效。 + + + + QCoreApplication + + + +YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. + +This appplication supports persistent settings, to set them up edit this file %1 +To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 + +此應用程式支援持久性設置,要設定它們,請編輯此文件 %1 +若要了解可用設置,請查看文件:https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + + + + QObject + + + Trace + 追蹤 + + + + Debug + 除錯 + + + + Info + 資訊 + + + + Warning + 警告 + + + + Error + 錯誤 + + + + Fatal + 嚴重錯誤 + + + + Select custom cover + 選擇自訂封面 + + + + Images (%1) + 圖片 (%1) + + + + 7z lib not found + 未找到 7z 庫檔 + + + + unable to load 7z lib from ./utils + 無法從 ./utils 載入 7z 庫檔 + + + + The file could not be read or is not valid JSON. + 無法讀取該檔案或該檔案不是有效的 JSON。 + + + + This theme is for %1, not %2. + 此主題適用於 %1,而不是 %2。 + + + + Libraries + + + + + Folders + 檔夾 + + + + Reading Lists + 閱讀列表 + + + + RenameLibraryDialog + + + New Library Name : + 新庫名: + + + + Rename + 重命名 + + + + Cancel + 取消 + + + + Rename current library + 重命名當前庫 + + + + ScraperResultsPaginator + + + Number of volumes found : %1 + 搜索結果: %1 + + + + + page %1 of %2 + 第 %1 頁 共 %2 頁 + + + + Number of %1 found : %2 + 第 %1 頁 共: %2 條 + + + + SearchSingleComic + + + Please provide some additional information for this comic. + 請提供附加資訊. + + + + Series: + 系列: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + 使用精確匹配搜尋。如果您想要尋找與名稱中某些單字相符的捲,請停用。 + + + + SearchVolume + + + Please provide some additional information. + 請提供附加資訊. + + + + Series: + 系列: + + + + Use exact match search. Disable if you want to find volumes that match some of the words in the name. + 使用精確匹配搜尋。如果您想要尋找與名稱中某些單字相符的捲,請停用。 + + + + SelectComic + + + Please, select the right comic info. + 請正確選擇漫畫資訊. + + + + comics + 漫畫 + + + + loading cover + 加載封面 + + + + loading description + 加載描述 + + + + comic description unavailable + 漫畫描述不可用 + + + + SelectVolume + + + Please, select the right series for your comic. + 請選擇正確的漫畫系列。 + + + + Filter: + 篩選: + + + + volumes + + + + + Nothing found, clear the filter if any. + 未找到任何內容,如果有,請清除過濾器。 + + + + loading cover + 加載封面 + + + + loading description + 加載描述 + + + + volume description unavailable + 卷描述不可用 + + + + SeriesQuestion + + + You are trying to get information for various comics at once, are they part of the same series? + 您正在嘗試同時獲取各種漫畫的資訊,它們是同一系列的嗎? + + + + yes + + + + + no + + + + + ServerConfigDialog + + + set port + 設置端口 + + + + Server connectivity information + 伺服器連接資訊 + + + + Scan it! + 掃一掃! + + + + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 + + + + Choose an IP address + 選擇IP地址 + + + + Port + 端口 + + + + enable the server + 啟用伺服器 + + + + SortVolumeComics + + + Please, sort the list of comics on the left until it matches the comics' information. + 請在左側對漫畫列表進行排序,直到它與漫畫的資訊相符。 + + + + sort comics to match comic information + 排序漫畫以匹配漫畫資訊 + + + + issues + 發行 + + + + remove selected comics + 移除所選漫畫 + + + + restore all removed comics + 恢復所有移除的漫畫 + + + + ThemeEditorDialog + + + Theme Editor + 主題編輯器 + + + + + + + + + + + - + - + + + + i + + + + + Expand all + 全部展開 + + + + Collapse all + 全部折疊 + + + + Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. + 按住可在 UI 中閃爍所選值(洋紅色/切換/0↔10)。發布後恢復原樣。 + + + + Search… + 搜尋… + + + + Light + 亮度 + + + + Dark + 黑暗的 + + + + ID: + ID: + + + + Display name: + 顯示名稱: + + + + Variant: + 變體: + + + + Theme info + 主題訊息 + + + + Parameter + 範圍 + + + + Value + 價值 + + + + Save and apply + 儲存並應用 + + + + Export to file... + 匯出到文件... + + + + Load from file... + 從檔案載入... + + + + Close + 關閉 + + + + Double-click to edit color + 雙擊編輯顏色 + + + + + + + + + true + 真的 + + + + + + + false + 錯誤的 + + + + Double-click to toggle + 按兩下切換 + + + + Double-click to edit value + 雙擊編輯值 + + + + + + Edit: %1 + 編輯:%1 + + + + Save theme + 儲存主題 + + + + + JSON files (*.json);;All files (*) + JSON 檔案 (*.json);;所有檔案 (*) + + + + Save failed + 保存失敗 + + + + Could not open file for writing: +%1 + 無法開啟文件進行寫入: +%1 + + + + Load theme + 載入主題 + + + + + + Load failed + 載入失敗 + + + + Could not open file: +%1 + 無法開啟檔案: +%1 + + + + Invalid JSON: +%1 + 無效的 JSON: +%1 + + + + Expected a JSON object. + 需要一個 JSON 物件。 + + + + TitleHeader + + + SEARCH + 搜索 + + + + UpdateLibraryDialog + + + Updating.... + 更新中... + + + + Cancel + 取消 + + + + Update library + 更新庫 + + + + Viewer + + + + Press 'O' to open comic. + 按下 'O' 以打開漫畫. + + + + Not found + 未找到 + + + + Comic not found + 未找到漫畫 + + + + Error opening comic + 打開漫畫時發生錯誤 + + + + CRC Error + CRC 校驗失敗 + + + + Loading...please wait! + 載入中... 請稍候! + + + + Page not available! + 頁面不可用! + + + + Cover! + 封面! + + + + Last page! + 尾頁! + + + + VolumeComicsModel + + + title + 標題 + + + + VolumesModel + + + year + + + + + issues + 發行 + + + + publisher + 出版者 + + + + YACReader3DFlowConfigWidget + + + Presets: + 預設: + + + + Classic look + 經典 + + + + Stripe look + 條狀 + + + + Overlapped Stripe look + 重疊條狀 + + + + Modern look + 現代 + + + + Roulette look + 輪盤 + + + + Show advanced settings + 顯示高級選項 + + + + Custom: + 自定義: + + + + View angle + 視角 + + + + Position + 位置 + + + + Cover gap + 封面間距 + + + + Central gap + 中心間距 + + + + Zoom + 縮放 + + + + Y offset + Y位移 + + + + Z offset + Z位移 + + + + Cover Angle + 封面角度 + + + + Visibility + 透明度 + + + + Light + 亮度 + + + + Max angle + 最大角度 + + + + Low Performance + 低性能 + + + + High Performance + 高性能 + + + + Use VSync (improve the image quality in fullscreen mode, worse performance) + 使用VSync (在全屏模式下提高圖像品質, 性能更差) + + + + Performance: + 性能: + + + + YACReader::MainWindowViewer + + + &Open + 打開(&O) + + + + Open a comic + 打開漫畫 + + + + New instance + 新建實例 + + + + Open Folder + 打開檔夾 + + + + Open image folder + 打開圖片檔夾 + + + + Open latest comic + 打開最近的漫畫 + + + + Open the latest comic opened in the previous reading session + 打開最近閱讀漫畫 + + + + Clear + 清空 + + + + Clear open recent list + 清空最近訪問列表 + + + + Save + 保存 + + + + + Save current page + 保存當前頁面 + + + + Previous Comic + 上一個漫畫 + + + + + + Open previous comic + 打開上一個漫畫 + + + + Next Comic + 下一個漫畫 + + + + + + Open next comic + 打開下一個漫畫 + + + + &Previous + 上一頁(&P) + + + + + + Go to previous page + 轉至上一頁 + + + + &Next + 下一頁(&N) + + + + + + Go to next page + 轉至下一頁 + + + + Fit Height + 適應高度 + + + + Fit image to height + 縮放圖片以適應高度 + + + + Fit Width + 適合寬度 + + + + Fit image to width + 縮放圖片以適應寬度 + + + + Show full size + 顯示全尺寸 + + + + Fit to page + 適應頁面 + + + + Continuous scroll + 連續滾動 + + + + Switch to continuous scroll mode + 切換到連續滾動模式 + + + + Reset zoom + 重置縮放 + + + + Show zoom slider + 顯示縮放滑塊 + + + + Zoom+ + 放大 + + + + Zoom- + 縮小 + + + + Rotate image to the left + 向左旋轉圖片 + + + + Rotate image to the right + 向右旋轉圖片 + + + + Double page mode + 雙頁模式 + + + + Switch to double page mode + 切換至雙頁模式 + + + + Double page manga mode + 雙頁漫畫模式 + + + + Reverse reading order in double page mode + 雙頁模式 (逆序閱讀) + + + + Go To + 跳轉 + + + + Go to page ... + 跳轉至頁面 ... + + + + Options + 選項 + + + + YACReader options + YACReader 選項 + + + + + Help + 幫助 + + + + Help, About YACReader + 幫助, 關於 YACReader + + + + Magnifying glass + 放大鏡 + + + + Switch Magnifying glass + 切換放大鏡 + + + + Set bookmark + 設置書簽 + + + + Set a bookmark on the current page + 在當前頁面設置書簽 + + + + Show bookmarks + 顯示書簽 + + + + Show the bookmarks of the current comic + 顯示當前漫畫的書簽 + + + + Show keyboard shortcuts + 顯示鍵盤快捷鍵 + + + + Show Info + 顯示資訊 + + + + Close + 關閉 + + + + Show Dictionary + 顯示字典 + + + + Show go to flow + 顯示頁面流 + + + + Edit shortcuts + 編輯快捷鍵 + + + + &File + 檔(&F) + + + + + Open recent + 最近打開的檔 + + + + File + + + + + Edit + 編輯 + + + + View + 查看 + + + + Go + 轉到 + + + + Window + 窗口 + + + + + + Open Comic + 打開漫畫 + + + + + + Comic files + 漫畫檔 + + + + Open folder + 打開檔夾 + + + + page_%1.jpg + 頁_%1.jpg + + + + Image files (*.jpg) + 圖像檔 (*.jpg) + + + + + Comics + 漫畫 + + + + + General + 常規 + + + + + Magnifiying glass + 放大鏡 + + + + + Page adjustement + 頁面調整 + + + + + Reading + 閱讀 + + + + Toggle fullscreen mode + 切換全屏模式 + + + + Hide/show toolbar + 隱藏/顯示 工具欄 + + + + Size up magnifying glass + 增大放大鏡尺寸 + + + + Size down magnifying glass + 減小放大鏡尺寸 + + + + Zoom in magnifying glass + 增大縮放級別 + + + + Zoom out magnifying glass + 減小縮放級別 + + + + Reset magnifying glass + 重置放大鏡 + + + + Toggle between fit to width and fit to height + 切換顯示為"適應寬度"或"適應高度" + + + + Autoscroll down + 向下自動滾動 + + + + Autoscroll up + 向上自動滾動 + + + + Autoscroll forward, horizontal first + 向前自動滾動,水準優先 + + + + Autoscroll backward, horizontal first + 向後自動滾動,水準優先 + + + + Autoscroll forward, vertical first + 向前自動滾動,垂直優先 + + + + Autoscroll backward, vertical first + 向後自動滾動,垂直優先 + + + + Move down + 向下移動 + + + + Move up + 向上移動 + + + + Move left + 向左移動 + + + + Move right + 向右移動 + + + + Go to the first page + 轉到第一頁 + + + + Go to the last page + 轉到最後一頁 + + + + Offset double page to the left + 雙頁向左偏移 + + + + Offset double page to the right + 雙頁向右偏移 + + + + There is a new version available + 有新版本可用 + + + + Do you want to download the new version? + 你要下載新版本嗎? + + + + Remind me in 14 days + 14天後提醒我 + + + + Not now + 現在不 + + + + YACReader::TrayIconController + + + &Restore + 複位(&R) + + + + Systray + 系統託盤 + + + + YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. + YACReaderLibrary 將繼續在系統託盤中運行. 想要終止程式, 請在系統託盤圖示的上下文菜單中選擇<b>退出</b>. + + + + YACReaderFieldEdit + + + + Click to overwrite + 點擊以覆蓋 + + + + Restore to default + 恢復默認 + + + + YACReaderFieldPlainTextEdit + + + + + + Click to overwrite + 點擊以覆蓋 + + + + Restore to default + 恢復默認 + + + + YACReaderOptionsDialog + + + Save + 保存 + + + + Cancel + 取消 + + + + Edit shortcuts + 編輯快捷鍵 + + + + Shortcuts + 快捷鍵 + + + + YACReaderSearchLineEdit + + + type to search + 搜索類型 + + + + YACReaderSlider + + + Reset + 重置 - QsLogging::Window + YACReaderTranslator - - &Pause - + + YACReader translator + YACReader 翻譯 - - &Resume - + + + Translation + 翻譯 - - Save log - + + clear + 清空 - - Log file (*.log) - + + Service not available + 服務不可用 diff --git a/ci/win/build_installer_qt6.iss b/ci/win/build_installer_qt6.iss index c71942104..c5f229fd5 100644 --- a/ci/win/build_installer_qt6.iss +++ b/ci/win/build_installer_qt6.iss @@ -101,7 +101,7 @@ Source: README.md; DestDir: {app}; Flags: isreadme Source: COPYING.txt; DestDir: {app} ;Languages -Source: languages\*; DestDir: {app}\languages\; Flags: recursesubdirs +Source: languages\*; DestDir: {app}\languages\; Flags: recursesubdirs; Excludes: "*_source.qm" ;Server Source: server\*; DestDir: {app}\server\; Flags: recursesubdirs diff --git a/ci/win/create_installer.cmd b/ci/win/create_installer.cmd index 10f0d6c86..2a6580737 100644 --- a/ci/win/create_installer.cmd +++ b/ci/win/create_installer.cmd @@ -46,7 +46,8 @@ rem Collect cmake-generated .qm translation files from the build tree rem (release\languages is not tracked in git; cmake generates .qm in build subdirs) mkdir languages for /r %src_path%\build %%f in (*.qm) do ( - copy "%%f" .\languages\ >nul + echo %%~nf | findstr /I /R "_source$" >nul + if errorlevel 1 copy "%%f" .\languages\ >nul ) copy %src_path%\vc_redist.%ARCH%.exe . diff --git a/common/app_language_utils.h b/common/app_language_utils.h new file mode 100644 index 000000000..d76c63b9e --- /dev/null +++ b/common/app_language_utils.h @@ -0,0 +1,131 @@ +#ifndef APP_LANGUAGE_UTILS_H +#define APP_LANGUAGE_UTILS_H + +#include "yacreader_global_gui.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace YACReader::UiLanguage { + +struct LanguageOption { + QString code; + QString displayName; +}; + +inline QStringList translationDirectories() +{ + QStringList directories; +#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) + directories << QString(DATADIR) + "/yacreader/languages"; +#endif + directories << QCoreApplication::applicationDirPath() + "/languages"; + directories.removeDuplicates(); + return directories; +} + +inline bool loadFromLocale(QTranslator &translator, const QString &prefix, const QLocale &locale) +{ + const auto dirs = translationDirectories(); + for (const auto &dir : dirs) { + if (translator.load(locale, prefix, "_", dir)) + return true; + } + + return false; +} + +inline bool loadTranslator(QTranslator &translator, const QString &prefix, const QString &languageOverride = QString()) +{ + auto selectedLanguage = languageOverride.trimmed(); + if (!selectedLanguage.isEmpty()) { + selectedLanguage.replace('-', '_'); + + if (loadFromLocale(translator, prefix, QLocale(selectedLanguage))) + return true; + + auto baseLanguage = selectedLanguage.section('_', 0, 0); + if (baseLanguage != selectedLanguage && loadFromLocale(translator, prefix, QLocale(baseLanguage))) + return true; + } + + return loadFromLocale(translator, prefix, QLocale()); +} + +inline QTranslator &appTranslator() +{ + static QTranslator translator; + return translator; +} + +inline bool applyLanguage(const QString &prefix, const QString &languageOverride = QString()) +{ + auto &translator = appTranslator(); + QCoreApplication::removeTranslator(&translator); + const auto loaded = loadTranslator(translator, prefix, languageOverride); + QCoreApplication::installTranslator(&translator); + return loaded; +} + +inline QString languageDisplayName(const QString &languageCode) +{ + QLocale locale(languageCode); + + QString languageName = locale.nativeLanguageName(); + if (languageName.isEmpty()) + languageName = QLocale::languageToString(locale.language()); + + if (languageName.isEmpty()) + languageName = languageCode; + + QString territoryName; + if (locale.territory() != QLocale::AnyTerritory) + territoryName = locale.nativeTerritoryName(); + + if (!territoryName.isEmpty()) + return QString("%1 (%2)").arg(languageName, territoryName); + + return languageName; +} + +inline QList availableLanguages(const QString &prefix) +{ + QSet languageCodes; + const auto pattern = QRegularExpression( + "^" + QRegularExpression::escape(prefix) + "_(.+)\\.qm$"); + + const auto dirs = translationDirectories(); + for (const auto &dirPath : dirs) { + QDir dir(dirPath); + if (!dir.exists()) + continue; + + const auto files = dir.entryList( + QStringList { prefix + "_*.qm" }, QDir::Files, QDir::Name); + for (const auto &file : files) { + auto match = pattern.match(file); + if (match.hasMatch()) + languageCodes.insert(match.captured(1)); + } + } + + QList options; + for (const auto &languageCode : languageCodes) { + options.append({ languageCode, languageDisplayName(languageCode) }); + } + + std::sort(options.begin(), options.end(), [](const LanguageOption &lhs, const LanguageOption &rhs) { + return lhs.displayName.localeAwareCompare(rhs.displayName) < 0; + }); + + return options; +} + +} // namespace YACReader::UiLanguage + +#endif // APP_LANGUAGE_UTILS_H diff --git a/common/yacreader_global_gui.h b/common/yacreader_global_gui.h index 2065bd2d2..88d53a004 100644 --- a/common/yacreader_global_gui.h +++ b/common/yacreader_global_gui.h @@ -7,6 +7,7 @@ #include #define PATH "PATH" +#define UI_LANGUAGE "UI_LANGUAGE" #define MAG_GLASS_SIZE "MAG_GLASS_SIZE" #define MAG_GLASS_ZOOM "MAG_GLASS_ZOOM" #define ZOOM_LEVEL "ZOOM_LEVEL" diff --git a/compileOSX.sh b/compileOSX.sh index 8a5d043dc..b75e3f9eb 100755 --- a/compileOSX.sh +++ b/compileOSX.sh @@ -70,9 +70,9 @@ cp -R release/server YACReaderLibraryServer.app/Contents/MacOS/ mkdir -p YACReader.app/Contents/MacOS/languages mkdir -p YACReaderLibrary.app/Contents/MacOS/languages mkdir -p YACReaderLibraryServer.app/Contents/MacOS/languages -find build -name "*.qm" -exec cp {} YACReader.app/Contents/MacOS/languages/ \; -find build -name "*.qm" -exec cp {} YACReaderLibrary.app/Contents/MacOS/languages/ \; -find build -name "*.qm" -exec cp {} YACReaderLibraryServer.app/Contents/MacOS/languages/ \; +find build -name "*.qm" ! -name "*_source.qm" -exec cp {} YACReader.app/Contents/MacOS/languages/ \; +find build -name "*.qm" ! -name "*_source.qm" -exec cp {} YACReaderLibrary.app/Contents/MacOS/languages/ \; +find build -name "*.qm" ! -name "*_source.qm" -exec cp {} YACReaderLibraryServer.app/Contents/MacOS/languages/ \; /usr/libexec/PlistBuddy -c "Add :CFBundleVersion string ${BUILD_NUMBER}" YACReader.app/Contents/Info.plist /usr/libexec/PlistBuddy -c "Add :CFBundleShortVersionString string ${VERSION}" YACReader.app/Contents/Info.plist From e649a9e3e0e74bf8c3f8b11e0b074967d791de37 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Wed, 11 Mar 2026 18:30:58 +0100 Subject: [PATCH 146/187] Update CHANGELOG --- CHANGELOG.md | 1 + custom_widgets/whats_new_dialog.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 994b25641..968ce1bec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Version counting is based on semantic versioning (Major.Feature.Patch) * Migrate Flow implementation from OpenGL to QRhi. This is a full new implementation with better performance and compatibility with operating systems and hardware. * Add light/dark themes support that follow the system configuration. * Add a theme editor and support for custom themes. +* Add an application language setting with a system default option in YACReader and YACReaderLibrary. ## 9.16.4 diff --git a/custom_widgets/whats_new_dialog.cpp b/custom_widgets/whats_new_dialog.cpp index bd4a15463..5718ee7ba 100644 --- a/custom_widgets/whats_new_dialog.cpp +++ b/custom_widgets/whats_new_dialog.cpp @@ -48,6 +48,7 @@ YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent) " • Migrate Flow implementation from OpenGL to QRhi. This is a full new implementation with better performance and compatibility with operating systems and hardware
" " • Add light/dark themes support that follow the system configuration
" " • Add a theme editor and support for custom themes
" + " • Add an application language setting with a system default option in YACReader and YACReaderLibrary
" "
" "I hope you enjoy the new update. Please, if you like YACReader consider to become a patron in Patreon " "or donate some money using Pay-Pal and help keeping the project alive. " From 2caf5c8608b91cd44b9de9ecf802c4b38a99fe6e Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Wed, 11 Mar 2026 19:09:23 +0100 Subject: [PATCH 147/187] Bump actions versions --- .github/workflows/build.yml | 46 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index efa5c5d71..165f44aef 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,7 +40,7 @@ jobs: runs-on: macos-latest needs: initialization steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install dependencies run: brew install clang-format @@ -60,7 +60,7 @@ jobs: runs-on: ubuntu-24.04 needs: [initialization, code-format-validation] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install dependencies run: | @@ -93,7 +93,7 @@ jobs: runs-on: ubuntu-24.04 needs: [initialization, code-format-validation] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install dependencies run: | @@ -126,10 +126,10 @@ jobs: runs-on: macos-15 needs: [initialization, code-format-validation] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: '18' @@ -166,7 +166,7 @@ jobs: xcrun stapler staple *.dmg - name: Upload DMG - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: macos-qt6-universal-${{ needs.initialization.outputs.build_number }}-dmg path: "*.dmg" @@ -177,10 +177,10 @@ jobs: runs-on: windows-2022 needs: [initialization, code-format-validation] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.10' architecture: 'x64' @@ -213,7 +213,7 @@ jobs: - name: Upload executables for signing if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 id: upload_executables with: name: windows-x64-qt6-executables-unsigned-${{ needs.initialization.outputs.build_number }} @@ -269,7 +269,7 @@ jobs: - name: Upload unsigned installer if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 id: upload_unsigned with: name: windows-x64-qt6-unsigned-${{ needs.initialization.outputs.build_number }} @@ -311,7 +311,7 @@ jobs: Write-Host "Cleaned up signed directory" - name: Upload installer - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: windows-x64-qt6-${{ needs.initialization.outputs.build_number }} path: ci/win/Output/YACReader*.exe @@ -322,10 +322,10 @@ jobs: runs-on: windows-2022 needs: [initialization, code-format-validation] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.10' architecture: 'x64' @@ -351,7 +351,7 @@ jobs: - name: Upload executables for signing if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 id: upload_executables with: name: windows-arm64-qt6-executables-unsigned-${{ needs.initialization.outputs.build_number }} @@ -402,7 +402,7 @@ jobs: - name: Upload unsigned installer if: github.repository == 'YACReader/yacreader' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/yacreader10') - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 id: upload_unsigned with: name: windows-arm64-qt6-unsigned-${{ needs.initialization.outputs.build_number }} @@ -437,7 +437,7 @@ jobs: Write-Host "Cleaned up signed directory" - name: Upload installer - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: windows-arm64-qt6-${{ needs.initialization.outputs.build_number }} path: ci/win/Output/YACReader*.exe @@ -448,7 +448,7 @@ jobs: runs-on: ubuntu-latest needs: [initialization, code-format-validation] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -460,7 +460,7 @@ jobs: docker save yacreader/yacreaderlibraryserver:develop-amd64 -o amd64.tar - name: Upload Docker Image - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: docker-amd64 path: docker/amd64.tar @@ -471,7 +471,7 @@ jobs: runs-on: ubuntu-24.04-arm needs: [initialization, code-format-validation] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Build arm64 Image (native) working-directory: docker @@ -480,7 +480,7 @@ jobs: docker save yacreader/yacreaderlibraryserver:develop-arm64 -o arm64.tar - name: Upload Docker Image - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: docker-arm64 path: docker/arm64.tar @@ -500,7 +500,7 @@ jobs: - docker-amd64 - docker-arm64 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Prepare release artifacts uses: ./.github/actions/prepare-release-artifacts @@ -567,7 +567,7 @@ jobs: - docker-amd64 - docker-arm64 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Prepare release artifacts uses: ./.github/actions/prepare-release-artifacts @@ -638,7 +638,7 @@ jobs: - docker-amd64 - docker-arm64 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Prepare release artifacts uses: ./.github/actions/prepare-release-artifacts From 5bda2241f424dbb12a521af29c71547f7584501c Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Wed, 11 Mar 2026 19:45:56 +0100 Subject: [PATCH 148/187] Fixed and normalized multiple translations --- YACReader/yacreader_de.ts | 65 ++--- YACReader/yacreader_es.ts | 100 ++++--- YACReader/yacreader_fr.ts | 268 +++++++++--------- YACReader/yacreader_it.ts | 160 +++++------ YACReader/yacreader_nl.ts | 78 ++--- YACReader/yacreader_pt.ts | 62 ++-- YACReader/yacreader_ru.ts | 64 ++--- YACReader/yacreader_tr.ts | 76 ++--- YACReader/yacreader_zh_CN.ts | 62 ++-- YACReader/yacreader_zh_HK.ts | 62 ++-- YACReader/yacreader_zh_TW.ts | 62 ++-- YACReaderLibrary/yacreaderlibrary_de.ts | 69 ++--- YACReaderLibrary/yacreaderlibrary_es.ts | 100 ++++--- YACReaderLibrary/yacreaderlibrary_fr.ts | 264 ++++++++--------- YACReaderLibrary/yacreaderlibrary_it.ts | 166 +++++------ YACReaderLibrary/yacreaderlibrary_nl.ts | 78 ++--- YACReaderLibrary/yacreaderlibrary_pt.ts | 64 ++--- YACReaderLibrary/yacreaderlibrary_ru.ts | 68 ++--- YACReaderLibrary/yacreaderlibrary_tr.ts | 84 +++--- YACReaderLibrary/yacreaderlibrary_zh_CN.ts | 66 ++--- YACReaderLibrary/yacreaderlibrary_zh_HK.ts | 72 ++--- YACReaderLibrary/yacreaderlibrary_zh_TW.ts | 72 ++--- .../yacreaderlibraryserver_de.ts | 63 ++-- .../yacreaderlibraryserver_es.ts | 98 ++++--- .../yacreaderlibraryserver_fr.ts | 254 ++++++++--------- .../yacreaderlibraryserver_nl.ts | 76 ++--- .../yacreaderlibraryserver_pt.ts | 62 ++-- .../yacreaderlibraryserver_ru.ts | 62 ++-- .../yacreaderlibraryserver_tr.ts | 74 ++--- .../yacreaderlibraryserver_zh_CN.ts | 62 ++-- .../yacreaderlibraryserver_zh_HK.ts | 62 ++-- .../yacreaderlibraryserver_zh_TW.ts | 62 ++-- 32 files changed, 1547 insertions(+), 1490 deletions(-) diff --git a/YACReader/yacreader_de.ts b/YACReader/yacreader_de.ts index 077f25ab8..b5fe18b39 100644 --- a/YACReader/yacreader_de.ts +++ b/YACReader/yacreader_de.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Bevor du dich mit Comic Vine verbindest, brauchst du deinen eigenen API-Schlüssel. Du kannst <a href="http://www.comicvine.com/api/">hier</a> einen kostenlosen bekommen. + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Bevor du dich mit Comic Vine verbindest, brauchst du deinen eigenen API-Schlüssel. Du kannst <a href="http://www.comicvine.com/api/">hier</a> einen kostenlosen bekommen. @@ -228,7 +228,7 @@ Hide comic flow - Comic "Flow" verstecken + Comic Flow ausblenden
@@ -441,15 +441,15 @@
- The shortcut "%1" is already assigned to other function - Das Kürzel "%1" ist bereits für eine andere Funktion in Verwendung + The shortcut "%1" is already assigned to other function + Das Kürzel "%1" ist bereits für eine andere Funktion in Verwendung
EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Dieser Ordner enthält noch keine Comics @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Dieses Label enthält noch keine Comics
@@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - Bibliothek '%1' ist nicht mehr verfügbar. Wollen Sie sie entfernen? + Library '%1' is no longer available. Do you want to remove it? + Bibliothek '%1' ist nicht mehr verfügbar. Wollen Sie sie entfernen? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Bibliothek '%1' wurde mit einer älteren Version von YACReader erstellt. Sie muss neu erzeugt werden. Wollen Sie die Bibliothek jetzt erzeugen? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Bibliothek '%1' wurde mit einer älteren Version von YACReader erstellt. Sie muss neu erzeugt werden. Wollen Sie die Bibliothek jetzt erzeugen? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Beim Aufrufen des Ordnerpfades kam es zu einem Fehler @@ -1036,7 +1036,8 @@ You probably only need one library in your top level comics folder, you can brow YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. Sie fügen zu viele Bibliotheken hinzu. - Wahrscheinlich brauchen Sie nur eine Bibliothek in Ihrem obersten Comic-Ordner, Sie können alle Unterordner mit Hilfe des Ordnerbereichs in der linken Seitenleiste durchsuchen. + +Wahrscheinlich brauchen Sie nur eine Bibliothek in Ihrem obersten Comic-Ordner, Sie können alle Unterordner mit Hilfe des Ordnerbereichs in der linken Seitenleiste durchsuchen. YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen, aber Sie sollten die Anzahl der Bibliotheken gering halten. @@ -1073,7 +1074,7 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. Der ausgewählte Ordner enthält keine Bibliothek. @@ -1178,8 +1179,8 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen - There is another library with the name '%1'. - Es gibt bereits eine Bibliothek mit dem Namen '%1'. + There is another library with the name '%1'. + Es gibt bereits eine Bibliothek mit dem Namen '%1'.
@@ -1839,7 +1840,7 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen Show go to flow - "Go to Flow" anzeigen + "Gehe zu Comic Flow" anzeigen Previous Comic @@ -2042,12 +2043,12 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet Sie haben aktuell noch keine Bibliothek - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Sie können eine Bibliothek in jedem beliebigen Ordner erstellen, YACReaderLibrary wird alle Comics und Unterordner von diesem Ordner importieren. Wenn Sie bereits eine Bibliothek erstellt haben, können Sie sie öffnen.</p><p>Vergessen Sie nicht, dass Sie YACReader als eigentsändige Anwendung nutzen können, um Comics auf Ihrem Computer zu lesen.</p> @@ -2118,8 +2119,8 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen - "Go to flow" size - "Go to flow" Größe + "Go to flow" size + Größe von "Gehe zu Comic Flow" @@ -2145,7 +2146,7 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen Comic Flow - Comic-Flow + Comic Flow @@ -2219,7 +2220,7 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago Berücksichtigen Sie „neue“ Elemente, die seit X Tagen hinzugefügt oder aktualisiert wurden @@ -2306,7 +2307,7 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WARNUNG! Während Bibliotheksaktualisierungen sind Schreibvorgänge in die Datenbank deaktiviert! @@ -2723,8 +2724,8 @@ Um eine automatische Aktualisierung zu stoppen, tippen Sie auf die Ladeanzeige n - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine-Link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ansehen </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine-Link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ansehen </a> @@ -3066,8 +3067,8 @@ Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Do - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader ist für iOS- und Android-Geräte verfügbar.<br/>Entdecken Sie es für <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> oder <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader ist für iOS- und Android-Geräte verfügbar.<br/>Entdecken Sie es für <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> oder <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -3104,7 +3105,7 @@ Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Do SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Sortieren Sie bitte die Comic-Informationen links, bis die Informationen mit den Comics übereinstimmen. @@ -3361,8 +3362,8 @@ Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Do - Press 'O' to open comic. - 'O' drücken, um Comic zu öffnen. + Press 'O' to open comic. + 'O' drücken, um Comic zu öffnen. @@ -3824,7 +3825,7 @@ Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Do Show go to flow - "Go to Flow" anzeigen + "Gehe zu Comic Flow" anzeigen diff --git a/YACReader/yacreader_es.ts b/YACReader/yacreader_es.ts index 471791646..b073d0383 100644 --- a/YACReader/yacreader_es.ts +++ b/YACReader/yacreader_es.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Antes de que te puedas conectar a Comic Vine necesitas tu propia clave API. Por favor, obtén una gratis <a href="http://www.comicvine.com/api/">aquí</a> + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Antes de que te puedas conectar a Comic Vine necesitas tu propia clave API. Por favor, obtén una gratis <a href="http://www.comicvine.com/api/">aquí</a> @@ -179,7 +179,8 @@ Could not import theme from: %1 - No se pudo importar el tema desde:\n%1 + No se pudo importar el tema desde: +%1 @@ -187,7 +188,10 @@ %1 %2 - No se pudo importar el tema desde:\n%1\n\n%2 + No se pudo importar el tema desde: +%1 + +%2 @@ -224,7 +228,7 @@ Hide comic flow - Ocultar cómic flow + Ocultar Comic Flow @@ -437,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - El acceso directo "%1" ya está asignado a otra función + The shortcut "%1" is already assigned to other function + El acceso directo "%1" ya está asignado a otra función EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Esta carpeta aún no contiene cómics @@ -453,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Esta etiqueta aún no contiene ningún cómic
@@ -866,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - La biblioteca '%1' no está disponible. ¿Deseas eliminarla? + Library '%1' is no longer available. Do you want to remove it? + La biblioteca '%1' no está disponible. ¿Deseas eliminarla? @@ -876,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - La biblioteca '%1' ha sido creada con una versión más antigua de YACReaderLibrary y debe ser creada de nuevo. ¿Deseas crear la biblioteca ahora? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La biblioteca '%1' ha sido creada con una versión más antigua de YACReaderLibrary y debe ser creada de nuevo. ¿Deseas crear la biblioteca ahora? @@ -918,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Hubo un error al acceder a la ruta de la carpeta @@ -1031,7 +1035,11 @@ You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - Estás añadiendo demasiadas bibliotecas.\n\nProbablemente solo necesites una biblioteca en la carpeta principal de tus cómics, puedes explorar cualquier subcarpeta utilizando la sección de carpetas en la barra lateral izquierda.\n\nYACReaderLibrary no te detendrá de crear más bibliotecas, pero deberías mantener el número de bibliotecas bajo control. + Estás añadiendo demasiadas bibliotecas. + +Probablemente solo necesites una biblioteca en la carpeta principal de tus cómics, puedes explorar cualquier subcarpeta utilizando la sección de carpetas en la barra lateral izquierda. + +YACReaderLibrary no te detendrá de crear más bibliotecas, pero deberías mantener el número de bibliotecas bajo control. @@ -1066,7 +1074,7 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. La carpeta seleccionada no contiene ninguna biblioteca. @@ -1171,8 +1179,8 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - There is another library with the name '%1'. - Hay otra biblioteca con el nombre '%1'. + There is another library with the name '%1'. + Hay otra biblioteca con el nombre '%1'.
@@ -1801,7 +1809,7 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Show go to flow - Mostrar flow ir a + Mostrar "Ir a Comic Flow" Previous Comic @@ -1840,12 +1848,12 @@ YACReaderLibrary will not stop you from creating more libraries but you should k NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet Aún no tienes ninguna biblioteca - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Puedes crear una biblioteca en cualquier carpeta, YACReaderLibrary importará todos las carpetas y cómics de esa carpeta. Si has creado alguna biblioteca anteriormente, puedes abrirla sin volver a crearla.</p><p>No olvides que puedes usar YACReader como una aplicación independiente para leer los cómics en tu ordenador.</p> @@ -1916,8 +1924,8 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - "Go to flow" size - Tamaño de "Go to flow" + "Go to flow" size + Tamaño de "Ir a Comic Flow" @@ -1943,7 +1951,7 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Comic Flow - Flujo cómico + Comic Flow @@ -2017,8 +2025,8 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - Consider 'recent' items added or updated since X days ago - Considerar elementos 'recientes' añadidos o actualizados desde hace X días + Consider 'recent' items added or updated since X days ago + Considerar elementos 'recientes' añadidos o actualizados desde hace X días @@ -2104,10 +2112,13 @@ YACReaderLibrary will not stop you from creating more libraries but you should k WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. - ¡ADVERTENCIA! Durante las actualizaciones de la biblioteca se desactivan las escrituras en la base de datos. No programes actualizaciones mientras puedas estar usando la aplicación activamente. Durante las actualizaciones automáticas, la aplicación bloqueará algunas de las acciones hasta que la actualización esté terminada. Para detener una actualización automática, toca en el indicador de carga junto al título de Bibliotecas. + ¡ADVERTENCIA! Durante las actualizaciones de la biblioteca se desactivan las escrituras en la base de datos. +No programes actualizaciones mientras puedas estar usando la aplicación activamente. +Durante las actualizaciones automáticas, la aplicación bloqueará algunas de las acciones hasta que la actualización esté terminada. +Para detener una actualización automática, toca en el indicador de carga junto al título de Bibliotecas. @@ -2152,7 +2163,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Display continue reading banner - Mostrar banner de "Continuar leyendo" + Mostrar banner de "Continuar leyendo" @@ -2518,8 +2529,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ver </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ver </a> @@ -2561,7 +2572,11 @@ YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. This appplication supports persistent settings, to set them up edit this file %1 To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md - \nYACReaderLibraryServer es la versión sin interfaz gráfica (headless) de YACReaderLibrary.\n\nEsta aplicación admite ajustes persistentes; para configurarlos, edita este archivo %1\nPara conocer los ajustes disponibles, consulta la documentación en https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer es la versión sin interfaz gráfica (headless) de YACReaderLibrary. + +Esta aplicación admite ajustes persistentes; para configurarlos, edita este archivo %1 +Para conocer los ajustes disponibles, consulta la documentación en https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md @@ -2823,8 +2838,8 @@ To learn about the available settings please check the documentation at https:// - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader está disponible para iOS y Android.<br/> Descúbrela para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a>o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader está disponible para iOS y Android.<br/> Descúbrela para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a>o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2861,7 +2876,7 @@ To learn about the available settings please check the documentation at https:// SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Por favor, ordena la lista de cómics en la izquiera hasta que coincida con la información adecuada. @@ -3047,7 +3062,8 @@ To learn about the available settings please check the documentation at https:// Could not open file for writing: %1 - No se pudo abrir el archivo para escribir:\n%1 + No se pudo abrir el archivo para escribir: +%1 @@ -3065,13 +3081,15 @@ To learn about the available settings please check the documentation at https:// Could not open file: %1 - No se pudo abrir el archivo:\n%1 + No se pudo abrir el archivo: +%1 Invalid JSON: %1 - JSON no válido:\n%1 + JSON no válido: +%1 @@ -3115,8 +3133,8 @@ To learn about the available settings please check the documentation at https:// - Press 'O' to open comic. - Pulsa 'O' para abrir un fichero. + Press 'O' to open comic. + Pulsa 'O' para abrir un fichero. @@ -3578,7 +3596,7 @@ To learn about the available settings please check the documentation at https:// Show go to flow - Mostrar flow ir a + Mostrar "Ir a Comic Flow" diff --git a/YACReader/yacreader_fr.ts b/YACReader/yacreader_fr.ts index 70d120a19..c38b7cda7 100644 --- a/YACReader/yacreader_fr.ts +++ b/YACReader/yacreader_fr.ts @@ -14,7 +14,7 @@ Label name: - Nom de l'étiquette : + Nom de l'étiquette : @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Avant de pouvoir vous connecter à Comic Vine, vous avez besoin de votre propre clé API. Veuillez en obtenir une gratuitement ici: <a href="http://www.comicvine.com/api/"></a> + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Avant de pouvoir vous connecter à Comic Vine, vous avez besoin de votre propre clé API. Veuillez en obtenir une gratuitement ici: <a href="http://www.comicvine.com/api/"></a> @@ -118,7 +118,7 @@ Remove this user-imported theme - Supprimer ce thème importé par l'utilisateur + Supprimer ce thème importé par l'utilisateur @@ -153,17 +153,17 @@ Open Theme Editor... - Ouvrir l'éditeur de thème... + Ouvrir l'éditeur de thème... Theme editor error - Erreur de l'éditeur de thème + Erreur de l'éditeur de thème The current theme JSON could not be loaded. - Le thème actuel JSON n'a pas pu être chargé. + Le thème actuel JSON n'a pas pu être chargé. @@ -179,7 +179,7 @@ Could not import theme from: %1 - Impossible d'importer le thème depuis : + Impossible d'importer le thème depuis : %1 @@ -188,7 +188,7 @@ %1 %2 - Impossible d'importer le thème depuis : + Impossible d'importer le thème depuis : %1 %2 @@ -196,7 +196,7 @@ Import failed - Échec de l'importation + Échec de l'importation @@ -228,7 +228,7 @@ Hide comic flow - Cacher le flux de bande dessinée + Masquer Comic Flow @@ -296,7 +296,7 @@ Story Arc - Arc d'histoire + Arc d'histoire @@ -399,7 +399,7 @@ Create a library could take several minutes. You can stop the process and update the library later for completing the task. - La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et continuer plus tard. + La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et continuer plus tard. @@ -414,7 +414,7 @@ The selected path does not exist or is not a valid path. Be sure that you have write access to this folder - Le chemin sélectionné n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + Le chemin sélectionné n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier @@ -422,7 +422,7 @@ Shortcut in use - Raccourci en cours d'utilisation + Raccourci en cours d'utilisation @@ -436,8 +436,8 @@ - The shortcut "%1" is already assigned to other function - Le raccourci "%1" est déjà affecté à une autre fonction + The shortcut "%1" is already assigned to other function + Le raccourci "%1" est déjà affecté à une autre fonction @@ -449,7 +449,7 @@ EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Ce dossier ne contient pas encore de bandes dessinées @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Ce dossier ne contient pas encore de bandes dessinées
@@ -484,7 +484,7 @@ There are no recent comics! - Il n'y a pas de BD récente ! + Il n'y a pas de BD récente !
@@ -517,12 +517,12 @@ Problem found while writing - Problème durant l'écriture + Problème durant l'écriture The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier @@ -550,12 +550,12 @@ Problem found while writing - Problème durant l'écriture + Problème durant l'écriture The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier @@ -578,12 +578,12 @@ Unknown error opening the file - Erreur inconnue lors de l'ouverture du fichier + Erreur inconnue lors de l'ouverture du fichier CRC error on page (%1): some of the pages will not be displayed correctly - Erreur CRC sur la page (%1): certaines pages ne s'afficheront pas correctement + Erreur CRC sur la page (%1): certaines pages ne s'afficheront pas correctement @@ -735,7 +735,7 @@ <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - <p>YACReaderLibrary est en train de créer une nouvelle librairie.</p><p>La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et poursuivre plus tard.</p> + <p>YACReaderLibrary est en train de créer une nouvelle librairie.</p><p>La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et poursuivre plus tard.</p> @@ -765,7 +765,7 @@ <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> - <p>La bibliothèque actuelle est en cours d'analyse pour rechercher des informations sur les métadonnées XML héritées.</p><p>Ceci n'est nécessaire qu'une seule fois, et uniquement si la bibliothèque a été créée avec YACReaderLibrary 9.8.2 ou une version antérieure.</p> + <p>La bibliothèque actuelle est en cours d'analyse pour rechercher des informations sur les métadonnées XML héritées.</p><p>Ceci n'est nécessaire qu'une seule fois, et uniquement si la bibliothèque a été créée avec YACReaderLibrary 9.8.2 ou une version antérieure.</p> @@ -841,7 +841,7 @@ There were errors during library upgrade in: - Des erreurs se sont produites lors de la mise à niveau de la bibliothèque dans : + Des erreurs se sont produites lors de la mise à niveau de la bibliothèque dans : @@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - La librarie '%1' n'est plus disponible. Voulez-vous la supprimer? + Library '%1' is no longer available. Do you want to remove it? + La librarie '%1' n'est plus disponible. Voulez-vous la supprimer? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - La librarie '%1' a été créée avec une ancienne version de YACReaderLibrary. Elle doit être re-créée. Voulez-vous créer la librairie? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La librarie '%1' a été créée avec une ancienne version de YACReaderLibrary. Elle doit être re-créée. Voulez-vous créer la librairie? @@ -903,7 +903,7 @@ Folder name: - Nom du dossier : + Nom du dossier : @@ -913,7 +913,7 @@ Please, select a folder first - Veuillez d'abord sélectionner un dossier + Veuillez d'abord sélectionner un dossier @@ -922,8 +922,8 @@ - There was an error accessing the folder's path - Une erreur s'est produite lors de l'accès au chemin du dossier + There was an error accessing the folder's path + Une erreur s'est produite lors de l'accès au chemin du dossier @@ -944,7 +944,7 @@ There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - Un problème est survenu lors de la tentative de suppression des dossiers sélectionnés. Veuillez vérifier les autorisations d'écriture et assurez-vous que toutes les applications utilisent ces dossiers ou l'un des fichiers contenus. + Un problème est survenu lors de la tentative de suppression des dossiers sélectionnés. Veuillez vérifier les autorisations d'écriture et assurez-vous que toutes les applications utilisent ces dossiers ou l'un des fichiers contenus. @@ -955,17 +955,17 @@ List name: - Nom de la liste : + Nom de la liste : Delete list/label - Supprimer la liste/l'étiquette + Supprimer la liste/l'étiquette The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - L'élément sélectionné sera supprimé, vos bandes dessinées ou dossiers ne seront pas supprimés de votre disque. Êtes-vous sûr? + L'élément sélectionné sera supprimé, vos bandes dessinées ou dossiers ne seront pas supprimés de votre disque. Êtes-vous sûr? @@ -1037,7 +1037,7 @@ You probably only need one library in your top level comics folder, you can brow YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. Vous ajoutez trop de bibliothèques. -Vous n'avez probablement besoin que d'une bibliothèque dans votre dossier BD de niveau supérieur, vous pouvez parcourir les sous-dossiers en utilisant la section des dossiers dans la barre latérale gauche. +Vous n'avez probablement besoin que d'une bibliothèque dans votre dossier BD de niveau supérieur, vous pouvez parcourir les sous-dossiers en utilisant la section des dossiers dans la barre latérale gauche. YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais vous devriez garder le nombre de bibliothèques bas. @@ -1055,7 +1055,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v YACReader not found. There might be a problem with your YACReader installation. - YACReader introuvable. Il se peut qu'il y ait un problème avec votre installation de YACReader. + YACReader introuvable. Il se peut qu'il y ait un problème avec votre installation de YACReader. @@ -1065,7 +1065,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Error opening comic with third party reader. - Erreur lors de l'ouverture de la bande dessinée avec un lecteur tiers. + Erreur lors de l'ouverture de la bande dessinée avec un lecteur tiers. @@ -1074,7 +1074,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. Le dossier sélectionné ne contient aucune librairie. @@ -1105,7 +1105,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - Un problème est survenu lors de la tentative de suppression des bandes dessinées sélectionnées. Veuillez vérifier les autorisations d'écriture dans les fichiers sélectionnés ou le dossier contenant. + Un problème est survenu lors de la tentative de suppression des bandes dessinées sélectionnées. Veuillez vérifier les autorisations d'écriture dans les fichiers sélectionnés ou le dossier contenant. @@ -1115,7 +1115,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Assign numbers starting in: - Attribuez des numéros commençant par : + Attribuez des numéros commençant par : @@ -1125,17 +1125,17 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v The selected file is not a valid image. - Le fichier sélectionné n'est pas une image valide. + Le fichier sélectionné n'est pas une image valide. Error saving cover - Erreur lors de l'enregistrement de la couverture + Erreur lors de l'enregistrement de la couverture There was an error saving the cover image. - Une erreur s'est produite lors de l'enregistrement de l'image de couverture. + Une erreur s'est produite lors de l'enregistrement de l'image de couverture. @@ -1150,7 +1150,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Error opening the library - Erreur lors de l'ouverture de la librairie + Erreur lors de l'ouverture de la librairie @@ -1179,8 +1179,8 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v - There is another library with the name '%1'. - Une autre librairie a le nom '%1'. + There is another library with the name '%1'. + Une autre librairie a le nom '%1'. @@ -1339,7 +1339,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Set issue as normal - Définir le problème comme d'habitude + Définir le problème comme d'habitude @@ -1386,12 +1386,12 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Show/Hide recent indicator - Afficher/Masquer l'indicateur récent + Afficher/Masquer l'indicateur récent Show or hide recent indicator - Afficher ou masquer l'indicateur récent + Afficher ou masquer l'indicateur récent @@ -1493,7 +1493,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Reset comic rating - Supprimer la note d'évaluation + Supprimer la note d'évaluation @@ -1508,7 +1508,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Assign current order to comics - Assigner l'ordre actuel aux bandes dessinées + Assigner l'ordre actuel aux bandes dessinées @@ -1689,7 +1689,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Open image folder - Ouvrir un dossier d'images + Ouvrir un dossier d'images Size down magnifying glass @@ -1821,7 +1821,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Fit image to width - Ajuster l'image à la largeur + Ajuster l'image à la largeur Toggle fullscreen mode @@ -1901,7 +1901,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Fit image to height - Ajuster l'image à la hauteur + Ajuster l'image à la hauteur Reset zoom @@ -1933,7 +1933,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Clear open recent list - Vider la liste d'ouverture récente + Vider la liste d'ouverture récente Help, About YACReader @@ -1941,7 +1941,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Show go to flow - Afficher le flux + Afficher "Aller à Comic Flow" Previous Comic @@ -1953,7 +1953,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Hide/show toolbar - Masquer / afficher la barre d'outils + Masquer / afficher la barre d'outils Magnifying glass @@ -2004,13 +2004,13 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v NoLibrariesWidget - You don't have any libraries yet - Vous n'avez pas encore de librairie + You don't have any libraries yet + Vous n'avez pas encore de librairie - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> - <p>Vous pouvez creer une librairie dans n'importe quel dossierr, YACReaderLibrary importera les dossiers et les bandes dessinées contenus dans ce dossier. Si vous avez déjà crer des librairies, vous pouvez les ouvrir.</p><p>N'oubliez pas que vous pouvez utiliser YACReader en tant que stand alone pour lire vos bandes dessinées sur votre ordinateur.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Vous pouvez creer une librairie dans n'importe quel dossierr, YACReaderLibrary importera les dossiers et les bandes dessinées contenus dans ce dossier. Si vous avez déjà crer des librairies, vous pouvez les ouvrir.</p><p>N'oubliez pas que vous pouvez utiliser YACReader en tant que stand alone pour lire vos bandes dessinées sur votre ordinateur.</p> @@ -2051,12 +2051,12 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Image adjustment - Ajustement de l'image + Ajustement de l'image - "Go to flow" size - Taille du flux + "Go to flow" size + Taille de "Aller à Comic Flow" @@ -2066,7 +2066,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Image options - Option de l'image + Option de l'image @@ -2082,7 +2082,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Comic Flow - Flux comique + Comic Flow @@ -2111,7 +2111,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Application language - Langue de l'application + Langue de l'application @@ -2122,7 +2122,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Tray icon settings (experimental) - Paramètres de l'icône de la barre d'état (expérimental) + Paramètres de l'icône de la barre d'état (expérimental) @@ -2132,7 +2132,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Start into the system tray - Commencez dans la barre d'état système + Commencez dans la barre d'état système @@ -2152,11 +2152,11 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Import metadata from ComicInfo.xml when adding new comics - Importer des métadonnées depuis ComicInfo.xml lors de l'ajout de nouvelles bandes dessinées + Importer des métadonnées depuis ComicInfo.xml lors de l'ajout de nouvelles bandes dessinées - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago Considérez les éléments « récents » ajoutés ou mis à jour depuis X jours @@ -2243,13 +2243,13 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. - AVERTISSEMENT! Lors des mises à jour de la bibliothèque, les écritures dans la base de données sont désactivées ! -Ne planifiez pas de mises à jour pendant que vous utilisez activement l'application. -Lors des mises à jour automatiques, l'application bloquera certaines actions jusqu'à ce que la mise à jour soit terminée. -Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de chargement à côté du titre Bibliothèques. + AVERTISSEMENT! Lors des mises à jour de la bibliothèque, les écritures dans la base de données sont désactivées ! +Ne planifiez pas de mises à jour pendant que vous utilisez activement l'application. +Lors des mises à jour automatiques, l'application bloquera certaines actions jusqu'à ce que la mise à jour soit terminée. +Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de chargement à côté du titre Bibliothèques. @@ -2259,17 +2259,17 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Compare the modified date of files when updating a library (not recommended) - Comparer la date de modification des fichiers lors de la mise à jour d'une bibliothèque (déconseillé) + Comparer la date de modification des fichiers lors de la mise à jour d'une bibliothèque (déconseillé) Enable background image - Activer l'image d'arrière-plan + Activer l'image d'arrière-plan Opacity level - Niveau d'opacité + Niveau d'opacité @@ -2324,12 +2324,12 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Show time in current page information label - Afficher l'heure dans l'étiquette d'information de la page actuelle + Afficher l'heure dans l'étiquette d'information de la page actuelle Background color - Couleur d'arrière plan + Couleur d'arrière plan @@ -2369,22 +2369,22 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Click left or right half of the screen to turn pages. - Cliquez sur la moitié gauche ou droite de l'écran pour tourner les pages. + Cliquez sur la moitié gauche ou droite de l'écran pour tourner les pages. Disable mouse over activation - Désactiver la souris sur l'activation + Désactiver la souris sur l'activation Scaling - Mise à l'échelle + Mise à l'échelle Scaling method - Méthode de mise à l'échelle + Méthode de mise à l'échelle @@ -2426,7 +2426,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Fit options - Options d'ajustement + Options d'ajustement @@ -2489,7 +2489,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Reset cover to the default image - Réinitialiser la couverture à l'image par défaut + Réinitialiser la couverture à l'image par défaut @@ -2541,12 +2541,12 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Alternate series: - Série alternative : + Série alternative : Series Group: - Groupe de séries : + Groupe de séries : @@ -2591,7 +2591,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Editor(s): - Editeur(s) : + Editeur(s) : @@ -2631,7 +2631,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Age rating: - Limite d'âge: + Limite d'âge: @@ -2641,7 +2641,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Language (ISO): - Langue (ISO) : + Langue (ISO) : @@ -2656,17 +2656,17 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Teams: - Équipes : + Équipes : Locations: - Emplacements : + Emplacements : Main character or team: - Personnage principal ou équipe : + Personnage principal ou équipe : @@ -2676,17 +2676,17 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Notes: - Remarques : + Remarques : Tags: - Balises : + Balises : - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Lien Comic Vine : <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> vue </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Lien Comic Vine : <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> vue </a> @@ -2716,7 +2716,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha The image is invalid. - L'image n'est pas valide. + L'image n'est pas valide. @@ -2790,7 +2790,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum The file could not be read or is not valid JSON. - Le fichier n'a pas pu être lu ou n'est pas un JSON valide. + Le fichier n'a pas pu être lu ou n'est pas un JSON valide. @@ -2852,7 +2852,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Number of %1 found : %2 - Nombre de %1 trouvés : %2 + Nombre de %1 trouvés : %2 @@ -2990,12 +2990,12 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Scan it! - Scannez-le ! + Scannez-le ! - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader est disponible pour les appareils iOS et Android.<br/>Découvrez-le pour <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader est disponible pour les appareils iOS et Android.<br/>Découvrez-le pour <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -3032,13 +3032,13 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. - Veuillez trier la liste des bandes dessinées sur la gauche jusqu'à ce qu'elle corresponde aux informations des bandes dessinées. + Please, sort the list of comics on the left until it matches the comics' information. + Veuillez trier la liste des bandes dessinées sur la gauche jusqu'à ce qu'elle corresponde aux informations des bandes dessinées. sort comics to match comic information - trier les bandes dessinées pour qu'elles correspondent aux informations sur les bandes dessinées + trier les bandes dessinées pour qu'elles correspondent aux informations sur les bandes dessinées @@ -3091,7 +3091,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - Maintenez enfoncé pour faire clignoter la valeur sélectionnée dans l'interface utilisateur (magenta / basculé / 0↔10). Les versions restaurent l'original. + Maintenez enfoncé pour faire clignoter la valeur sélectionnée dans l'interface utilisateur (magenta / basculé / 0↔10). Les versions restaurent l'original. @@ -3116,7 +3116,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Display name: - Nom d'affichage : + Nom d'affichage : @@ -3196,7 +3196,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Edit: %1 - Modifier : %1 + Modifier : %1 @@ -3212,13 +3212,13 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Save failed - Échec de l'enregistrement + Échec de l'enregistrement Could not open file for writing: %1 - Impossible d'ouvrir le fichier en écriture : + Impossible d'ouvrir le fichier en écriture : %1 @@ -3237,14 +3237,14 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Could not open file: %1 - Impossible d'ouvrir le fichier : + Impossible d'ouvrir le fichier : %1 Invalid JSON: %1 - JSON invalide : + JSON invalide : %1 @@ -3289,13 +3289,13 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum - Press 'O' to open comic. - Appuyez sur "O" pour ouvrir une bande dessinée. + Press 'O' to open comic. + Appuyez sur "O" pour ouvrir une bande dessinée. Error opening comic - Erreur d'ouverture de la bande dessinée + Erreur d'ouverture de la bande dessinée @@ -3464,7 +3464,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Use VSync (improve the image quality in fullscreen mode, worse performance) - Utiliser VSync (Améliore la qualité d'image en mode plein écran, ralentit la performance) + Utiliser VSync (Améliore la qualité d'image en mode plein écran, ralentit la performance) @@ -3497,7 +3497,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Open image folder - Ouvrir un dossier d'images + Ouvrir un dossier d'images @@ -3517,7 +3517,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Clear open recent list - Vider la liste d'ouverture récente + Vider la liste d'ouverture récente @@ -3586,7 +3586,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Fit image to height - Ajuster l'image à la hauteur + Ajuster l'image à la hauteur @@ -3596,7 +3596,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Fit image to width - Ajuster l'image à la largeur + Ajuster l'image à la largeur @@ -3752,7 +3752,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Show go to flow - Afficher le flux + Afficher "Aller à Comic Flow" @@ -3838,7 +3838,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Hide/show toolbar - Masquer / afficher la barre d'outils + Masquer / afficher la barre d'outils @@ -4000,7 +4000,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quit</b> dans le menu contextuel de l'icône de la barre d'état système. + YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quit</b> dans le menu contextuel de l'icône de la barre d'état système. @@ -4143,7 +4143,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Use VSync (improve the image quality in fullscreen mode, worse performance) - Utiliser VSync (Améliore la qualité d'image en mode plein écran, ralentit la performance) + Utiliser VSync (Améliore la qualité d'image en mode plein écran, ralentit la performance) Visibility diff --git a/YACReader/yacreader_it.ts b/YACReader/yacreader_it.ts index b3ee44186..2812cc445 100644 --- a/YACReader/yacreader_it.ts +++ b/YACReader/yacreader_it.ts @@ -64,13 +64,13 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Prima di conneterti a "Comic Vine" devi avere la tua chiave API. Per favore recuperane una da <a href="http://www.comicvine.com/api/">QUI</a + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Prima di conneterti a "Comic Vine" devi avere la tua chiave API. Per favore recuperane una da <a href="http://www.comicvine.com/api/">QUI</a Paste here your Comic Vine API key - Incolla qui la tua chiave API di "Comic Vine" + Incolla qui la tua chiave API di "Comic Vine" @@ -118,7 +118,7 @@ Remove this user-imported theme - Rimuovi questo tema importato dall'utente + Rimuovi questo tema importato dall'utente @@ -153,12 +153,12 @@ Open Theme Editor... - Apri l'editor del tema... + Apri l'editor del tema... Theme editor error - Errore nell'editor del tema + Errore nell'editor del tema @@ -228,7 +228,7 @@ Hide comic flow - Nascondi il flusso dei fumetti + Nascondi Comic Flow @@ -358,7 +358,7 @@ Retrieving volume info... - Sto ricevendo le informazioni per l'abum... + Sto ricevendo le informazioni per l'abum... @@ -436,8 +436,8 @@ - The shortcut "%1" is already assigned to other function - La scorciatoia "%1" è già assegnata ad un'altra funzione + The shortcut "%1" is already assigned to other function + La scorciatoia "%1" è già assegnata ad un'altra funzione @@ -449,7 +449,7 @@ EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Questa cartella non contiene ancora fumetti @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Per ora questa etichetta non contiene fumetti
@@ -735,7 +735,7 @@ <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - <p>YacReader sta creando una nuova libreria.</p><p>La creazione di una libreria può durare diversi minuti. Puoi fermare l'attività ed aggiornare la libreria più tardi, completando l'attività</p> + <p>YacReader sta creando una nuova libreria.</p><p>La creazione di una libreria può durare diversi minuti. Puoi fermare l'attività ed aggiornare la libreria più tardi, completando l'attività</p> @@ -755,7 +755,7 @@ <p>The current library is being upgraded, please wait.</p> - <p>È in corso l'aggiornamento della libreria corrente, attendi.</p> + <p>È in corso l'aggiornamento della libreria corrente, attendi.</p> @@ -808,7 +808,7 @@ 4koma (top to botom) - 4koma (dall'alto verso il basso) + 4koma (dall'alto verso il basso) @@ -841,7 +841,7 @@ There were errors during library upgrade in: - Si sono verificati errori durante l'aggiornamento della libreria in: + Si sono verificati errori durante l'aggiornamento della libreria in: @@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - La libreria '%1' non è più disponibile, la vuoi cancellare? + Library '%1' is no longer available. Do you want to remove it? + La libreria '%1' non è più disponibile, la vuoi cancellare? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - La libreria '%1' è stata creata con una versione precedente di YACREaderLibrary. Deve essere ricreata. Lo vuoi fare ora? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La libreria '%1' è stata creata con una versione precedente di YACREaderLibrary. Deve essere ricreata. Lo vuoi fare ora? @@ -922,8 +922,8 @@ - There was an error accessing the folder's path - C'è stato un errore nell'accesso al percorso della cartella + There was an error accessing the folder's path + C'è stato un errore nell'accesso al percorso della cartella @@ -944,7 +944,7 @@ There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - C'è stato un problema cancellando le cartelle selezionate. Per favore controlla i tuoi permessi di scrittura e sii sicuro che non ci siano altre applicazioni che usano le stesse cartelle. + C'è stato un problema cancellando le cartelle selezionate. Per favore controlla i tuoi permessi di scrittura e sii sicuro che non ci siano altre applicazioni che usano le stesse cartelle. @@ -1055,7 +1055,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu YACReader not found. There might be a problem with your YACReader installation. - YACReader non trovato. Potrebbe esserci un problema con l'installazione di YACReader. + YACReader non trovato. Potrebbe esserci un problema con l'installazione di YACReader. @@ -1065,7 +1065,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Error opening comic with third party reader. - Errore nell'apertura del fumetto con un lettore di terze parti. + Errore nell'apertura del fumetto con un lettore di terze parti. @@ -1074,7 +1074,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. La cartella selezionata non contiene nessuna Libreria. @@ -1105,7 +1105,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - C'è un problema nel cancellare i fumetti selezionati. Per favore controlla i tuoi permessi di scrittura sui file o sulla cartella. + C'è un problema nel cancellare i fumetti selezionati. Per favore controlla i tuoi permessi di scrittura sui file o sulla cartella. @@ -1125,7 +1125,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu The selected file is not a valid image. - Il file selezionato non è un'immagine valida. + Il file selezionato non è un'immagine valida. @@ -1135,7 +1135,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu There was an error saving the cover image. - Si è verificato un errore durante il salvataggio dell'immagine di copertina. + Si è verificato un errore durante il salvataggio dell'immagine di copertina. @@ -1150,7 +1150,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Error opening the library - Errore nell'apertura della libreria + Errore nell'apertura della libreria @@ -1170,7 +1170,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Comics will only be deleted from the current label/list. Are you sure? - I fumetti verranno cancellati dall'etichetta/lista corrente. Sei sicuro? + I fumetti verranno cancellati dall'etichetta/lista corrente. Sei sicuro? @@ -1179,8 +1179,8 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu - There is another library with the name '%1'. - Esiste già una libreria con il nome '%1'. + There is another library with the name '%1'. + Esiste già una libreria con il nome '%1'.
@@ -1386,12 +1386,12 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Show/Hide recent indicator - Mostra/Nascondi l'indicatore recente + Mostra/Nascondi l'indicatore recente Show or hide recent indicator - Mostra o nascondi l'indicatore recente + Mostra o nascondi l'indicatore recente @@ -1508,7 +1508,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Assign current order to comics - Assegna l'ordinamento corrente ai fumetti + Assegna l'ordinamento corrente ai fumetti @@ -1705,7 +1705,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Open latest comic - Apri l'ultimo fumetto + Apri l'ultimo fumetto Autoscroll up @@ -1785,7 +1785,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Open the latest comic opened in the previous reading session - Apri l'ultimo fumetto aperto nella sessione precedente + Apri l'ultimo fumetto aperto nella sessione precedente Open a comic @@ -1905,7 +1905,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Fit image to height - Adatta immagine all'altezza + Adatta immagine all'altezza Reset zoom @@ -1945,7 +1945,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Show go to flow - Mostra vai all'elenco + Mostra "Vai a Comic Flow" Previous Comic @@ -1985,7 +1985,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Go to the last page - Vai all'ultima pagina + Vai all'ultima pagina Do you want to download the new version? @@ -2008,12 +2008,12 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet Per ora non hai ancora nessuna libreria - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Puoi creare una libreria in qualsiasi cartella, YACReader importerà tutti i fumetti e struttura da questa certella. Se hai creato una qualsiasia libreria nel passato la puoi aprire. </p><p>Non dimenticare che puoi usare YACReader come applicazione stand alone per leggere i fumetti sul tuo PC.</p> @@ -2059,8 +2059,8 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu - "Go to flow" size - Dimensione "Vai all'elenco" + "Go to flow" size + Dimensione di "Vai a Comic Flow" @@ -2086,7 +2086,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Comic Flow - Flusso dei fumetti + Comic Flow @@ -2115,7 +2115,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Application language - Lingua dell'applicazione + Lingua dell'applicazione @@ -2126,7 +2126,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Tray icon settings (experimental) - Impostazioni dell'icona nella barra delle applicazioni (sperimentale) + Impostazioni dell'icona nella barra delle applicazioni (sperimentale) @@ -2141,7 +2141,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Edit Comic Vine API key - Edita l'API di ComicVine + Edita l'API di ComicVine @@ -2160,8 +2160,8 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu - Consider 'recent' items added or updated since X days ago - Considera gli elementi "recenti" aggiunti o aggiornati da X giorni fa + Consider 'recent' items added or updated since X days ago + Considera gli elementi "recenti" aggiunti o aggiornati da X giorni fa @@ -2182,7 +2182,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Update libraries at startup - Aggiorna le librerie all'avvio + Aggiorna le librerie all'avvio @@ -2247,13 +2247,13 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. AVVERTIMENTO! Durante gli aggiornamenti della libreria le scritture sul database sono disabilitate! -Non pianificare gli aggiornamenti mentre potresti utilizzare l'app attivamente. -Durante gli aggiornamenti automatici l'app bloccherà alcune azioni fino al termine dell'aggiornamento. -Per interrompere un aggiornamento automatico, tocca l'indicatore di caricamento accanto al titolo Librerie. +Non pianificare gli aggiornamenti mentre potresti utilizzare l'app attivamente. +Durante gli aggiornamenti automatici l'app bloccherà alcune azioni fino al termine dell'aggiornamento. +Per interrompere un aggiornamento automatico, tocca l'indicatore di caricamento accanto al titolo Librerie. @@ -2263,12 +2263,12 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam Compare the modified date of files when updating a library (not recommended) - Confronta la data di modifica dei file durante l'aggiornamento di una libreria (non consigliato) + Confronta la data di modifica dei file durante l'aggiornamento di una libreria (non consigliato) Enable background image - Abilita l'immagine di sfondo + Abilita l'immagine di sfondo @@ -2328,7 +2328,7 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam Show time in current page information label - Mostra l'ora nell'etichetta delle informazioni della pagina corrente + Mostra l'ora nell'etichetta delle informazioni della pagina corrente @@ -2378,7 +2378,7 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam Disable mouse over activation - Disabilita il mouse all'attivazione + Disabilita il mouse all'attivazione @@ -2493,12 +2493,12 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam Reset cover to the default image - Ripristina la copertina sull'immagine predefinita + Ripristina la copertina sull'immagine predefinita Load custom cover image - Carica l'immagine di copertina personalizzata + Carica l'immagine di copertina personalizzata @@ -2530,7 +2530,7 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam Arc number: - Numero dell'arco: + Numero dell'arco: @@ -2689,8 +2689,8 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Vai </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Vai </a> @@ -2720,7 +2720,7 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam The image is invalid. - L'immagine non è valida. + L'immagine non è valida. @@ -2998,8 +2998,8 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader è disponibile per dispositivi iOS e Android.<br/>Scoprilo per <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader è disponibile per dispositivi iOS e Android.<br/>Scoprilo per <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -3036,7 +3036,7 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Per favore ordina la lista dei fumetti a sinistra sino a che corrisponde alle informazioni dei fumetti. @@ -3095,7 +3095,7 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - Tieni premuto per far lampeggiare il valore selezionato nell'interfaccia utente (magenta / alternato / 0↔10). Le versioni ripristinano l'originale. + Tieni premuto per far lampeggiare il valore selezionato nell'interfaccia utente (magenta / alternato / 0↔10). Le versioni ripristinano l'originale. @@ -3293,13 +3293,13 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https - Press 'O' to open comic. - Premi "O" per aprire il fumettto. + Press 'O' to open comic. + Premi "O" per aprire il fumettto. Error opening comic - Errore nell'apertura + Errore nell'apertura @@ -3506,12 +3506,12 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https Open latest comic - Apri l'ultimo fumetto + Apri l'ultimo fumetto Open the latest comic opened in the previous reading session - Apri l'ultimo fumetto aperto nella sessione precedente + Apri l'ultimo fumetto aperto nella sessione precedente @@ -3590,7 +3590,7 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https Fit image to height - Adatta immagine all'altezza + Adatta immagine all'altezza @@ -3756,7 +3756,7 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https Show go to flow - Mostra vai all'elenco + Mostra "Vai a Comic Flow" @@ -3873,7 +3873,7 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https Reset magnifying glass - Reimposta la lente d'ingrandimento + Reimposta la lente d'ingrandimento @@ -3950,7 +3950,7 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https Go to the last page - Vai all'ultima pagina + Vai all'ultima pagina @@ -4004,7 +4004,7 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary continuerà a essere eseguito nella barra delle applicazioni. Per terminare il programma, scegli <b>Esci</b> nel menu contestuale dell'icona nella barra delle applicazioni. + YACReaderLibrary continuerà a essere eseguito nella barra delle applicazioni. Per terminare il programma, scegli <b>Esci</b> nel menu contestuale dell'icona nella barra delle applicazioni. diff --git a/YACReader/yacreader_nl.ts b/YACReader/yacreader_nl.ts index 8d389ff04..2855d7889 100644 --- a/YACReader/yacreader_nl.ts +++ b/YACReader/yacreader_nl.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Voordat je verbinding kunt maken met Comic Vine, heb je een eigen API-sleutel nodig. Vraag er <a href="http://www.comicvine.com/api/">hier</a> één gratis aan + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Voordat je verbinding kunt maken met Comic Vine, heb je een eigen API-sleutel nodig. Vraag er <a href="http://www.comicvine.com/api/">hier</a> één gratis aan @@ -228,7 +228,7 @@ Hide comic flow - Sluit de Omslagbrowser + Comic Flow verbergen @@ -256,7 +256,7 @@ Pages - Pagina's + Pagina's @@ -441,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - De sneltoets "%1" is al aan een andere functie toegewezen + The shortcut "%1" is already assigned to other function + De sneltoets "%1" is al aan een andere functie toegewezen EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Deze map bevat nog geen strips @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Dit label bevat nog geen strips
@@ -573,7 +573,7 @@ CRC error on page (%1): some of the pages will not be displayed correctly - CRC-fout op pagina (%1): sommige pagina's worden niet correct weergegeven + CRC-fout op pagina (%1): sommige pagina's worden niet correct weergegeven @@ -602,7 +602,7 @@ Total pages : - Totaal aantal pagina's : + Totaal aantal pagina's : @@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - Bibliotheek ' %1' is niet langer beschikbaar. Wilt u het verwijderen? + Library '%1' is no longer available. Do you want to remove it? + Bibliotheek ' %1' is niet langer beschikbaar. Wilt u het verwijderen? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Bibliotheek ' %1' is gemaakt met een oudere versie van YACReaderLibrary. Zij moet opnieuw worden aangemaakt. Wilt u de bibliotheek nu aanmaken? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Bibliotheek ' %1' is gemaakt met een oudere versie van YACReaderLibrary. Zij moet opnieuw worden aangemaakt. Wilt u de bibliotheek nu aanmaken? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Er is een fout opgetreden bij het verkrijgen van toegang tot het pad van de map @@ -1074,7 +1074,7 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. De geselecteerde map bevat geen bibliotheek. @@ -1179,8 +1179,8 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, - There is another library with the name '%1'. - Er is al een bibliotheek met de naam ' %1 '. + There is another library with the name '%1'. + Er is al een bibliotheek met de naam ' %1 '.
@@ -1793,7 +1793,7 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, Show go to flow - Toon ga naar de Omslagbrowser + "Ga naar Comic Flow" tonen Previous Comic @@ -1832,12 +1832,12 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet Je hebt geen nog libraries - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <P>u kunt een bibliotheek maken in een willekeurige map, YACReaderLibrary importeert alle strips en mappen uit deze map. Alle bibliotheek aangemaakt in het verleden kan je openen. < /p> <p>vergeet niet dat u YACReader kan gebruiken als stand-alone applicatie voor het lezen van de strips op de computer. < /p> @@ -1908,8 +1908,8 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, - "Go to flow" size - "Naar Omslagbrowser" afmetingen + "Go to flow" size + Grootte van "Ga naar Comic Flow" @@ -1935,7 +1935,7 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, Comic Flow - Komische stroom + Comic Flow @@ -2009,8 +2009,8 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, - Consider 'recent' items added or updated since X days ago - Overweeg 'recente' items die sinds X dagen geleden zijn toegevoegd of bijgewerkt + Consider 'recent' items added or updated since X days ago + Overweeg 'recente' items die sinds X dagen geleden zijn toegevoegd of bijgewerkt @@ -2096,7 +2096,7 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WAARSCHUWING! Tijdens bibliotheekupdates is schrijven naar de database uitgeschakeld! @@ -2234,17 +2234,17 @@ Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de Only Back/Forward buttons can turn pages - Alleen de knoppen Terug/Vooruit kunnen pagina's omslaan + Alleen de knoppen Terug/Vooruit kunnen pagina's omslaan Use the Left/Right buttons to turn pages. - Gebruik de knoppen Links/Rechts om pagina's om te slaan. + Gebruik de knoppen Links/Rechts om pagina's om te slaan. Click left or right half of the screen to turn pages. - Klik op de linker- of rechterhelft van het scherm om pagina's om te slaan. + Klik op de linker- of rechterhelft van het scherm om pagina's om te slaan. @@ -2264,7 +2264,7 @@ Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de Double Page options - Opties voor dubbele pagina's + Opties voor dubbele pagina's @@ -2513,8 +2513,8 @@ Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine-link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> bekijken </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine-link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> bekijken </a> @@ -2822,8 +2822,8 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader is beschikbaar voor iOS- en Android-apparaten.<br/>Ontdek het voor <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> of <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is beschikbaar voor iOS- en Android-apparaten.<br/>Ontdek het voor <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> of <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2860,7 +2860,7 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Sorteer de lijst met strips aan de linkerkant totdat deze overeenkomt met de informatie over de strips. @@ -3112,8 +3112,8 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa - Press 'O' to open comic. - Druk 'O' om een strip te openen. + Press 'O' to open comic. + Druk 'O' om een strip te openen. @@ -3580,7 +3580,7 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa Show go to flow - Toon ga naar de Omslagbrowser + "Ga naar Comic Flow" tonen diff --git a/YACReader/yacreader_pt.ts b/YACReader/yacreader_pt.ts index 12d6d5106..fada5a6ac 100644 --- a/YACReader/yacreader_pt.ts +++ b/YACReader/yacreader_pt.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Antes de se conectar ao Comic Vine, você precisa de sua própria chave de API. Por favor, ganhe um <a href="http://www.comicvine.com/api/">aqui</a> grátis + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Antes de se conectar ao Comic Vine, você precisa de sua própria chave de API. Por favor, ganhe um <a href="http://www.comicvine.com/api/">aqui</a> grátis @@ -228,7 +228,7 @@ Hide comic flow - Ocultar fluxo de quadrinhos + Ocultar Comic Flow @@ -441,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - O atalho "%1" já está atribuído a outra função + The shortcut "%1" is already assigned to other function + O atalho "%1" já está atribuído a outra função EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Esta pasta ainda não contém quadrinhos @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Este rótulo ainda não contém quadrinhos
@@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - A biblioteca '%1' não está mais disponível. Você quer removê-lo? + Library '%1' is no longer available. Do you want to remove it? + A biblioteca '%1' não está mais disponível. Você quer removê-lo? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - A biblioteca '%1' foi criada com uma versão mais antiga do YACReaderLibrary. Deve ser criado novamente. Deseja criar a biblioteca agora? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + A biblioteca '%1' foi criada com uma versão mais antiga do YACReaderLibrary. Deve ser criado novamente. Deseja criar a biblioteca agora? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Ocorreu um erro ao acessar o caminho da pasta @@ -1074,7 +1074,7 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. A pasta selecionada não contém nenhuma biblioteca. @@ -1179,8 +1179,8 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve - There is another library with the name '%1'. - Existe outra biblioteca com o nome '%1'. + There is another library with the name '%1'. + Existe outra biblioteca com o nome '%1'.
@@ -1792,12 +1792,12 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet Você ainda não tem nenhuma biblioteca - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Você pode criar uma biblioteca em qualquer pasta, YACReaderLibrary importará todos os quadrinhos e pastas desta pasta. Se você já criou alguma biblioteca, poderá abri-la.</p><p>Não se esqueça de que você pode usar o YACReader como um aplicativo independente para ler quadrinhos em seu computador.</p> @@ -1828,8 +1828,8 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve - "Go to flow" size - Tamanho do "Ir para cheia" + "Go to flow" size + Tamanho de "Ir para Comic Flow" @@ -1840,7 +1840,7 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve Comic Flow - Fluxo de quadrinhos + Comic Flow @@ -1914,8 +1914,8 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve - Consider 'recent' items added or updated since X days ago - Considere itens 'recentes' adicionados ou atualizados há X dias + Consider 'recent' items added or updated since X days ago + Considere itens 'recentes' adicionados ou atualizados há X dias @@ -2001,7 +2001,7 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. AVISO! Durante as atualizações da biblioteca, as gravações no banco de dados são desativadas! @@ -2473,8 +2473,8 @@ Para interromper uma atualização automática, toque no indicador de carregamen - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Link do Comic Vine: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> visualizar </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Link do Comic Vine: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> visualizar </a> @@ -2782,8 +2782,8 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - O YACReader está disponível para dispositivos iOS e Android.<br/>Descubra-o para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + O YACReader está disponível para dispositivos iOS e Android.<br/>Descubra-o para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2816,7 +2816,7 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Por favor, classifique a lista de quadrinhos à esquerda até que corresponda às informações dos quadrinhos. @@ -3068,8 +3068,8 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã - Press 'O' to open comic. - Pressione 'O' para abrir um quadrinho. + Press 'O' to open comic. + Pressione 'O' para abrir um quadrinho. @@ -3536,7 +3536,7 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã Show go to flow - Mostrar ir para o fluxo + Mostrar "Ir para Comic Flow" diff --git a/YACReader/yacreader_ru.ts b/YACReader/yacreader_ru.ts index 62c6c5ac2..c1b68c389 100644 --- a/YACReader/yacreader_ru.ts +++ b/YACReader/yacreader_ru.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Для подключения к Comic Vine вам потребуется ваш личный API ключ. Приобретите его бесплатно вот <a href="http://www.comicvine.com/api/">здесь</a> + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Для подключения к Comic Vine вам потребуется ваш личный API ключ. Приобретите его бесплатно вот <a href="http://www.comicvine.com/api/">здесь</a> @@ -228,7 +228,7 @@ Hide comic flow - Показать/скрыть поток комиксов + Скрыть Comic Flow @@ -436,8 +436,8 @@ - The shortcut "%1" is already assigned to other function - Сочетание клавиш "%1" уже назначено для другой функции + The shortcut "%1" is already assigned to other function + Сочетание клавиш "%1" уже назначено для другой функции @@ -449,7 +449,7 @@ EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet В этой папке еще нет комиксов @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Этот ярлык пока ничего не содержит
@@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - Библиотека '%1' больше не доступна. Вы хотите удалить ее? + Library '%1' is no longer available. Do you want to remove it? + Библиотека '%1' больше не доступна. Вы хотите удалить ее? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Библиотека '%1' была создана старой версией YACReaderLibrary. Она должна быть вновь создана. Вы хотите создать библиотеку сейчас? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Библиотека '%1' была создана старой версией YACReaderLibrary. Она должна быть вновь создана. Вы хотите создать библиотеку сейчас? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Ошибка доступа к пути папки @@ -1074,7 +1074,7 @@ YACReaderLibrary не помешает вам создать больше биб - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. Выбранная папка не содержит ни одной библиотеки. @@ -1179,8 +1179,8 @@ YACReaderLibrary не помешает вам создать больше биб - There is another library with the name '%1'. - Уже существует другая папка с именем '%1'. + There is another library with the name '%1'. + Уже существует другая папка с именем '%1'.
@@ -1945,7 +1945,7 @@ YACReaderLibrary не помешает вам создать больше биб Show go to flow - Показать поток страниц + Показать "Перейти к Comic Flow" Previous Comic @@ -2008,12 +2008,12 @@ YACReaderLibrary не помешает вам создать больше биб NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet У вас нет ни одной библиотеки - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Вы можете создать библиотеку в любой папке, YACReaderLibrary будет импортировать все комиксы и папки из этой папки. Если вы уже ранее создавали библиотеки, их можно будет открыть.< / p > <p>Не забывайте, что Вы можете использовать YACReader в качестве отдельного приложения для чтения комиксов на вашем компьютере.</п> @@ -2059,8 +2059,8 @@ YACReaderLibrary не помешает вам создать больше биб - "Go to flow" size - Размер потока страниц + "Go to flow" size + Размер "Перейти к Comic Flow" @@ -2086,7 +2086,7 @@ YACReaderLibrary не помешает вам создать больше биб Comic Flow - Поток комиксов + Comic Flow @@ -2160,8 +2160,8 @@ YACReaderLibrary не помешает вам создать больше биб - Consider 'recent' items added or updated since X days ago - Учитывайте «недавние» элементы, добавленные или обновленные X дней назад. + Consider 'recent' items added or updated since X days ago + Учитывайте «недавние» элементы, добавленные или обновленные X дней назад. @@ -2247,7 +2247,7 @@ YACReaderLibrary не помешает вам создать больше биб WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. ПРЕДУПРЕЖДЕНИЕ! Во время обновления библиотеки запись в базу данных отключена! @@ -2689,8 +2689,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - <a style='color: ##666666; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Открыть страницу этого комикса на сайте Comic Vine </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + <a style='color: ##666666; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Открыть страницу этого комикса на сайте Comic Vine </a> @@ -2998,8 +2998,8 @@ YACReaderLibraryServer — это безголовая (без графичес - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader доступен для устройств iOS и Android.<br/>Найдите его для <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> или <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader доступен для устройств iOS и Android.<br/>Найдите его для <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> или <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -3036,7 +3036,7 @@ YACReaderLibraryServer — это безголовая (без графичес SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Пожалуйста, отсортируйте список комиксов слева, пока он не будет соответствовать информации комикса. @@ -3293,8 +3293,8 @@ YACReaderLibraryServer — это безголовая (без графичес - Press 'O' to open comic. - Нажмите "O" чтобы открыть комикс. + Press 'O' to open comic. + Нажмите "O" чтобы открыть комикс. @@ -3756,7 +3756,7 @@ YACReaderLibraryServer — это безголовая (без графичес Show go to flow - Показать поток страниц + Показать "Перейти к Comic Flow" diff --git a/YACReader/yacreader_tr.ts b/YACReader/yacreader_tr.ts index 05e874c7b..8353996e7 100644 --- a/YACReader/yacreader_tr.ts +++ b/YACReader/yacreader_tr.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Comic Vine'a bağlanmadan önce kendi API anahtarınıza ihtiyacınız var. Lütfen <a href="http://www.comicvine.com/api/">buradan</a> ücretsiz bir tane edinin + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Comic Vine'a bağlanmadan önce kendi API anahtarınıza ihtiyacınız var. Lütfen <a href="http://www.comicvine.com/api/">buradan</a> ücretsiz bir tane edinin @@ -228,7 +228,7 @@ Hide comic flow - Çizgi roman akışını gizle + Comic Flow'u gizle @@ -441,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - "%1" kısayolu bir başka işleve zaten atanmış + The shortcut "%1" is already assigned to other function + "%1" kısayolu bir başka işleve zaten atanmış EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Bu klasör henüz çizgi roman içermiyor @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Bu etiket henüz çizgi roman içermiyor
@@ -871,8 +871,8 @@ - Library '%1' is no longer available. Do you want to remove it? - Kütüphane '%1'ulaşılabilir değil. Kaldırmak ister misin? + Library '%1' is no longer available. Do you want to remove it? + Kütüphane '%1'ulaşılabilir değil. Kaldırmak ister misin? @@ -881,8 +881,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Kütüphane '%1 YACRKütüphanenin eski bir sürümünde oluşturulmuş, Kütüphaneyi yeniden oluşturmak ister misin? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Kütüphane '%1 YACRKütüphanenin eski bir sürümünde oluşturulmuş, Kütüphaneyi yeniden oluşturmak ister misin? @@ -923,7 +923,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Klasörün yoluna erişilirken hata oluştu @@ -1075,7 +1075,7 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. Seçilen dosya kütüphanede yok. @@ -1096,7 +1096,7 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü Remove and delete metadata - Metadata'yı kaldır ve sil + Metadata'yı kaldır ve sil @@ -1180,8 +1180,8 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü - There is another library with the name '%1'. - Bu başka bir kütüphanenin adı '%1'. + There is another library with the name '%1'. + Bu başka bir kütüphanenin adı '%1'.
@@ -1286,7 +1286,7 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü Open current comic on YACReader - YACReader'ı geçerli çizgi roman okuyucsu seç + YACReader'ı geçerli çizgi roman okuyucsu seç @@ -1821,7 +1821,7 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü Show go to flow - Akışı göster + "Comic Flow'a git"i göster Previous Comic @@ -2040,12 +2040,12 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet Henüz bir kütüphaneye sahip değilsin - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Yeni bir kütüphane oluşturabilmeniçin kütüphane</p><p>No olvides que puedes usar YACReader como una aplicación independiente para leer los cómics en tu ordenador.</p> @@ -2116,8 +2116,8 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü - "Go to flow" size - Akış görünümüne git + "Go to flow" size + "Comic Flow'a git" boyutu @@ -2143,7 +2143,7 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü Comic Flow - Çizgi Roman Akışı + Comic Flow @@ -2213,12 +2213,12 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü Import metadata from ComicInfo.xml when adding new comics - Yeni çizgi roman eklerken meta verileri ComicInfo.xml'den içe aktarın + Yeni çizgi roman eklerken meta verileri ComicInfo.xml'den içe aktarın - Consider 'recent' items added or updated since X days ago - X gün öncesinden bu yana eklenen veya güncellenen 'en son' öğeleri göz önünde bulundurun + Consider 'recent' items added or updated since X days ago + X gün öncesinden bu yana eklenen veya güncellenen 'en son' öğeleri göz önünde bulundurun @@ -2304,7 +2304,7 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. UYARI! Kütüphane güncellemeleri sırasında veritabanına yazma işlemi devre dışı bırakılır! @@ -2360,7 +2360,7 @@ Otomatik güncellemeyi durdurmak için Kitaplıklar başlığının yanındaki y Display current comic banner - Mevcut çizgi roman banner'ını görüntüle + Mevcut çizgi roman banner'ını görüntüle @@ -2721,8 +2721,8 @@ Otomatik güncellemeyi durdurmak için Kitaplıklar başlığının yanındaki y - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine bağlantısı: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> görüntüle </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine bağlantısı: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> görüntüle </a> @@ -2765,7 +2765,7 @@ YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. This appplication supports persistent settings, to set them up edit this file %1 To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md -YACReaderLibraryServer, YACReaderLibrary'nin başsız (gui yok) sürümüdür. +YACReaderLibraryServer, YACReaderLibrary'nin başsız (gui yok) sürümüdür. Bu uygulama kalıcı ayarları destekler, bunları ayarlamak için bu dosyayı düzenleyin %1 Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md adresindeki belgelere bakın. @@ -3064,8 +3064,8 @@ Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubuserconte - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader, iOS ve Android cihazlarda kullanılabilir.<br/>Bunu <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> veya <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a> için keşfedin. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader, iOS ve Android cihazlarda kullanılabilir.<br/>Bunu <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> veya <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a> için keşfedin. @@ -3102,7 +3102,7 @@ Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubuserconte SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Lütfen, çizgi romanların bilgileriyle eşleşene kadar soldaki çizgi roman listesini sıralayın. @@ -3354,8 +3354,8 @@ Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubuserconte - Press 'O' to open comic. - 'O'ya basarak aç. + Press 'O' to open comic. + 'O'ya basarak aç. @@ -3822,7 +3822,7 @@ Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubuserconte Show go to flow - Akışı göster + "Comic Flow'a git"i göster @@ -4070,7 +4070,7 @@ Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubuserconte YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary sistem tepsisinde çalışmaya devam edecektir. Programı sonlandırmak için sistem tepsisi simgesinin bağlam menüsünden <b>Çık</b>'ı seçin. + YACReaderLibrary sistem tepsisinde çalışmaya devam edecektir. Programı sonlandırmak için sistem tepsisi simgesinin bağlam menüsünden <b>Çık</b>'ı seçin. diff --git a/YACReader/yacreader_zh_CN.ts b/YACReader/yacreader_zh_CN.ts index b76c7756c..e190f38cd 100644 --- a/YACReader/yacreader_zh_CN.ts +++ b/YACReader/yacreader_zh_CN.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - 你需要拥有自己的API密钥才能够连接Comic Vine. 你可以通过这个链接获得一个免费的<a href="http://www.comicvine.com/api/">API</a>密钥 + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要拥有自己的API密钥才能够连接Comic Vine. 你可以通过这个链接获得一个免费的<a href="http://www.comicvine.com/api/">API</a>密钥 @@ -228,7 +228,7 @@ Hide comic flow - 隐藏漫画流 + 隐藏 Comic Flow @@ -436,8 +436,8 @@ - The shortcut "%1" is already assigned to other function - 快捷键 "%1" 已被映射至其他功能 + The shortcut "%1" is already assigned to other function + 快捷键 "%1" 已被映射至其他功能 @@ -449,7 +449,7 @@ EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet 该文件夹还没有漫画 @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet 此标签尚未包含漫画
@@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - 库 '%1' 不再可用。 你想删除它吗? + Library '%1' is no longer available. Do you want to remove it? + 库 '%1' 不再可用。 你想删除它吗? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - 库 '%1' 是通过旧版本的YACReaderLibrary创建的。 必须再次创建。 你想现在创建吗? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 库 '%1' 是通过旧版本的YACReaderLibrary创建的。 必须再次创建。 你想现在创建吗? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path 访问文件夹的路径时出错 @@ -1074,7 +1074,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. 所选文件夹不包含任何库。 @@ -1179,8 +1179,8 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 - There is another library with the name '%1'. - 已存在另一个名为'%1'的库。 + There is another library with the name '%1'. + 已存在另一个名为'%1'的库。
@@ -1664,12 +1664,12 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet 你还没有库 - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>您可以在任何文件夹中创建库,YACReaderLibrary将导入此文件夹中的所有漫画和文件夹。如果已有库,则可以打开它们。</p><p>您可以把YACReader当成独立应用来阅读电脑上的漫画。</p> @@ -1730,8 +1730,8 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 - "Go to flow" size - 页面流尺寸 + "Go to flow" size + “转到 Comic Flow”大小 @@ -1802,7 +1802,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 Comic Flow - 漫画流 + Comic Flow @@ -1876,7 +1876,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago 参考自 X 天前添加或更新的“最近”项目 @@ -1963,7 +1963,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. 警告! 在库更新期间,将禁用对数据库的写入! @@ -2345,8 +2345,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine 连接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 连接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> @@ -2688,8 +2688,8 @@ YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader 适用于 iOS 和 Android 设备。<br/>搜索 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 适用于 iOS 和 Android 设备。<br/>搜索 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2711,7 +2711,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. 请在左侧对漫画列表进行排序,直到它与漫画的信息相符。 @@ -2968,8 +2968,8 @@ YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 - Press 'O' to open comic. - 按下 'O' 以打开漫画. + Press 'O' to open comic. + 按下 'O' 以打开漫画. @@ -3426,7 +3426,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 Toggle between fit to width and fit to height - 切换显示为"适应宽度"或"适应高度" + 切换显示为"适应宽度"或"适应高度" @@ -3594,7 +3594,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 Show go to flow - 显示页面流 + 显示“转到 Comic Flow” diff --git a/YACReader/yacreader_zh_HK.ts b/YACReader/yacreader_zh_HK.ts index 40017c5aa..1988e5cf7 100644 --- a/YACReader/yacreader_zh_HK.ts +++ b/YACReader/yacreader_zh_HK.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 @@ -228,7 +228,7 @@ Hide comic flow - 隱藏漫畫流 + 隱藏 Comic Flow @@ -441,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - 快捷鍵 "%1" 已被映射至其他功能 + The shortcut "%1" is already assigned to other function + 快捷鍵 "%1" 已被映射至其他功能 EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet 該資料夾還沒有漫畫 @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet 此標籤尚未包含漫畫
@@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - 庫 '%1' 不再可用。 你想刪除它嗎? + Library '%1' is no longer available. Do you want to remove it? + 庫 '%1' 不再可用。 你想刪除它嗎? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path 訪問檔夾的路徑時出錯 @@ -1074,7 +1074,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. 所選檔夾不包含任何庫。 @@ -1179,8 +1179,8 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - There is another library with the name '%1'. - 已存在另一個名為'%1'的庫。 + There is another library with the name '%1'. + 已存在另一個名為'%1'的庫。
@@ -1664,12 +1664,12 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet 你還沒有庫 - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>您可以在任何檔夾中創建庫,YACReaderLibrary將導入此檔夾中的所有漫畫和文件夾。如果已有庫,則可以打開它們。</p><p>您可以把YACReader當成獨立應用來閱讀電腦上的漫畫。</p> @@ -1695,8 +1695,8 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 OptionsDialog - "Go to flow" size - 頁面流尺寸 + "Go to flow" size + 「前往 Comic Flow」大小 @@ -1864,7 +1864,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 Comic Flow - 漫畫流 + Comic Flow @@ -1932,7 +1932,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago 考慮自 X 天前新增或更新的「最近」項目 @@ -2019,7 +2019,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. 警告!在庫更新期間,將停用對資料庫的寫入! @@ -2345,8 +2345,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> @@ -2688,8 +2688,8 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 @@ -2726,7 +2726,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. 請在左側對漫畫列表進行排序,直到它與漫畫的資訊相符。 @@ -2978,8 +2978,8 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 - Press 'O' to open comic. - 按下 'O' 以打開漫畫. + Press 'O' to open comic. + 按下 'O' 以打開漫畫. @@ -3446,7 +3446,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 Show go to flow - 顯示頁面流 + 顯示「前往 Comic Flow」 @@ -3574,7 +3574,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 Toggle between fit to width and fit to height - 切換顯示為"適應寬度"或"適應高度" + 切換顯示為"適應寬度"或"適應高度" diff --git a/YACReader/yacreader_zh_TW.ts b/YACReader/yacreader_zh_TW.ts index 07e46820a..58c26acf9 100644 --- a/YACReader/yacreader_zh_TW.ts +++ b/YACReader/yacreader_zh_TW.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 @@ -228,7 +228,7 @@ Hide comic flow - 隱藏漫畫流 + 隱藏 Comic Flow @@ -441,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - 快捷鍵 "%1" 已被映射至其他功能 + The shortcut "%1" is already assigned to other function + 快捷鍵 "%1" 已被映射至其他功能 EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet 該資料夾還沒有漫畫 @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet 此標籤尚未包含漫畫
@@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - 庫 '%1' 不再可用。 你想刪除它嗎? + Library '%1' is no longer available. Do you want to remove it? + 庫 '%1' 不再可用。 你想刪除它嗎? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path 訪問檔夾的路徑時出錯 @@ -1074,7 +1074,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. 所選檔夾不包含任何庫。 @@ -1179,8 +1179,8 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - There is another library with the name '%1'. - 已存在另一個名為'%1'的庫。 + There is another library with the name '%1'. + 已存在另一個名為'%1'的庫。
@@ -1664,12 +1664,12 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet 你還沒有庫 - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>您可以在任何檔夾中創建庫,YACReaderLibrary將導入此檔夾中的所有漫畫和文件夾。如果已有庫,則可以打開它們。</p><p>您可以把YACReader當成獨立應用來閱讀電腦上的漫畫。</p> @@ -1695,8 +1695,8 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 OptionsDialog - "Go to flow" size - 頁面流尺寸 + "Go to flow" size + 「前往 Comic Flow」大小 @@ -1864,7 +1864,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 Comic Flow - 漫畫流 + Comic Flow @@ -1932,7 +1932,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago 考慮自 X 天前新增或更新的「最近」項目 @@ -2019,7 +2019,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. 警告!在庫更新期間,將停用對資料庫的寫入! @@ -2345,8 +2345,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> @@ -2688,8 +2688,8 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 @@ -2726,7 +2726,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. 請在左側對漫畫列表進行排序,直到它與漫畫的資訊相符。 @@ -2978,8 +2978,8 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 - Press 'O' to open comic. - 按下 'O' 以打開漫畫. + Press 'O' to open comic. + 按下 'O' 以打開漫畫. @@ -3446,7 +3446,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 Show go to flow - 顯示頁面流 + 顯示「前往 Comic Flow」 @@ -3574,7 +3574,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 Toggle between fit to width and fit to height - 切換顯示為"適應寬度"或"適應高度" + 切換顯示為"適應寬度"或"適應高度" diff --git a/YACReaderLibrary/yacreaderlibrary_de.ts b/YACReaderLibrary/yacreaderlibrary_de.ts index a4aaacf32..643502110 100644 --- a/YACReaderLibrary/yacreaderlibrary_de.ts +++ b/YACReaderLibrary/yacreaderlibrary_de.ts @@ -112,8 +112,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Bevor du dich mit Comic Vine verbindest, brauchst du deinen eigenen API-Schlüssel. Du kannst <a href="http://www.comicvine.com/api/">hier</a> einen kostenlosen bekommen. + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Bevor du dich mit Comic Vine verbindest, brauchst du deinen eigenen API-Schlüssel. Du kannst <a href="http://www.comicvine.com/api/">hier</a> einen kostenlosen bekommen. @@ -276,7 +276,7 @@ Hide comic flow - Comic "Flow" verstecken + Comic Flow ausblenden @@ -572,8 +572,8 @@ - The shortcut "%1" is already assigned to other function - Das Kürzel "%1" ist bereits für eine andere Funktion in Verwendung + The shortcut "%1" is already assigned to other function + Das Kürzel "%1" ist bereits für eine andere Funktion in Verwendung @@ -592,7 +592,7 @@ - This folder doesn't contain comics yet + This folder doesn't contain comics yet Dieser Ordner enthält noch keine Comics @@ -600,7 +600,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Dieses Label enthält noch keine Comics
@@ -927,7 +927,7 @@ - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. Der ausgewählte Ordner enthält keine Bibliothek. @@ -1014,8 +1014,8 @@ - Library '%1' is no longer available. Do you want to remove it? - Bibliothek '%1' ist nicht mehr verfügbar. Wollen Sie sie entfernen? + Library '%1' is no longer available. Do you want to remove it? + Bibliothek '%1' ist nicht mehr verfügbar. Wollen Sie sie entfernen? Update library @@ -1056,8 +1056,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Bibliothek '%1' wurde mit einer älteren Version von YACReader erstellt. Sie muss neu erzeugt werden. Wollen Sie die Bibliothek jetzt erzeugen? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Bibliothek '%1' wurde mit einer älteren Version von YACReader erstellt. Sie muss neu erzeugt werden. Wollen Sie die Bibliothek jetzt erzeugen? Pack covers @@ -1132,8 +1132,8 @@ - There is another library with the name '%1'. - Es gibt bereits eine Bibliothek mit dem Namen '%1'. + There is another library with the name '%1'. + Es gibt bereits eine Bibliothek mit dem Namen '%1'. @@ -1425,7 +1425,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Beim Aufrufen des Ordnerpfades kam es zu einem Fehler @@ -1500,7 +1500,8 @@ You probably only need one library in your top level comics folder, you can brow YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. Sie fügen zu viele Bibliotheken hinzu. - Wahrscheinlich brauchen Sie nur eine Bibliothek in Ihrem obersten Comic-Ordner, Sie können alle Unterordner mit Hilfe des Ordnerbereichs in der linken Seitenleiste durchsuchen. + +Wahrscheinlich brauchen Sie nur eine Bibliothek in Ihrem obersten Comic-Ordner, Sie können alle Unterordner mit Hilfe des Ordnerbereichs in der linken Seitenleiste durchsuchen. YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen, aber Sie sollten die Anzahl der Bibliotheken gering halten. @@ -2056,12 +2057,12 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen - You don't have any libraries yet + You don't have any libraries yet Sie haben aktuell noch keine Bibliothek - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Sie können eine Bibliothek in jedem beliebigen Ordner erstellen, YACReaderLibrary wird alle Comics und Unterordner von diesem Ordner importieren. Wenn Sie bereits eine Bibliothek erstellt haben, können Sie sie öffnen.</p><p>Vergessen Sie nicht, dass Sie YACReader als eigentsändige Anwendung nutzen können, um Comics auf Ihrem Computer zu lesen.</p> @@ -2148,7 +2149,7 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago Berücksichtigen Sie „neue“ Elemente, die seit X Tagen hinzugefügt oder aktualisiert wurden @@ -2235,11 +2236,11 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. WARNUNG! Während Bibliotheksaktualisierungen sind Schreibvorgänge in die Datenbank deaktiviert! Planen Sie keine Updates, während Sie die App möglicherweise aktiv nutzen. @@ -2304,7 +2305,7 @@ Um eine automatische Aktualisierung zu stoppen, tippen Sie auf die Ladeanzeige n Comic Flow - Comic-Flow + Comic Flow @@ -2340,8 +2341,8 @@ Um eine automatische Aktualisierung zu stoppen, tippen Sie auf die Ladeanzeige n - "Go to flow" size - "Go to flow" Größe + "Go to flow" size + Größe von "Gehe zu Comic Flow" @@ -2739,8 +2740,8 @@ Um eine automatische Aktualisierung zu stoppen, tippen Sie auf die Ladeanzeige n - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine-Link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ansehen </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine-Link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ansehen </a> @@ -3102,12 +3103,12 @@ Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Do - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader ist für iOS- und Android-Geräte verfügbar.<br/>Entdecken Sie es für <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> oder <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader ist für iOS- und Android-Geräte verfügbar.<br/>Entdecken Sie es für <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> oder <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - YACReader ist für iOS-Geräte verfügbar. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Jetzt entdecken! </a> + YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> + YACReader ist für iOS-Geräte verfügbar. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Jetzt entdecken! </a> @@ -3149,7 +3150,7 @@ um die Leistung zu verbessern - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Sortieren Sie bitte die Comic-Informationen links, bis die Informationen mit den Comics übereinstimmen.
@@ -3381,8 +3382,8 @@ um die Leistung zu verbessern - Press 'O' to open comic. - 'O' drücken, um Comic zu öffnen. + Press 'O' to open comic. + 'O' drücken, um Comic zu öffnen. @@ -3849,7 +3850,7 @@ um die Leistung zu verbessern Show go to flow - "Go to Flow" anzeigen + "Gehe zu Comic Flow" anzeigen diff --git a/YACReaderLibrary/yacreaderlibrary_es.ts b/YACReaderLibrary/yacreaderlibrary_es.ts index c3db24d0a..7d0980459 100644 --- a/YACReaderLibrary/yacreaderlibrary_es.ts +++ b/YACReaderLibrary/yacreaderlibrary_es.ts @@ -117,8 +117,8 @@ - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Antes de que te puedas conectar a Comic Vine necesitas tu propia clave API. Por favor, obtén una gratis <a href="http://www.comicvine.com/api/">aquí</a> + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Antes de que te puedas conectar a Comic Vine necesitas tu propia clave API. Por favor, obtén una gratis <a href="http://www.comicvine.com/api/">aquí</a> @@ -227,7 +227,8 @@ Could not import theme from: %1 - No se pudo importar el tema desde:\n%1 + No se pudo importar el tema desde: +%1 @@ -235,7 +236,10 @@ %1 %2 - No se pudo importar el tema desde:\n%1\n\n%2 + No se pudo importar el tema desde: +%1 + +%2 @@ -272,7 +276,7 @@ Hide comic flow - Ocultar cómic flow + Ocultar Comic Flow
@@ -568,8 +572,8 @@ - The shortcut "%1" is already assigned to other function - El atajo "%1" ya está asignado a otra función + The shortcut "%1" is already assigned to other function + El atajo "%1" ya está asignado a otra función @@ -588,7 +592,7 @@ - This folder doesn't contain comics yet + This folder doesn't contain comics yet Esta carpeta aún no contiene cómics @@ -596,7 +600,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Esta etiqueta aún no contiene ningún cómic
@@ -930,7 +934,7 @@ - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. La carpeta seleccionada no contiene ninguna biblioteca. @@ -1013,8 +1017,8 @@ - Library '%1' is no longer available. Do you want to remove it? - La biblioteca '%1' no está disponible. ¿Deseas eliminarla? + Library '%1' is no longer available. Do you want to remove it? + La biblioteca '%1' no está disponible. ¿Deseas eliminarla? Update library @@ -1055,8 +1059,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - La biblioteca '%1' ha sido creada con una versión más antigua de YACReaderLibrary y debe ser creada de nuevo. ¿Deseas crear la biblioteca ahora? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La biblioteca '%1' ha sido creada con una versión más antigua de YACReaderLibrary y debe ser creada de nuevo. ¿Deseas crear la biblioteca ahora? Pack covers @@ -1131,8 +1135,8 @@ - There is another library with the name '%1'. - Hay otra biblioteca con el nombre '%1'. + There is another library with the name '%1'. + Hay otra biblioteca con el nombre '%1'. @@ -1460,7 +1464,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Hubo un error al acceder a la ruta de la carpeta @@ -1534,7 +1538,11 @@ You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - Estás añadiendo demasiadas bibliotecas.\n\nProbablemente solo necesites una biblioteca en la carpeta principal de tus cómics, puedes explorar cualquier subcarpeta utilizando la sección de carpetas en la barra lateral izquierda.\n\nYACReaderLibrary no te detendrá de crear más bibliotecas, pero deberías mantener el número de bibliotecas bajo control. + Estás añadiendo demasiadas bibliotecas. + +Probablemente solo necesites una biblioteca en la carpeta principal de tus cómics, puedes explorar cualquier subcarpeta utilizando la sección de carpetas en la barra lateral izquierda. + +YACReaderLibrary no te detendrá de crear más bibliotecas, pero deberías mantener el número de bibliotecas bajo control. @@ -2064,12 +2072,12 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - You don't have any libraries yet + You don't have any libraries yet Aún no tienes ninguna biblioteca - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Puedes crear una biblioteca en cualquier carpeta, YACReaderLibrary importará todos las carpetas y cómics de esa carpeta. Si has creado alguna biblioteca anteriormente, puedes abrirla sin volver a crearla.</p><p>No olvides que puedes usar YACReader como una aplicación independiente para leer los cómics en tu ordenador.</p> @@ -2156,8 +2164,8 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - Consider 'recent' items added or updated since X days ago - Considerar elementos 'recientes' añadidos o actualizados desde hace X días + Consider 'recent' items added or updated since X days ago + Considerar elementos 'recientes' añadidos o actualizados desde hace X días @@ -2243,13 +2251,16 @@ YACReaderLibrary will not stop you from creating more libraries but you should k WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. - ¡ADVERTENCIA! Durante las actualizaciones de la biblioteca se desactivan las escrituras en la base de datos. No programes actualizaciones mientras puedas estar usando la aplicación activamente. Durante las actualizaciones automáticas, la aplicación bloqueará algunas de las acciones hasta que la actualización esté terminada. Para detener una actualización automática, toca en el indicador de carga junto al título de Bibliotecas. + ¡ADVERTENCIA! Durante las actualizaciones de la biblioteca se desactivan las escrituras en la base de datos. +No programes actualizaciones mientras puedas estar usando la aplicación activamente. +Durante las actualizaciones automáticas, la aplicación bloqueará algunas de las acciones hasta que la actualización esté terminada. +Para detener una actualización automática, toca en el indicador de carga junto al título de Bibliotecas. @@ -2294,7 +2305,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Display continue reading banner - Mostrar banner de "Continuar leyendo" + Mostrar banner de "Continuar leyendo" @@ -2309,7 +2320,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Comic Flow - Flujo cómico + Comic Flow @@ -2345,8 +2356,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - "Go to flow" size - Tamaño de "Go to flow" + "Go to flow" size + Tamaño de "Ir a Comic Flow" @@ -2744,8 +2755,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ver </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ver </a> @@ -2784,7 +2795,11 @@ YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. This appplication supports persistent settings, to set them up edit this file %1 To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md - \nYACReaderLibraryServer es la versión sin interfaz gráfica (headless) de YACReaderLibrary.\n\nEsta aplicación admite ajustes persistentes; para configurarlos, edita este archivo %1\nPara conocer los ajustes disponibles, consulta la documentación en https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer es la versión sin interfaz gráfica (headless) de YACReaderLibrary. + +Esta aplicación admite ajustes persistentes; para configurarlos, edita este archivo %1 +Para conocer los ajustes disponibles, consulta la documentación en https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md
@@ -3099,8 +3114,8 @@ To learn about the available settings please check the documentation at https:// - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader está disponible para iOS y Android.<br/> Descúbrela para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a>o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader está disponible para iOS y Android.<br/> Descúbrela para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a>o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -3132,7 +3147,7 @@ To learn about the available settings please check the documentation at https:// - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Por favor, ordena la lista de cómics en la izquiera hasta que coincida con la información adecuada. @@ -3298,7 +3313,8 @@ To learn about the available settings please check the documentation at https:// Could not open file for writing: %1 - No se pudo abrir el archivo para escribir:\n%1 + No se pudo abrir el archivo para escribir: +%1 @@ -3316,13 +3332,15 @@ To learn about the available settings please check the documentation at https:// Could not open file: %1 - No se pudo abrir el archivo:\n%1 + No se pudo abrir el archivo: +%1 Invalid JSON: %1 - JSON no válido:\n%1 + JSON no válido: +%1 @@ -3361,8 +3379,8 @@ To learn about the available settings please check the documentation at https:// - Press 'O' to open comic. - Pulsa 'O' para abrir un fichero. + Press 'O' to open comic. + Pulsa 'O' para abrir un fichero. @@ -3829,7 +3847,7 @@ To learn about the available settings please check the documentation at https:// Show go to flow - Mostrar flow ir a + Mostrar "Ir a Comic Flow" diff --git a/YACReaderLibrary/yacreaderlibrary_fr.ts b/YACReaderLibrary/yacreaderlibrary_fr.ts index 54b978cbc..76d2fdeb0 100644 --- a/YACReaderLibrary/yacreaderlibrary_fr.ts +++ b/YACReaderLibrary/yacreaderlibrary_fr.ts @@ -77,7 +77,7 @@ Label name: - Nom de l'étiquette : + Nom de l'étiquette :
@@ -122,8 +122,8 @@ - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Avant de pouvoir vous connecter à Comic Vine, vous avez besoin de votre propre clé API. Veuillez en obtenir une gratuitement ici: <a href="http://www.comicvine.com/api/"></a> + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Avant de pouvoir vous connecter à Comic Vine, vous avez besoin de votre propre clé API. Veuillez en obtenir une gratuitement ici: <a href="http://www.comicvine.com/api/"></a> @@ -166,7 +166,7 @@ Remove this user-imported theme - Supprimer ce thème importé par l'utilisateur + Supprimer ce thème importé par l'utilisateur @@ -201,17 +201,17 @@ Open Theme Editor... - Ouvrir l'éditeur de thème... + Ouvrir l'éditeur de thème... Theme editor error - Erreur de l'éditeur de thème + Erreur de l'éditeur de thème The current theme JSON could not be loaded. - Le thème actuel JSON n'a pas pu être chargé. + Le thème actuel JSON n'a pas pu être chargé. @@ -227,7 +227,7 @@ Could not import theme from: %1 - Impossible d'importer le thème depuis : + Impossible d'importer le thème depuis : %1 @@ -236,7 +236,7 @@ %1 %2 - Impossible d'importer le thème depuis : + Impossible d'importer le thème depuis : %1 %2 @@ -244,7 +244,7 @@ Import failed - Échec de l'importation + Échec de l'importation @@ -276,7 +276,7 @@ Hide comic flow - Cacher le flux de bande dessinée + Masquer Comic Flow @@ -392,7 +392,7 @@ Story Arc - Arc d'histoire + Arc d'histoire @@ -525,12 +525,12 @@ Create a library could take several minutes. You can stop the process and update the library later for completing the task. - La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et continuer plus tard. + La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et continuer plus tard. The selected path does not exist or is not a valid path. Be sure that you have write access to this folder - Le chemin sélectionné n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + Le chemin sélectionné n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier @@ -568,12 +568,12 @@ Shortcut in use - Raccourci en cours d'utilisation + Raccourci en cours d'utilisation - The shortcut "%1" is already assigned to other function - Le raccourci "%1" est déjà affecté à une autre fonction + The shortcut "%1" is already assigned to other function + Le raccourci "%1" est déjà affecté à une autre fonction @@ -588,7 +588,7 @@ - This folder doesn't contain comics yet + This folder doesn't contain comics yet Ce dossier ne contient pas encore de bandes dessinées @@ -596,7 +596,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Ce dossier ne contient pas encore de bandes dessinées
@@ -623,7 +623,7 @@ There are no recent comics! - Il n'y a pas de BD récente ! + Il n'y a pas de BD récente !
@@ -651,7 +651,7 @@ The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier @@ -661,7 +661,7 @@ Problem found while writing - Problème durant l'écriture + Problème durant l'écriture @@ -679,7 +679,7 @@ The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier @@ -689,7 +689,7 @@ Problem found while writing - Problème durant l'écriture + Problème durant l'écriture @@ -712,12 +712,12 @@ CRC error on page (%1): some of the pages will not be displayed correctly - Erreur CRC sur la page (%1): certaines pages ne s'afficheront pas correctement + Erreur CRC sur la page (%1): certaines pages ne s'afficheront pas correctement Unknown error opening the file - Erreur inconnue lors de l'ouverture du fichier + Erreur inconnue lors de l'ouverture du fichier @@ -877,7 +877,7 @@ <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - <p>YACReaderLibrary est en train de créer une nouvelle librairie.</p><p>La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et poursuivre plus tard.</p> + <p>YACReaderLibrary est en train de créer une nouvelle librairie.</p><p>La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et poursuivre plus tard.</p> @@ -912,7 +912,7 @@ <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> - <p>La bibliothèque actuelle est en cours d'analyse pour rechercher des informations sur les métadonnées XML héritées.</p><p>Ceci n'est nécessaire qu'une seule fois, et uniquement si la bibliothèque a été créée avec YACReaderLibrary 9.8.2 ou une version antérieure.</p> + <p>La bibliothèque actuelle est en cours d'analyse pour rechercher des informations sur les métadonnées XML héritées.</p><p>Ceci n'est nécessaire qu'une seule fois, et uniquement si la bibliothèque a été créée avec YACReaderLibrary 9.8.2 ou une version antérieure.</p> @@ -923,7 +923,7 @@ - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. Le dossier sélectionné ne contient aucune librairie. @@ -943,7 +943,7 @@ Error opening the library - Erreur lors de l'ouverture de la librairie + Erreur lors de l'ouverture de la librairie Show/Hide marks @@ -1053,8 +1053,8 @@ - Library '%1' is no longer available. Do you want to remove it? - La librarie '%1' n'est plus disponible. Voulez-vous la supprimer? + Library '%1' is no longer available. Do you want to remove it? + La librarie '%1' n'est plus disponible. Voulez-vous la supprimer? Update library @@ -1077,7 +1077,7 @@ Reset comic rating - Supprimer la note d'évaluation + Supprimer la note d'évaluation @@ -1092,7 +1092,7 @@ The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - L'élément sélectionné sera supprimé, vos bandes dessinées ou dossiers ne seront pas supprimés de votre disque. Êtes-vous sûr? + L'élément sélectionné sera supprimé, vos bandes dessinées ou dossiers ne seront pas supprimés de votre disque. Êtes-vous sûr? Expand all nodes @@ -1104,8 +1104,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - La librarie '%1' a été créée avec une ancienne version de YACReaderLibrary. Elle doit être re-créée. Voulez-vous créer la librairie? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La librarie '%1' a été créée avec une ancienne version de YACReaderLibrary. Elle doit être re-créée. Voulez-vous créer la librairie? Pack covers @@ -1129,7 +1129,7 @@ You probably only need one library in your top level comics folder, you can brow YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. Vous ajoutez trop de bibliothèques. -Vous n'avez probablement besoin que d'une bibliothèque dans votre dossier BD de niveau supérieur, vous pouvez parcourir les sous-dossiers en utilisant la section des dossiers dans la barre latérale gauche. +Vous n'avez probablement besoin que d'une bibliothèque dans votre dossier BD de niveau supérieur, vous pouvez parcourir les sous-dossiers en utilisant la section des dossiers dans la barre latérale gauche. YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais vous devriez garder le nombre de bibliothèques bas. @@ -1218,8 +1218,8 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v - There is another library with the name '%1'. - Une autre librairie a le nom '%1'. + There is another library with the name '%1'. + Une autre librairie a le nom '%1'. Remove reading list @@ -1241,7 +1241,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Assign current order to comics - Assigner l'ordre actuel aux bandes dessinées + Assigner l'ordre actuel aux bandes dessinées Pack the covers of the selected library @@ -1343,12 +1343,12 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v There were errors during library upgrade in: - Des erreurs se sont produites lors de la mise à niveau de la bibliothèque dans : + Des erreurs se sont produites lors de la mise à niveau de la bibliothèque dans : Folder name: - Nom du dossier : + Nom du dossier : @@ -1358,7 +1358,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Please, select a folder first - Veuillez d'abord sélectionner un dossier + Veuillez d'abord sélectionner un dossier @@ -1367,8 +1367,8 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v - There was an error accessing the folder's path - Une erreur s'est produite lors de l'accès au chemin du dossier + There was an error accessing the folder's path + Une erreur s'est produite lors de l'accès au chemin du dossier @@ -1384,18 +1384,18 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - Un problème est survenu lors de la tentative de suppression des dossiers sélectionnés. Veuillez vérifier les autorisations d'écriture et assurez-vous que toutes les applications utilisent ces dossiers ou l'un des fichiers contenus. + Un problème est survenu lors de la tentative de suppression des dossiers sélectionnés. Veuillez vérifier les autorisations d'écriture et assurez-vous que toutes les applications utilisent ces dossiers ou l'un des fichiers contenus. List name: - Nom de la liste : + Nom de la liste : Delete list/label - Supprimer la liste/l'étiquette + Supprimer la liste/l'étiquette @@ -1444,7 +1444,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v YACReader not found. There might be a problem with your YACReader installation. - YACReader introuvable. Il se peut qu'il y ait un problème avec votre installation de YACReader. + YACReader introuvable. Il se peut qu'il y ait un problème avec votre installation de YACReader. @@ -1454,7 +1454,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Error opening comic with third party reader. - Erreur lors de l'ouverture de la bande dessinée avec un lecteur tiers. + Erreur lors de l'ouverture de la bande dessinée avec un lecteur tiers. @@ -1464,7 +1464,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - Un problème est survenu lors de la tentative de suppression des bandes dessinées sélectionnées. Veuillez vérifier les autorisations d'écriture dans les fichiers sélectionnés ou le dossier contenant. + Un problème est survenu lors de la tentative de suppression des bandes dessinées sélectionnées. Veuillez vérifier les autorisations d'écriture dans les fichiers sélectionnés ou le dossier contenant. @@ -1474,7 +1474,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Assign numbers starting in: - Attribuez des numéros commençant par : + Attribuez des numéros commençant par : @@ -1484,17 +1484,17 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v The selected file is not a valid image. - Le fichier sélectionné n'est pas une image valide. + Le fichier sélectionné n'est pas une image valide. Error saving cover - Erreur lors de l'enregistrement de la couverture + Erreur lors de l'enregistrement de la couverture There was an error saving the cover image. - Une erreur s'est produite lors de l'enregistrement de l'image de couverture. + Une erreur s'est produite lors de l'enregistrement de l'image de couverture. @@ -1663,7 +1663,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Set issue as normal - Définir le problème comme d'habitude + Définir le problème comme d'habitude @@ -1710,12 +1710,12 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Show/Hide recent indicator - Afficher/Masquer l'indicateur récent + Afficher/Masquer l'indicateur récent Show or hide recent indicator - Afficher ou masquer l'indicateur récent + Afficher ou masquer l'indicateur récent @@ -1817,7 +1817,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Reset comic rating - Supprimer la note d'évaluation + Supprimer la note d'évaluation @@ -1832,7 +1832,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Assign current order to comics - Assigner l'ordre actuel aux bandes dessinées + Assigner l'ordre actuel aux bandes dessinées @@ -1962,13 +1962,13 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v - You don't have any libraries yet - Vous n'avez pas encore de librairie + You don't have any libraries yet + Vous n'avez pas encore de librairie - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> - <p>Vous pouvez creer une librairie dans n'importe quel dossierr, YACReaderLibrary importera les dossiers et les bandes dessinées contenus dans ce dossier. Si vous avez déjà crer des librairies, vous pouvez les ouvrir.</p><p>N'oubliez pas que vous pouvez utiliser YACReader en tant que stand alone pour lire vos bandes dessinées sur votre ordinateur.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Vous pouvez creer une librairie dans n'importe quel dossierr, YACReaderLibrary importera les dossiers et les bandes dessinées contenus dans ce dossier. Si vous avez déjà crer des librairies, vous pouvez les ouvrir.</p><p>N'oubliez pas que vous pouvez utiliser YACReader en tant que stand alone pour lire vos bandes dessinées sur votre ordinateur.</p> @@ -2008,7 +2008,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Application language - Langue de l'application + Langue de l'application @@ -2019,7 +2019,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Tray icon settings (experimental) - Paramètres de l'icône de la barre d'état (expérimental) + Paramètres de l'icône de la barre d'état (expérimental) @@ -2029,7 +2029,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Start into the system tray - Commencez dans la barre d'état système + Commencez dans la barre d'état système @@ -2050,11 +2050,11 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Import metadata from ComicInfo.xml when adding new comics Import metada from ComicInfo.xml when adding new comics - Importer des métadonnées depuis ComicInfo.xml lors de l'ajout de nouvelles bandes dessinées + Importer des métadonnées depuis ComicInfo.xml lors de l'ajout de nouvelles bandes dessinées - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago Considérez les éléments « récents » ajoutés ou mis à jour depuis X jours @@ -2141,16 +2141,16 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. - AVERTISSEMENT! Lors des mises à jour de la bibliothèque, les écritures dans la base de données sont désactivées ! -Ne planifiez pas de mises à jour pendant que vous utilisez activement l'application. -Lors des mises à jour automatiques, l'application bloquera certaines actions jusqu'à ce que la mise à jour soit terminée. -Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de chargement à côté du titre Bibliothèques. + AVERTISSEMENT! Lors des mises à jour de la bibliothèque, les écritures dans la base de données sont désactivées ! +Ne planifiez pas de mises à jour pendant que vous utilisez activement l'application. +Lors des mises à jour automatiques, l'application bloquera certaines actions jusqu'à ce que la mise à jour soit terminée. +Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de chargement à côté du titre Bibliothèques. @@ -2160,17 +2160,17 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Compare the modified date of files when updating a library (not recommended) - Comparer la date de modification des fichiers lors de la mise à jour d'une bibliothèque (déconseillé) + Comparer la date de modification des fichiers lors de la mise à jour d'une bibliothèque (déconseillé) Enable background image - Activer l'image d'arrière-plan + Activer l'image d'arrière-plan Opacity level - Niveau d'opacité + Niveau d'opacité @@ -2210,7 +2210,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Comic Flow - Flux comique + Comic Flow @@ -2242,17 +2242,17 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Show time in current page information label - Afficher l'heure dans l'étiquette d'information de la page actuelle + Afficher l'heure dans l'étiquette d'information de la page actuelle - "Go to flow" size - Taille du flux + "Go to flow" size + Taille de "Aller à Comic Flow" Background color - Couleur d'arrière plan + Couleur d'arrière plan @@ -2297,7 +2297,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Click left or right half of the screen to turn pages. - Cliquez sur la moitié gauche ou droite de l'écran pour tourner les pages. + Cliquez sur la moitié gauche ou droite de l'écran pour tourner les pages. @@ -2307,7 +2307,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Disable mouse over activation - Désactiver la souris sur l'activation + Désactiver la souris sur l'activation @@ -2332,12 +2332,12 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Image options - Option de l'image + Option de l'image Fit options - Options d'ajustement + Options d'ajustement @@ -2357,12 +2357,12 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Scaling - Mise à l'échelle + Mise à l'échelle Scaling method - Méthode de mise à l'échelle + Méthode de mise à l'échelle @@ -2387,7 +2387,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Image adjustment - Ajustement de l'image + Ajustement de l'image @@ -2493,7 +2493,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Reset cover to the default image - Réinitialiser la couverture à l'image par défaut + Réinitialiser la couverture à l'image par défaut @@ -2518,17 +2518,17 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Alternate series: - Série alternative : + Série alternative : Series Group: - Groupe de séries : + Groupe de séries : Editor(s): - Editeur(s) : + Editeur(s) : @@ -2548,22 +2548,22 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Language (ISO): - Langue (ISO) : + Langue (ISO) : Teams: - Équipes : + Équipes : Locations: - Emplacements : + Emplacements : Main character or team: - Personnage principal ou équipe : + Personnage principal ou équipe : @@ -2573,7 +2573,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Notes: - Remarques : + Remarques : @@ -2583,7 +2583,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha The image is invalid. - L'image n'est pas valide. + L'image n'est pas valide. @@ -2603,7 +2603,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Tags: - Balises : + Balises : @@ -2623,7 +2623,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Age rating: - Limite d'âge: + Limite d'âge: @@ -2672,8 +2672,8 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Lien Comic Vine : <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> vue </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Lien Comic Vine : <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> vue </a> @@ -2747,7 +2747,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum The file could not be read or is not valid JSON. - Le fichier n'a pas pu être lu ou n'est pas un JSON valide. + Le fichier n'a pas pu être lu ou n'est pas un JSON valide. @@ -2809,7 +2809,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Number of %1 found : %2 - Nombre de %1 trouvés : %2 + Nombre de %1 trouvés : %2 @@ -2958,12 +2958,12 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Scan it! - Scannez-le ! + Scannez-le ! - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader est disponible pour les appareils iOS et Android.<br/>Découvrez-le pour <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader est disponible pour les appareils iOS et Android.<br/>Découvrez-le pour <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2975,13 +2975,13 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. - Veuillez trier la liste des bandes dessinées sur la gauche jusqu'à ce qu'elle corresponde aux informations des bandes dessinées. + Please, sort the list of comics on the left until it matches the comics' information. + Veuillez trier la liste des bandes dessinées sur la gauche jusqu'à ce qu'elle corresponde aux informations des bandes dessinées. sort comics to match comic information - trier les bandes dessinées pour qu'elles correspondent aux informations sur les bandes dessinées + trier les bandes dessinées pour qu'elles correspondent aux informations sur les bandes dessinées @@ -3034,7 +3034,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - Maintenez enfoncé pour faire clignoter la valeur sélectionnée dans l'interface utilisateur (magenta / basculé / 0↔10). Les versions restaurent l'original. + Maintenez enfoncé pour faire clignoter la valeur sélectionnée dans l'interface utilisateur (magenta / basculé / 0↔10). Les versions restaurent l'original. @@ -3059,7 +3059,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Display name: - Nom d'affichage : + Nom d'affichage : @@ -3139,7 +3139,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Edit: %1 - Modifier : %1 + Modifier : %1 @@ -3155,13 +3155,13 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Save failed - Échec de l'enregistrement + Échec de l'enregistrement Could not open file for writing: %1 - Impossible d'ouvrir le fichier en écriture : + Impossible d'ouvrir le fichier en écriture : %1 @@ -3180,14 +3180,14 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Could not open file: %1 - Impossible d'ouvrir le fichier : + Impossible d'ouvrir le fichier : %1 Invalid JSON: %1 - JSON invalide : + JSON invalide : %1 @@ -3227,8 +3227,8 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum - Press 'O' to open comic. - Appuyez sur "O" pour ouvrir une bande dessinée. + Press 'O' to open comic. + Appuyez sur "O" pour ouvrir une bande dessinée. @@ -3243,7 +3243,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Error opening comic - Erreur d'ouverture de la bande dessinée + Erreur d'ouverture de la bande dessinée @@ -3407,7 +3407,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Use VSync (improve the image quality in fullscreen mode, worse performance) - Utiliser VSync (améliore la qualité de l'image en plein écran, diminue la performance) + Utiliser VSync (améliore la qualité de l'image en plein écran, diminue la performance) @@ -3440,7 +3440,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Open image folder - Ouvrir un dossier d'images + Ouvrir un dossier d'images @@ -3460,7 +3460,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Clear open recent list - Vider la liste d'ouverture récente + Vider la liste d'ouverture récente @@ -3529,7 +3529,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Fit image to height - Ajuster l'image à la hauteur + Ajuster l'image à la hauteur @@ -3539,7 +3539,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Fit image to width - Ajuster l'image à la largeur + Ajuster l'image à la largeur @@ -3695,7 +3695,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Show go to flow - Afficher le flux + Afficher "Aller à Comic Flow" @@ -3805,7 +3805,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Hide/show toolbar - Masquer / afficher la barre d'outils + Masquer / afficher la barre d'outils @@ -3943,7 +3943,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quit</b> dans le menu contextuel de l'icône de la barre d'état système. + YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quit</b> dans le menu contextuel de l'icône de la barre d'état système. @@ -4079,7 +4079,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Use VSync (improve the image quality in fullscreen mode, worse performance) - Utiliser VSync (améliore la qualité de l'image en plein écran, diminue la performance) + Utiliser VSync (améliore la qualité de l'image en plein écran, diminue la performance) Visibility @@ -4110,7 +4110,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Use hardware acceleration (restart needed) - Utiliser l'accélération hardware (redémarrage nécessaire) + Utiliser l'accélération hardware (redémarrage nécessaire) diff --git a/YACReaderLibrary/yacreaderlibrary_it.ts b/YACReaderLibrary/yacreaderlibrary_it.ts index 1a561cb11..6316ee61f 100644 --- a/YACReaderLibrary/yacreaderlibrary_it.ts +++ b/YACReaderLibrary/yacreaderlibrary_it.ts @@ -126,13 +126,13 @@ - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Prima di conneterti a "Comic Vine" devi avere la tua chiave API. Per favore recuperane una da <a href="http://www.comicvine.com/api/">QUI</a + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Prima di conneterti a "Comic Vine" devi avere la tua chiave API. Per favore recuperane una da <a href="http://www.comicvine.com/api/">QUI</a Paste here your Comic Vine API key - Incolla qui la tua chiave API di "Comic Vine" + Incolla qui la tua chiave API di "Comic Vine" @@ -170,7 +170,7 @@ Remove this user-imported theme - Rimuovi questo tema importato dall'utente + Rimuovi questo tema importato dall'utente @@ -205,12 +205,12 @@ Open Theme Editor... - Apri l'editor del tema... + Apri l'editor del tema... Theme editor error - Errore nell'editor del tema + Errore nell'editor del tema @@ -280,7 +280,7 @@ Hide comic flow - Nascondi il flusso dei fumetti + Nascondi Comic Flow @@ -498,7 +498,7 @@ Retrieving volume info... - Sto ricevendo le informazioni per l'abum... + Sto ricevendo le informazioni per l'abum... @@ -571,8 +571,8 @@ - The shortcut "%1" is already assigned to other function - La scorciatoia "%1" è già assegnata ad un' altra funzione + The shortcut "%1" is already assigned to other function + La scorciatoia "%1" è già assegnata ad un' altra funzione @@ -596,7 +596,7 @@ - This folder doesn't contain comics yet + This folder doesn't contain comics yet Questa cartella non contiene ancora fumetti @@ -604,7 +604,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Per ora questa etichetta non contiene fumetti
@@ -725,7 +725,7 @@ Unknown error opening the file - Errore sconosciuto all'apertura del file + Errore sconosciuto all'apertura del file @@ -885,7 +885,7 @@ <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - <p>YacReader sta creando una nuova libreria.</p><p>La creazione di una libreria può durare diversi minuti. Puoi fermare l'attività ed aggiornare la libreria più tardi, completando l'attività</p> + <p>YacReader sta creando una nuova libreria.</p><p>La creazione di una libreria può durare diversi minuti. Puoi fermare l'attività ed aggiornare la libreria più tardi, completando l'attività</p> @@ -910,7 +910,7 @@ <p>The current library is being upgraded, please wait.</p> - <p>È in corso l'aggiornamento della libreria corrente, attendi.</p> + <p>È in corso l'aggiornamento della libreria corrente, attendi.</p> @@ -931,7 +931,7 @@ - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. La cartella selezionata non contiene nessuna Libreria. @@ -961,7 +961,7 @@ Error opening the library - Errore nell'apertura della libreria + Errore nell'apertura della libreria Show/Hide marks @@ -980,7 +980,7 @@ There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - C'è stato un problema cancellando le cartelle selezionate. Per favore controlla i tuoi permessi di scrittura e sii sicuro che non ci siano altre applicazioni che usano le stesse cartelle. + C'è stato un problema cancellando le cartelle selezionate. Per favore controlla i tuoi permessi di scrittura e sii sicuro che non ci siano altre applicazioni che usano le stesse cartelle. Remove current library from your collection @@ -1028,8 +1028,8 @@ - There was an error accessing the folder's path - C'è stato un errore nell'accesso al percorso della cartella + There was an error accessing the folder's path + C'è stato un errore nell'accesso al percorso della cartella @@ -1043,7 +1043,7 @@ Comics will only be deleted from the current label/list. Are you sure? - I fumetti verranno cancellati dall'etichetta/lista corrente. Sei sicuro? + I fumetti verranno cancellati dall'etichetta/lista corrente. Sei sicuro? Rename current library @@ -1080,8 +1080,8 @@ - Library '%1' is no longer available. Do you want to remove it? - La libreria '%1' non è più disponibile, la vuoi cancellare? + Library '%1' is no longer available. Do you want to remove it? + La libreria '%1' non è più disponibile, la vuoi cancellare? Update library @@ -1146,8 +1146,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - La libreria '%1' è stata creata con una versione precedente di YACREaderLibrary. Deve essere ricreata. Lo vuoi fare ora? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La libreria '%1' è stata creata con una versione precedente di YACREaderLibrary. Deve essere ricreata. Lo vuoi fare ora? Pack covers @@ -1230,13 +1230,13 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Importa informazioni fumetto - The current library can't be udpated. Check for write write permissions on: + The current library can't be udpated. Check for write write permissions on: La libreria corrente non può essere aggiornata. Controlla i tuoi permessi di scrittura su: There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - C'è un problema nel cancellare i fumetti selezionati. Per favore controlla i tuoi permessi di scrittura sui file o sulla cartella. + C'è un problema nel cancellare i fumetti selezionati. Per favore controlla i tuoi permessi di scrittura sui file o sulla cartella. Add new reading list @@ -1302,8 +1302,8 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu - There is another library with the name '%1'. - Esiste già una libreria con il nome '%1'. + There is another library with the name '%1'. + Esiste già una libreria con il nome '%1'. Remove reading list @@ -1332,7 +1332,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu The selected file is not a valid image. - Il file selezionato non è un'immagine valida. + Il file selezionato non è un'immagine valida. @@ -1342,7 +1342,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu There was an error saving the cover image. - Si è verificato un errore durante il salvataggio dell'immagine di copertina. + Si è verificato un errore durante il salvataggio dell'immagine di copertina. @@ -1360,7 +1360,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Assign current order to comics - Assegna l'ordinamento corrente ai fumetti + Assegna l'ordinamento corrente ai fumetti Pack the covers of the selected library @@ -1492,7 +1492,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu 4koma (top to botom) - 4koma (dall'alto verso il basso) + 4koma (dall'alto verso il basso) @@ -1520,7 +1520,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Error opening comic with third party reader. - Errore nell'apertura del fumetto con un lettore di terze parti. + Errore nell'apertura del fumetto con un lettore di terze parti. @@ -1549,7 +1549,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu There were errors during library upgrade in: - Si sono verificati errori durante l'aggiornamento della libreria in: + Si sono verificati errori durante l'aggiornamento della libreria in: @@ -1559,7 +1559,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu YACReader not found. There might be a problem with your YACReader installation. - YACReader non trovato. Potrebbe esserci un problema con l'installazione di YACReader. + YACReader non trovato. Potrebbe esserci un problema con l'installazione di YACReader.
@@ -1765,12 +1765,12 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Show/Hide recent indicator - Mostra/Nascondi l'indicatore recente + Mostra/Nascondi l'indicatore recente Show or hide recent indicator - Mostra o nascondi l'indicatore recente + Mostra o nascondi l'indicatore recente @@ -1887,7 +1887,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Assign current order to comics - Assegna l'ordinamento corrente ai fumetti + Assegna l'ordinamento corrente ai fumetti @@ -2017,12 +2017,12 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu - You don't have any libraries yet + You don't have any libraries yet Per ora non hai ancora nessuna libreria - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Puoi creare una libreria in qualsiasi cartella, YACReader importerà tutti i fumetti e struttura da questa certella. Se hai creato una qualsiasia libreria nel passato la puoi aprire. </p><p>Non dimenticare che puoi usare YACReader come applicazione stand alone per leggere i fumetti sul tuo PC.</p> @@ -2059,7 +2059,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Enable background image - Abilita l'immagine di sfondo + Abilita l'immagine di sfondo @@ -2075,7 +2075,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Edit Comic Vine API key - Edita l'API di ComicVine + Edita l'API di ComicVine @@ -2096,7 +2096,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Comic Flow - Flusso dei fumetti + Comic Flow @@ -2125,7 +2125,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Application language - Lingua dell'applicazione + Lingua dell'applicazione @@ -2136,7 +2136,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Tray icon settings (experimental) - Impostazioni dell'icona nella barra delle applicazioni (sperimentale) + Impostazioni dell'icona nella barra delle applicazioni (sperimentale) @@ -2161,8 +2161,8 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu - Consider 'recent' items added or updated since X days ago - Considera gli elementi "recenti" aggiunti o aggiornati da X giorni fa + Consider 'recent' items added or updated since X days ago + Considera gli elementi "recenti" aggiunti o aggiornati da X giorni fa @@ -2183,7 +2183,7 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu Update libraries at startup - Aggiorna le librerie all'avvio + Aggiorna le librerie all'avvio @@ -2248,16 +2248,16 @@ YACReader non ti fermerà dal creare altre librerie ma è meglio se terrai il nu WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. AVVERTIMENTO! Durante gli aggiornamenti della libreria le scritture sul database sono disabilitate! -Non pianificare gli aggiornamenti mentre potresti utilizzare l'app attivamente. -Durante gli aggiornamenti automatici l'app bloccherà alcune azioni fino al termine dell'aggiornamento. -Per interrompere un aggiornamento automatico, tocca l'indicatore di caricamento accanto al titolo Librerie. +Non pianificare gli aggiornamenti mentre potresti utilizzare l'app attivamente. +Durante gli aggiornamenti automatici l'app bloccherà alcune azioni fino al termine dell'aggiornamento. +Per interrompere un aggiornamento automatico, tocca l'indicatore di caricamento accanto al titolo Librerie. @@ -2267,7 +2267,7 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam Compare the modified date of files when updating a library (not recommended) - Confronta la data di modifica dei file durante l'aggiornamento di una libreria (non consigliato) + Confronta la data di modifica dei file durante l'aggiornamento di una libreria (non consigliato) @@ -2297,12 +2297,12 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam Show time in current page information label - Mostra l'ora nell'etichetta delle informazioni della pagina corrente + Mostra l'ora nell'etichetta delle informazioni della pagina corrente - "Go to flow" size - Dimensione "Vai all'elenco" + "Go to flow" size + Dimensione di "Vai a Comic Flow" @@ -2362,7 +2362,7 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam Disable mouse over activation - Disabilita il mouse all'attivazione + Disabilita il mouse all'attivazione @@ -2541,12 +2541,12 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam Reset cover to the default image - Ripristina la copertina sull'immagine predefinita + Ripristina la copertina sull'immagine predefinita Load custom cover image - Carica l'immagine di copertina personalizzata + Carica l'immagine di copertina personalizzata @@ -2631,7 +2631,7 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam The image is invalid. - L'immagine non è valida. + L'immagine non è valida. @@ -2700,8 +2700,8 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Vai </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Vai </a> @@ -2728,7 +2728,7 @@ Per interrompere un aggiornamento automatico, tocca l'indicatore di caricam Arc number: - Numero dell'arco: + Numero dell'arco: @@ -3004,8 +3004,8 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https Porta - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - YACReader è disponibile per dispositivi iOS. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Provalo! </a> + YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> + YACReader è disponibile per dispositivi iOS. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Provalo! </a> @@ -3039,8 +3039,8 @@ Migliora le prestazioni! - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader è disponibile per dispositivi iOS e Android.<br/>Scoprilo per <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader è disponibile per dispositivi iOS e Android.<br/>Scoprilo per <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -3072,7 +3072,7 @@ Migliora le prestazioni! - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Per favore ordina la lista dei fumetti a sinistra sino a che corrisponde alle informazioni dei fumetti. @@ -3115,7 +3115,7 @@ Migliora le prestazioni! Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - Tieni premuto per far lampeggiare il valore selezionato nell'interfaccia utente (magenta / alternato / 0↔10). Le versioni ripristinano l'originale. + Tieni premuto per far lampeggiare il valore selezionato nell'interfaccia utente (magenta / alternato / 0↔10). Le versioni ripristinano l'originale. @@ -3308,8 +3308,8 @@ Migliora le prestazioni! - Press 'O' to open comic. - Premi "O" per aprire il fumettto. + Press 'O' to open comic. + Premi "O" per aprire il fumettto. @@ -3324,7 +3324,7 @@ Migliora le prestazioni! Error opening comic - Errore nell'apertura + Errore nell'apertura @@ -3488,7 +3488,7 @@ Migliora le prestazioni! Use VSync (improve the image quality in fullscreen mode, worse performance) - UIsa VSync. (Migliora la qualità dell'immagine a modalità tutto schermo, peggiora le prestazioni) + UIsa VSync. (Migliora la qualità dell'immagine a modalità tutto schermo, peggiora le prestazioni) @@ -3526,12 +3526,12 @@ Migliora le prestazioni! Open latest comic - Apri l'ultimo fumetto + Apri l'ultimo fumetto Open the latest comic opened in the previous reading session - Apri l'ultimo fumetto aperto nella sessione precedente + Apri l'ultimo fumetto aperto nella sessione precedente @@ -3610,7 +3610,7 @@ Migliora le prestazioni! Fit image to height - Adatta immagine all'altezza + Adatta immagine all'altezza @@ -3776,7 +3776,7 @@ Migliora le prestazioni! Show go to flow - Mostra vai all'elenco + Mostra "Vai a Comic Flow" @@ -3911,7 +3911,7 @@ Migliora le prestazioni! Reset magnifying glass - Reimposta la lente d'ingrandimento + Reimposta la lente d'ingrandimento @@ -3976,7 +3976,7 @@ Migliora le prestazioni! Go to the last page - Vai all'ultima pagina + Vai all'ultima pagina @@ -4024,7 +4024,7 @@ Migliora le prestazioni! YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary continuerà a essere eseguito nella barra delle applicazioni. Per terminare il programma, scegli <b>Esci</b> nel menu contestuale dell'icona nella barra delle applicazioni. + YACReaderLibrary continuerà a essere eseguito nella barra delle applicazioni. Per terminare il programma, scegli <b>Esci</b> nel menu contestuale dell'icona nella barra delle applicazioni. @@ -4160,7 +4160,7 @@ Migliora le prestazioni! Use VSync (improve the image quality in fullscreen mode, worse performance) - UIsa VSync. (Migliora la qualità dell'immagine a modalità tutto schermo, peggiora le prestazioni) + UIsa VSync. (Migliora la qualità dell'immagine a modalità tutto schermo, peggiora le prestazioni) Visibility diff --git a/YACReaderLibrary/yacreaderlibrary_nl.ts b/YACReaderLibrary/yacreaderlibrary_nl.ts index 46b81edf3..c4059736c 100644 --- a/YACReaderLibrary/yacreaderlibrary_nl.ts +++ b/YACReaderLibrary/yacreaderlibrary_nl.ts @@ -69,8 +69,8 @@ - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Voordat je verbinding kunt maken met Comic Vine, heb je een eigen API-sleutel nodig. Vraag er <a href="http://www.comicvine.com/api/">hier</a> één gratis aan + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Voordat je verbinding kunt maken met Comic Vine, heb je een eigen API-sleutel nodig. Vraag er <a href="http://www.comicvine.com/api/">hier</a> één gratis aan @@ -228,7 +228,7 @@ Hide comic flow - Sluit de Omslagbrowser + Comic Flow verbergen @@ -339,7 +339,7 @@ Pages - Pagina's + Pagina's @@ -524,15 +524,15 @@ - The shortcut "%1" is already assigned to other function - De sneltoets "%1" is al aan een andere functie toegewezen + The shortcut "%1" is already assigned to other function + De sneltoets "%1" is al aan een andere functie toegewezen EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Deze map bevat nog geen strips @@ -540,7 +540,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Dit label bevat nog geen strips
@@ -656,7 +656,7 @@ CRC error on page (%1): some of the pages will not be displayed correctly - CRC-fout op pagina (%1): sommige pagina's worden niet correct weergegeven + CRC-fout op pagina (%1): sommige pagina's worden niet correct weergegeven @@ -698,7 +698,7 @@ Total pages : - Totaal aantal pagina's : + Totaal aantal pagina's : @@ -867,7 +867,7 @@ - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. De geselecteerde map bevat geen bibliotheek. @@ -938,8 +938,8 @@ - Library '%1' is no longer available. Do you want to remove it? - Bibliotheek ' %1' is niet langer beschikbaar. Wilt u het verwijderen? + Library '%1' is no longer available. Do you want to remove it? + Bibliotheek ' %1' is niet langer beschikbaar. Wilt u het verwijderen? Update library @@ -966,8 +966,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Bibliotheek ' %1' is gemaakt met een oudere versie van YACReaderLibrary. Zij moet opnieuw worden aangemaakt. Wilt u de bibliotheek nu aanmaken? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Bibliotheek ' %1' is gemaakt met een oudere versie van YACReaderLibrary. Zij moet opnieuw worden aangemaakt. Wilt u de bibliotheek nu aanmaken? Pack covers @@ -1037,8 +1037,8 @@ - There is another library with the name '%1'. - Er is al een bibliotheek met de naam ' %1 '. + There is another library with the name '%1'. + Er is al een bibliotheek met de naam ' %1 '. @@ -1232,7 +1232,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Er is een fout opgetreden bij het verkrijgen van toegang tot het pad van de map @@ -1850,12 +1850,12 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, - You don't have any libraries yet + You don't have any libraries yet Je hebt geen nog libraries - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <P>u kunt een bibliotheek maken in een willekeurige map, YACReaderLibrary importeert alle strips en mappen uit deze map. Alle bibliotheek aangemaakt in het verleden kan je openen. < /p> <p>vergeet niet dat u YACReader kan gebruiken als stand-alone applicatie voor het lezen van de strips op de computer. < /p> @@ -1942,8 +1942,8 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, - Consider 'recent' items added or updated since X days ago - Overweeg 'recente' items die sinds X dagen geleden zijn toegevoegd of bijgewerkt + Consider 'recent' items added or updated since X days ago + Overweeg 'recente' items die sinds X dagen geleden zijn toegevoegd of bijgewerkt @@ -2029,11 +2029,11 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. WAARSCHUWING! Tijdens bibliotheekupdates is schrijven naar de database uitgeschakeld! Plan geen updates terwijl u de app mogelijk actief gebruikt. @@ -2098,7 +2098,7 @@ Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de Comic Flow - Komische stroom + Comic Flow @@ -2134,8 +2134,8 @@ Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de - "Go to flow" size - "Naar Omslagbrowser" afmetingen + "Go to flow" size + Grootte van "Ga naar Comic Flow" @@ -2175,17 +2175,17 @@ Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de Only Back/Forward buttons can turn pages - Alleen de knoppen Terug/Vooruit kunnen pagina's omslaan + Alleen de knoppen Terug/Vooruit kunnen pagina's omslaan Use the Left/Right buttons to turn pages. - Gebruik de knoppen Links/Rechts om pagina's om te slaan. + Gebruik de knoppen Links/Rechts om pagina's om te slaan. Click left or right half of the screen to turn pages. - Klik op de linker- of rechterhelft van het scherm om pagina's om te slaan. + Klik op de linker- of rechterhelft van het scherm om pagina's om te slaan. @@ -2235,7 +2235,7 @@ Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de Double Page options - Opties voor dubbele pagina's + Opties voor dubbele pagina's @@ -2560,8 +2560,8 @@ Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine-link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> bekijken </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine-link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> bekijken </a>
@@ -2850,8 +2850,8 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader is beschikbaar voor iOS- en Android-apparaten.<br/>Ontdek het voor <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> of <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is beschikbaar voor iOS- en Android-apparaten.<br/>Ontdek het voor <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> of <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2863,7 +2863,7 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Sorteer de lijst met strips aan de linkerkant totdat deze overeenkomt met de informatie over de strips. @@ -3115,8 +3115,8 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa - Press 'O' to open comic. - Druk 'O' om een strip te openen. + Press 'O' to open comic. + Druk 'O' om een strip te openen. @@ -3583,7 +3583,7 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa Show go to flow - Toon ga naar de Omslagbrowser + "Ga naar Comic Flow" tonen diff --git a/YACReaderLibrary/yacreaderlibrary_pt.ts b/YACReaderLibrary/yacreaderlibrary_pt.ts index 1b0efd7e1..d891094e3 100644 --- a/YACReaderLibrary/yacreaderlibrary_pt.ts +++ b/YACReaderLibrary/yacreaderlibrary_pt.ts @@ -69,8 +69,8 @@ - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Antes de se conectar ao Comic Vine, você precisa de sua própria chave de API. Por favor, ganhe um <a href="http://www.comicvine.com/api/">aqui</a> grátis + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Antes de se conectar ao Comic Vine, você precisa de sua própria chave de API. Por favor, ganhe um <a href="http://www.comicvine.com/api/">aqui</a> grátis @@ -228,7 +228,7 @@ Hide comic flow - Ocultar fluxo de quadrinhos + Ocultar Comic Flow @@ -524,15 +524,15 @@ - The shortcut "%1" is already assigned to other function - O atalho "%1" já está atribuído a outra função + The shortcut "%1" is already assigned to other function + O atalho "%1" já está atribuído a outra função EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Esta pasta ainda não contém quadrinhos @@ -540,7 +540,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Este rótulo ainda não contém quadrinhos
@@ -1062,8 +1062,8 @@ - Library '%1' is no longer available. Do you want to remove it? - A biblioteca '%1' não está mais disponível. Você quer removê-lo? + Library '%1' is no longer available. Do you want to remove it? + A biblioteca '%1' não está mais disponível. Você quer removê-lo? @@ -1072,8 +1072,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - A biblioteca '%1' foi criada com uma versão mais antiga do YACReaderLibrary. Deve ser criado novamente. Deseja criar a biblioteca agora? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + A biblioteca '%1' foi criada com uma versão mais antiga do YACReaderLibrary. Deve ser criado novamente. Deseja criar a biblioteca agora? @@ -1109,7 +1109,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Ocorreu um erro ao acessar o caminho da pasta @@ -1228,7 +1228,7 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. A pasta selecionada não contém nenhuma biblioteca. @@ -1323,8 +1323,8 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve - There is another library with the name '%1'. - Existe outra biblioteca com o nome '%1'. + There is another library with the name '%1'. + Existe outra biblioteca com o nome '%1'.
@@ -1777,12 +1777,12 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet Você ainda não tem nenhuma biblioteca - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Você pode criar uma biblioteca em qualquer pasta, YACReaderLibrary importará todos os quadrinhos e pastas desta pasta. Se você já criou alguma biblioteca, poderá abri-la.</p><p>Não se esqueça de que você pode usar o YACReader como um aplicativo independente para ler quadrinhos em seu computador.</p> @@ -1862,8 +1862,8 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve - Consider 'recent' items added or updated since X days ago - Considere itens 'recentes' adicionados ou atualizados há X dias + Consider 'recent' items added or updated since X days ago + Considere itens 'recentes' adicionados ou atualizados há X dias @@ -1949,11 +1949,11 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. AVISO! Durante as atualizações da biblioteca, as gravações no banco de dados são desativadas! Não agende atualizações enquanto estiver usando o aplicativo ativamente. @@ -2018,7 +2018,7 @@ Para interromper uma atualização automática, toque no indicador de carregamen Comic Flow - Fluxo de quadrinhos + Comic Flow @@ -2066,8 +2066,8 @@ Para interromper uma atualização automática, toque no indicador de carregamen - "Go to flow" size - Tamanho do "Ir para cheia" + "Go to flow" size + Tamanho de "Ir para Comic Flow" @@ -2462,8 +2462,8 @@ Para interromper uma atualização automática, toque no indicador de carregamen - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Link do Comic Vine: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> visualizar </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Link do Comic Vine: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> visualizar </a> @@ -2772,8 +2772,8 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - O YACReader está disponível para dispositivos iOS e Android.<br/>Descubra-o para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + O YACReader está disponível para dispositivos iOS e Android.<br/>Descubra-o para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2795,7 +2795,7 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Por favor, classifique a lista de quadrinhos à esquerda até que corresponda às informações dos quadrinhos. @@ -3047,8 +3047,8 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã - Press 'O' to open comic. - Pressione 'O' para abrir um quadrinho. + Press 'O' to open comic. + Pressione 'O' para abrir um quadrinho. @@ -3515,7 +3515,7 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã Show go to flow - Mostrar ir para o fluxo + Mostrar "Ir para Comic Flow" diff --git a/YACReaderLibrary/yacreaderlibrary_ru.ts b/YACReaderLibrary/yacreaderlibrary_ru.ts index 039989172..d24815c9c 100644 --- a/YACReaderLibrary/yacreaderlibrary_ru.ts +++ b/YACReaderLibrary/yacreaderlibrary_ru.ts @@ -122,8 +122,8 @@ - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Для подключения к Comic Vine вам потребуется ваш личный API ключ. Приобретите его бесплатно вот <a href="http://www.comicvine.com/api/">здесь</a> + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Для подключения к Comic Vine вам потребуется ваш личный API ключ. Приобретите его бесплатно вот <a href="http://www.comicvine.com/api/">здесь</a> @@ -276,7 +276,7 @@ Hide comic flow - Показать/скрыть поток комиксов + Скрыть Comic Flow @@ -567,8 +567,8 @@ - The shortcut "%1" is already assigned to other function - Сочетание клавиш "%1" уже назначено для другой функции + The shortcut "%1" is already assigned to other function + Сочетание клавиш "%1" уже назначено для другой функции @@ -592,7 +592,7 @@ - This folder doesn't contain comics yet + This folder doesn't contain comics yet В этой папке еще нет комиксов @@ -600,7 +600,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Этот ярлык пока ничего не содержит
@@ -927,7 +927,7 @@ - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. Выбранная папка не содержит ни одной библиотеки. @@ -1020,7 +1020,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Ошибка доступа к пути папки @@ -1072,8 +1072,8 @@ - Library '%1' is no longer available. Do you want to remove it? - Библиотека '%1' больше не доступна. Вы хотите удалить ее? + Library '%1' is no longer available. Do you want to remove it? + Библиотека '%1' больше не доступна. Вы хотите удалить ее? Update library @@ -1138,8 +1138,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Библиотека '%1' была создана старой версией YACReaderLibrary. Она должна быть вновь создана. Вы хотите создать библиотеку сейчас? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Библиотека '%1' была создана старой версией YACReaderLibrary. Она должна быть вновь создана. Вы хотите создать библиотеку сейчас? Pack covers @@ -1286,8 +1286,8 @@ YACReaderLibrary не помешает вам создать больше биб - There is another library with the name '%1'. - Уже существует другая папка с именем '%1'. + There is another library with the name '%1'. + Уже существует другая папка с именем '%1'. Remove reading list @@ -2001,12 +2001,12 @@ YACReaderLibrary не помешает вам создать больше биб - You don't have any libraries yet + You don't have any libraries yet У вас нет ни одной библиотеки - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Вы можете создать библиотеку в любой папке, YACReaderLibrary будет импортировать все комиксы и папки из этой папки. Если вы уже ранее создавали библиотеки, их можно будет открыть.< / p > <p>Не забывайте, что Вы можете использовать YACReader в качестве отдельного приложения для чтения комиксов на вашем компьютере.</п> @@ -2080,7 +2080,7 @@ YACReaderLibrary не помешает вам создать больше биб Comic Flow - Поток комиксов + Comic Flow @@ -2145,8 +2145,8 @@ YACReaderLibrary не помешает вам создать больше биб - Consider 'recent' items added or updated since X days ago - Учитывайте «недавние» элементы, добавленные или обновленные X дней назад. + Consider 'recent' items added or updated since X days ago + Учитывайте «недавние» элементы, добавленные или обновленные X дней назад. @@ -2232,11 +2232,11 @@ YACReaderLibrary не помешает вам создать больше биб WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. ПРЕДУПРЕЖДЕНИЕ! Во время обновления библиотеки запись в базу данных отключена! Не планируйте обновления, пока вы активно используете приложение. @@ -2285,8 +2285,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - "Go to flow" size - Размер потока страниц + "Go to flow" size + Размер "Перейти к Comic Flow" @@ -2684,8 +2684,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - <a style='color: ##666666; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Открыть страницу этого комикса на сайте Comic Vine </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + <a style='color: ##666666; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Открыть страницу этого комикса на сайте Comic Vine </a> @@ -2988,8 +2988,8 @@ YACReaderLibraryServer — это безголовая (без графичес Порт - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - <a href='http://ios.yacreader.com' style='color:rgb(102,102,102)'>YACReader доступен для устройств с iOS.</a> + YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> + <a href='http://ios.yacreader.com' style='color:rgb(102,102,102)'>YACReader доступен для устройств с iOS.</a> @@ -3019,8 +3019,8 @@ to improve the performance - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader доступен для устройств iOS и Android.<br/>Найдите его для <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> или <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader доступен для устройств iOS и Android.<br/>Найдите его для <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> или <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -3052,7 +3052,7 @@ to improve the performance - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Пожалуйста, отсортируйте список комиксов слева, пока он не будет соответствовать информации комикса.
@@ -3284,8 +3284,8 @@ to improve the performance - Press 'O' to open comic. - Нажмите "O" чтобы открыть комикс. + Press 'O' to open comic. + Нажмите "O" чтобы открыть комикс. @@ -3752,7 +3752,7 @@ to improve the performance Show go to flow - Показать поток страниц + Показать "Перейти к Comic Flow" diff --git a/YACReaderLibrary/yacreaderlibrary_tr.ts b/YACReaderLibrary/yacreaderlibrary_tr.ts index 0339a9641..78eb8d1f6 100644 --- a/YACReaderLibrary/yacreaderlibrary_tr.ts +++ b/YACReaderLibrary/yacreaderlibrary_tr.ts @@ -117,8 +117,8 @@ - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Comic Vine'a bağlanmadan önce kendi API anahtarınıza ihtiyacınız var. Lütfen <a href="http://www.comicvine.com/api/">buradan</a> ücretsiz bir tane edinin + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Comic Vine'a bağlanmadan önce kendi API anahtarınıza ihtiyacınız var. Lütfen <a href="http://www.comicvine.com/api/">buradan</a> ücretsiz bir tane edinin @@ -276,7 +276,7 @@ Hide comic flow - Çizgi roman akışını gizle + Comic Flow'u gizle
@@ -572,8 +572,8 @@ - The shortcut "%1" is already assigned to other function - "%1" kısayalou zaten başka bir işlev tarafından kullanılıyor + The shortcut "%1" is already assigned to other function + "%1" kısayalou zaten başka bir işlev tarafından kullanılıyor @@ -592,7 +592,7 @@ - This folder doesn't contain comics yet + This folder doesn't contain comics yet Bu klasör henüz çizgi roman içermiyor @@ -600,7 +600,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Bu etiket henüz çizgi roman içermiyor
@@ -927,7 +927,7 @@ - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. Seçilen dosya kütüphanede yok. @@ -959,7 +959,7 @@ Remove and delete metadata - Metadata'yı kaldır ve sil + Metadata'yı kaldır ve sil @@ -991,7 +991,7 @@ Open current comic on YACReader - YACReader'ı geçerli çizgi roman okuyucsu seç + YACReader'ı geçerli çizgi roman okuyucsu seç Update current library @@ -999,8 +999,8 @@ - Library '%1' is no longer available. Do you want to remove it? - Kütüphane '%1'ulaşılabilir değil. Kaldırmak ister misin? + Library '%1' is no longer available. Do you want to remove it? + Kütüphane '%1'ulaşılabilir değil. Kaldırmak ister misin? Update library @@ -1027,8 +1027,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Kütüphane '%1 YACRKütüphanenin eski bir sürümünde oluşturulmuş, Kütüphaneyi yeniden oluşturmak ister misin? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Kütüphane '%1 YACRKütüphanenin eski bir sürümünde oluşturulmuş, Kütüphaneyi yeniden oluşturmak ister misin? Pack covers @@ -1098,8 +1098,8 @@ - There is another library with the name '%1'. - Bu başka bir kütüphanenin adı '%1'. + There is another library with the name '%1'. + Bu başka bir kütüphanenin adı '%1'. @@ -1409,7 +1409,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Klasörün yoluna erişilirken hata oluştu @@ -1674,7 +1674,7 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü Open current comic on YACReader - YACReader'ı geçerli çizgi roman okuyucsu seç + YACReader'ı geçerli çizgi roman okuyucsu seç @@ -2058,12 +2058,12 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü - You don't have any libraries yet + You don't have any libraries yet Henüz bir kütüphaneye sahip değilsin - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Yeni bir kütüphane oluşturabilmeniçin kütüphane</p><p>No olvides que puedes usar YACReader como una aplicación independiente para leer los cómics en tu ordenador.</p> @@ -2146,12 +2146,12 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü Import metadata from ComicInfo.xml when adding new comics Import metada from ComicInfo.xml when adding new comics - Yeni çizgi roman eklerken meta verileri ComicInfo.xml'den içe aktarın + Yeni çizgi roman eklerken meta verileri ComicInfo.xml'den içe aktarın - Consider 'recent' items added or updated since X days ago - X gün öncesinden bu yana eklenen veya güncellenen 'en son' öğeleri göz önünde bulundurun + Consider 'recent' items added or updated since X days ago + X gün öncesinden bu yana eklenen veya güncellenen 'en son' öğeleri göz önünde bulundurun @@ -2237,11 +2237,11 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. UYARI! Kütüphane güncellemeleri sırasında veritabanına yazma işlemi devre dışı bırakılır! Uygulamayı aktif olarak kullanırken güncelleme planlamayın. @@ -2296,7 +2296,7 @@ Otomatik güncellemeyi durdurmak için Kitaplıklar başlığının yanındaki y Display current comic banner - Mevcut çizgi roman banner'ını görüntüle + Mevcut çizgi roman banner'ını görüntüle @@ -2306,7 +2306,7 @@ Otomatik güncellemeyi durdurmak için Kitaplıklar başlığının yanındaki y Comic Flow - Çizgi Roman Akışı + Comic Flow @@ -2342,8 +2342,8 @@ Otomatik güncellemeyi durdurmak için Kitaplıklar başlığının yanındaki y - "Go to flow" size - Akış görünümüne git + "Go to flow" size + "Comic Flow'a git" boyutu @@ -2772,8 +2772,8 @@ Otomatik güncellemeyi durdurmak için Kitaplıklar başlığının yanındaki y - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine bağlantısı: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> görüntüle </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine bağlantısı: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> görüntüle </a>
@@ -2786,7 +2786,7 @@ YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. This appplication supports persistent settings, to set them up edit this file %1 To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md -YACReaderLibraryServer, YACReaderLibrary'nin başsız (gui yok) sürümüdür. +YACReaderLibraryServer, YACReaderLibrary'nin başsız (gui yok) sürümüdür. Bu uygulama kalıcı ayarları destekler, bunları ayarlamak için bu dosyayı düzenleyin %1 Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md adresindeki belgelere bakın. @@ -2802,7 +2802,7 @@ Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubuserconte unable to load 7z lib from ./utils - ./utils'den 7z lib yüklenemiyor + ./utils'den 7z lib yüklenemiyor @@ -3104,12 +3104,12 @@ Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubuserconte - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader, iOS ve Android cihazlarda kullanılabilir.<br/>Bunu <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> veya <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a> için keşfedin. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader, iOS ve Android cihazlarda kullanılabilir.<br/>Bunu <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> veya <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a> için keşfedin. - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - YACReader, iOS cihazlar için kullanılabilir. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Keşfedin! </a> + YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> + YACReader, iOS cihazlar için kullanılabilir. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Keşfedin! </a> @@ -3131,7 +3131,7 @@ performansı iyileştirmek için SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Lütfen, çizgi romanların bilgileriyle eşleşene kadar soldaki çizgi roman listesini sıralayın. @@ -3383,8 +3383,8 @@ performansı iyileştirmek için - Press 'O' to open comic. - 'O'ya basarak aç. + Press 'O' to open comic. + 'O'ya basarak aç. @@ -3851,7 +3851,7 @@ performansı iyileştirmek için Show go to flow - Akışı göster + "Comic Flow'a git"i göster @@ -4103,7 +4103,7 @@ performansı iyileştirmek için YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary sistem tepsisinde çalışmaya devam edecektir. Programı sonlandırmak için sistem tepsisi simgesinin bağlam menüsünden <b>Çık</b>'ı seçin. + YACReaderLibrary sistem tepsisinde çalışmaya devam edecektir. Programı sonlandırmak için sistem tepsisi simgesinin bağlam menüsünden <b>Çık</b>'ı seçin. diff --git a/YACReaderLibrary/yacreaderlibrary_zh_CN.ts b/YACReaderLibrary/yacreaderlibrary_zh_CN.ts index f975c8e8a..2223ff004 100644 --- a/YACReaderLibrary/yacreaderlibrary_zh_CN.ts +++ b/YACReaderLibrary/yacreaderlibrary_zh_CN.ts @@ -122,8 +122,8 @@ - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - 你需要拥有自己的API密钥才能够连接Comic Vine. 你可以通过这个链接获得一个免费的<a href="http://www.comicvine.com/api/">API</a>密钥 + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要拥有自己的API密钥才能够连接Comic Vine. 你可以通过这个链接获得一个免费的<a href="http://www.comicvine.com/api/">API</a>密钥 @@ -276,7 +276,7 @@ Hide comic flow - 隐藏漫画流 + 隐藏 Comic Flow @@ -567,8 +567,8 @@ - The shortcut "%1" is already assigned to other function - 快捷键 "%1" 已被映射至其他功能 + The shortcut "%1" is already assigned to other function + 快捷键 "%1" 已被映射至其他功能 @@ -592,7 +592,7 @@ - This folder doesn't contain comics yet + This folder doesn't contain comics yet 该文件夹还没有漫画 @@ -600,7 +600,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet 此标签尚未包含漫画
@@ -934,7 +934,7 @@ - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. 所选文件夹不包含任何库。 @@ -1076,7 +1076,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path 访问文件夹的路径时出错 @@ -1128,8 +1128,8 @@ - Library '%1' is no longer available. Do you want to remove it? - 库 '%1' 不再可用。 你想删除它吗? + Library '%1' is no longer available. Do you want to remove it? + 库 '%1' 不再可用。 你想删除它吗? Update library @@ -1244,8 +1244,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - 库 '%1' 是通过旧版本的YACReaderLibrary创建的。 必须再次创建。 你想现在创建吗? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 库 '%1' 是通过旧版本的YACReaderLibrary创建的。 必须再次创建。 你想现在创建吗? Pack covers @@ -1409,8 +1409,8 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 - There is another library with the name '%1'. - 已存在另一个名为'%1'的库。 + There is another library with the name '%1'. + 已存在另一个名为'%1'的库。 Remove reading list @@ -2111,12 +2111,12 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 - You don't have any libraries yet + You don't have any libraries yet 你还没有库 - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>您可以在任何文件夹中创建库,YACReaderLibrary将导入此文件夹中的所有漫画和文件夹。如果已有库,则可以打开它们。</p><p>您可以把YACReader当成独立应用来阅读电脑上的漫画。</p> @@ -2329,7 +2329,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. 警告! 在库更新期间,将禁用对数据库的写入! @@ -2355,7 +2355,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago 参考自 X 天前添加或更新的“最近”项目 @@ -2371,7 +2371,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Comic Flow - 漫画流 + Comic Flow @@ -2395,8 +2395,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - "Go to flow" size - 页面流尺寸 + "Go to flow" size + “转到 Comic Flow”大小 @@ -2810,8 +2810,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine 连接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 连接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> @@ -3136,8 +3136,8 @@ YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 端口 - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - YACReader适用于iOS设备. <a href='http://ios.yacreader.com'style ='color:rgb(193,148,65)'>下载</a> + YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> + YACReader适用于iOS设备. <a href='http://ios.yacreader.com'style ='color:rgb(193,148,65)'>下载</a> @@ -3176,8 +3176,8 @@ to improve the performance - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader 适用于 iOS 和 Android 设备。<br/>搜索 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 适用于 iOS 和 Android 设备。<br/>搜索 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>.
@@ -3204,7 +3204,7 @@ to improve the performance - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. 请在左侧对漫画列表进行排序,直到它与漫画的信息相符。 @@ -3436,8 +3436,8 @@ to improve the performance - Press 'O' to open comic. - 按下 'O' 以打开漫画. + Press 'O' to open comic. + 按下 'O' 以打开漫画. @@ -3904,7 +3904,7 @@ to improve the performance Show go to flow - 显示页面流 + 显示“转到 Comic Flow” @@ -4044,7 +4044,7 @@ to improve the performance Toggle between fit to width and fit to height - 切换显示为"适应宽度"或"适应高度" + 切换显示为"适应宽度"或"适应高度" diff --git a/YACReaderLibrary/yacreaderlibrary_zh_HK.ts b/YACReaderLibrary/yacreaderlibrary_zh_HK.ts index 49114dc2a..fad7af818 100644 --- a/YACReaderLibrary/yacreaderlibrary_zh_HK.ts +++ b/YACReaderLibrary/yacreaderlibrary_zh_HK.ts @@ -113,8 +113,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 @@ -277,7 +277,7 @@ Hide comic flow - 隱藏漫畫流 + 隱藏 Comic Flow
@@ -573,8 +573,8 @@ - The shortcut "%1" is already assigned to other function - 快捷鍵 "%1" 已被映射至其他功能 + The shortcut "%1" is already assigned to other function + 快捷鍵 "%1" 已被映射至其他功能 @@ -593,7 +593,7 @@ - This folder doesn't contain comics yet + This folder doesn't contain comics yet 該資料夾還沒有漫畫 @@ -601,7 +601,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet 此標籤尚未包含漫畫
@@ -610,7 +610,7 @@ This reading list does not contain any comics yet - This reading list doesn't contain any comics yet + This reading list doesn't contain any comics yet 此閱讀列表尚未包含任何漫畫
@@ -1067,7 +1067,7 @@ Library not available - Library ' + Library ' 庫不可用 @@ -1282,8 +1282,8 @@ - Library '%1' is no longer available. Do you want to remove it? - 庫 '%1' 不再可用。 你想刪除它嗎? + Library '%1' is no longer available. Do you want to remove it? + 庫 '%1' 不再可用。 你想刪除它嗎? @@ -1292,8 +1292,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? @@ -1329,7 +1329,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path 訪問檔夾的路徑時出錯 @@ -1439,7 +1439,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. 所選檔夾不包含任何庫。 @@ -1581,8 +1581,8 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - There is another library with the name '%1'. - 已存在另一個名為'%1'的庫。 + There is another library with the name '%1'. + 已存在另一個名為'%1'的庫。
@@ -2066,12 +2066,12 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet 你還沒有庫 - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>您可以在任何檔夾中創建庫,YACReaderLibrary將導入此檔夾中的所有漫畫和文件夾。如果已有庫,則可以打開它們。</p><p>您可以把YACReader當成獨立應用來閱讀電腦上的漫畫。</p> @@ -2151,7 +2151,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago 考慮自 X 天前新增或更新的「最近」項目 @@ -2238,11 +2238,11 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. 警告!在庫更新期間,將停用對資料庫的寫入! 當您可能正在積極使用應用程式時,請勿安排更新。 @@ -2307,7 +2307,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Comic Flow - 漫畫流 + Comic Flow @@ -2355,8 +2355,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - "Go to flow" size - 頁面流尺寸 + "Go to flow" size + 「前往 Comic Flow」大小 @@ -2766,8 +2766,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> @@ -3108,12 +3108,12 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - YACReader適用於iOS設備. <a href='http://ios.yacreader.com'style ='color:rgb(193,148,65)'>下載</a> + YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> + YACReader適用於iOS設備. <a href='http://ios.yacreader.com'style ='color:rgb(193,148,65)'>下載</a> @@ -3145,7 +3145,7 @@ to improve the performance SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. 請在左側對漫畫列表進行排序,直到它與漫畫的資訊相符。 @@ -3397,8 +3397,8 @@ to improve the performance - Press 'O' to open comic. - 按下 'O' 以打開漫畫. + Press 'O' to open comic. + 按下 'O' 以打開漫畫. @@ -3865,7 +3865,7 @@ to improve the performance Show go to flow - 顯示頁面流 + 顯示「前往 Comic Flow」 @@ -4005,7 +4005,7 @@ to improve the performance Toggle between fit to width and fit to height - 切換顯示為"適應寬度"或"適應高度" + 切換顯示為"適應寬度"或"適應高度" diff --git a/YACReaderLibrary/yacreaderlibrary_zh_TW.ts b/YACReaderLibrary/yacreaderlibrary_zh_TW.ts index ffb428bed..0320b163d 100644 --- a/YACReaderLibrary/yacreaderlibrary_zh_TW.ts +++ b/YACReaderLibrary/yacreaderlibrary_zh_TW.ts @@ -113,8 +113,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 @@ -277,7 +277,7 @@ Hide comic flow - 隱藏漫畫流 + 隱藏 Comic Flow @@ -573,8 +573,8 @@ - The shortcut "%1" is already assigned to other function - 快捷鍵 "%1" 已被映射至其他功能 + The shortcut "%1" is already assigned to other function + 快捷鍵 "%1" 已被映射至其他功能 @@ -593,7 +593,7 @@ - This folder doesn't contain comics yet + This folder doesn't contain comics yet 該資料夾還沒有漫畫 @@ -601,7 +601,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet 此標籤尚未包含漫畫
@@ -610,7 +610,7 @@ This reading list does not contain any comics yet - This reading list doesn't contain any comics yet + This reading list doesn't contain any comics yet 此閱讀列表尚未包含任何漫畫
@@ -1067,7 +1067,7 @@ Library not available - Library ' + Library ' 庫不可用 @@ -1282,8 +1282,8 @@ - Library '%1' is no longer available. Do you want to remove it? - 庫 '%1' 不再可用。 你想刪除它嗎? + Library '%1' is no longer available. Do you want to remove it? + 庫 '%1' 不再可用。 你想刪除它嗎? @@ -1292,8 +1292,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? @@ -1329,7 +1329,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path 訪問檔夾的路徑時出錯 @@ -1439,7 +1439,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. 所選檔夾不包含任何庫。 @@ -1581,8 +1581,8 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - There is another library with the name '%1'. - 已存在另一個名為'%1'的庫。 + There is another library with the name '%1'. + 已存在另一個名為'%1'的庫。
@@ -2066,12 +2066,12 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet 你還沒有庫 - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>您可以在任何檔夾中創建庫,YACReaderLibrary將導入此檔夾中的所有漫畫和文件夾。如果已有庫,則可以打開它們。</p><p>您可以把YACReader當成獨立應用來閱讀電腦上的漫畫。</p> @@ -2151,7 +2151,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago 考慮自 X 天前新增或更新的「最近」項目 @@ -2238,11 +2238,11 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. To stop an automatic update tap on the loading indicator next to the Libraries title. 警告!在庫更新期間,將停用對資料庫的寫入! 當您可能正在積極使用應用程式時,請勿安排更新。 @@ -2307,7 +2307,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Comic Flow - 漫畫流 + Comic Flow @@ -2355,8 +2355,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - "Go to flow" size - 頁面流尺寸 + "Go to flow" size + 「前往 Comic Flow」大小 @@ -2766,8 +2766,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> @@ -3108,12 +3108,12 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 - YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> - YACReader適用於iOS設備. <a href='http://ios.yacreader.com'style ='color:rgb(193,148,65)'>下載</a> + YACReader is available for iOS devices. <a href='http://ios.yacreader.com' style='color:rgb(193, 148, 65)'> Discover it! </a> + YACReader適用於iOS設備. <a href='http://ios.yacreader.com'style ='color:rgb(193,148,65)'>下載</a> @@ -3145,7 +3145,7 @@ to improve the performance SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. 請在左側對漫畫列表進行排序,直到它與漫畫的資訊相符。 @@ -3397,8 +3397,8 @@ to improve the performance - Press 'O' to open comic. - 按下 'O' 以打開漫畫. + Press 'O' to open comic. + 按下 'O' 以打開漫畫. @@ -3865,7 +3865,7 @@ to improve the performance Show go to flow - 顯示頁面流 + 顯示「前往 Comic Flow」 @@ -4005,7 +4005,7 @@ to improve the performance Toggle between fit to width and fit to height - 切換顯示為"適應寬度"或"適應高度" + 切換顯示為"適應寬度"或"適應高度" diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_de.ts b/YACReaderLibraryServer/yacreaderlibraryserver_de.ts index f3726463e..00b49974a 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_de.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_de.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Bevor du dich mit Comic Vine verbindest, brauchst du deinen eigenen API-Schlüssel. Du kannst <a href="http://www.comicvine.com/api/">hier</a> einen kostenlosen bekommen. + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Bevor du dich mit Comic Vine verbindest, brauchst du deinen eigenen API-Schlüssel. Du kannst <a href="http://www.comicvine.com/api/">hier</a> einen kostenlosen bekommen. @@ -228,7 +228,7 @@ Hide comic flow - Comic "Flow" verstecken + Comic Flow ausblenden @@ -441,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - Das Kürzel "%1" ist bereits für eine andere Funktion in Verwendung + The shortcut "%1" is already assigned to other function + Das Kürzel "%1" ist bereits für eine andere Funktion in Verwendung EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Dieser Ordner enthält noch keine Comics @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Dieses Label enthält noch keine Comics
@@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - Bibliothek '%1' ist nicht mehr verfügbar. Wollen Sie sie entfernen? + Library '%1' is no longer available. Do you want to remove it? + Bibliothek '%1' ist nicht mehr verfügbar. Wollen Sie sie entfernen? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Bibliothek '%1' wurde mit einer älteren Version von YACReader erstellt. Sie muss neu erzeugt werden. Wollen Sie die Bibliothek jetzt erzeugen? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Bibliothek '%1' wurde mit einer älteren Version von YACReader erstellt. Sie muss neu erzeugt werden. Wollen Sie die Bibliothek jetzt erzeugen? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Beim Aufrufen des Ordnerpfades kam es zu einem Fehler @@ -1036,7 +1036,8 @@ You probably only need one library in your top level comics folder, you can brow YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. Sie fügen zu viele Bibliotheken hinzu. - Wahrscheinlich brauchen Sie nur eine Bibliothek in Ihrem obersten Comic-Ordner, Sie können alle Unterordner mit Hilfe des Ordnerbereichs in der linken Seitenleiste durchsuchen. + +Wahrscheinlich brauchen Sie nur eine Bibliothek in Ihrem obersten Comic-Ordner, Sie können alle Unterordner mit Hilfe des Ordnerbereichs in der linken Seitenleiste durchsuchen. YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen, aber Sie sollten die Anzahl der Bibliotheken gering halten. @@ -1073,7 +1074,7 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. Der ausgewählte Ordner enthält keine Bibliothek. @@ -1178,8 +1179,8 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen - There is another library with the name '%1'. - Es gibt bereits eine Bibliothek mit dem Namen '%1'. + There is another library with the name '%1'. + Es gibt bereits eine Bibliothek mit dem Namen '%1'.
@@ -1632,12 +1633,12 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet Sie haben aktuell noch keine Bibliothek - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Sie können eine Bibliothek in jedem beliebigen Ordner erstellen, YACReaderLibrary wird alle Comics und Unterordner von diesem Ordner importieren. Wenn Sie bereits eine Bibliothek erstellt haben, können Sie sie öffnen.</p><p>Vergessen Sie nicht, dass Sie YACReader als eigentsändige Anwendung nutzen können, um Comics auf Ihrem Computer zu lesen.</p> @@ -1676,7 +1677,7 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen Comic Flow - Comic-Flow + Comic Flow @@ -1750,7 +1751,7 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago Berücksichtigen Sie „neue“ Elemente, die seit X Tagen hinzugefügt oder aktualisiert wurden @@ -1837,7 +1838,7 @@ YACReaderLibrary wird Sie nicht daran hindern, weitere Bibliotheken zu erstellen WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WARNUNG! Während Bibliotheksaktualisierungen sind Schreibvorgänge in die Datenbank deaktiviert! @@ -1917,8 +1918,8 @@ Um eine automatische Aktualisierung zu stoppen, tippen Sie auf die Ladeanzeige n - "Go to flow" size - "Go to flow" Größe + "Go to flow" size + Größe von "Gehe zu Comic Flow" @@ -2313,8 +2314,8 @@ Um eine automatische Aktualisierung zu stoppen, tippen Sie auf die Ladeanzeige n - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine-Link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ansehen </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine-Link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ansehen </a> @@ -2622,8 +2623,8 @@ Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Do - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader ist für iOS- und Android-Geräte verfügbar.<br/>Entdecken Sie es für <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> oder <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader ist für iOS- und Android-Geräte verfügbar.<br/>Entdecken Sie es für <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> oder <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2645,7 +2646,7 @@ Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Do SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Sortieren Sie bitte die Comic-Informationen links, bis die Informationen mit den Comics übereinstimmen. @@ -2897,8 +2898,8 @@ Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Do - Press 'O' to open comic. - 'O' drücken, um Comic zu öffnen. + Press 'O' to open comic. + 'O' drücken, um Comic zu öffnen. @@ -3365,7 +3366,7 @@ Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Do Show go to flow - "Go to Flow" anzeigen + "Gehe zu Comic Flow" anzeigen diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_es.ts b/YACReaderLibraryServer/yacreaderlibraryserver_es.ts index b4d17cb38..b7b49cab0 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_es.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_es.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Antes de que te puedas conectar a Comic Vine necesitas tu propia clave API. Por favor, obtén una gratis <a href="http://www.comicvine.com/api/">aquí</a> + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Antes de que te puedas conectar a Comic Vine necesitas tu propia clave API. Por favor, obtén una gratis <a href="http://www.comicvine.com/api/">aquí</a> @@ -179,7 +179,8 @@ Could not import theme from: %1 - No se pudo importar el tema desde:\n%1 + No se pudo importar el tema desde: +%1 @@ -187,7 +188,10 @@ %1 %2 - No se pudo importar el tema desde:\n%1\n\n%2 + No se pudo importar el tema desde: +%1 + +%2 @@ -224,7 +228,7 @@ Hide comic flow - Ocultar cómic flow + Ocultar Comic Flow @@ -437,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - El acceso directo "%1" ya está asignado a otra función + The shortcut "%1" is already assigned to other function + El acceso directo "%1" ya está asignado a otra función EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Esta carpeta aún no contiene cómics @@ -453,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Esta etiqueta aún no contiene ningún cómic
@@ -866,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - La biblioteca '%1' no está disponible. ¿Deseas eliminarla? + Library '%1' is no longer available. Do you want to remove it? + La biblioteca '%1' no está disponible. ¿Deseas eliminarla? @@ -876,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - La biblioteca '%1' ha sido creada con una versión más antigua de YACReaderLibrary y debe ser creada de nuevo. ¿Deseas crear la biblioteca ahora? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La biblioteca '%1' ha sido creada con una versión más antigua de YACReaderLibrary y debe ser creada de nuevo. ¿Deseas crear la biblioteca ahora? @@ -918,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Hubo un error al acceder a la ruta de la carpeta @@ -1031,7 +1035,11 @@ You probably only need one library in your top level comics folder, you can browse any subfolders using the folders section in the left sidebar. YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. - Estás añadiendo demasiadas bibliotecas.\n\nProbablemente solo necesites una biblioteca en la carpeta principal de tus cómics, puedes explorar cualquier subcarpeta utilizando la sección de carpetas en la barra lateral izquierda.\n\nYACReaderLibrary no te detendrá de crear más bibliotecas, pero deberías mantener el número de bibliotecas bajo control. + Estás añadiendo demasiadas bibliotecas. + +Probablemente solo necesites una biblioteca en la carpeta principal de tus cómics, puedes explorar cualquier subcarpeta utilizando la sección de carpetas en la barra lateral izquierda. + +YACReaderLibrary no te detendrá de crear más bibliotecas, pero deberías mantener el número de bibliotecas bajo control. @@ -1066,7 +1074,7 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. La carpeta seleccionada no contiene ninguna biblioteca. @@ -1171,8 +1179,8 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - There is another library with the name '%1'. - Hay otra biblioteca con el nombre '%1'. + There is another library with the name '%1'. + Hay otra biblioteca con el nombre '%1'.
@@ -1625,12 +1633,12 @@ YACReaderLibrary will not stop you from creating more libraries but you should k NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet Aún no tienes ninguna biblioteca - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Puedes crear una biblioteca en cualquier carpeta, YACReaderLibrary importará todos las carpetas y cómics de esa carpeta. Si has creado alguna biblioteca anteriormente, puedes abrirla sin volver a crearla.</p><p>No olvides que puedes usar YACReader como una aplicación independiente para leer los cómics en tu ordenador.</p> @@ -1669,7 +1677,7 @@ YACReaderLibrary will not stop you from creating more libraries but you should k Comic Flow - Flujo cómico + Comic Flow @@ -1743,8 +1751,8 @@ YACReaderLibrary will not stop you from creating more libraries but you should k - Consider 'recent' items added or updated since X days ago - Considerar elementos 'recientes' añadidos o actualizados desde hace X días + Consider 'recent' items added or updated since X days ago + Considerar elementos 'recientes' añadidos o actualizados desde hace X días @@ -1830,10 +1838,13 @@ YACReaderLibrary will not stop you from creating more libraries but you should k WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. - ¡ADVERTENCIA! Durante las actualizaciones de la biblioteca se desactivan las escrituras en la base de datos. No programes actualizaciones mientras puedas estar usando la aplicación activamente. Durante las actualizaciones automáticas, la aplicación bloqueará algunas de las acciones hasta que la actualización esté terminada. Para detener una actualización automática, toca en el indicador de carga junto al título de Bibliotecas. + ¡ADVERTENCIA! Durante las actualizaciones de la biblioteca se desactivan las escrituras en la base de datos. +No programes actualizaciones mientras puedas estar usando la aplicación activamente. +Durante las actualizaciones automáticas, la aplicación bloqueará algunas de las acciones hasta que la actualización esté terminada. +Para detener una actualización automática, toca en el indicador de carga junto al título de Bibliotecas. @@ -1878,7 +1889,7 @@ To stop an automatic update tap on the loading indicator next to the Libraries t Display continue reading banner - Mostrar banner de "Continuar leyendo" + Mostrar banner de "Continuar leyendo" @@ -1907,8 +1918,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - "Go to flow" size - Tamaño de "Go to flow" + "Go to flow" size + Tamaño de "Ir a Comic Flow" @@ -2303,8 +2314,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ver </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> ver </a> @@ -2346,7 +2357,11 @@ YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. This appplication supports persistent settings, to set them up edit this file %1 To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md - \nYACReaderLibraryServer es la versión sin interfaz gráfica (headless) de YACReaderLibrary.\n\nEsta aplicación admite ajustes persistentes; para configurarlos, edita este archivo %1\nPara conocer los ajustes disponibles, consulta la documentación en https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md + +YACReaderLibraryServer es la versión sin interfaz gráfica (headless) de YACReaderLibrary. + +Esta aplicación admite ajustes persistentes; para configurarlos, edita este archivo %1 +Para conocer los ajustes disponibles, consulta la documentación en https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md @@ -2608,8 +2623,8 @@ To learn about the available settings please check the documentation at https:// - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader está disponible para iOS y Android.<br/> Descúbrela para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a>o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader está disponible para iOS y Android.<br/> Descúbrela para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a>o <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2631,7 +2646,7 @@ To learn about the available settings please check the documentation at https:// SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Por favor, ordena la lista de cómics en la izquiera hasta que coincida con la información adecuada. @@ -2817,7 +2832,8 @@ To learn about the available settings please check the documentation at https:// Could not open file for writing: %1 - No se pudo abrir el archivo para escribir:\n%1 + No se pudo abrir el archivo para escribir: +%1 @@ -2835,13 +2851,15 @@ To learn about the available settings please check the documentation at https:// Could not open file: %1 - No se pudo abrir el archivo:\n%1 + No se pudo abrir el archivo: +%1 Invalid JSON: %1 - JSON no válido:\n%1 + JSON no válido: +%1 @@ -2880,8 +2898,8 @@ To learn about the available settings please check the documentation at https:// - Press 'O' to open comic. - Pulsa 'O' para abrir un fichero. + Press 'O' to open comic. + Pulsa 'O' para abrir un fichero. @@ -3348,7 +3366,7 @@ To learn about the available settings please check the documentation at https:// Show go to flow - Mostrar flow ir a + Mostrar "Ir a Comic Flow" diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_fr.ts b/YACReaderLibraryServer/yacreaderlibraryserver_fr.ts index f0aa9106d..7b9897884 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_fr.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_fr.ts @@ -14,7 +14,7 @@ Label name: - Nom de l'étiquette : + Nom de l'étiquette : @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Avant de pouvoir vous connecter à Comic Vine, vous avez besoin de votre propre clé API. Veuillez en obtenir une gratuitement ici: <a href="http://www.comicvine.com/api/"></a> + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Avant de pouvoir vous connecter à Comic Vine, vous avez besoin de votre propre clé API. Veuillez en obtenir une gratuitement ici: <a href="http://www.comicvine.com/api/"></a> @@ -118,7 +118,7 @@ Remove this user-imported theme - Supprimer ce thème importé par l'utilisateur + Supprimer ce thème importé par l'utilisateur @@ -153,17 +153,17 @@ Open Theme Editor... - Ouvrir l'éditeur de thème... + Ouvrir l'éditeur de thème... Theme editor error - Erreur de l'éditeur de thème + Erreur de l'éditeur de thème The current theme JSON could not be loaded. - Le thème actuel JSON n'a pas pu être chargé. + Le thème actuel JSON n'a pas pu être chargé. @@ -179,7 +179,7 @@ Could not import theme from: %1 - Impossible d'importer le thème depuis : + Impossible d'importer le thème depuis : %1 @@ -188,7 +188,7 @@ %1 %2 - Impossible d'importer le thème depuis : + Impossible d'importer le thème depuis : %1 %2 @@ -196,7 +196,7 @@ Import failed - Échec de l'importation + Échec de l'importation @@ -228,7 +228,7 @@ Hide comic flow - Cacher le flux de bande dessinée + Masquer Comic Flow @@ -296,7 +296,7 @@ Story Arc - Arc d'histoire + Arc d'histoire @@ -399,7 +399,7 @@ Create a library could take several minutes. You can stop the process and update the library later for completing the task. - La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et continuer plus tard. + La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et continuer plus tard. @@ -414,7 +414,7 @@ The selected path does not exist or is not a valid path. Be sure that you have write access to this folder - Le chemin sélectionné n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + Le chemin sélectionné n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier @@ -437,19 +437,19 @@ Shortcut in use - Raccourci en cours d'utilisation + Raccourci en cours d'utilisation - The shortcut "%1" is already assigned to other function - Le raccourci "%1" est déjà affecté à une autre fonction + The shortcut "%1" is already assigned to other function + Le raccourci "%1" est déjà affecté à une autre fonction EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Ce dossier ne contient pas encore de bandes dessinées @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Ce dossier ne contient pas encore de bandes dessinées
@@ -484,7 +484,7 @@ There are no recent comics! - Il n'y a pas de BD récente ! + Il n'y a pas de BD récente !
@@ -517,12 +517,12 @@ Problem found while writing - Problème durant l'écriture + Problème durant l'écriture The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier @@ -550,12 +550,12 @@ Problem found while writing - Problème durant l'écriture + Problème durant l'écriture The selected path for the output file does not exist or is not a valid path. Be sure that you have write access to this folder - Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier + Le chemin sélectionné pour le fichier n'existe pas ou contient un chemin invalide. Assurez-vous d'avoir les droits d'accès à ce dossier @@ -568,12 +568,12 @@ CRC error on page (%1): some of the pages will not be displayed correctly - Erreur CRC sur la page (%1): certaines pages ne s'afficheront pas correctement + Erreur CRC sur la page (%1): certaines pages ne s'afficheront pas correctement Unknown error opening the file - Erreur inconnue lors de l'ouverture du fichier + Erreur inconnue lors de l'ouverture du fichier @@ -735,7 +735,7 @@ <p>YACReaderLibrary is now creating a new library.</p><p>Create a library could take several minutes. You can stop the process and update the library later for completing the task.</p> - <p>YACReaderLibrary est en train de créer une nouvelle librairie.</p><p>La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et poursuivre plus tard.</p> + <p>YACReaderLibrary est en train de créer une nouvelle librairie.</p><p>La création d'une librairie peut prendre quelques minutes. Vous pouvez arrêter le processus et poursuivre plus tard.</p> @@ -765,7 +765,7 @@ <p>Current library is being scanned for legacy XML metadata information.</p><p>This is only needed once, and only if the library was crated with YACReaderLibrary 9.8.2 or earlier.</p> - <p>La bibliothèque actuelle est en cours d'analyse pour rechercher des informations sur les métadonnées XML héritées.</p><p>Ceci n'est nécessaire qu'une seule fois, et uniquement si la bibliothèque a été créée avec YACReaderLibrary 9.8.2 ou une version antérieure.</p> + <p>La bibliothèque actuelle est en cours d'analyse pour rechercher des informations sur les métadonnées XML héritées.</p><p>Ceci n'est nécessaire qu'une seule fois, et uniquement si la bibliothèque a été créée avec YACReaderLibrary 9.8.2 ou une version antérieure.</p> @@ -841,7 +841,7 @@ There were errors during library upgrade in: - Des erreurs se sont produites lors de la mise à niveau de la bibliothèque dans : + Des erreurs se sont produites lors de la mise à niveau de la bibliothèque dans : @@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - La librarie '%1' n'est plus disponible. Voulez-vous la supprimer? + Library '%1' is no longer available. Do you want to remove it? + La librarie '%1' n'est plus disponible. Voulez-vous la supprimer? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - La librarie '%1' a été créée avec une ancienne version de YACReaderLibrary. Elle doit être re-créée. Voulez-vous créer la librairie? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + La librarie '%1' a été créée avec une ancienne version de YACReaderLibrary. Elle doit être re-créée. Voulez-vous créer la librairie? @@ -903,7 +903,7 @@ Folder name: - Nom du dossier : + Nom du dossier : @@ -913,7 +913,7 @@ Please, select a folder first - Veuillez d'abord sélectionner un dossier + Veuillez d'abord sélectionner un dossier @@ -922,8 +922,8 @@ - There was an error accessing the folder's path - Une erreur s'est produite lors de l'accès au chemin du dossier + There was an error accessing the folder's path + Une erreur s'est produite lors de l'accès au chemin du dossier @@ -944,7 +944,7 @@ There was an issue trying to delete the selected folders. Please, check for write permissions and be sure that any applications are using these folders or any of the contained files. - Un problème est survenu lors de la tentative de suppression des dossiers sélectionnés. Veuillez vérifier les autorisations d'écriture et assurez-vous que toutes les applications utilisent ces dossiers ou l'un des fichiers contenus. + Un problème est survenu lors de la tentative de suppression des dossiers sélectionnés. Veuillez vérifier les autorisations d'écriture et assurez-vous que toutes les applications utilisent ces dossiers ou l'un des fichiers contenus. @@ -955,17 +955,17 @@ List name: - Nom de la liste : + Nom de la liste : Delete list/label - Supprimer la liste/l'étiquette + Supprimer la liste/l'étiquette The selected item will be deleted, your comics or folders will NOT be deleted from your disk. Are you sure? - L'élément sélectionné sera supprimé, vos bandes dessinées ou dossiers ne seront pas supprimés de votre disque. Êtes-vous sûr? + L'élément sélectionné sera supprimé, vos bandes dessinées ou dossiers ne seront pas supprimés de votre disque. Êtes-vous sûr? @@ -1037,7 +1037,7 @@ You probably only need one library in your top level comics folder, you can brow YACReaderLibrary will not stop you from creating more libraries but you should keep the number of libraries low. Vous ajoutez trop de bibliothèques. -Vous n'avez probablement besoin que d'une bibliothèque dans votre dossier BD de niveau supérieur, vous pouvez parcourir les sous-dossiers en utilisant la section des dossiers dans la barre latérale gauche. +Vous n'avez probablement besoin que d'une bibliothèque dans votre dossier BD de niveau supérieur, vous pouvez parcourir les sous-dossiers en utilisant la section des dossiers dans la barre latérale gauche. YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais vous devriez garder le nombre de bibliothèques bas. @@ -1055,7 +1055,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v YACReader not found. There might be a problem with your YACReader installation. - YACReader introuvable. Il se peut qu'il y ait un problème avec votre installation de YACReader. + YACReader introuvable. Il se peut qu'il y ait un problème avec votre installation de YACReader. @@ -1065,7 +1065,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Error opening comic with third party reader. - Erreur lors de l'ouverture de la bande dessinée avec un lecteur tiers. + Erreur lors de l'ouverture de la bande dessinée avec un lecteur tiers. @@ -1074,7 +1074,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. Le dossier sélectionné ne contient aucune librairie. @@ -1105,7 +1105,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v There was an issue trying to delete the selected comics. Please, check for write permissions in the selected files or containing folder. - Un problème est survenu lors de la tentative de suppression des bandes dessinées sélectionnées. Veuillez vérifier les autorisations d'écriture dans les fichiers sélectionnés ou le dossier contenant. + Un problème est survenu lors de la tentative de suppression des bandes dessinées sélectionnées. Veuillez vérifier les autorisations d'écriture dans les fichiers sélectionnés ou le dossier contenant. @@ -1115,7 +1115,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Assign numbers starting in: - Attribuez des numéros commençant par : + Attribuez des numéros commençant par : @@ -1125,17 +1125,17 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v The selected file is not a valid image. - Le fichier sélectionné n'est pas une image valide. + Le fichier sélectionné n'est pas une image valide. Error saving cover - Erreur lors de l'enregistrement de la couverture + Erreur lors de l'enregistrement de la couverture There was an error saving the cover image. - Une erreur s'est produite lors de l'enregistrement de l'image de couverture. + Une erreur s'est produite lors de l'enregistrement de l'image de couverture. @@ -1150,7 +1150,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Error opening the library - Erreur lors de l'ouverture de la librairie + Erreur lors de l'ouverture de la librairie @@ -1179,8 +1179,8 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v - There is another library with the name '%1'. - Une autre librairie a le nom '%1'. + There is another library with the name '%1'. + Une autre librairie a le nom '%1'. @@ -1339,7 +1339,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Set issue as normal - Définir le problème comme d'habitude + Définir le problème comme d'habitude @@ -1386,12 +1386,12 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Show/Hide recent indicator - Afficher/Masquer l'indicateur récent + Afficher/Masquer l'indicateur récent Show or hide recent indicator - Afficher ou masquer l'indicateur récent + Afficher ou masquer l'indicateur récent @@ -1493,7 +1493,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Reset comic rating - Supprimer la note d'évaluation + Supprimer la note d'évaluation @@ -1508,7 +1508,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Assign current order to comics - Assigner l'ordre actuel aux bandes dessinées + Assigner l'ordre actuel aux bandes dessinées @@ -1633,13 +1633,13 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v NoLibrariesWidget - You don't have any libraries yet - Vous n'avez pas encore de librairie + You don't have any libraries yet + Vous n'avez pas encore de librairie - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> - <p>Vous pouvez creer une librairie dans n'importe quel dossierr, YACReaderLibrary importera les dossiers et les bandes dessinées contenus dans ce dossier. Si vous avez déjà crer des librairies, vous pouvez les ouvrir.</p><p>N'oubliez pas que vous pouvez utiliser YACReader en tant que stand alone pour lire vos bandes dessinées sur votre ordinateur.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>Vous pouvez creer une librairie dans n'importe quel dossierr, YACReaderLibrary importera les dossiers et les bandes dessinées contenus dans ce dossier. Si vous avez déjà crer des librairies, vous pouvez les ouvrir.</p><p>N'oubliez pas que vous pouvez utiliser YACReader en tant que stand alone pour lire vos bandes dessinées sur votre ordinateur.</p> @@ -1677,7 +1677,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Comic Flow - Flux comique + Comic Flow @@ -1706,7 +1706,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Application language - Langue de l'application + Langue de l'application @@ -1717,7 +1717,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Tray icon settings (experimental) - Paramètres de l'icône de la barre d'état (expérimental) + Paramètres de l'icône de la barre d'état (expérimental) @@ -1727,7 +1727,7 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Start into the system tray - Commencez dans la barre d'état système + Commencez dans la barre d'état système @@ -1747,11 +1747,11 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v Import metadata from ComicInfo.xml when adding new comics - Importer des métadonnées depuis ComicInfo.xml lors de l'ajout de nouvelles bandes dessinées + Importer des métadonnées depuis ComicInfo.xml lors de l'ajout de nouvelles bandes dessinées - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago Considérez les éléments « récents » ajoutés ou mis à jour depuis X jours @@ -1838,13 +1838,13 @@ YACReaderLibrary ne vous empêchera pas de créer plus de bibliothèques, mais v WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. - AVERTISSEMENT! Lors des mises à jour de la bibliothèque, les écritures dans la base de données sont désactivées ! -Ne planifiez pas de mises à jour pendant que vous utilisez activement l'application. -Lors des mises à jour automatiques, l'application bloquera certaines actions jusqu'à ce que la mise à jour soit terminée. -Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de chargement à côté du titre Bibliothèques. + AVERTISSEMENT! Lors des mises à jour de la bibliothèque, les écritures dans la base de données sont désactivées ! +Ne planifiez pas de mises à jour pendant que vous utilisez activement l'application. +Lors des mises à jour automatiques, l'application bloquera certaines actions jusqu'à ce que la mise à jour soit terminée. +Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de chargement à côté du titre Bibliothèques. @@ -1854,17 +1854,17 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Compare the modified date of files when updating a library (not recommended) - Comparer la date de modification des fichiers lors de la mise à jour d'une bibliothèque (déconseillé) + Comparer la date de modification des fichiers lors de la mise à jour d'une bibliothèque (déconseillé) Enable background image - Activer l'image d'arrière-plan + Activer l'image d'arrière-plan Opacity level - Niveau d'opacité + Niveau d'opacité @@ -1914,17 +1914,17 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Show time in current page information label - Afficher l'heure dans l'étiquette d'information de la page actuelle + Afficher l'heure dans l'étiquette d'information de la page actuelle - "Go to flow" size - Taille du flux + "Go to flow" size + Taille de "Aller à Comic Flow" Background color - Couleur d'arrière plan + Couleur d'arrière plan @@ -1969,7 +1969,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Click left or right half of the screen to turn pages. - Cliquez sur la moitié gauche ou droite de l'écran pour tourner les pages. + Cliquez sur la moitié gauche ou droite de l'écran pour tourner les pages. @@ -1979,7 +1979,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Disable mouse over activation - Désactiver la souris sur l'activation + Désactiver la souris sur l'activation @@ -2004,12 +2004,12 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Image options - Option de l'image + Option de l'image Fit options - Options d'ajustement + Options d'ajustement @@ -2029,12 +2029,12 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Scaling - Mise à l'échelle + Mise à l'échelle Scaling method - Méthode de mise à l'échelle + Méthode de mise à l'échelle @@ -2059,7 +2059,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Image adjustment - Ajustement de l'image + Ajustement de l'image @@ -2118,7 +2118,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Reset cover to the default image - Réinitialiser la couverture à l'image par défaut + Réinitialiser la couverture à l'image par défaut @@ -2170,12 +2170,12 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Alternate series: - Série alternative : + Série alternative : Series Group: - Groupe de séries : + Groupe de séries : @@ -2220,7 +2220,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Editor(s): - Editeur(s) : + Editeur(s) : @@ -2260,7 +2260,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Age rating: - Limite d'âge: + Limite d'âge: @@ -2270,7 +2270,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Language (ISO): - Langue (ISO) : + Langue (ISO) : @@ -2285,17 +2285,17 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Teams: - Équipes : + Équipes : Locations: - Emplacements : + Emplacements : Main character or team: - Personnage principal ou équipe : + Personnage principal ou équipe : @@ -2305,17 +2305,17 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha Notes: - Remarques : + Remarques : Tags: - Balises : + Balises : - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Lien Comic Vine : <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> vue </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Lien Comic Vine : <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> vue </a> @@ -2345,7 +2345,7 @@ Pour arrêter une mise à jour automatique, appuyez sur l'indicateur de cha The image is invalid. - L'image n'est pas valide. + L'image n'est pas valide. @@ -2419,7 +2419,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum The file could not be read or is not valid JSON. - Le fichier n'a pas pu être lu ou n'est pas un JSON valide. + Le fichier n'a pas pu être lu ou n'est pas un JSON valide. @@ -2481,7 +2481,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Number of %1 found : %2 - Nombre de %1 trouvés : %2 + Nombre de %1 trouvés : %2 @@ -2619,12 +2619,12 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Scan it! - Scannez-le ! + Scannez-le ! - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader est disponible pour les appareils iOS et Android.<br/>Découvrez-le pour <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader est disponible pour les appareils iOS et Android.<br/>Découvrez-le pour <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2646,13 +2646,13 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. - Veuillez trier la liste des bandes dessinées sur la gauche jusqu'à ce qu'elle corresponde aux informations des bandes dessinées. + Please, sort the list of comics on the left until it matches the comics' information. + Veuillez trier la liste des bandes dessinées sur la gauche jusqu'à ce qu'elle corresponde aux informations des bandes dessinées. sort comics to match comic information - trier les bandes dessinées pour qu'elles correspondent aux informations sur les bandes dessinées + trier les bandes dessinées pour qu'elles correspondent aux informations sur les bandes dessinées @@ -2705,7 +2705,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - Maintenez enfoncé pour faire clignoter la valeur sélectionnée dans l'interface utilisateur (magenta / basculé / 0↔10). Les versions restaurent l'original. + Maintenez enfoncé pour faire clignoter la valeur sélectionnée dans l'interface utilisateur (magenta / basculé / 0↔10). Les versions restaurent l'original. @@ -2730,7 +2730,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Display name: - Nom d'affichage : + Nom d'affichage : @@ -2810,7 +2810,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Edit: %1 - Modifier : %1 + Modifier : %1 @@ -2826,13 +2826,13 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Save failed - Échec de l'enregistrement + Échec de l'enregistrement Could not open file for writing: %1 - Impossible d'ouvrir le fichier en écriture : + Impossible d'ouvrir le fichier en écriture : %1 @@ -2851,14 +2851,14 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Could not open file: %1 - Impossible d'ouvrir le fichier : + Impossible d'ouvrir le fichier : %1 Invalid JSON: %1 - JSON invalide : + JSON invalide : %1 @@ -2898,8 +2898,8 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum - Press 'O' to open comic. - Appuyez sur "O" pour ouvrir une bande dessinée. + Press 'O' to open comic. + Appuyez sur "O" pour ouvrir une bande dessinée. @@ -2914,7 +2914,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Error opening comic - Erreur d'ouverture de la bande dessinée + Erreur d'ouverture de la bande dessinée @@ -3078,7 +3078,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Use VSync (improve the image quality in fullscreen mode, worse performance) - Utiliser VSync (Améliore la qualité d'image en mode plein écran, ralentit la performance) + Utiliser VSync (Améliore la qualité d'image en mode plein écran, ralentit la performance) @@ -3111,7 +3111,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Open image folder - Ouvrir un dossier d'images + Ouvrir un dossier d'images @@ -3131,7 +3131,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Clear open recent list - Vider la liste d'ouverture récente + Vider la liste d'ouverture récente @@ -3200,7 +3200,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Fit image to height - Ajuster l'image à la hauteur + Ajuster l'image à la hauteur @@ -3210,7 +3210,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Fit image to width - Ajuster l'image à la largeur + Ajuster l'image à la largeur @@ -3366,7 +3366,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Show go to flow - Afficher le flux + Afficher "Aller à Comic Flow" @@ -3476,7 +3476,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum Hide/show toolbar - Masquer / afficher la barre d'outils + Masquer / afficher la barre d'outils @@ -3614,7 +3614,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quit</b> dans le menu contextuel de l'icône de la barre d'état système. + YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quit</b> dans le menu contextuel de l'icône de la barre d'état système. diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_nl.ts b/YACReaderLibraryServer/yacreaderlibraryserver_nl.ts index 1367b2426..1115a03f3 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_nl.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_nl.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Voordat je verbinding kunt maken met Comic Vine, heb je een eigen API-sleutel nodig. Vraag er <a href="http://www.comicvine.com/api/">hier</a> één gratis aan + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Voordat je verbinding kunt maken met Comic Vine, heb je een eigen API-sleutel nodig. Vraag er <a href="http://www.comicvine.com/api/">hier</a> één gratis aan @@ -228,7 +228,7 @@ Hide comic flow - Sluit de Omslagbrowser + Comic Flow verbergen @@ -256,7 +256,7 @@ Pages - Pagina's + Pagina's @@ -441,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - De sneltoets "%1" is al aan een andere functie toegewezen + The shortcut "%1" is already assigned to other function + De sneltoets "%1" is al aan een andere functie toegewezen EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Deze map bevat nog geen strips @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Dit label bevat nog geen strips
@@ -568,7 +568,7 @@ CRC error on page (%1): some of the pages will not be displayed correctly - CRC-fout op pagina (%1): sommige pagina's worden niet correct weergegeven + CRC-fout op pagina (%1): sommige pagina's worden niet correct weergegeven @@ -607,7 +607,7 @@ Total pages : - Totaal aantal pagina's : + Totaal aantal pagina's : @@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - Bibliotheek ' %1' is niet langer beschikbaar. Wilt u het verwijderen? + Library '%1' is no longer available. Do you want to remove it? + Bibliotheek ' %1' is niet langer beschikbaar. Wilt u het verwijderen? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Bibliotheek ' %1' is gemaakt met een oudere versie van YACReaderLibrary. Zij moet opnieuw worden aangemaakt. Wilt u de bibliotheek nu aanmaken? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Bibliotheek ' %1' is gemaakt met een oudere versie van YACReaderLibrary. Zij moet opnieuw worden aangemaakt. Wilt u de bibliotheek nu aanmaken? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Er is een fout opgetreden bij het verkrijgen van toegang tot het pad van de map @@ -1074,7 +1074,7 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. De geselecteerde map bevat geen bibliotheek. @@ -1179,8 +1179,8 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, - There is another library with the name '%1'. - Er is al een bibliotheek met de naam ' %1 '. + There is another library with the name '%1'. + Er is al een bibliotheek met de naam ' %1 '.
@@ -1633,12 +1633,12 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet Je hebt geen nog libraries - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <P>u kunt een bibliotheek maken in een willekeurige map, YACReaderLibrary importeert alle strips en mappen uit deze map. Alle bibliotheek aangemaakt in het verleden kan je openen. < /p> <p>vergeet niet dat u YACReader kan gebruiken als stand-alone applicatie voor het lezen van de strips op de computer. < /p> @@ -1677,7 +1677,7 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, Comic Flow - Komische stroom + Comic Flow @@ -1751,8 +1751,8 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, - Consider 'recent' items added or updated since X days ago - Overweeg 'recente' items die sinds X dagen geleden zijn toegevoegd of bijgewerkt + Consider 'recent' items added or updated since X days ago + Overweeg 'recente' items die sinds X dagen geleden zijn toegevoegd of bijgewerkt @@ -1838,7 +1838,7 @@ YACReaderLibrary zal u er niet van weerhouden om meer bibliotheken te creëren, WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. WAARSCHUWING! Tijdens bibliotheekupdates is schrijven naar de database uitgeschakeld! @@ -1918,8 +1918,8 @@ Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de - "Go to flow" size - "Naar Omslagbrowser" afmetingen + "Go to flow" size + Grootte van "Ga naar Comic Flow" @@ -1959,17 +1959,17 @@ Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de Only Back/Forward buttons can turn pages - Alleen de knoppen Terug/Vooruit kunnen pagina's omslaan + Alleen de knoppen Terug/Vooruit kunnen pagina's omslaan Use the Left/Right buttons to turn pages. - Gebruik de knoppen Links/Rechts om pagina's om te slaan. + Gebruik de knoppen Links/Rechts om pagina's om te slaan. Click left or right half of the screen to turn pages. - Klik op de linker- of rechterhelft van het scherm om pagina's om te slaan. + Klik op de linker- of rechterhelft van het scherm om pagina's om te slaan. @@ -2019,7 +2019,7 @@ Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de Double Page options - Opties voor dubbele pagina's + Opties voor dubbele pagina's @@ -2314,8 +2314,8 @@ Om een ​​automatische update te stoppen, tikt u op de laadindicator naast de - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine-link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> bekijken </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine-link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> bekijken </a> @@ -2623,8 +2623,8 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader is beschikbaar voor iOS- en Android-apparaten.<br/>Ontdek het voor <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> of <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is beschikbaar voor iOS- en Android-apparaten.<br/>Ontdek het voor <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> of <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2646,7 +2646,7 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Sorteer de lijst met strips aan de linkerkant totdat deze overeenkomt met de informatie over de strips. @@ -2898,8 +2898,8 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa - Press 'O' to open comic. - Druk 'O' om een strip te openen. + Press 'O' to open comic. + Druk 'O' om een strip te openen. @@ -3366,7 +3366,7 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa Show go to flow - Toon ga naar de Omslagbrowser + "Ga naar Comic Flow" tonen diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_pt.ts b/YACReaderLibraryServer/yacreaderlibraryserver_pt.ts index c62cc90e7..f99923569 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_pt.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_pt.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Antes de se conectar ao Comic Vine, você precisa de sua própria chave de API. Por favor, ganhe um <a href="http://www.comicvine.com/api/">aqui</a> grátis + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Antes de se conectar ao Comic Vine, você precisa de sua própria chave de API. Por favor, ganhe um <a href="http://www.comicvine.com/api/">aqui</a> grátis @@ -228,7 +228,7 @@ Hide comic flow - Ocultar fluxo de quadrinhos + Ocultar Comic Flow @@ -441,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - O atalho "%1" já está atribuído a outra função + The shortcut "%1" is already assigned to other function + O atalho "%1" já está atribuído a outra função EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Esta pasta ainda não contém quadrinhos @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Este rótulo ainda não contém quadrinhos
@@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - A biblioteca '%1' não está mais disponível. Você quer removê-lo? + Library '%1' is no longer available. Do you want to remove it? + A biblioteca '%1' não está mais disponível. Você quer removê-lo? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - A biblioteca '%1' foi criada com uma versão mais antiga do YACReaderLibrary. Deve ser criado novamente. Deseja criar a biblioteca agora? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + A biblioteca '%1' foi criada com uma versão mais antiga do YACReaderLibrary. Deve ser criado novamente. Deseja criar a biblioteca agora? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Ocorreu um erro ao acessar o caminho da pasta @@ -1074,7 +1074,7 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. A pasta selecionada não contém nenhuma biblioteca. @@ -1179,8 +1179,8 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve - There is another library with the name '%1'. - Existe outra biblioteca com o nome '%1'. + There is another library with the name '%1'. + Existe outra biblioteca com o nome '%1'.
@@ -1633,12 +1633,12 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet Você ainda não tem nenhuma biblioteca - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Você pode criar uma biblioteca em qualquer pasta, YACReaderLibrary importará todos os quadrinhos e pastas desta pasta. Se você já criou alguma biblioteca, poderá abri-la.</p><p>Não se esqueça de que você pode usar o YACReader como um aplicativo independente para ler quadrinhos em seu computador.</p> @@ -1677,7 +1677,7 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve Comic Flow - Fluxo de quadrinhos + Comic Flow @@ -1751,8 +1751,8 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve - Consider 'recent' items added or updated since X days ago - Considere itens 'recentes' adicionados ou atualizados há X dias + Consider 'recent' items added or updated since X days ago + Considere itens 'recentes' adicionados ou atualizados há X dias @@ -1838,7 +1838,7 @@ YACReaderLibrary não impedirá você de criar mais bibliotecas, mas você deve WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. AVISO! Durante as atualizações da biblioteca, as gravações no banco de dados são desativadas! @@ -1918,8 +1918,8 @@ Para interromper uma atualização automática, toque no indicador de carregamen - "Go to flow" size - Tamanho do "Ir para cheia" + "Go to flow" size + Tamanho de "Ir para Comic Flow" @@ -2314,8 +2314,8 @@ Para interromper uma atualização automática, toque no indicador de carregamen - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Link do Comic Vine: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> visualizar </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Link do Comic Vine: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> visualizar </a> @@ -2623,8 +2623,8 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - O YACReader está disponível para dispositivos iOS e Android.<br/>Descubra-o para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + O YACReader está disponível para dispositivos iOS e Android.<br/>Descubra-o para <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> ou <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2646,7 +2646,7 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Por favor, classifique a lista de quadrinhos à esquerda até que corresponda às informações dos quadrinhos. @@ -2898,8 +2898,8 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã - Press 'O' to open comic. - Pressione 'O' para abrir um quadrinho. + Press 'O' to open comic. + Pressione 'O' para abrir um quadrinho. @@ -3366,7 +3366,7 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã Show go to flow - Mostrar ir para o fluxo + Mostrar "Ir para Comic Flow" diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_ru.ts b/YACReaderLibraryServer/yacreaderlibraryserver_ru.ts index 05e5aea42..3e334affd 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_ru.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_ru.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Для подключения к Comic Vine вам потребуется ваш личный API ключ. Приобретите его бесплатно вот <a href="http://www.comicvine.com/api/">здесь</a> + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Для подключения к Comic Vine вам потребуется ваш личный API ключ. Приобретите его бесплатно вот <a href="http://www.comicvine.com/api/">здесь</a> @@ -228,7 +228,7 @@ Hide comic flow - Показать/скрыть поток комиксов + Скрыть Comic Flow @@ -441,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - Сочетание клавиш "%1" уже назначено для другой функции + The shortcut "%1" is already assigned to other function + Сочетание клавиш "%1" уже назначено для другой функции EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet В этой папке еще нет комиксов @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Этот ярлык пока ничего не содержит
@@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - Библиотека '%1' больше не доступна. Вы хотите удалить ее? + Library '%1' is no longer available. Do you want to remove it? + Библиотека '%1' больше не доступна. Вы хотите удалить ее? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Библиотека '%1' была создана старой версией YACReaderLibrary. Она должна быть вновь создана. Вы хотите создать библиотеку сейчас? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Библиотека '%1' была создана старой версией YACReaderLibrary. Она должна быть вновь создана. Вы хотите создать библиотеку сейчас? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Ошибка доступа к пути папки @@ -1074,7 +1074,7 @@ YACReaderLibrary не помешает вам создать больше биб - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. Выбранная папка не содержит ни одной библиотеки. @@ -1179,8 +1179,8 @@ YACReaderLibrary не помешает вам создать больше биб - There is another library with the name '%1'. - Уже существует другая папка с именем '%1'. + There is another library with the name '%1'. + Уже существует другая папка с именем '%1'.
@@ -1633,12 +1633,12 @@ YACReaderLibrary не помешает вам создать больше биб NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet У вас нет ни одной библиотеки - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Вы можете создать библиотеку в любой папке, YACReaderLibrary будет импортировать все комиксы и папки из этой папки. Если вы уже ранее создавали библиотеки, их можно будет открыть.< / p > <p>Не забывайте, что Вы можете использовать YACReader в качестве отдельного приложения для чтения комиксов на вашем компьютере.</п> @@ -1677,7 +1677,7 @@ YACReaderLibrary не помешает вам создать больше биб Comic Flow - Поток комиксов + Comic Flow @@ -1751,8 +1751,8 @@ YACReaderLibrary не помешает вам создать больше биб - Consider 'recent' items added or updated since X days ago - Учитывайте «недавние» элементы, добавленные или обновленные X дней назад. + Consider 'recent' items added or updated since X days ago + Учитывайте «недавние» элементы, добавленные или обновленные X дней назад. @@ -1838,7 +1838,7 @@ YACReaderLibrary не помешает вам создать больше биб WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. ПРЕДУПРЕЖДЕНИЕ! Во время обновления библиотеки запись в базу данных отключена! @@ -1918,8 +1918,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - "Go to flow" size - Размер потока страниц + "Go to flow" size + Размер "Перейти к Comic Flow" @@ -2314,8 +2314,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - <a style='color: ##666666; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Открыть страницу этого комикса на сайте Comic Vine </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + <a style='color: ##666666; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> Открыть страницу этого комикса на сайте Comic Vine </a> @@ -2623,8 +2623,8 @@ YACReaderLibraryServer — это безголовая (без графичес - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader доступен для устройств iOS и Android.<br/>Найдите его для <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> или <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader доступен для устройств iOS и Android.<br/>Найдите его для <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> или <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2646,7 +2646,7 @@ YACReaderLibraryServer — это безголовая (без графичес SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Пожалуйста, отсортируйте список комиксов слева, пока он не будет соответствовать информации комикса. @@ -2898,8 +2898,8 @@ YACReaderLibraryServer — это безголовая (без графичес - Press 'O' to open comic. - Нажмите "O" чтобы открыть комикс. + Press 'O' to open comic. + Нажмите "O" чтобы открыть комикс. @@ -3366,7 +3366,7 @@ YACReaderLibraryServer — это безголовая (без графичес Show go to flow - Показать поток страниц + Показать "Перейти к Comic Flow" diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_tr.ts b/YACReaderLibraryServer/yacreaderlibraryserver_tr.ts index 9e8582c4c..8189dc920 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_tr.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_tr.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - Comic Vine'a bağlanmadan önce kendi API anahtarınıza ihtiyacınız var. Lütfen <a href="http://www.comicvine.com/api/">buradan</a> ücretsiz bir tane edinin + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + Comic Vine'a bağlanmadan önce kendi API anahtarınıza ihtiyacınız var. Lütfen <a href="http://www.comicvine.com/api/">buradan</a> ücretsiz bir tane edinin @@ -228,7 +228,7 @@ Hide comic flow - Çizgi roman akışını gizle + Comic Flow'u gizle @@ -441,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - "%1" kısayolu bir başka işleve zaten atanmış + The shortcut "%1" is already assigned to other function + "%1" kısayolu bir başka işleve zaten atanmış EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet Bu klasör henüz çizgi roman içermiyor @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet Bu etiket henüz çizgi roman içermiyor
@@ -871,8 +871,8 @@ - Library '%1' is no longer available. Do you want to remove it? - Kütüphane '%1'ulaşılabilir değil. Kaldırmak ister misin? + Library '%1' is no longer available. Do you want to remove it? + Kütüphane '%1'ulaşılabilir değil. Kaldırmak ister misin? @@ -881,8 +881,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - Kütüphane '%1 YACRKütüphanenin eski bir sürümünde oluşturulmuş, Kütüphaneyi yeniden oluşturmak ister misin? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + Kütüphane '%1 YACRKütüphanenin eski bir sürümünde oluşturulmuş, Kütüphaneyi yeniden oluşturmak ister misin? @@ -923,7 +923,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path Klasörün yoluna erişilirken hata oluştu @@ -1075,7 +1075,7 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. Seçilen dosya kütüphanede yok. @@ -1096,7 +1096,7 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü Remove and delete metadata - Metadata'yı kaldır ve sil + Metadata'yı kaldır ve sil @@ -1180,8 +1180,8 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü - There is another library with the name '%1'. - Bu başka bir kütüphanenin adı '%1'. + There is another library with the name '%1'. + Bu başka bir kütüphanenin adı '%1'.
@@ -1286,7 +1286,7 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü Open current comic on YACReader - YACReader'ı geçerli çizgi roman okuyucsu seç + YACReader'ı geçerli çizgi roman okuyucsu seç @@ -1634,12 +1634,12 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet Henüz bir kütüphaneye sahip değilsin - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>Yeni bir kütüphane oluşturabilmeniçin kütüphane</p><p>No olvides que puedes usar YACReader como una aplicación independiente para leer los cómics en tu ordenador.</p> @@ -1678,7 +1678,7 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü Comic Flow - Çizgi Roman Akışı + Comic Flow @@ -1748,12 +1748,12 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü Import metadata from ComicInfo.xml when adding new comics - Yeni çizgi roman eklerken meta verileri ComicInfo.xml'den içe aktarın + Yeni çizgi roman eklerken meta verileri ComicInfo.xml'den içe aktarın - Consider 'recent' items added or updated since X days ago - X gün öncesinden bu yana eklenen veya güncellenen 'en son' öğeleri göz önünde bulundurun + Consider 'recent' items added or updated since X days ago + X gün öncesinden bu yana eklenen veya güncellenen 'en son' öğeleri göz önünde bulundurun @@ -1839,7 +1839,7 @@ YACReaderLibrary daha fazla kütüphane oluşturmanıza engel olmaz ancak kütü WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. UYARI! Kütüphane güncellemeleri sırasında veritabanına yazma işlemi devre dışı bırakılır! @@ -1895,7 +1895,7 @@ Otomatik güncellemeyi durdurmak için Kitaplıklar başlığının yanındaki y Display current comic banner - Mevcut çizgi roman banner'ını görüntüle + Mevcut çizgi roman banner'ını görüntüle @@ -1919,8 +1919,8 @@ Otomatik güncellemeyi durdurmak için Kitaplıklar başlığının yanındaki y - "Go to flow" size - Akış görünümüne git + "Go to flow" size + "Comic Flow'a git" boyutu @@ -2315,8 +2315,8 @@ Otomatik güncellemeyi durdurmak için Kitaplıklar başlığının yanındaki y - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine bağlantısı: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> görüntüle </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine bağlantısı: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> görüntüle </a> @@ -2359,7 +2359,7 @@ YACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary. This appplication supports persistent settings, to set them up edit this file %1 To learn about the available settings please check the documentation at https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md -YACReaderLibraryServer, YACReaderLibrary'nin başsız (gui yok) sürümüdür. +YACReaderLibraryServer, YACReaderLibrary'nin başsız (gui yok) sürümüdür. Bu uygulama kalıcı ayarları destekler, bunları ayarlamak için bu dosyayı düzenleyin %1 Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubusercontent.com/YACReader/yacreader/develop/YACReaderLibraryServer/SETTINGS_README.md adresindeki belgelere bakın. @@ -2624,8 +2624,8 @@ Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubuserconte - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader, iOS ve Android cihazlarda kullanılabilir.<br/>Bunu <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> veya <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a> için keşfedin. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader, iOS ve Android cihazlarda kullanılabilir.<br/>Bunu <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> veya <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a> için keşfedin. @@ -2647,7 +2647,7 @@ Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubuserconte SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. Lütfen, çizgi romanların bilgileriyle eşleşene kadar soldaki çizgi roman listesini sıralayın. @@ -2899,8 +2899,8 @@ Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubuserconte - Press 'O' to open comic. - 'O'ya basarak aç. + Press 'O' to open comic. + 'O'ya basarak aç. @@ -3367,7 +3367,7 @@ Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubuserconte Show go to flow - Akışı göster + "Comic Flow'a git"i göster @@ -3615,7 +3615,7 @@ Mevcut ayarlar hakkında bilgi edinmek için lütfen https://raw.githubuserconte YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary sistem tepsisinde çalışmaya devam edecektir. Programı sonlandırmak için sistem tepsisi simgesinin bağlam menüsünden <b>Çık</b>'ı seçin. + YACReaderLibrary sistem tepsisinde çalışmaya devam edecektir. Programı sonlandırmak için sistem tepsisi simgesinin bağlam menüsünden <b>Çık</b>'ı seçin. diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_zh_CN.ts b/YACReaderLibraryServer/yacreaderlibraryserver_zh_CN.ts index 9c36ddbde..ca25decee 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_zh_CN.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_zh_CN.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - 你需要拥有自己的API密钥才能够连接Comic Vine. 你可以通过这个链接获得一个免费的<a href="http://www.comicvine.com/api/">API</a>密钥 + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要拥有自己的API密钥才能够连接Comic Vine. 你可以通过这个链接获得一个免费的<a href="http://www.comicvine.com/api/">API</a>密钥 @@ -228,7 +228,7 @@ Hide comic flow - 隐藏漫画流 + 隐藏 Comic Flow @@ -441,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - 快捷键 "%1" 已被映射至其他功能 + The shortcut "%1" is already assigned to other function + 快捷键 "%1" 已被映射至其他功能 EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet 该文件夹还没有漫画 @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet 此标签尚未包含漫画
@@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - 库 '%1' 不再可用。 你想删除它吗? + Library '%1' is no longer available. Do you want to remove it? + 库 '%1' 不再可用。 你想删除它吗? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - 库 '%1' 是通过旧版本的YACReaderLibrary创建的。 必须再次创建。 你想现在创建吗? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 库 '%1' 是通过旧版本的YACReaderLibrary创建的。 必须再次创建。 你想现在创建吗? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path 访问文件夹的路径时出错 @@ -1074,7 +1074,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. 所选文件夹不包含任何库。 @@ -1179,8 +1179,8 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 - There is another library with the name '%1'. - 已存在另一个名为'%1'的库。 + There is another library with the name '%1'. + 已存在另一个名为'%1'的库。
@@ -1633,12 +1633,12 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet 你还没有库 - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>您可以在任何文件夹中创建库,YACReaderLibrary将导入此文件夹中的所有漫画和文件夹。如果已有库,则可以打开它们。</p><p>您可以把YACReader当成独立应用来阅读电脑上的漫画。</p> @@ -1677,7 +1677,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 Comic Flow - 漫画流 + Comic Flow @@ -1751,7 +1751,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago 参考自 X 天前添加或更新的“最近”项目 @@ -1838,7 +1838,7 @@ YACReaderLibrary不会阻止您创建更多的库,但是您应该保持较低 WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. 警告! 在库更新期间,将禁用对数据库的写入! @@ -1918,8 +1918,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - "Go to flow" size - 页面流尺寸 + "Go to flow" size + “转到 Comic Flow”大小 @@ -2314,8 +2314,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine 连接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 连接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> @@ -2623,8 +2623,8 @@ YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader 适用于 iOS 和 Android 设备。<br/>搜索 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 适用于 iOS 和 Android 设备。<br/>搜索 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. @@ -2646,7 +2646,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. 请在左侧对漫画列表进行排序,直到它与漫画的信息相符。 @@ -2898,8 +2898,8 @@ YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 - Press 'O' to open comic. - 按下 'O' 以打开漫画. + Press 'O' to open comic. + 按下 'O' 以打开漫画. @@ -3366,7 +3366,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 Show go to flow - 显示页面流 + 显示“转到 Comic Flow” @@ -3506,7 +3506,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的无头(无 GUI)版本。 Toggle between fit to width and fit to height - 切换显示为"适应宽度"或"适应高度" + 切换显示为"适应宽度"或"适应高度" diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_zh_HK.ts b/YACReaderLibraryServer/yacreaderlibraryserver_zh_HK.ts index 1f5e317e5..955790945 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_zh_HK.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_zh_HK.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 @@ -228,7 +228,7 @@ Hide comic flow - 隱藏漫畫流 + 隱藏 Comic Flow @@ -441,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - 快捷鍵 "%1" 已被映射至其他功能 + The shortcut "%1" is already assigned to other function + 快捷鍵 "%1" 已被映射至其他功能 EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet 該資料夾還沒有漫畫 @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet 此標籤尚未包含漫畫
@@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - 庫 '%1' 不再可用。 你想刪除它嗎? + Library '%1' is no longer available. Do you want to remove it? + 庫 '%1' 不再可用。 你想刪除它嗎? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path 訪問檔夾的路徑時出錯 @@ -1074,7 +1074,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. 所選檔夾不包含任何庫。 @@ -1179,8 +1179,8 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - There is another library with the name '%1'. - 已存在另一個名為'%1'的庫。 + There is another library with the name '%1'. + 已存在另一個名為'%1'的庫。
@@ -1633,12 +1633,12 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet 你還沒有庫 - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>您可以在任何檔夾中創建庫,YACReaderLibrary將導入此檔夾中的所有漫畫和文件夾。如果已有庫,則可以打開它們。</p><p>您可以把YACReader當成獨立應用來閱讀電腦上的漫畫。</p> @@ -1677,7 +1677,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 Comic Flow - 漫畫流 + Comic Flow @@ -1751,7 +1751,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago 考慮自 X 天前新增或更新的「最近」項目 @@ -1838,7 +1838,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. 警告!在庫更新期間,將停用對資料庫的寫入! @@ -1918,8 +1918,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - "Go to flow" size - 頁面流尺寸 + "Go to flow" size + 「前往 Comic Flow」大小 @@ -2314,8 +2314,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> @@ -2623,8 +2623,8 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 @@ -2646,7 +2646,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. 請在左側對漫畫列表進行排序,直到它與漫畫的資訊相符。 @@ -2898,8 +2898,8 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 - Press 'O' to open comic. - 按下 'O' 以打開漫畫. + Press 'O' to open comic. + 按下 'O' 以打開漫畫. @@ -3366,7 +3366,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 Show go to flow - 顯示頁面流 + 顯示「前往 Comic Flow」 @@ -3506,7 +3506,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 Toggle between fit to width and fit to height - 切換顯示為"適應寬度"或"適應高度" + 切換顯示為"適應寬度"或"適應高度" diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_zh_TW.ts b/YACReaderLibraryServer/yacreaderlibraryserver_zh_TW.ts index 7d47fa5c5..760a5f042 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_zh_TW.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_zh_TW.ts @@ -64,8 +64,8 @@ ApiKeyDialog - Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> - 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 + Before you can connect to Comic Vine, you need your own API key. Please, get one free <a href="http://www.comicvine.com/api/">here</a> + 你需要擁有自己的API密鑰才能夠連接Comic Vine. 你可以通過這個鏈接獲得一個免費的<a href="http://www.comicvine.com/api/">API</a>密鑰 @@ -228,7 +228,7 @@ Hide comic flow - 隱藏漫畫流 + 隱藏 Comic Flow @@ -441,15 +441,15 @@ - The shortcut "%1" is already assigned to other function - 快捷鍵 "%1" 已被映射至其他功能 + The shortcut "%1" is already assigned to other function + 快捷鍵 "%1" 已被映射至其他功能 EmptyFolderWidget - This folder doesn't contain comics yet + This folder doesn't contain comics yet 該資料夾還沒有漫畫 @@ -457,7 +457,7 @@ EmptyLabelWidget - This label doesn't contain comics yet + This label doesn't contain comics yet 此標籤尚未包含漫畫
@@ -870,8 +870,8 @@ - Library '%1' is no longer available. Do you want to remove it? - 庫 '%1' 不再可用。 你想刪除它嗎? + Library '%1' is no longer available. Do you want to remove it? + 庫 '%1' 不再可用。 你想刪除它嗎? @@ -880,8 +880,8 @@ - Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? - 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? + Library '%1' has been created with an older version of YACReaderLibrary. It must be created again. Do you want to create the library now? + 庫 '%1' 是通過舊版本的YACReaderLibrary創建的。 必須再次創建。 你想現在創建嗎? @@ -922,7 +922,7 @@ - There was an error accessing the folder's path + There was an error accessing the folder's path 訪問檔夾的路徑時出錯 @@ -1074,7 +1074,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - The selected folder doesn't contain any library. + The selected folder doesn't contain any library. 所選檔夾不包含任何庫。 @@ -1179,8 +1179,8 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - There is another library with the name '%1'. - 已存在另一個名為'%1'的庫。 + There is another library with the name '%1'. + 已存在另一個名為'%1'的庫。
@@ -1633,12 +1633,12 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 NoLibrariesWidget - You don't have any libraries yet + You don't have any libraries yet 你還沒有庫 - <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> + <p>You can create a library in any folder, YACReaderLibrary will import all comics and folders from this folder. If you have created any library in the past you can open them.</p><p>Don't forget that you can use YACReader as a stand alone application for reading the comics on your computer.</p> <p>您可以在任何檔夾中創建庫,YACReaderLibrary將導入此檔夾中的所有漫畫和文件夾。如果已有庫,則可以打開它們。</p><p>您可以把YACReader當成獨立應用來閱讀電腦上的漫畫。</p> @@ -1677,7 +1677,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 Comic Flow - 漫畫流 + Comic Flow @@ -1751,7 +1751,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 - Consider 'recent' items added or updated since X days ago + Consider 'recent' items added or updated since X days ago 考慮自 X 天前新增或更新的「最近」項目 @@ -1838,7 +1838,7 @@ YACReaderLibrary不會阻止您創建更多的庫,但是您應該保持較低 WARNING! During library updates writes to the database are disabled! -Don't schedule updates while you may be using the app actively. +Don't schedule updates while you may be using the app actively. During automatic updates the app will block some of the actions until the update is finished. To stop an automatic update tap on the loading indicator next to the Libraries title. 警告!在庫更新期間,將停用對資料庫的寫入! @@ -1918,8 +1918,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - "Go to flow" size - 頁面流尺寸 + "Go to flow" size + 「前往 Comic Flow」大小 @@ -2314,8 +2314,8 @@ To stop an automatic update tap on the loading indicator next to the Libraries t - Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> - Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> + Comic Vine link: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> view </a> + Comic Vine 連接: <a style='color: #FFCB00; text-decoration:none; font-weight:bold;' href="http://www.comicvine.com/comic/4000-%1/"> 查看 </a> @@ -2623,8 +2623,8 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 - YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. - YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 + YACReader is available for iOS and Android devices.<br/>Discover it for <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> or <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>. + YACReader 適用於 iOS 和 Android 裝置。 <br/>發現它適用於 <a href='https://ios.yacreader.com' style='color:rgb(193, 148, 65)'>iOS</a> 或 <a href='https://android.yacreader.com' style='color:rgb(193, 148, 65)'>Android</a>。 @@ -2646,7 +2646,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 SortVolumeComics - Please, sort the list of comics on the left until it matches the comics' information. + Please, sort the list of comics on the left until it matches the comics' information. 請在左側對漫畫列表進行排序,直到它與漫畫的資訊相符。 @@ -2898,8 +2898,8 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 - Press 'O' to open comic. - 按下 'O' 以打開漫畫. + Press 'O' to open comic. + 按下 'O' 以打開漫畫. @@ -3366,7 +3366,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 Show go to flow - 顯示頁面流 + 顯示「前往 Comic Flow」 @@ -3506,7 +3506,7 @@ YACReaderLibraryServer 是 YACReaderLibrary 的無頭(無 GUI)版本。 Toggle between fit to width and fit to height - 切換顯示為"適應寬度"或"適應高度" + 切換顯示為"適應寬度"或"適應高度" From 221ce60760d1a77319a4c73eb075b9fb012af3e1 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Thu, 12 Mar 2026 18:18:13 +0100 Subject: [PATCH 149/187] Better console output in Windows This way QtCreator can actually get the output from the app. --- third_party/QsLog/QsLogDestConsole.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/third_party/QsLog/QsLogDestConsole.cpp b/third_party/QsLog/QsLogDestConsole.cpp index d7d21646b..1e6fa1ec3 100644 --- a/third_party/QsLog/QsLogDestConsole.cpp +++ b/third_party/QsLog/QsLogDestConsole.cpp @@ -39,11 +39,17 @@ void QsDebugOutput::output( const QString& message ) #include void QsDebugOutput::output( const QString& message ) { - WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), message.utf16(), message.size(), NULL, NULL); - WriteConsoleW(GetStdHandle(STD_ERROR_HANDLE), L"\n", 1, NULL, NULL); - - fprintf(stdout, "%s\n", qPrintable(message)); - fflush(stdout); + HANDLE stdErr = GetStdHandle(STD_ERROR_HANDLE); + DWORD mode; + if (GetConsoleMode(stdErr, &mode)) { + // Real console attached — use Unicode-aware WriteConsoleW + WriteConsoleW(stdErr, message.utf16(), message.size(), NULL, NULL); + WriteConsoleW(stdErr, L"\n", 1, NULL, NULL); + } else { + // Pipe (Qt Creator, redirect, etc.) — use stdio + fprintf(stdout, "%s\n", qPrintable(message)); + fflush(stdout); + } } #endif From f0943995c62b117e9139a0a61f979e6e0cd6f81f Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 13 Mar 2026 11:06:25 +0100 Subject: [PATCH 150/187] Include sanitation --- YACReader/goto_flow_toolbar.cpp | 9 ++++++- YACReader/magnifying_glass.h | 1 - YACReader/main.cpp | 3 +-- YACReader/main_window_viewer.cpp | 9 ++++--- YACReader/mouse_handler.cpp | 2 +- YACReader/notifications_label_widget.cpp | 9 ++++++- YACReader/page_label_widget.cpp | 7 ++++- YACReader/render.cpp | 2 -- YACReader/themes/theme.h | 2 +- YACReader/viewer.cpp | 7 +++-- YACReader/width_slider.cpp | 8 +++--- YACReaderLibrary/add_label_dialog.cpp | 3 +++ YACReaderLibrary/add_label_dialog.h | 5 +++- YACReaderLibrary/bundle_creator.h | 2 +- YACReaderLibrary/classic_comics_view.cpp | 10 ++++++- YACReaderLibrary/classic_comics_view.h | 2 ++ .../comic_vine/comic_vine_dialog.cpp | 3 ++- .../comic_vine/search_single_comic.h | 2 -- YACReaderLibrary/comic_vine/search_volume.h | 4 ++- YACReaderLibrary/comic_vine/select_comic.h | 2 -- YACReaderLibrary/comic_vine/select_volume.cpp | 1 - YACReaderLibrary/comic_vine/select_volume.h | 2 -- .../comic_vine/sort_volume_comics.h | 1 - YACReaderLibrary/comics_remover.h | 1 - YACReaderLibrary/comics_view.cpp | 2 +- YACReaderLibrary/comics_view.h | 4 ++- YACReaderLibrary/db/comic_model.cpp | 3 ++- YACReaderLibrary/db/comic_model.h | 2 +- .../db/comic_query_result_processor.cpp | 2 ++ .../db/comic_query_result_processor.h | 1 - YACReaderLibrary/db/data_base_management.cpp | 6 +++-- YACReaderLibrary/db/data_base_management.h | 1 - YACReaderLibrary/db/folder_model.cpp | 4 +-- .../db/folder_query_result_processor.cpp | 3 ++- YACReaderLibrary/db/query_parser.cpp | 4 +-- YACReaderLibrary/db/reading_list_item.h | 1 - YACReaderLibrary/db/reading_list_model.cpp | 4 ++- YACReaderLibrary/db_helper.cpp | 2 +- YACReaderLibrary/empty_container_info.cpp | 2 +- YACReaderLibrary/empty_container_info.h | 7 ++++- YACReaderLibrary/empty_folder_widget.h | 1 - YACReaderLibrary/empty_label_widget.h | 3 +-- YACReaderLibrary/empty_reading_list_widget.h | 1 - YACReaderLibrary/empty_special_list.h | 1 - YACReaderLibrary/folder_content_view.cpp | 6 +++-- YACReaderLibrary/folder_content_view.h | 5 +++- YACReaderLibrary/grid_comics_view.cpp | 14 ++++++---- YACReaderLibrary/grid_comics_view.h | 1 + YACReaderLibrary/import_widget.h | 10 ++++++- YACReaderLibrary/info_comics_view.cpp | 9 +++---- .../initial_comic_info_extractor.h | 6 ++++- YACReaderLibrary/library_comic_opener.cpp | 1 - YACReaderLibrary/library_creator.cpp | 1 + YACReaderLibrary/library_creator.h | 1 - YACReaderLibrary/library_window.cpp | 26 +++++++++++++------ YACReaderLibrary/library_window.h | 1 - YACReaderLibrary/library_window_actions.cpp | 1 - YACReaderLibrary/options_dialog.cpp | 13 +++++++--- YACReaderLibrary/options_dialog.h | 12 ++++++--- YACReaderLibrary/properties_dialog.cpp | 1 + .../recent_visibility_coordinator.h | 2 -- .../controllers/v2/comiccontroller_v2.cpp | 3 --- .../v2/comiccontrollerinreadinglist_v2.cpp | 5 ---- .../v2/comicdownloadinfocontroller_v2.cpp | 3 ++- .../v2/comicfullinfocontroller_v2.cpp | 2 -- .../controllers/v2/errorcontroller_v2.cpp | 3 --- .../v2/foldercontentcontroller_v2.cpp | 1 - .../v2/folderinfocontroller_v2.cpp | 6 ++--- .../v2/readinglistinfocontroller_v2.cpp | 6 ++--- .../controllers/v2/taginfocontroller_v2.cpp | 6 ++--- .../v2/updatecomiccontroller_v2.cpp | 7 ++--- .../server/yacreader_http_session_store.cpp | 2 ++ .../server/yacreader_http_session_store.h | 3 ++- YACReaderLibrary/server_config_dialog.cpp | 1 - YACReaderLibrary/themes/theme.h | 1 - YACReaderLibrary/themes/theme_factory.cpp | 3 +++ YACReaderLibrary/trayicon_controller.cpp | 2 +- YACReaderLibrary/trayicon_controller.h | 4 ++- YACReaderLibrary/xml_info_library_scanner.cpp | 2 ++ .../yacreader_comics_selection_helper.h | 4 ++- .../yacreader_content_views_manager.cpp | 11 ++++---- .../yacreader_content_views_manager.h | 3 ++- YACReaderLibrary/yacreader_folders_view.cpp | 2 -- YACReaderLibrary/yacreader_folders_view.h | 6 +++-- .../yacreader_navigation_controller.cpp | 5 ++-- .../yacreader_reading_lists_view.cpp | 1 - .../yacreader_reading_lists_view.h | 6 +++-- YACReaderLibraryServer/main.cpp | 2 -- common/check_new_version.h | 1 - common/comic.cpp | 1 + common/comic.h | 1 - common/custom_widgets.cpp | 1 - common/rhi/yacreader_comic_flow_rhi.h | 3 +++ common/rhi/yacreader_flow_rhi.cpp | 1 + common/rhi/yacreader_flow_rhi.h | 2 -- common/rhi/yacreader_page_flow_rhi.h | 3 +++ common/scroll_management.cpp | 1 - common/themes/icon_utils.cpp | 1 + common/themes/icon_utils.h | 4 ++- compressed_archive/compressed_archive.cpp | 3 --- custom_widgets/rounded_corners_dialog.cpp | 2 +- custom_widgets/whats_new_controller.cpp | 2 -- custom_widgets/whats_new_dialog.cpp | 11 ++++++-- .../yacreader_library_item_widget.cpp | 5 ++-- custom_widgets/yacreader_search_line_edit.h | 1 - custom_widgets/yacreader_sidebar.cpp | 1 - custom_widgets/yacreader_sidebar.h | 8 +++++- custom_widgets/yacreader_table_view.cpp | 2 -- custom_widgets/yacreader_titled_toolbar.cpp | 1 - custom_widgets/yacreader_treeview.cpp | 2 +- custom_widgets/yacreader_treeview.h | 9 ++++++- .../edit_shortcuts_dialog.cpp | 4 --- 112 files changed, 252 insertions(+), 179 deletions(-) diff --git a/YACReader/goto_flow_toolbar.cpp b/YACReader/goto_flow_toolbar.cpp index 2f45af1de..f3428ecad 100644 --- a/YACReader/goto_flow_toolbar.cpp +++ b/YACReader/goto_flow_toolbar.cpp @@ -1,6 +1,13 @@ #include "goto_flow_toolbar.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include #include "configuration.h" diff --git a/YACReader/magnifying_glass.h b/YACReader/magnifying_glass.h index 33137de0a..d174c93f0 100644 --- a/YACReader/magnifying_glass.h +++ b/YACReader/magnifying_glass.h @@ -2,7 +2,6 @@ #define __MAGNIFYING_GLASS #include -#include #include #include diff --git a/YACReader/main.cpp b/YACReader/main.cpp index 5d1e9e77b..27d0d08c9 100644 --- a/YACReader/main.cpp +++ b/YACReader/main.cpp @@ -4,7 +4,6 @@ #include #include "main_window_viewer.h" -#include "configuration.h" #include "exit_check.h" #include "appearance_configuration.h" #include "theme_manager.h" @@ -16,10 +15,10 @@ #include "QsLogDest.h" using namespace QsLogging; +using namespace YACReader; #if defined(WIN32) && defined(_DEBUG) #define _CRTDBG_MAP_ALLOC -#include #include #define DEBUG_NEW new (_NORMAL_BLOCK, __FILE__, __LINE__) #define new DEBUG_NEW diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 35a270099..bb210bc69 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -1,12 +1,10 @@ #include "main_window_viewer.h" +#include "bookmarks_dialog.h" #include "configuration.h" #include "viewer.h" -#include "goto_dialog.h" -#include "custom_widgets.h" #include "options_dialog.h" #include "check_new_version.h" #include "comic.h" -#include "bookmarks_dialog.h" #include "width_slider.h" #include "qnaturalsorting.h" #include "help_about_dialog.h" @@ -22,12 +20,14 @@ #include "whats_new_controller.h" -#include #include #include +#include #include #include +#include +#include #include #include #include @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef use_unarr #include "unarr.h" diff --git a/YACReader/mouse_handler.cpp b/YACReader/mouse_handler.cpp index 9ab6055e7..4ac97da7f 100644 --- a/YACReader/mouse_handler.cpp +++ b/YACReader/mouse_handler.cpp @@ -1,6 +1,6 @@ #include "mouse_handler.h" -#include +#include #include "configuration.h" #include "goto_flow_widget.h" diff --git a/YACReader/notifications_label_widget.cpp b/YACReader/notifications_label_widget.cpp index 2d5ff56f2..480025fb9 100644 --- a/YACReader/notifications_label_widget.cpp +++ b/YACReader/notifications_label_widget.cpp @@ -1,6 +1,13 @@ #include "notifications_label_widget.h" -#include +#include +#include +#include +#include +#include +#include +#include +#include NotificationsLabelWidget::NotificationsLabelWidget(QWidget *parent) : QWidget(parent) diff --git a/YACReader/page_label_widget.cpp b/YACReader/page_label_widget.cpp index 4a1e7cad2..93ddf4aee 100644 --- a/YACReader/page_label_widget.cpp +++ b/YACReader/page_label_widget.cpp @@ -1,6 +1,11 @@ #include "page_label_widget.h" -#include +#include +#include +#include +#include +#include +#include PageLabelWidget::PageLabelWidget(QWidget *parent) : QWidget(parent) diff --git a/YACReader/render.cpp b/YACReader/render.cpp index 59996fea4..9ad49ec46 100644 --- a/YACReader/render.cpp +++ b/YACReader/render.cpp @@ -7,8 +7,6 @@ #include #include -#include - #include "comic_db.h" #include "yacreader_global_gui.h" #include "configuration.h" diff --git a/YACReader/themes/theme.h b/YACReader/themes/theme.h index 99715f646..658fe8a6d 100644 --- a/YACReader/themes/theme.h +++ b/YACReader/themes/theme.h @@ -1,7 +1,7 @@ #ifndef THEME_H #define THEME_H -#include +#include #include #include "help_about_dialog_theme.h" diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index 3eb44db4d..ba08498d0 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -12,14 +12,13 @@ #include "page_label_widget.h" #include "notifications_label_widget.h" #include "comic_db.h" -#include "shortcuts_manager.h" -#include "theme_manager.h" #include #include +#include #include - -#include +#include +#include Viewer::Viewer(QWidget *parent) : QScrollArea(parent), diff --git a/YACReader/width_slider.cpp b/YACReader/width_slider.cpp index 70912043f..162610d8c 100644 --- a/YACReader/width_slider.cpp +++ b/YACReader/width_slider.cpp @@ -1,8 +1,10 @@ #include "width_slider.h" -#include - -#include "configuration.h" +#include +#include +#include +#include +#include YACReaderSliderAction::YACReaderSliderAction(QWidget *parent) : QWidgetAction(parent) diff --git a/YACReaderLibrary/add_label_dialog.cpp b/YACReaderLibrary/add_label_dialog.cpp index c1cc0c79a..b8399a847 100644 --- a/YACReaderLibrary/add_label_dialog.cpp +++ b/YACReaderLibrary/add_label_dialog.cpp @@ -1,5 +1,8 @@ #include "add_label_dialog.h" +#include +#include + namespace { const char *labelColorNames[] = { QT_TR_NOOP("red"), diff --git a/YACReaderLibrary/add_label_dialog.h b/YACReaderLibrary/add_label_dialog.h index e16216d64..fd9431197 100644 --- a/YACReaderLibrary/add_label_dialog.h +++ b/YACReaderLibrary/add_label_dialog.h @@ -1,7 +1,10 @@ #ifndef ADD_LABEL_DIALOG_H #define ADD_LABEL_DIALOG_H -#include +#include +#include +#include +#include #include "yacreader_global.h" #include "themable.h" diff --git a/YACReaderLibrary/bundle_creator.h b/YACReaderLibrary/bundle_creator.h index a5ed56f60..7fb05e710 100644 --- a/YACReaderLibrary/bundle_creator.h +++ b/YACReaderLibrary/bundle_creator.h @@ -1,7 +1,7 @@ #ifndef __BUNDLE_CREATOR_H #define __BUNDLE_CREATOR_H -#include +#include class BundleCreator : public QObject { diff --git a/YACReaderLibrary/classic_comics_view.cpp b/YACReaderLibrary/classic_comics_view.cpp index e3eccd485..6c5d883fe 100644 --- a/YACReaderLibrary/classic_comics_view.cpp +++ b/YACReaderLibrary/classic_comics_view.cpp @@ -2,7 +2,15 @@ #include "yacreader_global.h" -#include "QStackedWidget" +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "comic_flow_widget.h" #include "shortcuts_manager.h" diff --git a/YACReaderLibrary/classic_comics_view.h b/YACReaderLibrary/classic_comics_view.h index af67ee676..836dce9c1 100644 --- a/YACReaderLibrary/classic_comics_view.h +++ b/YACReaderLibrary/classic_comics_view.h @@ -4,8 +4,10 @@ #include "comics_view.h" #include "themable.h" +#include #include #include +#include class QSplitter; class QStackedWidget; diff --git a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp index 5efab5272..acdc37aca 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp +++ b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp @@ -1,5 +1,7 @@ #include "comic_vine_dialog.h" +#include #include +#include #include #include #include @@ -7,7 +9,6 @@ #include #include #include -#include #include #include "data_base_management.h" #include diff --git a/YACReaderLibrary/comic_vine/search_single_comic.h b/YACReaderLibrary/comic_vine/search_single_comic.h index e3a1bd165..7fa7151e7 100644 --- a/YACReaderLibrary/comic_vine/search_single_comic.h +++ b/YACReaderLibrary/comic_vine/search_single_comic.h @@ -1,8 +1,6 @@ #ifndef SEARCH_SINGLE_COMIC_H #define SEARCH_SINGLE_COMIC_H -#include - #include "scraper_checkbox.h" #include "themable.h" diff --git a/YACReaderLibrary/comic_vine/search_volume.h b/YACReaderLibrary/comic_vine/search_volume.h index 9d874273e..2fa386085 100644 --- a/YACReaderLibrary/comic_vine/search_volume.h +++ b/YACReaderLibrary/comic_vine/search_volume.h @@ -1,7 +1,9 @@ #ifndef SEARCH_VOLUME_H #define SEARCH_VOLUME_H -#include +#include +#include + #include "scraper_checkbox.h" #include "themable.h" diff --git a/YACReaderLibrary/comic_vine/select_comic.h b/YACReaderLibrary/comic_vine/select_comic.h index e6c7f3c8a..cf2b290c2 100644 --- a/YACReaderLibrary/comic_vine/select_comic.h +++ b/YACReaderLibrary/comic_vine/select_comic.h @@ -1,8 +1,6 @@ #ifndef SELECT_COMIC_H #define SELECT_COMIC_H -#include - #include "scraper_results_paginator.h" #include "themable.h" diff --git a/YACReaderLibrary/comic_vine/select_volume.cpp b/YACReaderLibrary/comic_vine/select_volume.cpp index 66e6c5ee4..924c6358b 100644 --- a/YACReaderLibrary/comic_vine/select_volume.cpp +++ b/YACReaderLibrary/comic_vine/select_volume.cpp @@ -21,7 +21,6 @@ #include "comic_vine_client.h" #include "scraper_scroll_label.h" -#include "response_parser.h" #include "scraper_results_paginator.h" #include "selected_volume_info.h" diff --git a/YACReaderLibrary/comic_vine/select_volume.h b/YACReaderLibrary/comic_vine/select_volume.h index be50d2bbd..077937874 100644 --- a/YACReaderLibrary/comic_vine/select_volume.h +++ b/YACReaderLibrary/comic_vine/select_volume.h @@ -1,8 +1,6 @@ #ifndef SELECT_VOLUME_H #define SELECT_VOLUME_H -#include - #include "scraper_results_paginator.h" #include "selected_volume_info.h" #include "volume_search_query.h" diff --git a/YACReaderLibrary/comic_vine/sort_volume_comics.h b/YACReaderLibrary/comic_vine/sort_volume_comics.h index c3a1a160f..b516f7c54 100644 --- a/YACReaderLibrary/comic_vine/sort_volume_comics.h +++ b/YACReaderLibrary/comic_vine/sort_volume_comics.h @@ -1,7 +1,6 @@ #ifndef SORT_VOLUME_COMICS_H #define SORT_VOLUME_COMICS_H -#include #include #include #include diff --git a/YACReaderLibrary/comics_remover.h b/YACReaderLibrary/comics_remover.h index c46a4cbe5..f153af6e4 100644 --- a/YACReaderLibrary/comics_remover.h +++ b/YACReaderLibrary/comics_remover.h @@ -4,7 +4,6 @@ #include #include -#include class ComicsRemover : public QObject { diff --git a/YACReaderLibrary/comics_view.cpp b/YACReaderLibrary/comics_view.cpp index f3e705f12..5e537837d 100644 --- a/YACReaderLibrary/comics_view.cpp +++ b/YACReaderLibrary/comics_view.cpp @@ -5,7 +5,7 @@ #include "QsLog.h" -#include +#include #include ComicsView::ComicsView(QWidget *parent) diff --git a/YACReaderLibrary/comics_view.h b/YACReaderLibrary/comics_view.h index 484c73543..f516d2d46 100644 --- a/YACReaderLibrary/comics_view.h +++ b/YACReaderLibrary/comics_view.h @@ -1,7 +1,9 @@ #ifndef COMICS_VIEW_H #define COMICS_VIEW_H -#include +#include +#include +#include #include "comic_model.h" diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index d85339b04..8701aca5f 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include "comic_item.h" #include "comic_model.h" @@ -11,6 +11,7 @@ #include "comic_db.h" #include "db_helper.h" #include "reading_list_model.h" +#include "yacreader_global_gui.h" #ifdef use_unarr #include diff --git a/YACReaderLibrary/db/comic_model.h b/YACReaderLibrary/db/comic_model.h index d82b8369a..484a69f66 100644 --- a/YACReaderLibrary/db/comic_model.h +++ b/YACReaderLibrary/db/comic_model.h @@ -8,7 +8,7 @@ #include #include -#include "yacreader_global_gui.h" +#include "yacreader_global.h" class ComicDB; diff --git a/YACReaderLibrary/db/comic_query_result_processor.cpp b/YACReaderLibrary/db/comic_query_result_processor.cpp index e1cf5e526..da0c9c5d0 100644 --- a/YACReaderLibrary/db/comic_query_result_processor.cpp +++ b/YACReaderLibrary/db/comic_query_result_processor.cpp @@ -1,5 +1,7 @@ #include "comic_query_result_processor.h" +#include + #include "comic_item.h" #include "comic_model.h" #include "data_base_management.h" diff --git a/YACReaderLibrary/db/comic_query_result_processor.h b/YACReaderLibrary/db/comic_query_result_processor.h index 1a7359ee8..a99623ad9 100644 --- a/YACReaderLibrary/db/comic_query_result_processor.h +++ b/YACReaderLibrary/db/comic_query_result_processor.h @@ -4,7 +4,6 @@ #include #include -#include "yacreader_global.h" #include "concurrent_queue.h" class ComicItem; diff --git a/YACReaderLibrary/db/data_base_management.cpp b/YACReaderLibrary/db/data_base_management.cpp index 2a3ad18bd..0a1bc6560 100644 --- a/YACReaderLibrary/db/data_base_management.cpp +++ b/YACReaderLibrary/db/data_base_management.cpp @@ -1,10 +1,12 @@ #include "data_base_management.h" #include +#include +#include +#include +#include #include "initial_comic_info_extractor.h" -#include "check_new_version.h" #include "db_helper.h" -#include "yacreader_libraries.h" #include "QsLog.h" diff --git a/YACReaderLibrary/db/data_base_management.h b/YACReaderLibrary/db/data_base_management.h index 3bb844e8c..c1d4aa7d2 100644 --- a/YACReaderLibrary/db/data_base_management.h +++ b/YACReaderLibrary/db/data_base_management.h @@ -2,7 +2,6 @@ #define __DATA_BASE_MANAGEMENT_H #include -#include #include class ComicsInfoExporter : public QThread diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 17b70cf6e..5d36f4473 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -7,10 +7,10 @@ #include "qnaturalsorting.h" #include "yacreader_global.h" -#include "yacreader_global_gui.h" -#include #include +#include +#include #include diff --git a/YACReaderLibrary/db/folder_query_result_processor.cpp b/YACReaderLibrary/db/folder_query_result_processor.cpp index ec276a592..c936c5094 100644 --- a/YACReaderLibrary/db/folder_query_result_processor.cpp +++ b/YACReaderLibrary/db/folder_query_result_processor.cpp @@ -5,8 +5,9 @@ #include "data_base_management.h" #include "search_query.h" -#include #include +#include +#include // Copy/pasted from "folder_model.cpp" #define ROOT 1 diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index d66919301..81a7df168 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -1,12 +1,10 @@ #include "query_parser.h" +#include #include -#include #include #include -#include - const std::map> QueryParser::fieldNames { { FieldType::numeric, { "numpages", "count", "arccount", "alternateCount", "rating" } }, { FieldType::text, { "date", "number", "arcnumber", "title", "volume", "storyarc", "genere", "writer", "penciller", "inker", "colorist", "letterer", "coverartist", "publisher", "format", "agerating", "synopsis", "characters", "notes", "editor", "imprint", "teams", "locations", "series", "alternateSeries", "alternateNumber", "languageISO", "seriesGroup", "mainCharacterOrTeam", "review", "tags" } }, diff --git a/YACReaderLibrary/db/reading_list_item.h b/YACReaderLibrary/db/reading_list_item.h index 58af7483c..81876887b 100644 --- a/YACReaderLibrary/db/reading_list_item.h +++ b/YACReaderLibrary/db/reading_list_item.h @@ -4,7 +4,6 @@ #include #include -#include "yacreader_global_gui.h" #include "reading_list_model.h" // TODO add propper constructors, using QList is not safe diff --git a/YACReaderLibrary/db/reading_list_model.cpp b/YACReaderLibrary/db/reading_list_model.cpp index 55aa626ec..ca19bc55f 100644 --- a/YACReaderLibrary/db/reading_list_model.cpp +++ b/YACReaderLibrary/db/reading_list_model.cpp @@ -8,7 +8,9 @@ #include "QsLog.h" -#include +#include + +#include "yacreader_global_gui.h" ReadingListModel::ReadingListModel(QObject *parent) : QAbstractItemModel(parent), rootItem(0) diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index 42d1bf822..ea08ce1b5 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -9,11 +9,11 @@ #include #include #include +#include #include #include #include -#include #include "reading_list.h" #include "library_item.h" diff --git a/YACReaderLibrary/empty_container_info.cpp b/YACReaderLibrary/empty_container_info.cpp index e06eabfe3..b6ee15db3 100644 --- a/YACReaderLibrary/empty_container_info.cpp +++ b/YACReaderLibrary/empty_container_info.cpp @@ -1,6 +1,6 @@ #include "empty_container_info.h" -#include "yacreader_global.h" +#include EmptyContainerInfo::EmptyContainerInfo(QWidget *parent) : QWidget(parent), iconLabel(new QLabel()), titleLabel(new QLabel()) diff --git a/YACReaderLibrary/empty_container_info.h b/YACReaderLibrary/empty_container_info.h index ac61a3ec6..9adbfa9d5 100644 --- a/YACReaderLibrary/empty_container_info.h +++ b/YACReaderLibrary/empty_container_info.h @@ -1,7 +1,12 @@ #ifndef EMPTY_CONTAINER_INFO_H #define EMPTY_CONTAINER_INFO_H -#include +#include +#include +#include +#include +#include +#include #include "themable.h" diff --git a/YACReaderLibrary/empty_folder_widget.h b/YACReaderLibrary/empty_folder_widget.h index 028039257..1b8fdf695 100644 --- a/YACReaderLibrary/empty_folder_widget.h +++ b/YACReaderLibrary/empty_folder_widget.h @@ -1,7 +1,6 @@ #ifndef EMPTY_FOLDER_WIDGET_H #define EMPTY_FOLDER_WIDGET_H -#include #include "empty_container_info.h" class EmptyFolderWidget : public EmptyContainerInfo diff --git a/YACReaderLibrary/empty_label_widget.h b/YACReaderLibrary/empty_label_widget.h index a9ac9826e..c17dfd55f 100644 --- a/YACReaderLibrary/empty_label_widget.h +++ b/YACReaderLibrary/empty_label_widget.h @@ -1,9 +1,8 @@ #ifndef EMPTY_LABEL_WIDGET_H #define EMPTY_LABEL_WIDGET_H -#include #include "empty_container_info.h" -#include "yacreader_global_gui.h" +#include "yacreader_global.h" class EmptyLabelWidget : public EmptyContainerInfo { diff --git a/YACReaderLibrary/empty_reading_list_widget.h b/YACReaderLibrary/empty_reading_list_widget.h index 70ef65eb5..7abd2760e 100644 --- a/YACReaderLibrary/empty_reading_list_widget.h +++ b/YACReaderLibrary/empty_reading_list_widget.h @@ -1,7 +1,6 @@ #ifndef EMPTY_READING_LIST_WIDGET_H #define EMPTY_READING_LIST_WIDGET_H -#include #include "empty_container_info.h" class EmptyReadingListWidget : public EmptyContainerInfo diff --git a/YACReaderLibrary/empty_special_list.h b/YACReaderLibrary/empty_special_list.h index 0c926144a..87967c9ce 100644 --- a/YACReaderLibrary/empty_special_list.h +++ b/YACReaderLibrary/empty_special_list.h @@ -1,7 +1,6 @@ #ifndef EMPTY_SPECIAL_LIST_H #define EMPTY_SPECIAL_LIST_H -#include #include "empty_container_info.h" class EmptySpecialListWidget : public EmptyContainerInfo diff --git a/YACReaderLibrary/folder_content_view.cpp b/YACReaderLibrary/folder_content_view.cpp index 77106bc7a..ec01ab003 100644 --- a/YACReaderLibrary/folder_content_view.cpp +++ b/YACReaderLibrary/folder_content_view.cpp @@ -2,18 +2,20 @@ #include "folder_model.h" #include "grid_comics_view.h" -#include "yacreader_global.h" #include "yacreader_global_gui.h" #include "yacreader_tool_bar_stretch.h" #include "comic.h" #include "comic_files_manager.h" -#include "theme_manager.h" #include "QsLog.h" +#include +#include #include #include #include +#include +#include using namespace YACReader; diff --git a/YACReaderLibrary/folder_content_view.h b/YACReaderLibrary/folder_content_view.h index cd0187f72..3e15797a9 100644 --- a/YACReaderLibrary/folder_content_view.h +++ b/YACReaderLibrary/folder_content_view.h @@ -1,7 +1,10 @@ #ifndef FOLDERCONTENTVIEW_H #define FOLDERCONTENTVIEW_H -#include +#include +#include +#include +#include #include "comic_model.h" #include "themable.h" diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index c93ffcd26..601d9df52 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -1,15 +1,19 @@ #include "grid_comics_view.h" -#include +#include +#include +#include +#include +#include +#include #include -#include +#include +#include +#include "yacreader_global_gui.h" #include "comic.h" -#include "theme_manager.h" #include "comic_files_manager.h" #include "QsLog.h" -#include "yacreader_global.h" -#include "yacreader_tool_bar_stretch.h" #include "comic_db.h" #include "yacreader_comics_selection_helper.h" #include "yacreader_comic_info_helper.h" diff --git a/YACReaderLibrary/grid_comics_view.h b/YACReaderLibrary/grid_comics_view.h index 6ba587fdd..9f60201d9 100644 --- a/YACReaderLibrary/grid_comics_view.h +++ b/YACReaderLibrary/grid_comics_view.h @@ -4,6 +4,7 @@ #include "comics_view.h" #include "themable.h" +#include #include #include "comic_db.h" diff --git a/YACReaderLibrary/import_widget.h b/YACReaderLibrary/import_widget.h index 833660629..9e54ba5ec 100644 --- a/YACReaderLibrary/import_widget.h +++ b/YACReaderLibrary/import_widget.h @@ -1,7 +1,15 @@ #ifndef IMPORT_WIDGET_H #define IMPORT_WIDGET_H -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "themable.h" diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp index 5e506d5cc..b801b6d5a 100644 --- a/YACReaderLibrary/info_comics_view.cpp +++ b/YACReaderLibrary/info_comics_view.cpp @@ -1,15 +1,14 @@ #include "info_comics_view.h" -#include "yacreader_global.h" -#include "theme_manager.h" - -#include +#include +#include #include +#include +#include #include "comic.h" #include "comic_files_manager.h" #include "comic_model.h" -#include "comic_db.h" #include "yacreader_comic_info_helper.h" #include "yacreader_comics_selection_helper.h" diff --git a/YACReaderLibrary/initial_comic_info_extractor.h b/YACReaderLibrary/initial_comic_info_extractor.h index 5382d81f3..3e8f99cea 100644 --- a/YACReaderLibrary/initial_comic_info_extractor.h +++ b/YACReaderLibrary/initial_comic_info_extractor.h @@ -1,7 +1,11 @@ #ifndef INITIALCOMICINFOEXTRACTOR_H #define INITIALCOMICINFOEXTRACTOR_H -#include +#include +#include +#include +#include +#include namespace YACReader { class InitialComicInfoExtractor : public QObject diff --git a/YACReaderLibrary/library_comic_opener.cpp b/YACReaderLibrary/library_comic_opener.cpp index ede63f33b..026d677ca 100644 --- a/YACReaderLibrary/library_comic_opener.cpp +++ b/YACReaderLibrary/library_comic_opener.cpp @@ -3,7 +3,6 @@ #include "comic_db.h" #include -#include bool YACReader::openComic(const ComicDB &comic, unsigned long long libraryId, diff --git a/YACReaderLibrary/library_creator.cpp b/YACReaderLibrary/library_creator.cpp index 877a96bbc..139dea240 100644 --- a/YACReaderLibrary/library_creator.cpp +++ b/YACReaderLibrary/library_creator.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include diff --git a/YACReaderLibrary/library_creator.h b/YACReaderLibrary/library_creator.h index 0c13f3447..401e08cd9 100644 --- a/YACReaderLibrary/library_creator.h +++ b/YACReaderLibrary/library_creator.h @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index e7e9551e4..d1689ede2 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -3,11 +3,23 @@ #include "yacreader_global.h" #include "yacreader_global_gui.h" +#include +#include #include +#include +#include +#include +#include +#include #include +#include +#include #include +#include +#include #include #include +#include #include #include #include @@ -19,6 +31,11 @@ #include #include +#ifdef Q_OS_WIN +#include +#include +#endif + #include "folder_item.h" #include "data_base_management.h" #include "no_libraries_widget.h" @@ -51,6 +68,7 @@ #include "comics_remover.h" #include "yacreader_library_list_widget.h" #include "yacreader_folders_view.h" +#include "yacreader_reading_lists_view.h" #include "comic_vine_dialog.h" #include "api_key_dialog.h" @@ -63,7 +81,6 @@ #include "comic_files_manager.h" #include "reading_list_model.h" -#include "yacreader_reading_lists_view.h" #include "add_label_dialog.h" #include "yacreader_history_controller.h" @@ -84,18 +101,11 @@ #include "cover_utils.h" -#include "theme_manager.h" - #include "QsLog.h" #include "yacreader_http_server.h" extern YACReaderHttpServer *httpServer; -#ifdef Q_OS_WIN -#include -#include -#endif - #include namespace { diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index 091ef2757..4e5e0a885 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -8,7 +8,6 @@ #include "library_window_actions.h" #include "yacreader_global.h" -#include "yacreader_global_gui.h" #include "yacreader_libraries.h" #include "libraries_update_coordinator.h" diff --git a/YACReaderLibrary/library_window_actions.cpp b/YACReaderLibrary/library_window_actions.cpp index ce6e9f0fe..4c6edbded 100644 --- a/YACReaderLibrary/library_window_actions.cpp +++ b/YACReaderLibrary/library_window_actions.cpp @@ -15,7 +15,6 @@ #include "theme_manager.h" #include -#include LibraryWindowActions::LibraryWindowActions() { diff --git a/YACReaderLibrary/options_dialog.cpp b/YACReaderLibrary/options_dialog.cpp index aa00080cc..288b162b2 100644 --- a/YACReaderLibrary/options_dialog.cpp +++ b/YACReaderLibrary/options_dialog.cpp @@ -2,14 +2,21 @@ #include "yacreader_3d_flow_config_widget.h" #include "api_key_dialog.h" +#include "appearance_tab_widget.h" +#include "theme_factory.h" +#include "theme_manager.h" #include "yacreader_global_gui.h" -#include "theme_manager.h" -#include "theme_factory.h" -#include "appearance_tab_widget.h" #include "app_language_utils.h" +#include +#include +#include +#include #include +#include +#include +#include FlowType flowType = Strip; diff --git a/YACReaderLibrary/options_dialog.h b/YACReaderLibrary/options_dialog.h index 68faa16bd..af878bfa9 100644 --- a/YACReaderLibrary/options_dialog.h +++ b/YACReaderLibrary/options_dialog.h @@ -1,11 +1,17 @@ #ifndef __OPTIONS_DIALOG_H #define __OPTIONS_DIALOG_H -#include - -#include "yacreader_options_dialog.h" +#include +#include +#include +#include +#include +#include +#include +#include #include "yacreader_global.h" +#include "yacreader_options_dialog.h" using namespace YACReader; diff --git a/YACReaderLibrary/properties_dialog.cpp b/YACReaderLibrary/properties_dialog.cpp index 435e0d6dc..b23d5dd8c 100644 --- a/YACReaderLibrary/properties_dialog.cpp +++ b/YACReaderLibrary/properties_dialog.cpp @@ -10,6 +10,7 @@ #include "db_helper.h" #include "yacreader_cover_label.h" +#include #include #include #include diff --git a/YACReaderLibrary/recent_visibility_coordinator.h b/YACReaderLibrary/recent_visibility_coordinator.h index 22fb1db4a..518c9c17b 100644 --- a/YACReaderLibrary/recent_visibility_coordinator.h +++ b/YACReaderLibrary/recent_visibility_coordinator.h @@ -2,8 +2,6 @@ #ifndef RECENT_VISIBILITY_COORDINATOR_H #define RECENT_VISIBILITY_COORDINATOR_H -#include - #include "folder_model.h" #include "comic_model.h" #include "folder_content_view.h" diff --git a/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.cpp index c2d457be3..816ac19eb 100644 --- a/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.cpp @@ -4,7 +4,6 @@ #include "yacreader_libraries.h" #include "yacreader_http_session.h" -#include "template.h" #include "../static.h" #include "comic_db.h" @@ -14,8 +13,6 @@ #include "QsLog.h" -#include - using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/comiccontrollerinreadinglist_v2.cpp b/YACReaderLibrary/server/controllers/v2/comiccontrollerinreadinglist_v2.cpp index 96113d2e2..82b54030c 100644 --- a/YACReaderLibrary/server/controllers/v2/comiccontrollerinreadinglist_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/comiccontrollerinreadinglist_v2.cpp @@ -4,18 +4,13 @@ #include "yacreader_libraries.h" #include "yacreader_http_session.h" -#include "template.h" #include "../static.h" #include "comic_db.h" #include "comic.h" -#include "qnaturalsorting.h" - #include "QsLog.h" -#include - using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/comicdownloadinfocontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/comicdownloadinfocontroller_v2.cpp index c9a97a0bc..903fa9aea 100644 --- a/YACReaderLibrary/server/controllers/v2/comicdownloadinfocontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/comicdownloadinfocontroller_v2.cpp @@ -1,7 +1,8 @@ #include "comicdownloadinfocontroller_v2.h" +#include + #include "db_helper.h" -#include "yacreader_libraries.h" #include "comic_db.h" diff --git a/YACReaderLibrary/server/controllers/v2/comicfullinfocontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/comicfullinfocontroller_v2.cpp index 8f06c83b5..2f5af2fec 100644 --- a/YACReaderLibrary/server/controllers/v2/comicfullinfocontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/comicfullinfocontroller_v2.cpp @@ -8,8 +8,6 @@ #include "yacreader_libraries.h" #include "yacreader_server_data_helper.h" -#include - using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; using namespace std; diff --git a/YACReaderLibrary/server/controllers/v2/errorcontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/errorcontroller_v2.cpp index cedbbc30b..e0f6c618b 100644 --- a/YACReaderLibrary/server/controllers/v2/errorcontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/errorcontroller_v2.cpp @@ -1,8 +1,5 @@ #include "errorcontroller_v2.h" -#include "template.h" -#include "../static.h" - using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp index 6f99993ec..0ecc765d2 100644 --- a/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp @@ -14,7 +14,6 @@ #include "QsLog.h" #include -#include using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.cpp index c6988435e..5b5c1e3db 100644 --- a/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.cpp @@ -1,12 +1,12 @@ #include "folderinfocontroller_v2.h" + +#include + #include "db_helper.h" //get libraries #include "folder.h" #include "comic_db.h" -#include "template.h" -#include "../static.h" - using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.cpp index 6145cf63d..7468bb40d 100644 --- a/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.cpp @@ -1,13 +1,11 @@ #include "readinglistinfocontroller_v2.h" +#include + #include "db_helper.h" -#include "folder.h" #include "comic_db.h" -#include "template.h" -#include "../static.h" - using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.cpp index 29dad28cb..215930678 100644 --- a/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.cpp @@ -1,13 +1,11 @@ #include "taginfocontroller_v2.h" +#include + #include "db_helper.h" -#include "folder.h" #include "comic_db.h" -#include "template.h" -#include "../static.h" - using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp index 943248385..03401063d 100644 --- a/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp @@ -1,13 +1,10 @@ #include "updatecomiccontroller_v2.h" -#include "db_helper.h" -#include "yacreader_libraries.h" +#include -#include "template.h" -#include "../static.h" +#include "db_helper.h" #include "comic_db.h" -#include "comic.h" #include "QsLog.h" diff --git a/YACReaderLibrary/server/yacreader_http_session_store.cpp b/YACReaderLibrary/server/yacreader_http_session_store.cpp index aadb6a313..b8fa889a7 100644 --- a/YACReaderLibrary/server/yacreader_http_session_store.cpp +++ b/YACReaderLibrary/server/yacreader_http_session_store.cpp @@ -1,5 +1,7 @@ #include "yacreader_http_session_store.h" +#include + #include "yacreader_http_session.h" YACReaderHttpSessionStore::YACReaderHttpSessionStore(QObject *parent) diff --git a/YACReaderLibrary/server/yacreader_http_session_store.h b/YACReaderLibrary/server/yacreader_http_session_store.h index c3a6caa22..6771c999d 100644 --- a/YACReaderLibrary/server/yacreader_http_session_store.h +++ b/YACReaderLibrary/server/yacreader_http_session_store.h @@ -1,8 +1,9 @@ #ifndef YACREADERHTTPSESSIONSTORE_H #define YACREADERHTTPSESSIONSTORE_H +#include +#include #include -#include class YACReaderHttpSession; diff --git a/YACReaderLibrary/server_config_dialog.cpp b/YACReaderLibrary/server_config_dialog.cpp index 9352db740..924349d2f 100644 --- a/YACReaderLibrary/server_config_dialog.cpp +++ b/YACReaderLibrary/server_config_dialog.cpp @@ -11,7 +11,6 @@ #include "ip_config_helper.h" #include "qrcodegen.hpp" -#include "theme_manager.h" extern YACReaderHttpServer *httpServer; diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index bc0ca8ccb..6c208d699 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -1,7 +1,6 @@ #ifndef THEME_H #define THEME_H -#include #include #include "yacreader_icon.h" diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 550611d87..e7bcc688a 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -1,6 +1,9 @@ #include "theme_factory.h" #include +#include +#include +#include #include "icon_utils.h" #include "yacreader_global.h" diff --git a/YACReaderLibrary/trayicon_controller.cpp b/YACReaderLibrary/trayicon_controller.cpp index de7902eeb..2fbda2e0c 100644 --- a/YACReaderLibrary/trayicon_controller.cpp +++ b/YACReaderLibrary/trayicon_controller.cpp @@ -4,7 +4,7 @@ #include "library_window.h" -#include +#include #include #ifdef Q_OS_MACOS diff --git a/YACReaderLibrary/trayicon_controller.h b/YACReaderLibrary/trayicon_controller.h index 1ff9d407d..5d8687b9a 100644 --- a/YACReaderLibrary/trayicon_controller.h +++ b/YACReaderLibrary/trayicon_controller.h @@ -1,7 +1,9 @@ #ifndef TRAYICON_CONTROLLER_H #define TRAYICON_CONTROLLER_H -#include +#include +#include +#include #include class LibraryWindow; diff --git a/YACReaderLibrary/xml_info_library_scanner.cpp b/YACReaderLibrary/xml_info_library_scanner.cpp index 2740e416a..20cadfbd3 100644 --- a/YACReaderLibrary/xml_info_library_scanner.cpp +++ b/YACReaderLibrary/xml_info_library_scanner.cpp @@ -1,5 +1,7 @@ #include "xml_info_library_scanner.h" +#include + #include "comic_db.h" #include "data_base_management.h" #include "db_helper.h" diff --git a/YACReaderLibrary/yacreader_comics_selection_helper.h b/YACReaderLibrary/yacreader_comics_selection_helper.h index aad8d799b..05566d89d 100644 --- a/YACReaderLibrary/yacreader_comics_selection_helper.h +++ b/YACReaderLibrary/yacreader_comics_selection_helper.h @@ -1,8 +1,10 @@ #ifndef YACREADERCOMICSSELECTIONHELPER_H #define YACREADERCOMICSSELECTIONHELPER_H +#include +#include +#include #include -#include class ComicModel; diff --git a/YACReaderLibrary/yacreader_content_views_manager.cpp b/YACReaderLibrary/yacreader_content_views_manager.cpp index b36f33d65..8d56c1ea1 100644 --- a/YACReaderLibrary/yacreader_content_views_manager.cpp +++ b/YACReaderLibrary/yacreader_content_views_manager.cpp @@ -4,21 +4,22 @@ #include "classic_comics_view.h" #include "grid_comics_view.h" +#include "folder_content_view.h" + +#include "yacreader_sidebar.h" + #include "info_comics_view.h" #include "comics_view_transition.h" -#include "folder_content_view.h" #include "empty_label_widget.h" #include "empty_special_list.h" #include "empty_reading_list_widget.h" #include "empty_folder_widget.h" #include "no_search_results_widget.h" - -#include "yacreader_sidebar.h" +#include "yacreader_options_dialog.h" +#include "options_dialog.h" //-- #include "yacreader_search_line_edit.h" -#include "options_dialog.h" -#include "theme_manager.h" YACReaderContentViewsManager::YACReaderContentViewsManager(QSettings *settings, LibraryWindow *parent) : QObject(parent), libraryWindow(parent), classicComicsView(nullptr), gridComicsView(nullptr), infoComicsView(nullptr) diff --git a/YACReaderLibrary/yacreader_content_views_manager.h b/YACReaderLibrary/yacreader_content_views_manager.h index 8ef45fd17..ed03b2d8c 100644 --- a/YACReaderLibrary/yacreader_content_views_manager.h +++ b/YACReaderLibrary/yacreader_content_views_manager.h @@ -1,7 +1,8 @@ #ifndef YACREADERCONTENTVIEWSMANAGER_H #define YACREADERCONTENTVIEWSMANAGER_H -#include +#include +#include #include "yacreader_global_gui.h" #include "themable.h" diff --git a/YACReaderLibrary/yacreader_folders_view.cpp b/YACReaderLibrary/yacreader_folders_view.cpp index 27346279e..546a06952 100644 --- a/YACReaderLibrary/yacreader_folders_view.cpp +++ b/YACReaderLibrary/yacreader_folders_view.cpp @@ -1,9 +1,7 @@ #include "yacreader_folders_view.h" -#include "yacreader_global.h" #include "yacreader_treeview.h" -#include "folder_item.h" #include "folder_model.h" #include "comic.h" diff --git a/YACReaderLibrary/yacreader_folders_view.h b/YACReaderLibrary/yacreader_folders_view.h index efb8d3c79..534859dba 100644 --- a/YACReaderLibrary/yacreader_folders_view.h +++ b/YACReaderLibrary/yacreader_folders_view.h @@ -1,11 +1,13 @@ #ifndef YACREADER_FOLDERS_VIEW_H #define YACREADER_FOLDERS_VIEW_H +#include +#include +#include + #include "yacreader_treeview.h" #include "theme.h" -#include - class YACReaderFoldersView : public YACReaderTreeView { Q_OBJECT diff --git a/YACReaderLibrary/yacreader_navigation_controller.cpp b/YACReaderLibrary/yacreader_navigation_controller.cpp index 43ab4bee0..0fb74f3cd 100644 --- a/YACReaderLibrary/yacreader_navigation_controller.cpp +++ b/YACReaderLibrary/yacreader_navigation_controller.cpp @@ -3,8 +3,6 @@ #include #include "library_window.h" -#include "yacreader_folders_view.h" -#include "yacreader_reading_lists_view.h" #include "folder_item.h" #include "yacreader_history_controller.h" #include "comic_model.h" @@ -12,11 +10,12 @@ #include "reading_list_model.h" #include "comics_view.h" #include "folder_content_view.h" -#include "yacreader_search_line_edit.h" #include "yacreader_global.h" #include "empty_label_widget.h" #include "empty_special_list.h" #include "yacreader_content_views_manager.h" +#include "yacreader_folders_view.h" +#include "yacreader_reading_lists_view.h" #include "QsLog.h" diff --git a/YACReaderLibrary/yacreader_reading_lists_view.cpp b/YACReaderLibrary/yacreader_reading_lists_view.cpp index 62b4aea28..080845569 100644 --- a/YACReaderLibrary/yacreader_reading_lists_view.cpp +++ b/YACReaderLibrary/yacreader_reading_lists_view.cpp @@ -1,6 +1,5 @@ #include "yacreader_reading_lists_view.h" -#include "reading_list_item.h" #include "reading_list_model.h" YACReaderReadingListsView::YACReaderReadingListsView(QWidget *parent) diff --git a/YACReaderLibrary/yacreader_reading_lists_view.h b/YACReaderLibrary/yacreader_reading_lists_view.h index 12965afe1..566ab45e7 100644 --- a/YACReaderLibrary/yacreader_reading_lists_view.h +++ b/YACReaderLibrary/yacreader_reading_lists_view.h @@ -1,9 +1,11 @@ #ifndef YACREADER_READING_LISTS_VIEW_H #define YACREADER_READING_LISTS_VIEW_H -#include "yacreader_treeview.h" +#include +#include +#include -#include +#include "yacreader_treeview.h" class YACReaderReadingListsView : public YACReaderTreeView { diff --git a/YACReaderLibraryServer/main.cpp b/YACReaderLibraryServer/main.cpp index ac6fb4351..acd064e44 100644 --- a/YACReaderLibraryServer/main.cpp +++ b/YACReaderLibraryServer/main.cpp @@ -19,8 +19,6 @@ #include "console_ui_library_creator.h" -#include - #include "QsLog.h" #include "QsLogDest.h" #include "qrcodegen.hpp" diff --git a/common/check_new_version.h b/common/check_new_version.h index 260ab426f..37cae0563 100644 --- a/common/check_new_version.h +++ b/common/check_new_version.h @@ -2,7 +2,6 @@ #define __CHECKUPDATE_H #include "http_worker.h" -#include "yacreader_global.h" #include #include diff --git a/common/comic.cpp b/common/comic.cpp index 04ea4886d..0be6a3a00 100644 --- a/common/comic.cpp +++ b/common/comic.cpp @@ -1,5 +1,6 @@ #include "comic.h" +#include #include #include #include diff --git a/common/comic.h b/common/comic.h index 2241eb78c..91952e6f3 100644 --- a/common/comic.h +++ b/common/comic.h @@ -2,7 +2,6 @@ #define __COMIC_H #include #include -#include #include #include diff --git a/common/custom_widgets.cpp b/common/custom_widgets.cpp index be7653933..e69de29bb 100644 --- a/common/custom_widgets.cpp +++ b/common/custom_widgets.cpp @@ -1 +0,0 @@ -#include "custom_widgets.h" diff --git a/common/rhi/yacreader_comic_flow_rhi.h b/common/rhi/yacreader_comic_flow_rhi.h index c64db0e89..61d65300e 100644 --- a/common/rhi/yacreader_comic_flow_rhi.h +++ b/common/rhi/yacreader_comic_flow_rhi.h @@ -3,6 +3,9 @@ #include "yacreader_flow_rhi.h" +#include +#include + class ImageLoader3D; class YACReaderComicFlow3D : public YACReaderFlow3D diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index 93bd88a73..3cf29c0da 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -1,5 +1,6 @@ #include "yacreader_flow_rhi.h" #include +#include #if defined(YACREADER_RHI_PERF) #include #endif diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index b7b31fe40..89a479c75 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -8,8 +8,6 @@ #if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) #include -#include -#include #include #include "flow_types.h" diff --git a/common/rhi/yacreader_page_flow_rhi.h b/common/rhi/yacreader_page_flow_rhi.h index b188b6ff0..6ec70f9ae 100644 --- a/common/rhi/yacreader_page_flow_rhi.h +++ b/common/rhi/yacreader_page_flow_rhi.h @@ -3,6 +3,9 @@ #include "yacreader_flow_rhi.h" +#include +#include + class ImageLoaderByteArray3D; class YACReaderPageFlow3D : public YACReaderFlow3D diff --git a/common/scroll_management.cpp b/common/scroll_management.cpp index 6bdef5cd6..ddef42dc9 100644 --- a/common/scroll_management.cpp +++ b/common/scroll_management.cpp @@ -1,5 +1,4 @@ #include "scroll_management.h" -#include #include ScrollManagement::ScrollManagement() diff --git a/common/themes/icon_utils.cpp b/common/themes/icon_utils.cpp index 395347ddc..9430dae9b 100644 --- a/common/themes/icon_utils.cpp +++ b/common/themes/icon_utils.cpp @@ -1,5 +1,6 @@ #include "icon_utils.h" +#include #include #include "yacreader_global.h" diff --git a/common/themes/icon_utils.h b/common/themes/icon_utils.h index aef05bd70..952cf19ef 100644 --- a/common/themes/icon_utils.h +++ b/common/themes/icon_utils.h @@ -1,7 +1,9 @@ #ifndef ICON_UTILS_H #define ICON_UTILS_H -#include +#include +#include +#include // Render an SVG file to a QPixmap at a specific logical size with HiDPI support. // Uses QSvgRenderer to rasterize directly at the target resolution (no upscaling). diff --git a/compressed_archive/compressed_archive.cpp b/compressed_archive/compressed_archive.cpp index 2962eba74..0926e14e4 100644 --- a/compressed_archive/compressed_archive.cpp +++ b/compressed_archive/compressed_archive.cpp @@ -12,9 +12,6 @@ #include "open_callbacks.h" #include "extract_callbacks.h" -#include "7z_includes.h" -#include "lib7zip/CPP/Common/MyInitGuid.h" - #include "QsLog.h" #define _MY_WINAPI WINAPI diff --git a/custom_widgets/rounded_corners_dialog.cpp b/custom_widgets/rounded_corners_dialog.cpp index 2529b6d71..f4e32e5e6 100644 --- a/custom_widgets/rounded_corners_dialog.cpp +++ b/custom_widgets/rounded_corners_dialog.cpp @@ -1,6 +1,6 @@ #include "rounded_corners_dialog.h" -#include +#include YACReader::RoundedCornersDialog::RoundedCornersDialog(QWidget *parent) : QDialog(parent) diff --git a/custom_widgets/whats_new_controller.cpp b/custom_widgets/whats_new_controller.cpp index df550ab77..8e4b38048 100644 --- a/custom_widgets/whats_new_controller.cpp +++ b/custom_widgets/whats_new_controller.cpp @@ -3,8 +3,6 @@ #include "whats_new_dialog.h" #include "yacreader_global.h" -#include - YACReader::WhatsNewController::WhatsNewController() { } void YACReader::WhatsNewController::showWhatsNewIfNeeded(QWidget *fromParent) diff --git a/custom_widgets/whats_new_dialog.cpp b/custom_widgets/whats_new_dialog.cpp index 5718ee7ba..8f6aa98f4 100644 --- a/custom_widgets/whats_new_dialog.cpp +++ b/custom_widgets/whats_new_dialog.cpp @@ -1,7 +1,14 @@ #include "whats_new_dialog.h" -#include "yacreader_global.h" -#include +#include +#include +#include +#include +#include +#include +#include + +#include "yacreader_global.h" YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent) : RoundedCornersDialog(parent) diff --git a/custom_widgets/yacreader_library_item_widget.cpp b/custom_widgets/yacreader_library_item_widget.cpp index 295714f9c..0bd5d2c51 100644 --- a/custom_widgets/yacreader_library_item_widget.cpp +++ b/custom_widgets/yacreader_library_item_widget.cpp @@ -1,9 +1,8 @@ #include "yacreader_library_item_widget.h" -#include "yacreader_global.h" -#include "yacreader_global_gui.h" - #include + +#include "yacreader_global.h" #include #include #include diff --git a/custom_widgets/yacreader_search_line_edit.h b/custom_widgets/yacreader_search_line_edit.h index 3f901dc65..dbaeebd29 100644 --- a/custom_widgets/yacreader_search_line_edit.h +++ b/custom_widgets/yacreader_search_line_edit.h @@ -4,7 +4,6 @@ #include #include -#include "yacreader_global.h" #include "themable.h" class QToolButton; diff --git a/custom_widgets/yacreader_sidebar.cpp b/custom_widgets/yacreader_sidebar.cpp index bac2364ce..ade0550e7 100644 --- a/custom_widgets/yacreader_sidebar.cpp +++ b/custom_widgets/yacreader_sidebar.cpp @@ -6,7 +6,6 @@ #include "yacreader_folders_view.h" #include "yacreader_reading_lists_view.h" #include "yacreader_library_list_widget.h" -#include "yacreader_search_line_edit.h" #include "yacreader_titled_toolbar.h" #include "yacreader_global.h" diff --git a/custom_widgets/yacreader_sidebar.h b/custom_widgets/yacreader_sidebar.h index ca511b782..0d05c5a3b 100644 --- a/custom_widgets/yacreader_sidebar.h +++ b/custom_widgets/yacreader_sidebar.h @@ -1,7 +1,13 @@ #ifndef YACREADER_SIDEBAR_H #define YACREADER_SIDEBAR_H -#include +#include +#include +#include +#include +#include +#include +#include #include "themable.h" diff --git a/custom_widgets/yacreader_table_view.cpp b/custom_widgets/yacreader_table_view.cpp index 1075f9dd4..08b671560 100644 --- a/custom_widgets/yacreader_table_view.cpp +++ b/custom_widgets/yacreader_table_view.cpp @@ -1,6 +1,5 @@ #include "yacreader_table_view.h" -#include "yacreader_global.h" #include "yacreader_global_gui.h" #include @@ -10,7 +9,6 @@ #include #include #include -#include #include "QsLog.h" diff --git a/custom_widgets/yacreader_titled_toolbar.cpp b/custom_widgets/yacreader_titled_toolbar.cpp index 0265bc46e..ab8e04366 100644 --- a/custom_widgets/yacreader_titled_toolbar.cpp +++ b/custom_widgets/yacreader_titled_toolbar.cpp @@ -1,6 +1,5 @@ #include "yacreader_titled_toolbar.h" -#include "yacreader_global.h" #include "yacreader_busy_widget.h" #include diff --git a/custom_widgets/yacreader_treeview.cpp b/custom_widgets/yacreader_treeview.cpp index c2699bd43..5ddaadcfd 100644 --- a/custom_widgets/yacreader_treeview.cpp +++ b/custom_widgets/yacreader_treeview.cpp @@ -1,6 +1,6 @@ #include "yacreader_treeview.h" -#include "yacreader_global.h" +#include YACReaderTreeView::YACReaderTreeView(QWidget *parent) : QTreeView(parent), clicking(false) diff --git a/custom_widgets/yacreader_treeview.h b/custom_widgets/yacreader_treeview.h index 4a4d67306..a2d76daae 100644 --- a/custom_widgets/yacreader_treeview.h +++ b/custom_widgets/yacreader_treeview.h @@ -1,7 +1,14 @@ #ifndef YACREADER_TREEVIEW_H #define YACREADER_TREEVIEW_H -#include +#include +#include +#include +#include +#include +#include +#include +#include #include "themable.h" diff --git a/shortcuts_management/edit_shortcuts_dialog.cpp b/shortcuts_management/edit_shortcuts_dialog.cpp index 8face33d3..50d7f5efb 100644 --- a/shortcuts_management/edit_shortcuts_dialog.cpp +++ b/shortcuts_management/edit_shortcuts_dialog.cpp @@ -1,7 +1,5 @@ #include "edit_shortcuts_dialog.h" -#include "yacreader_global.h" - #include "actions_groups_model.h" #include "actions_shortcuts_model.h" #include "edit_shortcut_item_delegate.h" @@ -15,8 +13,6 @@ #include #include -#include "QsLog.h" - EditShortcutsDialog::EditShortcutsDialog(QWidget *parent) : QDialog(parent) { From 3709b6e737db7c4f9a479ffbe8908fc7d6b22fa6 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Fri, 13 Mar 2026 18:21:38 +0100 Subject: [PATCH 151/187] Format includes using clang-format --- .clang-format | 19 ++- YACReader/bookmarks_dialog.cpp | 8 +- YACReader/bookmarks_dialog.h | 10 +- YACReader/configuration.cpp | 7 +- YACReader/configuration.h | 14 +-- YACReader/continuous_page_widget.cpp | 5 +- YACReader/continuous_page_widget.h | 10 +- YACReader/continuous_view_model.cpp | 2 +- YACReader/goto_dialog.cpp | 2 +- YACReader/goto_dialog.h | 2 +- YACReader/goto_flow_toolbar.cpp | 6 +- YACReader/goto_flow_toolbar.h | 6 +- YACReader/goto_flow_widget.cpp | 10 +- YACReader/goto_flow_widget.h | 8 +- YACReader/magnifying_glass.cpp | 1 + YACReader/main.cpp | 19 ++- YACReader/main_window_viewer.cpp | 38 +++--- YACReader/main_window_viewer.h | 14 +-- YACReader/mouse_handler.cpp | 4 +- YACReader/options_dialog.cpp | 35 +++--- YACReader/options_dialog.h | 2 +- YACReader/page_label_widget.h | 4 +- YACReader/render.cpp | 18 +-- YACReader/render.h | 7 +- YACReader/themes/theme.h | 8 +- YACReader/themes/theme_factory.cpp | 4 +- YACReader/translator.cpp | 34 +++-- YACReader/translator.h | 7 +- YACReader/viewer.cpp | 17 +-- YACReader/viewer.h | 23 ++-- YACReader/width_slider.h | 2 +- YACReader/yacreader_local_client.cpp | 4 +- YACReader/yacreader_local_client.h | 2 +- YACReaderLibrary/add_label_dialog.h | 6 +- YACReaderLibrary/add_library_dialog.cpp | 4 +- YACReaderLibrary/classic_comics_view.cpp | 7 +- YACReaderLibrary/comic_files_manager.cpp | 8 +- YACReaderLibrary/comic_files_manager.h | 4 +- YACReaderLibrary/comic_flow_widget.cpp | 1 + YACReaderLibrary/comic_flow_widget.h | 9 +- .../comic_vine/api_key_dialog.cpp | 6 +- .../comic_vine/comic_vine_client.cpp | 2 +- .../comic_vine/comic_vine_dialog.cpp | 38 +++--- .../comic_vine/comic_vine_dialog.h | 6 +- .../comic_vine/model/local_comic_list_model.h | 4 +- .../comic_vine/model/response_parser.cpp | 1 + .../comic_vine/model/volume_comics_model.cpp | 1 + .../comic_vine/scraper_checkbox.h | 4 +- .../comic_vine/scraper_lineedit.h | 4 +- .../comic_vine/scraper_results_paginator.cpp | 1 + .../comic_vine/scraper_scroll_label.cpp | 2 +- .../comic_vine/scraper_scroll_label.h | 4 +- .../comic_vine/scraper_tableview.h | 4 +- .../comic_vine/search_single_comic.cpp | 2 +- YACReaderLibrary/comic_vine/search_volume.cpp | 2 +- YACReaderLibrary/comic_vine/search_volume.h | 6 +- YACReaderLibrary/comic_vine/select_volume.cpp | 21 ++-- YACReaderLibrary/comic_vine/select_volume.h | 2 +- .../comic_vine/series_question.cpp | 2 +- YACReaderLibrary/comic_vine/series_question.h | 4 +- .../comic_vine/sort_volume_comics.cpp | 14 +-- .../comic_vine/sort_volume_comics.h | 8 +- YACReaderLibrary/comic_vine/title_header.cpp | 2 +- YACReaderLibrary/comic_vine/title_header.h | 4 +- YACReaderLibrary/comics_remover.cpp | 6 +- YACReaderLibrary/comics_remover.h | 3 +- YACReaderLibrary/comics_view.cpp | 6 +- YACReaderLibrary/comics_view.h | 4 +- YACReaderLibrary/comics_view_transition.h | 4 +- YACReaderLibrary/create_library_dialog.cpp | 7 +- YACReaderLibrary/create_library_dialog.h | 4 +- YACReaderLibrary/db/comic_item.cpp | 4 +- YACReaderLibrary/db/comic_model.cpp | 15 +-- YACReaderLibrary/db/comic_model.h | 8 +- .../db/comic_query_result_processor.cpp | 4 +- .../db/comic_query_result_processor.h | 6 +- YACReaderLibrary/db/data_base_management.cpp | 10 +- YACReaderLibrary/db/data_base_management.h | 2 +- YACReaderLibrary/db/folder_item.cpp | 5 +- YACReaderLibrary/db/folder_item.h | 2 +- YACReaderLibrary/db/folder_model.cpp | 5 +- YACReaderLibrary/db/folder_model.h | 18 +-- .../db/folder_query_result_processor.cpp | 2 +- .../db/folder_query_result_processor.h | 4 +- YACReaderLibrary/db/query_parser.cpp | 1 + YACReaderLibrary/db/query_parser.h | 5 +- YACReaderLibrary/db/reading_list_item.cpp | 6 +- YACReaderLibrary/db/reading_list_item.h | 4 +- YACReaderLibrary/db/reading_list_model.cpp | 11 +- YACReaderLibrary/db/reading_list_model.h | 10 +- YACReaderLibrary/db/search_query.cpp | 3 +- YACReaderLibrary/db_helper.cpp | 34 +++-- YACReaderLibrary/db_helper.h | 5 +- YACReaderLibrary/empty_container_info.h | 4 +- .../export_comics_info_dialog.cpp | 10 +- YACReaderLibrary/export_library_dialog.cpp | 7 +- YACReaderLibrary/export_library_dialog.h | 2 +- YACReaderLibrary/folder_content_view.cpp | 7 +- YACReaderLibrary/folder_content_view.h | 11 +- YACReaderLibrary/grid_comics_view.cpp | 18 +-- YACReaderLibrary/grid_comics_view.h | 3 +- .../import_comics_info_dialog.cpp | 8 +- YACReaderLibrary/import_comics_info_dialog.h | 3 +- YACReaderLibrary/import_library_dialog.cpp | 6 +- YACReaderLibrary/import_library_dialog.h | 4 +- YACReaderLibrary/import_widget.cpp | 21 ++-- YACReaderLibrary/import_widget.h | 5 +- YACReaderLibrary/info_comics_view.cpp | 13 +- YACReaderLibrary/info_comics_view.h | 3 +- .../initial_comic_info_extractor.cpp | 7 +- YACReaderLibrary/ip_config_helper.cpp | 4 +- YACReaderLibrary/ip_config_helper.h | 4 + .../libraries_update_coordinator.cpp | 2 +- YACReaderLibrary/library_creator.cpp | 24 ++-- YACReaderLibrary/library_creator.h | 19 +-- YACReaderLibrary/library_window.cpp | 118 ++++++++---------- YACReaderLibrary/library_window.h | 25 ++-- YACReaderLibrary/library_window_actions.cpp | 13 +- YACReaderLibrary/library_window_actions.h | 4 +- YACReaderLibrary/main.cpp | 24 ++-- YACReaderLibrary/no_libraries_widget.cpp | 4 +- YACReaderLibrary/no_libraries_widget.h | 4 +- YACReaderLibrary/options_dialog.cpp | 5 +- YACReaderLibrary/options_dialog.h | 6 +- YACReaderLibrary/package_manager.cpp | 1 + YACReaderLibrary/properties_dialog.cpp | 25 ++-- YACReaderLibrary/properties_dialog.h | 1 - .../recent_visibility_coordinator.h | 2 +- YACReaderLibrary/rename_library_dialog.cpp | 2 +- .../controllers/v2/comiccontroller_v2.cpp | 14 +-- .../controllers/v2/comiccontroller_v2.h | 2 +- .../v2/comiccontrollerinreadinglist_v2.cpp | 13 +- .../v2/comiccontrollerinreadinglist_v2.h | 2 +- .../v2/comicdownloadinfocontroller_v2.cpp | 5 +- .../v2/comicdownloadinfocontroller_v2.h | 2 +- .../v2/comicfullinfocontroller_v2.cpp | 7 +- .../v2/comicfullinfocontroller_v2.h | 2 +- .../controllers/v2/covercontroller_v2.cpp | 6 +- .../controllers/v2/covercontroller_v2.h | 2 +- .../controllers/v2/errorcontroller_v2.h | 2 +- .../controllers/v2/favoritescontroller_v2.cpp | 3 +- .../controllers/v2/favoritescontroller_v2.h | 2 +- .../v2/foldercontentcontroller_v2.cpp | 11 +- .../v2/foldercontentcontroller_v2.h | 2 +- .../v2/folderinfocontroller_v2.cpp | 7 +- .../controllers/v2/folderinfocontroller_v2.h | 2 +- .../v2/foldermetadatacontroller_v2.cpp | 1 - .../v2/foldermetadatacontroller_v2.h | 2 +- .../controllers/v2/librariescontroller_v2.cpp | 1 + .../controllers/v2/librariescontroller_v2.h | 2 +- .../controllers/v2/pagecontroller_v2.cpp | 2 - .../server/controllers/v2/pagecontroller_v2.h | 2 +- .../v2/readingcomicscontroller_v2.cpp | 3 +- .../v2/readingcomicscontroller_v2.h | 2 +- .../v2/readinglistcontentcontroller_v2.cpp | 3 +- .../v2/readinglistcontentcontroller_v2.h | 2 +- .../v2/readinglistinfocontroller_v2.cpp | 5 +- .../v2/readinglistinfocontroller_v2.h | 2 +- .../v2/readinglistscontroller_v2.h | 2 +- .../controllers/v2/searchcontroller_v2.cpp | 2 +- .../controllers/v2/searchcontroller_v2.h | 2 +- .../controllers/v2/synccontroller_v2.cpp | 4 +- .../server/controllers/v2/synccontroller_v2.h | 6 +- .../v2/tagcontentcontroller_v2.cpp | 3 +- .../controllers/v2/tagcontentcontroller_v2.h | 2 +- .../controllers/v2/taginfocontroller_v2.cpp | 5 +- .../controllers/v2/taginfocontroller_v2.h | 2 +- .../controllers/v2/tagscontroller_v2.cpp | 4 +- .../server/controllers/v2/tagscontroller_v2.h | 2 +- .../v2/updatecomiccontroller_v2.cpp | 8 +- .../controllers/v2/updatecomiccontroller_v2.h | 2 +- .../server/controllers/versioncontroller.h | 2 +- .../webui/statuspagecontroller.cpp | 2 +- .../controllers/webui/statuspagecontroller.h | 2 +- YACReaderLibrary/server/requestmapper.cpp | 43 +++---- YACReaderLibrary/server/requestmapper.h | 1 + YACReaderLibrary/server/static.cpp | 1 + YACReaderLibrary/server/static.h | 4 +- .../server/yacreader_http_server.cpp | 6 +- .../server/yacreader_http_session.h | 4 +- .../server/yacreader_http_session_store.cpp | 4 +- .../server/yacreader_server_data_helper.h | 5 +- YACReaderLibrary/server_config_dialog.cpp | 18 +-- YACReaderLibrary/server_config_dialog.h | 8 +- YACReaderLibrary/themes/theme.h | 8 +- YACReaderLibrary/themes/theme_factory.cpp | 6 +- YACReaderLibrary/trayhandler.mm | 3 +- YACReaderLibrary/trayicon_controller.cpp | 3 +- YACReaderLibrary/xml_info_library_scanner.cpp | 7 +- YACReaderLibrary/xml_info_library_scanner.h | 2 +- .../yacreader_content_views_manager.cpp | 19 ++- .../yacreader_content_views_manager.h | 6 +- YACReaderLibrary/yacreader_folders_view.cpp | 9 +- YACReaderLibrary/yacreader_folders_view.h | 8 +- .../yacreader_history_controller.h | 3 +- YACReaderLibrary/yacreader_libraries.cpp | 1 + YACReaderLibrary/yacreader_local_server.cpp | 12 +- YACReaderLibrary/yacreader_local_server.h | 2 +- YACReaderLibrary/yacreader_main_toolbar.cpp | 8 +- YACReaderLibrary/yacreader_main_toolbar.h | 4 +- .../yacreader_navigation_controller.cpp | 19 ++- .../yacreader_reading_lists_view.h | 6 +- .../console_ui_library_creator.cpp | 6 +- YACReaderLibraryServer/libraries_updater.cpp | 2 +- YACReaderLibraryServer/main.cpp | 32 +++-- common/app_language_utils.h | 1 + common/bookmarks.cpp | 10 +- common/bookmarks.h | 7 +- common/check_new_version.cpp | 13 +- common/comic.cpp | 20 +-- common/comic.h | 10 +- common/comic_db.cpp | 2 +- common/comic_db.h | 7 +- common/concurrent_queue.h | 9 +- common/global_info_provider.cpp | 2 +- common/http_worker.cpp | 13 +- common/pdf_comic.cpp | 3 +- common/pdf_comic.h | 4 +- common/pdf_comic.mm | 8 +- common/qnaturalsorting.h | 5 +- common/rhi/yacreader_comic_flow_rhi.cpp | 1 + common/rhi/yacreader_flow_rhi.cpp | 1 + common/rhi/yacreader_flow_rhi.h | 9 +- common/rhi/yacreader_page_flow_rhi.cpp | 1 + common/scroll_management.cpp | 1 + common/themes/appearance_tab_widget.h | 1 + common/themes/icon_utils.cpp | 4 +- common/themes/theme_editor_dialog.cpp | 25 ++-- common/worker_thread.h | 4 +- common/yacreader_global.cpp | 6 +- common/yacreader_global.h | 6 +- common/yacreader_global_gui.cpp | 4 +- common/yacreader_global_gui.h | 2 +- compressed_archive/7z_includes.h | 5 + compressed_archive/StdAfx.h | 2 +- compressed_archive/compressed_archive.cpp | 18 ++- compressed_archive/compressed_archive.h | 2 +- compressed_archive/extract_callbacks.h | 1 + .../libarchive/compressed_archive.h | 2 +- compressed_archive/open_callbacks.h | 1 + .../unarr/compressed_archive.cpp | 5 +- compressed_archive/unarr/compressed_archive.h | 3 +- custom_widgets/help_about_dialog.cpp | 13 +- custom_widgets/help_about_dialog.h | 4 +- custom_widgets/whats_new_dialog.cpp | 4 +- .../yacreader_3d_flow_config_widget.cpp | 8 +- .../yacreader_3d_flow_config_widget.h | 1 + custom_widgets/yacreader_busy_widget.cpp | 2 +- custom_widgets/yacreader_cover_label.cpp | 1 + custom_widgets/yacreader_cover_label.h | 2 +- custom_widgets/yacreader_dark_menu.cpp | 2 +- .../yacreader_library_item_widget.cpp | 6 +- .../yacreader_library_item_widget.h | 6 +- .../yacreader_library_list_widget.cpp | 7 +- custom_widgets/yacreader_macosx_toolbar.h | 1 + custom_widgets/yacreader_macosx_toolbar.mm | 3 +- custom_widgets/yacreader_options_dialog.cpp | 6 +- custom_widgets/yacreader_search_line_edit.cpp | 4 +- custom_widgets/yacreader_search_line_edit.h | 6 +- custom_widgets/yacreader_sidebar.cpp | 11 +- custom_widgets/yacreader_sidebar.h | 4 +- custom_widgets/yacreader_social_dialog.cpp | 14 +-- .../yacreader_spin_slider_widget.cpp | 2 +- custom_widgets/yacreader_table_view.cpp | 18 ++- custom_widgets/yacreader_table_view.h | 6 +- custom_widgets/yacreader_titled_toolbar.h | 6 +- custom_widgets/yacreader_tool_bar_stretch.h | 2 +- custom_widgets/yacreader_treeview.h | 4 +- image_processing/lancir.h | 2 +- .../actions_shortcuts_model.cpp | 1 + .../edit_shortcut_item_delegate.h | 2 +- .../edit_shortcuts_dialog.cpp | 10 +- shortcuts_management/edit_shortcuts_dialog.h | 4 +- shortcuts_management/shortcuts_manager.cpp | 5 +- shortcuts_management/shortcuts_manager.h | 4 +- tests/compressed_archive_test/main.cpp | 6 +- 276 files changed, 967 insertions(+), 1001 deletions(-) diff --git a/.clang-format b/.clang-format index d68fa440c..238060c55 100644 --- a/.clang-format +++ b/.clang-format @@ -50,11 +50,20 @@ BreakTemplateDeclarations: Yes # clang-format does not handle that. AllowShortFunctionsOnASingleLine: Inline -# The coding style specifies some include order categories, but also tells to -# separate categories with an empty line. It does not specify the order within -# the categories. Since the SortInclude feature of clang-format does not -# re-order includes separated by empty lines, the feature is not used. -SortIncludes: false +# Sort includes and regroup them into consistent blocks: +# 0. self include (the .h matching the .cpp, automatic) +# 1. project includes "" +# 2. Qt includes +# 3. system includes <...> +SortIncludes: CaseSensitive +IncludeBlocks: Regroup +IncludeCategories: + - Regex: "^\"" + Priority: 1 + - Regex: "^ -#include +#include "bookmarks.h" + #include #include +#include #include +#include #include -#include "bookmarks.h" - BookmarksDialog::BookmarksDialog(QWidget *parent) : QDialog(parent) { diff --git a/YACReader/bookmarks_dialog.h b/YACReader/bookmarks_dialog.h index a440b8957..375223fc2 100644 --- a/YACReader/bookmarks_dialog.h +++ b/YACReader/bookmarks_dialog.h @@ -1,15 +1,15 @@ #ifndef __BOOKMARKS_DIALOG_H #define __BOOKMARKS_DIALOG_H -#include +#include "bookmarks.h" + #include -#include -#include #include #include +#include #include - -#include "bookmarks.h" +#include +#include class BookmarksDialog : public QDialog { diff --git a/YACReader/configuration.cpp b/YACReader/configuration.cpp index 93a93d329..9e2b0d4a8 100644 --- a/YACReader/configuration.cpp +++ b/YACReader/configuration.cpp @@ -1,11 +1,10 @@ #include "configuration.h" -#include -#include -#include #include -#include +#include #include +#include +#include Configuration::Configuration() { diff --git a/YACReader/configuration.h b/YACReader/configuration.h index 10d499386..2556b6fba 100644 --- a/YACReader/configuration.h +++ b/YACReader/configuration.h @@ -1,16 +1,16 @@ #ifndef __CONFIGURATION_H #define __CONFIGURATION_H +#include "resize_image.h" +#include "yacreader_global_gui.h" + #include -#include -#include -#include #include -#include #include - -#include "yacreader_global_gui.h" -#include "resize_image.h" +#include +#include +#include +#include #define CONF_FILE_PATH "." #define SLIDE_ASPECT_RATIO 1.585 diff --git a/YACReader/continuous_page_widget.cpp b/YACReader/continuous_page_widget.cpp index 514156c6a..e3c9cc722 100644 --- a/YACReader/continuous_page_widget.cpp +++ b/YACReader/continuous_page_widget.cpp @@ -1,11 +1,12 @@ #include "continuous_page_widget.h" + +#include "configuration.h" #include "continuous_view_model.h" #include "render.h" #include "resize_image.h" -#include "configuration.h" -#include #include +#include ContinuousPageWidget::ContinuousPageWidget(QWidget *parent) : QWidget(parent) diff --git a/YACReader/continuous_page_widget.h b/YACReader/continuous_page_widget.h index aff9b809b..aae139234 100644 --- a/YACReader/continuous_page_widget.h +++ b/YACReader/continuous_page_widget.h @@ -1,13 +1,13 @@ #ifndef CONTINUOUS_PAGE_WIDGET_H #define CONTINUOUS_PAGE_WIDGET_H -#include -#include -#include +#include "themable.h" + #include #include - -#include "themable.h" +#include +#include +#include class Render; class ContinuousViewModel; diff --git a/YACReader/continuous_view_model.cpp b/YACReader/continuous_view_model.cpp index 8d88443d3..7e2f55aaf 100644 --- a/YACReader/continuous_view_model.cpp +++ b/YACReader/continuous_view_model.cpp @@ -1,7 +1,7 @@ #include "continuous_view_model.h" -#include #include +#include #include #include diff --git a/YACReader/goto_dialog.cpp b/YACReader/goto_dialog.cpp index 537ab9104..f442b93b3 100644 --- a/YACReader/goto_dialog.cpp +++ b/YACReader/goto_dialog.cpp @@ -1,8 +1,8 @@ #include "goto_dialog.h" #include -#include #include +#include GoToDialog::GoToDialog(QWidget *parent) : QDialog(parent) diff --git a/YACReader/goto_dialog.h b/YACReader/goto_dialog.h index 3e16a9740..e62f8d2d4 100644 --- a/YACReader/goto_dialog.h +++ b/YACReader/goto_dialog.h @@ -2,10 +2,10 @@ #define __GOTODIALOG_H #include +#include #include #include #include -#include class GoToDialog : public QDialog { diff --git a/YACReader/goto_flow_toolbar.cpp b/YACReader/goto_flow_toolbar.cpp index f3428ecad..5905d76b8 100644 --- a/YACReader/goto_flow_toolbar.cpp +++ b/YACReader/goto_flow_toolbar.cpp @@ -1,16 +1,16 @@ #include "goto_flow_toolbar.h" +#include "configuration.h" + #include -#include #include #include #include #include +#include #include #include -#include "configuration.h" - GoToFlowToolBar::GoToFlowToolBar(QWidget *parent) : QStackedWidget(parent) { diff --git a/YACReader/goto_flow_toolbar.h b/YACReader/goto_flow_toolbar.h index 615a3511d..1f87526f1 100644 --- a/YACReader/goto_flow_toolbar.h +++ b/YACReader/goto_flow_toolbar.h @@ -1,11 +1,11 @@ #ifndef GOTO_FLOW_TOOLBAR_H #define GOTO_FLOW_TOOLBAR_H -#include -#include - #include "themable.h" +#include +#include + class QLineEdit; class QIntValidator; class QPushButton; diff --git a/YACReader/goto_flow_widget.cpp b/YACReader/goto_flow_widget.cpp index 782b9b87e..8071c6e14 100644 --- a/YACReader/goto_flow_widget.cpp +++ b/YACReader/goto_flow_widget.cpp @@ -1,14 +1,14 @@ #include "goto_flow_widget.h" +#include "configuration.h" +#include "goto_flow_toolbar.h" + +#include +#include #include #include -#include -#include #include -#include "goto_flow_toolbar.h" -#include "configuration.h" - GoToFlowWidget::GoToFlowWidget(QWidget *parent, FlowType flowType) : QWidget(parent) { diff --git a/YACReader/goto_flow_widget.h b/YACReader/goto_flow_widget.h index 7d5c73a2c..809673a2e 100644 --- a/YACReader/goto_flow_widget.h +++ b/YACReader/goto_flow_widget.h @@ -1,12 +1,12 @@ #ifndef __GOTO_FLOW_WIDGET_H #define __GOTO_FLOW_WIDGET_H -#include -#include +#include "themable.h" #include "yacreader_global_gui.h" - #include "yacreader_page_flow_rhi.h" -#include "themable.h" + +#include +#include using namespace YACReader; diff --git a/YACReader/magnifying_glass.cpp b/YACReader/magnifying_glass.cpp index 5bc1f78df..306c48a8f 100644 --- a/YACReader/magnifying_glass.cpp +++ b/YACReader/magnifying_glass.cpp @@ -1,4 +1,5 @@ #include "magnifying_glass.h" + #include "viewer.h" MagnifyingGlass::MagnifyingGlass(int w, int h, float zoomLevel, QWidget *parent) diff --git a/YACReader/main.cpp b/YACReader/main.cpp index 27d0d08c9..4a554d85a 100644 --- a/YACReader/main.cpp +++ b/YACReader/main.cpp @@ -1,18 +1,17 @@ -#include -#include -#include -#include - -#include "main_window_viewer.h" -#include "exit_check.h" +#include "QsLog.h" +#include "QsLogDest.h" +#include "app_language_utils.h" #include "appearance_configuration.h" +#include "exit_check.h" +#include "main_window_viewer.h" #include "theme_manager.h" #include "theme_repository.h" -#include "app_language_utils.h" #include "yacreader_global.h" -#include "QsLog.h" -#include "QsLogDest.h" +#include +#include +#include +#include using namespace QsLogging; using namespace YACReader; diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index bb210bc69..28b7747c7 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -1,41 +1,39 @@ #include "main_window_viewer.h" + #include "bookmarks_dialog.h" -#include "configuration.h" -#include "viewer.h" -#include "options_dialog.h" #include "check_new_version.h" #include "comic.h" -#include "width_slider.h" -#include "qnaturalsorting.h" -#include "help_about_dialog.h" -#include "yacreader_tool_bar_stretch.h" - #include "comic_db.h" -#include "yacreader_local_client.h" - -#include "yacreader_global.h" +#include "configuration.h" #include "edit_shortcuts_dialog.h" +#include "help_about_dialog.h" +#include "options_dialog.h" +#include "qnaturalsorting.h" #include "shortcuts_manager.h" #include "theme_manager.h" - +#include "viewer.h" #include "whats_new_controller.h" - -#include -#include +#include "width_slider.h" +#include "yacreader_global.h" +#include "yacreader_local_client.h" +#include "yacreader_tool_bar_stretch.h" #include #include #include +#include #include -#include -#include -#include #include -#include #include -#include +#include #include +#include #include +#include +#include + +#include +#include #ifdef use_unarr #include "unarr.h" diff --git a/YACReader/main_window_viewer.h b/YACReader/main_window_viewer.h index 561c54c88..24b6a4f7f 100644 --- a/YACReader/main_window_viewer.h +++ b/YACReader/main_window_viewer.h @@ -1,16 +1,16 @@ #ifndef __MAIN_WINDOW_VIEWER_H #define __MAIN_WINDOW_VIEWER_H +#include "themable.h" +#include "yacreader_global.h" + +#include +#include #include +#include #include +#include #include #include -#include -#include -#include -#include - -#include "yacreader_global.h" -#include "themable.h" #ifdef Y_MAC_UI #include "yacreader_macosx_toolbar.h" diff --git a/YACReader/mouse_handler.cpp b/YACReader/mouse_handler.cpp index 4ac97da7f..dcdfec9f4 100644 --- a/YACReader/mouse_handler.cpp +++ b/YACReader/mouse_handler.cpp @@ -1,13 +1,13 @@ #include "mouse_handler.h" -#include - #include "configuration.h" #include "goto_flow_widget.h" #include "magnifying_glass.h" #include "render.h" #include "viewer.h" +#include + using namespace YACReader; YACReader::MouseHandler::MouseHandler(Viewer *viewer) diff --git a/YACReader/options_dialog.cpp b/YACReader/options_dialog.cpp index 38b7e6d3f..0c4a96dc3 100644 --- a/YACReader/options_dialog.cpp +++ b/YACReader/options_dialog.cpp @@ -1,26 +1,27 @@ #include "options_dialog.h" + +#include "app_language_utils.h" +#include "appearance_tab_widget.h" #include "configuration.h" -#include -#include +#include "theme_factory.h" +#include "theme_manager.h" +#include "yacreader_3d_flow_config_widget.h" +#include "yacreader_spin_slider_widget.h" + +#include +#include +#include #include #include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include +#include #include -#include "theme_manager.h" -#include "theme_factory.h" -#include "appearance_tab_widget.h" -#include "app_language_utils.h" - -#include "yacreader_spin_slider_widget.h" -#include "yacreader_3d_flow_config_widget.h" +#include +#include +#include +#include +#include OptionsDialog::OptionsDialog(QWidget *parent) : YACReaderOptionsDialog(parent) diff --git a/YACReader/options_dialog.h b/YACReader/options_dialog.h index 874e1c9f5..e89f0d0be 100644 --- a/YACReader/options_dialog.h +++ b/YACReader/options_dialog.h @@ -1,8 +1,8 @@ #ifndef __OPTIONS_DIALOG_H #define __OPTIONS_DIALOG_H -#include "yacreader_options_dialog.h" #include "themable.h" +#include "yacreader_options_dialog.h" #include diff --git a/YACReader/page_label_widget.h b/YACReader/page_label_widget.h index 1bec7c4e6..898c5b1d4 100644 --- a/YACReader/page_label_widget.h +++ b/YACReader/page_label_widget.h @@ -1,10 +1,10 @@ #ifndef PAGE_LABEL_WIDGET_H #define PAGE_LABEL_WIDGET_H -#include - #include "themable.h" +#include + class QLabel; class QPropertyAnimation; diff --git a/YACReader/render.cpp b/YACReader/render.cpp index 9ad49ec46..bfba392b9 100644 --- a/YACReader/render.cpp +++ b/YACReader/render.cpp @@ -1,15 +1,17 @@ #include "render.h" -#include -#include -#include -#include -#include -#include -#include #include "comic_db.h" -#include "yacreader_global_gui.h" #include "configuration.h" +#include "yacreader_global_gui.h" + +#include +#include +#include +#include +#include + +#include +#include template inline const T &kClamp(const T &x, const T &low, const T &high) diff --git a/YACReader/render.h b/YACReader/render.h index 25ad71663..da7a57ce3 100644 --- a/YACReader/render.h +++ b/YACReader/render.h @@ -1,13 +1,14 @@ #ifndef RENDER_H #define RENDER_H +#include "comic.h" + +#include #include -#include #include +#include #include -#include #include -#include "comic.h" //----------------------------------------------------------------------------- // FILTERS //----------------------------------------------------------------------------- diff --git a/YACReader/themes/theme.h b/YACReader/themes/theme.h index 658fe8a6d..f5c073518 100644 --- a/YACReader/themes/theme.h +++ b/YACReader/themes/theme.h @@ -1,12 +1,12 @@ #ifndef THEME_H #define THEME_H -#include -#include - #include "help_about_dialog_theme.h" -#include "whats_new_dialog_theme.h" #include "theme_meta.h" +#include "whats_new_dialog_theme.h" + +#include +#include struct ToolbarThemeTemplates { QString toolbarQSS = "QToolBar { border: none; background: %1; }\n" diff --git a/YACReader/themes/theme_factory.cpp b/YACReader/themes/theme_factory.cpp index 6f5cfa8e9..deb855175 100644 --- a/YACReader/themes/theme_factory.cpp +++ b/YACReader/themes/theme_factory.cpp @@ -1,10 +1,10 @@ #include "theme_factory.h" -#include - #include "icon_utils.h" #include "theme_meta.h" +#include + struct ToolbarParams { ToolbarThemeTemplates t; diff --git a/YACReader/translator.cpp b/YACReader/translator.cpp index d1a447e00..ad593d1f1 100644 --- a/YACReader/translator.cpp +++ b/YACReader/translator.cpp @@ -1,30 +1,28 @@ -#include -#include -#include - -#include -#include -#include -#include -#include #include "translator.h" -#include "viewer.h" +#include "viewer.h" #include "yacreader_busy_widget.h" +#include +#include #include -#include -#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include #include -#include #include -#include -#include - -#include +#include +#include YACReaderTranslator::YACReaderTranslator(Viewer *parent) : QWidget(parent), drag(false) diff --git a/YACReader/translator.h b/YACReader/translator.h index 3cfb7fa56..ba2cec307 100644 --- a/YACReader/translator.h +++ b/YACReader/translator.h @@ -10,11 +10,12 @@ class QPushButton; class YACReaderBusyWidget; class QTextToSpeech; -#include +#include "themable.h" +#include "viewer.h" + #include #include -#include "viewer.h" -#include "themable.h" +#include class YACReaderTranslator : public QWidget, protected Themable { diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index ba08498d0..5a0334cfa 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -1,17 +1,18 @@ #include "viewer.h" + +#include "bookmarks_dialog.h" +#include "comic_db.h" +#include "configuration.h" #include "continuous_page_widget.h" #include "continuous_view_model.h" -#include "resize_image.h" -#include "configuration.h" -#include "magnifying_glass.h" +#include "goto_dialog.h" #include "goto_flow_widget.h" -#include "bookmarks_dialog.h" +#include "magnifying_glass.h" +#include "notifications_label_widget.h" +#include "page_label_widget.h" #include "render.h" -#include "goto_dialog.h" +#include "resize_image.h" #include "translator.h" -#include "page_label_widget.h" -#include "notifications_label_widget.h" -#include "comic_db.h" #include #include diff --git a/YACReader/viewer.h b/YACReader/viewer.h index 0189c7f45..62071d112 100644 --- a/YACReader/viewer.h +++ b/YACReader/viewer.h @@ -1,24 +1,23 @@ #ifndef __VIEWER_H #define __VIEWER_H -#include +#include "mouse_handler.h" +#include "scroll_management.h" +#include "themable.h" -#include #include -#include +#include #include -#include -#include -#include +#include #include -#include -#include #include +#include +#include +#include +#include #include - -#include "scroll_management.h" -#include "mouse_handler.h" -#include "themable.h" +#include +#include class ComicDB; class Comic; diff --git a/YACReader/width_slider.h b/YACReader/width_slider.h index df5522ff3..d1bafa596 100644 --- a/YACReader/width_slider.h +++ b/YACReader/width_slider.h @@ -1,8 +1,8 @@ #ifndef WIDTH_SLIDER_H #define WIDTH_SLIDER_H -#include #include +#include class QLabel; class QSlider; diff --git a/YACReader/yacreader_local_client.cpp b/YACReader/yacreader_local_client.cpp index d845d67e4..6cb6cb922 100644 --- a/YACReader/yacreader_local_client.cpp +++ b/YACReader/yacreader_local_client.cpp @@ -1,11 +1,11 @@ #include "yacreader_local_client.h" + +#include "QsLog.h" #include "comic_db.h" #include "yacreader_global.h" #include -#include "QsLog.h" - using namespace YACReader; YACReaderLocalClient::YACReaderLocalClient(QObject *parent) diff --git a/YACReader/yacreader_local_client.h b/YACReader/yacreader_local_client.h index b683d6946..d4472b0b9 100644 --- a/YACReader/yacreader_local_client.h +++ b/YACReader/yacreader_local_client.h @@ -1,8 +1,8 @@ #ifndef YACREADER_LOCAL_CLIENT_H #define YACREADER_LOCAL_CLIENT_H -#include "yacreader_global.h" #include "comic_db.h" +#include "yacreader_global.h" #include diff --git a/YACReaderLibrary/add_label_dialog.h b/YACReaderLibrary/add_label_dialog.h index fd9431197..54a64fe9a 100644 --- a/YACReaderLibrary/add_label_dialog.h +++ b/YACReaderLibrary/add_label_dialog.h @@ -1,14 +1,14 @@ #ifndef ADD_LABEL_DIALOG_H #define ADD_LABEL_DIALOG_H +#include "themable.h" +#include "yacreader_global.h" + #include #include #include #include -#include "yacreader_global.h" -#include "themable.h" - class AddLabelDialog : public QDialog, protected Themable { Q_OBJECT diff --git a/YACReaderLibrary/add_library_dialog.cpp b/YACReaderLibrary/add_library_dialog.cpp index d5ebc09b7..557cf5287 100644 --- a/YACReaderLibrary/add_library_dialog.cpp +++ b/YACReaderLibrary/add_library_dialog.cpp @@ -1,9 +1,9 @@ #include "add_library_dialog.h" -#include -#include #include #include +#include +#include AddLibraryDialog::AddLibraryDialog(QWidget *parent) : QDialog(parent) diff --git a/YACReaderLibrary/classic_comics_view.cpp b/YACReaderLibrary/classic_comics_view.cpp index 6c5d883fe..ba7c6a082 100644 --- a/YACReaderLibrary/classic_comics_view.cpp +++ b/YACReaderLibrary/classic_comics_view.cpp @@ -1,6 +1,9 @@ #include "classic_comics_view.h" +#include "comic_flow_widget.h" +#include "shortcuts_manager.h" #include "yacreader_global.h" +#include "yacreader_table_view.h" #include #include @@ -12,10 +15,6 @@ #include #include -#include "comic_flow_widget.h" -#include "shortcuts_manager.h" -#include "yacreader_table_view.h" - ClassicComicsView::ClassicComicsView(QWidget *parent) : ComicsView(parent), searching(false) { diff --git a/YACReaderLibrary/comic_files_manager.cpp b/YACReaderLibrary/comic_files_manager.cpp index 091e36fa3..517c4f121 100644 --- a/YACReaderLibrary/comic_files_manager.cpp +++ b/YACReaderLibrary/comic_files_manager.cpp @@ -1,12 +1,12 @@ #include "comic_files_manager.h" + +#include "comic.h" + +#include #include #include -#include - #include -#include "comic.h" - ComicFilesManager::ComicFilesManager(QObject *parent) : QObject(parent), canceled(false) { diff --git a/YACReaderLibrary/comic_files_manager.h b/YACReaderLibrary/comic_files_manager.h index ae39c23df..870f85a82 100644 --- a/YACReaderLibrary/comic_files_manager.h +++ b/YACReaderLibrary/comic_files_manager.h @@ -1,10 +1,10 @@ #ifndef COMIC_FILES_MANAGER_H #define COMIC_FILES_MANAGER_H -#include #include -#include #include +#include +#include // this class is intended to work in background, just use moveToThread and process to start working class ComicFilesManager : public QObject diff --git a/YACReaderLibrary/comic_flow_widget.cpp b/YACReaderLibrary/comic_flow_widget.cpp index 7e54ae6ae..b75fdb527 100644 --- a/YACReaderLibrary/comic_flow_widget.cpp +++ b/YACReaderLibrary/comic_flow_widget.cpp @@ -1,4 +1,5 @@ #include "comic_flow_widget.h" + #include ComicFlowWidget::ComicFlowWidget(QWidget *parent) diff --git a/YACReaderLibrary/comic_flow_widget.h b/YACReaderLibrary/comic_flow_widget.h index 8492bfa27..175564967 100644 --- a/YACReaderLibrary/comic_flow_widget.h +++ b/YACReaderLibrary/comic_flow_widget.h @@ -1,13 +1,12 @@ #ifndef __COMIC_FLOW_WIDGET_H #define __COMIC_FLOW_WIDGET_H -#include - -#include "yacreader_global.h" - +#include "themable.h" #include "yacreader_comic_flow_rhi.h" +#include "yacreader_global.h" #include "yacreader_global_gui.h" -#include "themable.h" + +#include class ComicFlowWidget : public QWidget, protected Themable { diff --git a/YACReaderLibrary/comic_vine/api_key_dialog.cpp b/YACReaderLibrary/comic_vine/api_key_dialog.cpp index ae063da45..9aa581e7a 100644 --- a/YACReaderLibrary/comic_vine/api_key_dialog.cpp +++ b/YACReaderLibrary/comic_vine/api_key_dialog.cpp @@ -1,13 +1,13 @@ #include "api_key_dialog.h" -#include +#include "yacreader_global_gui.h" + #include #include #include #include #include - -#include "yacreader_global_gui.h" +#include ApiKeyDialog::ApiKeyDialog(QWidget *parent) : QDialog(parent) diff --git a/YACReaderLibrary/comic_vine/comic_vine_client.cpp b/YACReaderLibrary/comic_vine/comic_vine_client.cpp index 67ee031a1..888bfa487 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_client.cpp +++ b/YACReaderLibrary/comic_vine/comic_vine_client.cpp @@ -1,7 +1,7 @@ #include "comic_vine_client.h" -#include "yacreader_global_gui.h" #include "comic_vine_all_volume_comics_retriever.h" +#include "yacreader_global_gui.h" // this is the API key used by YACReader to access Comic Vine // please, do not use it in your own software, get one for free at Comic Vine diff --git a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp index acdc37aca..15effb3a2 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp +++ b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp @@ -1,34 +1,34 @@ #include "comic_vine_dialog.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "data_base_management.h" -#include -#include "yacreader_busy_widget.h" +#include "QsLog.h" #include "comic_vine_client.h" #include "comic_vine_json_parser.h" +#include "data_base_management.h" +#include "db_helper.h" +#include "response_parser.h" #include "scraper_lineedit.h" -#include "title_header.h" -#include "series_question.h" #include "search_single_comic.h" #include "search_volume.h" #include "select_comic.h" #include "select_volume.h" #include "selected_volume_info.h" +#include "series_question.h" #include "sort_volume_comics.h" -#include "db_helper.h" -#include "response_parser.h" +#include "title_header.h" +#include "yacreader_busy_widget.h" -#include "QsLog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include ComicVineDialog::ComicVineDialog(QWidget *parent) : QDialog(parent) diff --git a/YACReaderLibrary/comic_vine/comic_vine_dialog.h b/YACReaderLibrary/comic_vine/comic_vine_dialog.h index 364680233..ecd4485b6 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_dialog.h +++ b/YACReaderLibrary/comic_vine/comic_vine_dialog.h @@ -1,11 +1,11 @@ #ifndef COMIC_VINE_DIALOG_H #define COMIC_VINE_DIALOG_H -#include - #include "comic_db.h" -#include "volume_search_query.h" #include "themable.h" +#include "volume_search_query.h" + +#include class QPushButton; class QStackedWidget; diff --git a/YACReaderLibrary/comic_vine/model/local_comic_list_model.h b/YACReaderLibrary/comic_vine/model/local_comic_list_model.h index 14baff981..dd2cde968 100644 --- a/YACReaderLibrary/comic_vine/model/local_comic_list_model.h +++ b/YACReaderLibrary/comic_vine/model/local_comic_list_model.h @@ -1,10 +1,10 @@ #ifndef LOCAL_COMIC_LIST_MODEL_H #define LOCAL_COMIC_LIST_MODEL_H -#include - #include "comic_db.h" +#include + class LocalComicListModel : public QAbstractItemModel { Q_OBJECT diff --git a/YACReaderLibrary/comic_vine/model/response_parser.cpp b/YACReaderLibrary/comic_vine/model/response_parser.cpp index dd2582120..5c46f3c11 100644 --- a/YACReaderLibrary/comic_vine/model/response_parser.cpp +++ b/YACReaderLibrary/comic_vine/model/response_parser.cpp @@ -1,4 +1,5 @@ #include "response_parser.h" + #include #include #include diff --git a/YACReaderLibrary/comic_vine/model/volume_comics_model.cpp b/YACReaderLibrary/comic_vine/model/volume_comics_model.cpp index 908d7614d..d88700a92 100644 --- a/YACReaderLibrary/comic_vine/model/volume_comics_model.cpp +++ b/YACReaderLibrary/comic_vine/model/volume_comics_model.cpp @@ -1,4 +1,5 @@ #include "volume_comics_model.h" + #include "qnaturalsorting.h" #include diff --git a/YACReaderLibrary/comic_vine/scraper_checkbox.h b/YACReaderLibrary/comic_vine/scraper_checkbox.h index d2362650e..6c4081f0f 100644 --- a/YACReaderLibrary/comic_vine/scraper_checkbox.h +++ b/YACReaderLibrary/comic_vine/scraper_checkbox.h @@ -1,10 +1,10 @@ #ifndef SCRAPER_CHECKBOX_H #define SCRAPER_CHECKBOX_H -#include - #include "themable.h" +#include + class ScraperCheckBox : public QCheckBox, protected Themable { public: diff --git a/YACReaderLibrary/comic_vine/scraper_lineedit.h b/YACReaderLibrary/comic_vine/scraper_lineedit.h index 977e4d0f0..93d13823e 100644 --- a/YACReaderLibrary/comic_vine/scraper_lineedit.h +++ b/YACReaderLibrary/comic_vine/scraper_lineedit.h @@ -1,10 +1,10 @@ #ifndef SCRAPPER_LINEEDIT_H #define SCRAPPER_LINEEDIT_H -#include - #include "themable.h" +#include + class QLabel; class ScraperLineEdit : public QLineEdit, protected Themable diff --git a/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp b/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp index 8594656fc..cfffdecb7 100644 --- a/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp +++ b/YACReaderLibrary/comic_vine/scraper_results_paginator.cpp @@ -1,4 +1,5 @@ #include "scraper_results_paginator.h" + #include "response_parser.h" #include diff --git a/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp b/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp index f9422890f..751413543 100644 --- a/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp +++ b/YACReaderLibrary/comic_vine/scraper_scroll_label.cpp @@ -1,7 +1,7 @@ #include "scraper_scroll_label.h" -#include #include +#include #include ScraperScrollLabel::ScraperScrollLabel(QWidget *parent) diff --git a/YACReaderLibrary/comic_vine/scraper_scroll_label.h b/YACReaderLibrary/comic_vine/scraper_scroll_label.h index f78da91ac..0fe79baf2 100644 --- a/YACReaderLibrary/comic_vine/scraper_scroll_label.h +++ b/YACReaderLibrary/comic_vine/scraper_scroll_label.h @@ -1,10 +1,10 @@ #ifndef SCRAPER_SCROLL_LABEL_H #define SCRAPER_SCROLL_LABEL_H -#include - #include "themable.h" +#include + class QLabel; class ScraperScrollLabel : public QScrollArea, protected Themable diff --git a/YACReaderLibrary/comic_vine/scraper_tableview.h b/YACReaderLibrary/comic_vine/scraper_tableview.h index 98159dce8..9f8eaf74d 100644 --- a/YACReaderLibrary/comic_vine/scraper_tableview.h +++ b/YACReaderLibrary/comic_vine/scraper_tableview.h @@ -1,10 +1,10 @@ #ifndef SCRAPPER_TABLEVIEW_H #define SCRAPPER_TABLEVIEW_H -#include - #include "themable.h" +#include + class ScraperTableView : public QTableView, protected Themable { Q_OBJECT diff --git a/YACReaderLibrary/comic_vine/search_single_comic.cpp b/YACReaderLibrary/comic_vine/search_single_comic.cpp index 9dd7c7db2..9af75d070 100644 --- a/YACReaderLibrary/comic_vine/search_single_comic.cpp +++ b/YACReaderLibrary/comic_vine/search_single_comic.cpp @@ -2,9 +2,9 @@ #include "scraper_lineedit.h" +#include #include #include -#include SearchSingleComic::SearchSingleComic(QWidget *parent) : QWidget(parent) diff --git a/YACReaderLibrary/comic_vine/search_volume.cpp b/YACReaderLibrary/comic_vine/search_volume.cpp index 7a0a4cfab..ed42dd0ae 100644 --- a/YACReaderLibrary/comic_vine/search_volume.cpp +++ b/YACReaderLibrary/comic_vine/search_volume.cpp @@ -1,7 +1,7 @@ #include "search_volume.h" -#include "scraper_lineedit.h" #include "scraper_checkbox.h" +#include "scraper_lineedit.h" #include #include diff --git a/YACReaderLibrary/comic_vine/search_volume.h b/YACReaderLibrary/comic_vine/search_volume.h index 2fa386085..c38fa7032 100644 --- a/YACReaderLibrary/comic_vine/search_volume.h +++ b/YACReaderLibrary/comic_vine/search_volume.h @@ -1,12 +1,12 @@ #ifndef SEARCH_VOLUME_H #define SEARCH_VOLUME_H -#include -#include - #include "scraper_checkbox.h" #include "themable.h" +#include +#include + class ScraperLineEdit; class ScraperCheckBox; diff --git a/YACReaderLibrary/comic_vine/select_volume.cpp b/YACReaderLibrary/comic_vine/select_volume.cpp index 924c6358b..2e778f323 100644 --- a/YACReaderLibrary/comic_vine/select_volume.cpp +++ b/YACReaderLibrary/comic_vine/select_volume.cpp @@ -1,5 +1,14 @@ #include "select_volume.h" +#include "comic_vine_client.h" +#include "scraper_lineedit.h" +#include "scraper_results_paginator.h" +#include "scraper_scroll_label.h" +#include "scraper_tableview.h" +#include "selected_volume_info.h" +#include "volumes_model.h" + +#include #include #include #include @@ -12,18 +21,6 @@ #include #include #include -#include - -#include "scraper_tableview.h" -#include "scraper_lineedit.h" - -#include "volumes_model.h" -#include "comic_vine_client.h" -#include "scraper_scroll_label.h" - -#include "scraper_results_paginator.h" - -#include "selected_volume_info.h" SelectVolume::SelectVolume(QWidget *parent) : QWidget(parent), model(0) diff --git a/YACReaderLibrary/comic_vine/select_volume.h b/YACReaderLibrary/comic_vine/select_volume.h index 077937874..79852d5aa 100644 --- a/YACReaderLibrary/comic_vine/select_volume.h +++ b/YACReaderLibrary/comic_vine/select_volume.h @@ -3,8 +3,8 @@ #include "scraper_results_paginator.h" #include "selected_volume_info.h" -#include "volume_search_query.h" #include "themable.h" +#include "volume_search_query.h" class QLabel; class VolumesModel; diff --git a/YACReaderLibrary/comic_vine/series_question.cpp b/YACReaderLibrary/comic_vine/series_question.cpp index 34c53c7ec..31e0ede21 100644 --- a/YACReaderLibrary/comic_vine/series_question.cpp +++ b/YACReaderLibrary/comic_vine/series_question.cpp @@ -1,8 +1,8 @@ #include "series_question.h" +#include #include #include -#include SeriesQuestion::SeriesQuestion(QWidget *parent) : QWidget(parent) diff --git a/YACReaderLibrary/comic_vine/series_question.h b/YACReaderLibrary/comic_vine/series_question.h index 26b850c09..26a140dae 100644 --- a/YACReaderLibrary/comic_vine/series_question.h +++ b/YACReaderLibrary/comic_vine/series_question.h @@ -1,10 +1,10 @@ #ifndef SERIES_QUESTION_H #define SERIES_QUESTION_H -#include - #include "themable.h" +#include + class QRadioButton; class QLabel; diff --git a/YACReaderLibrary/comic_vine/sort_volume_comics.cpp b/YACReaderLibrary/comic_vine/sort_volume_comics.cpp index 5bb2d6c5e..16cf75c65 100644 --- a/YACReaderLibrary/comic_vine/sort_volume_comics.cpp +++ b/YACReaderLibrary/comic_vine/sort_volume_comics.cpp @@ -1,15 +1,15 @@ #include "sort_volume_comics.h" -#include +#include "local_comic_list_model.h" +#include "scraper_tableview.h" +#include "theme_manager.h" +#include "volume_comics_model.h" + +#include #include +#include #include #include -#include - -#include "scraper_tableview.h" -#include "local_comic_list_model.h" -#include "volume_comics_model.h" -#include "theme_manager.h" ScrapperToolButton::ScrapperToolButton(ScrapperToolButton::Appearance appearance, QWidget *parent) : QPushButton(parent), appearance(appearance) diff --git a/YACReaderLibrary/comic_vine/sort_volume_comics.h b/YACReaderLibrary/comic_vine/sort_volume_comics.h index b516f7c54..c57248687 100644 --- a/YACReaderLibrary/comic_vine/sort_volume_comics.h +++ b/YACReaderLibrary/comic_vine/sort_volume_comics.h @@ -1,14 +1,14 @@ #ifndef SORT_VOLUME_COMICS_H #define SORT_VOLUME_COMICS_H -#include -#include -#include - #include "comic_db.h" #include "scraper_results_paginator.h" #include "themable.h" +#include +#include +#include + class ScraperTableView; class LocalComicListModel; class VolumeComicsModel; diff --git a/YACReaderLibrary/comic_vine/title_header.cpp b/YACReaderLibrary/comic_vine/title_header.cpp index 8f54c5b3a..3a13905e6 100644 --- a/YACReaderLibrary/comic_vine/title_header.cpp +++ b/YACReaderLibrary/comic_vine/title_header.cpp @@ -1,7 +1,7 @@ #include "title_header.h" -#include #include +#include #include TitleHeader::TitleHeader(QWidget *parent) diff --git a/YACReaderLibrary/comic_vine/title_header.h b/YACReaderLibrary/comic_vine/title_header.h index 1ad00c8e9..93df1e38b 100644 --- a/YACReaderLibrary/comic_vine/title_header.h +++ b/YACReaderLibrary/comic_vine/title_header.h @@ -1,10 +1,10 @@ #ifndef TITLE_HEADER_H #define TITLE_HEADER_H -#include - #include "themable.h" +#include + class QLabel; class TitleHeader : public QWidget, protected Themable diff --git a/YACReaderLibrary/comics_remover.cpp b/YACReaderLibrary/comics_remover.cpp index 7d11e9282..fcc197f9f 100644 --- a/YACReaderLibrary/comics_remover.cpp +++ b/YACReaderLibrary/comics_remover.cpp @@ -1,10 +1,10 @@ #include "comics_remover.h" -#include -#include - #include "QsLog.h" +#include +#include + ComicsRemover::ComicsRemover(QModelIndexList &il, QList &ps, qulonglong parentId, QObject *parent) : QObject(parent), indexList(il), paths(ps), parentId(parentId) { diff --git a/YACReaderLibrary/comics_remover.h b/YACReaderLibrary/comics_remover.h index f153af6e4..9fed42567 100644 --- a/YACReaderLibrary/comics_remover.h +++ b/YACReaderLibrary/comics_remover.h @@ -1,9 +1,8 @@ #ifndef COMICS_REMOVER_H #define COMICS_REMOVER_H -#include - #include +#include class ComicsRemover : public QObject { diff --git a/YACReaderLibrary/comics_view.cpp b/YACReaderLibrary/comics_view.cpp index 5e537837d..c00d0aa4f 100644 --- a/YACReaderLibrary/comics_view.cpp +++ b/YACReaderLibrary/comics_view.cpp @@ -1,9 +1,9 @@ #include "comics_view.h" -#include "comic.h" -#include "comic_files_manager.h" -#include "comic_db.h" #include "QsLog.h" +#include "comic.h" +#include "comic_db.h" +#include "comic_files_manager.h" #include #include diff --git a/YACReaderLibrary/comics_view.h b/YACReaderLibrary/comics_view.h index f516d2d46..22ab71e38 100644 --- a/YACReaderLibrary/comics_view.h +++ b/YACReaderLibrary/comics_view.h @@ -1,12 +1,12 @@ #ifndef COMICS_VIEW_H #define COMICS_VIEW_H +#include "comic_model.h" + #include #include #include -#include "comic_model.h" - class YACReaderTableView; class QSplitter; class ComicFlowWidget; diff --git a/YACReaderLibrary/comics_view_transition.h b/YACReaderLibrary/comics_view_transition.h index d428e6744..26438dc9b 100644 --- a/YACReaderLibrary/comics_view_transition.h +++ b/YACReaderLibrary/comics_view_transition.h @@ -1,10 +1,10 @@ #ifndef COMICS_VIEW_TRANSITION_H #define COMICS_VIEW_TRANSITION_H -#include - #include "themable.h" +#include + class ComicsViewTransition : public QWidget, protected Themable { Q_OBJECT diff --git a/YACReaderLibrary/create_library_dialog.cpp b/YACReaderLibrary/create_library_dialog.cpp index 4fe223278..5c3a12788 100644 --- a/YACReaderLibrary/create_library_dialog.cpp +++ b/YACReaderLibrary/create_library_dialog.cpp @@ -1,11 +1,12 @@ #include "create_library_dialog.h" + #include "yacreader_global.h" -#include -#include #include -#include +#include #include +#include +#include using namespace YACReader; diff --git a/YACReaderLibrary/create_library_dialog.h b/YACReaderLibrary/create_library_dialog.h index 6adfb6614..82412a0f2 100644 --- a/YACReaderLibrary/create_library_dialog.h +++ b/YACReaderLibrary/create_library_dialog.h @@ -1,15 +1,15 @@ #ifndef __CREATE_LIBRARY_DIALOG_H #define __CREATE_LIBRARY_DIALOG_H -#include "yacreader_libraries.h" #include "themable.h" +#include "yacreader_libraries.h" #include #include #include +#include #include #include -#include class CreateLibraryDialog : public QDialog, protected Themable { diff --git a/YACReaderLibrary/db/comic_item.cpp b/YACReaderLibrary/db/comic_item.cpp index 96cc0d800..d7abfd6ec 100644 --- a/YACReaderLibrary/db/comic_item.cpp +++ b/YACReaderLibrary/db/comic_item.cpp @@ -1,8 +1,8 @@ -#include - #include "comic_item.h" +#include + //! [0] ComicItem::ComicItem(const QList &data) diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index 8701aca5f..01cf7039f 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -1,18 +1,19 @@ -#include -#include -#include -#include +#include "comic_model.h" +#include "comic_db.h" #include "comic_item.h" -#include "comic_model.h" #include "data_base_management.h" -#include "qnaturalsorting.h" -#include "comic_db.h" #include "db_helper.h" +#include "qnaturalsorting.h" #include "reading_list_model.h" #include "yacreader_global_gui.h" +#include +#include +#include +#include + #ifdef use_unarr #include #endif diff --git a/YACReaderLibrary/db/comic_model.h b/YACReaderLibrary/db/comic_model.h index 484a69f66..9426ed57b 100644 --- a/YACReaderLibrary/db/comic_model.h +++ b/YACReaderLibrary/db/comic_model.h @@ -1,14 +1,14 @@ #ifndef TABLEMODEL_H #define TABLEMODEL_H +#include "yacreader_global.h" + #include #include -#include -#include #include +#include #include - -#include "yacreader_global.h" +#include class ComicDB; diff --git a/YACReaderLibrary/db/comic_query_result_processor.cpp b/YACReaderLibrary/db/comic_query_result_processor.cpp index da0c9c5d0..edfe35d5a 100644 --- a/YACReaderLibrary/db/comic_query_result_processor.cpp +++ b/YACReaderLibrary/db/comic_query_result_processor.cpp @@ -1,13 +1,13 @@ #include "comic_query_result_processor.h" -#include - #include "comic_item.h" #include "comic_model.h" #include "data_base_management.h" #include "qnaturalsorting.h" #include "search_query.h" +#include + YACReader::ComicQueryResultProcessor::ComicQueryResultProcessor() : querySearchQueue(1) { diff --git a/YACReaderLibrary/db/comic_query_result_processor.h b/YACReaderLibrary/db/comic_query_result_processor.h index a99623ad9..103b522e0 100644 --- a/YACReaderLibrary/db/comic_query_result_processor.h +++ b/YACReaderLibrary/db/comic_query_result_processor.h @@ -1,11 +1,11 @@ #ifndef COMIC_QUERY_RESULT_PROCESSOR_H #define COMIC_QUERY_RESULT_PROCESSOR_H -#include -#include - #include "concurrent_queue.h" +#include +#include + class ComicItem; namespace YACReader { diff --git a/YACReaderLibrary/db/data_base_management.cpp b/YACReaderLibrary/db/data_base_management.cpp index 0a1bc6560..05d1cceb1 100644 --- a/YACReaderLibrary/db/data_base_management.cpp +++ b/YACReaderLibrary/db/data_base_management.cpp @@ -1,14 +1,14 @@ #include "data_base_management.h" -#include +#include "QsLog.h" +#include "db_helper.h" +#include "initial_comic_info_extractor.h" + #include #include #include #include -#include "initial_comic_info_extractor.h" -#include "db_helper.h" - -#include "QsLog.h" +#include using namespace YACReader; diff --git a/YACReaderLibrary/db/data_base_management.h b/YACReaderLibrary/db/data_base_management.h index c1d4aa7d2..1e170afd5 100644 --- a/YACReaderLibrary/db/data_base_management.h +++ b/YACReaderLibrary/db/data_base_management.h @@ -1,8 +1,8 @@ #ifndef __DATA_BASE_MANAGEMENT_H #define __DATA_BASE_MANAGEMENT_H -#include #include +#include class ComicsInfoExporter : public QThread { diff --git a/YACReaderLibrary/db/folder_item.cpp b/YACReaderLibrary/db/folder_item.cpp index 3b54f13b2..8b539b4ab 100644 --- a/YACReaderLibrary/db/folder_item.cpp +++ b/YACReaderLibrary/db/folder_item.cpp @@ -1,8 +1,9 @@ -#include - #include "folder_item.h" + #include "qnaturalsorting.h" +#include + FolderItem::FolderItem(const QList &data, FolderItem *parent) { parentItem = parent; diff --git a/YACReaderLibrary/db/folder_item.h b/YACReaderLibrary/db/folder_item.h index ef77c4d9b..071e0a9b4 100644 --- a/YACReaderLibrary/db/folder_item.h +++ b/YACReaderLibrary/db/folder_item.h @@ -42,8 +42,8 @@ #define TREEITEM_H #include -#include #include +#include class FolderItem { diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index 5d36f4473..de9b6b7a8 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -1,11 +1,10 @@ #include "folder_model.h" -#include "folder_item.h" #include "data_base_management.h" -#include "folder.h" #include "db_helper.h" +#include "folder.h" +#include "folder_item.h" #include "qnaturalsorting.h" - #include "yacreader_global.h" #include diff --git a/YACReaderLibrary/db/folder_model.h b/YACReaderLibrary/db/folder_model.h index 84a759d26..f1cf381ba 100644 --- a/YACReaderLibrary/db/folder_model.h +++ b/YACReaderLibrary/db/folder_model.h @@ -1,19 +1,19 @@ #ifndef TREEMODEL_H #define TREEMODEL_H +#include "folder.h" +#include "folder_query_result_processor.h" +#include "themable.h" +#include "yacreader_global.h" + #include -#include +#include #include -#include -#include +#include #include +#include #include -#include - -#include "folder.h" -#include "folder_query_result_processor.h" -#include "yacreader_global.h" -#include "themable.h" +#include class FolderItem; diff --git a/YACReaderLibrary/db/folder_query_result_processor.cpp b/YACReaderLibrary/db/folder_query_result_processor.cpp index c936c5094..6ce4705c7 100644 --- a/YACReaderLibrary/db/folder_query_result_processor.cpp +++ b/YACReaderLibrary/db/folder_query_result_processor.cpp @@ -1,8 +1,8 @@ #include "folder_query_result_processor.h" +#include "data_base_management.h" #include "folder_item.h" #include "folder_model.h" -#include "data_base_management.h" #include "search_query.h" #include diff --git a/YACReaderLibrary/db/folder_query_result_processor.h b/YACReaderLibrary/db/folder_query_result_processor.h index fd966aee8..5114e7d04 100644 --- a/YACReaderLibrary/db/folder_query_result_processor.h +++ b/YACReaderLibrary/db/folder_query_result_processor.h @@ -1,10 +1,10 @@ #ifndef FOLDER_QUERY_RESULT_PROCESSOR_H #define FOLDER_QUERY_RESULT_PROCESSOR_H -#include - #include "concurrent_queue.h" +#include + class FolderItem; class FolderModel; class QSqlQuery; diff --git a/YACReaderLibrary/db/query_parser.cpp b/YACReaderLibrary/db/query_parser.cpp index 81a7df168..e79cde4f2 100644 --- a/YACReaderLibrary/db/query_parser.cpp +++ b/YACReaderLibrary/db/query_parser.cpp @@ -2,6 +2,7 @@ #include #include + #include #include diff --git a/YACReaderLibrary/db/query_parser.h b/YACReaderLibrary/db/query_parser.h index 3e22c9dd1..1e1f5ee5d 100644 --- a/YACReaderLibrary/db/query_parser.h +++ b/YACReaderLibrary/db/query_parser.h @@ -3,11 +3,12 @@ #include "query_lexer.h" -#include #include + +#include +#include #include #include -#include #define SEARCH_FOLDERS_QUERY "SELECT DISTINCT f.* FROM folder f LEFT JOIN comic c ON (f.id = c.parentId) INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) WHERE " #define SEARCH_COMICS_QUERY "SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.currentPage,ci.rating,ci.hasBeenOpened,ci.date,ci.added,ci.type,ci.lastTimeOpened,ci.series,ci.volume,ci.storyArc FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) LEFT JOIN folder f ON (f.id == c.parentId) WHERE " diff --git a/YACReaderLibrary/db/reading_list_item.cpp b/YACReaderLibrary/db/reading_list_item.cpp index 0fd02f3d0..985fe4aad 100644 --- a/YACReaderLibrary/db/reading_list_item.cpp +++ b/YACReaderLibrary/db/reading_list_item.cpp @@ -1,11 +1,11 @@ #include "reading_list_item.h" -#include "qnaturalsorting.h" - -#include #include "QsLog.h" +#include "qnaturalsorting.h" #include "theme_manager.h" +#include + ListItem::ListItem(const QList &data) : itemData(data) { diff --git a/YACReaderLibrary/db/reading_list_item.h b/YACReaderLibrary/db/reading_list_item.h index 81876887b..61bfbf6e5 100644 --- a/YACReaderLibrary/db/reading_list_item.h +++ b/YACReaderLibrary/db/reading_list_item.h @@ -1,10 +1,10 @@ #ifndef READING_LIST_ITEM_H #define READING_LIST_ITEM_H +#include "reading_list_model.h" + #include #include - -#include "reading_list_model.h" // TODO add propper constructors, using QList is not safe class ListItem diff --git a/YACReaderLibrary/db/reading_list_model.cpp b/YACReaderLibrary/db/reading_list_model.cpp index ca19bc55f..d503042ab 100644 --- a/YACReaderLibrary/db/reading_list_model.cpp +++ b/YACReaderLibrary/db/reading_list_model.cpp @@ -1,17 +1,14 @@ #include "reading_list_model.h" -#include "reading_list_item.h" - +#include "QsLog.h" #include "data_base_management.h" -#include "qnaturalsorting.h" #include "db_helper.h" - -#include "QsLog.h" +#include "qnaturalsorting.h" +#include "reading_list_item.h" +#include "yacreader_global_gui.h" #include -#include "yacreader_global_gui.h" - ReadingListModel::ReadingListModel(QObject *parent) : QAbstractItemModel(parent), rootItem(0) { diff --git a/YACReaderLibrary/db/reading_list_model.h b/YACReaderLibrary/db/reading_list_model.h index 2e0b73b2a..7f5efb515 100644 --- a/YACReaderLibrary/db/reading_list_model.h +++ b/YACReaderLibrary/db/reading_list_model.h @@ -1,14 +1,14 @@ #ifndef READING_LIST_MODEL_H #define READING_LIST_MODEL_H +#include "yacreader_global.h" + #include -#include #include -#include -#include +#include #include - -#include "yacreader_global.h" +#include +#include class LabelItem; class SpecialListItem; diff --git a/YACReaderLibrary/db/search_query.cpp b/YACReaderLibrary/db/search_query.cpp index bd1d6cd3d..0ede13fad 100644 --- a/YACReaderLibrary/db/search_query.cpp +++ b/YACReaderLibrary/db/search_query.cpp @@ -1,9 +1,10 @@ #include "search_query.h" + #include "query_parser.h" -#include #include +#include QSqlQuery foldersSearchQuery(QSqlDatabase &db, const QString &filter) { diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index ea08ce1b5..a0c4d4735 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -1,32 +1,30 @@ #include "db_helper.h" -#include -#include -#include +#include "QsLog.h" +#include "comic_db.h" +#include "data_base_management.h" +#include "folder.h" +#include "library_item.h" +#include "qnaturalsorting.h" +#include "reading_list.h" +#include "yacreader_global.h" +#include "yacreader_libraries.h" + +#include #include #include #include -#include -#include +#include +#include #include #include -#include #include +#include +#include +#include #include -#include "reading_list.h" -#include "library_item.h" -#include "comic_db.h" -#include "data_base_management.h" -#include "folder.h" -#include "yacreader_libraries.h" -#include "yacreader_global.h" - -#include "qnaturalsorting.h" - -#include "QsLog.h" - using namespace YACReader; // server diff --git a/YACReaderLibrary/db_helper.h b/YACReaderLibrary/db_helper.h index 56d22670a..c67b38921 100644 --- a/YACReaderLibrary/db_helper.h +++ b/YACReaderLibrary/db_helper.h @@ -2,10 +2,11 @@ #define DB_HELPER_H class QString; -#include -#include #include "yacreader_global.h" +#include +#include + class ComicDB; class Folder; class LibraryItem; diff --git a/YACReaderLibrary/empty_container_info.h b/YACReaderLibrary/empty_container_info.h index 9adbfa9d5..a2c19be36 100644 --- a/YACReaderLibrary/empty_container_info.h +++ b/YACReaderLibrary/empty_container_info.h @@ -1,6 +1,8 @@ #ifndef EMPTY_CONTAINER_INFO_H #define EMPTY_CONTAINER_INFO_H +#include "themable.h" + #include #include #include @@ -8,8 +10,6 @@ #include #include -#include "themable.h" - class EmptyContainerInfo : public QWidget, protected Themable { Q_OBJECT diff --git a/YACReaderLibrary/export_comics_info_dialog.cpp b/YACReaderLibrary/export_comics_info_dialog.cpp index dac2ac808..9b06cd43b 100644 --- a/YACReaderLibrary/export_comics_info_dialog.cpp +++ b/YACReaderLibrary/export_comics_info_dialog.cpp @@ -1,12 +1,12 @@ #include "export_comics_info_dialog.h" -#include -#include -#include +#include "data_base_management.h" + #include +#include +#include #include - -#include "data_base_management.h" +#include ExportComicsInfoDialog::ExportComicsInfoDialog(QWidget *parent) : QDialog(parent) diff --git a/YACReaderLibrary/export_library_dialog.cpp b/YACReaderLibrary/export_library_dialog.cpp index 066f7192c..0548b5019 100644 --- a/YACReaderLibrary/export_library_dialog.cpp +++ b/YACReaderLibrary/export_library_dialog.cpp @@ -1,9 +1,10 @@ #include "export_library_dialog.h" -#include -#include + +#include #include +#include #include -#include +#include ExportLibraryDialog::ExportLibraryDialog(QWidget *parent) : QDialog(parent), progressCount(0) diff --git a/YACReaderLibrary/export_library_dialog.h b/YACReaderLibrary/export_library_dialog.h index 5321dcb42..32a9c847b 100644 --- a/YACReaderLibrary/export_library_dialog.h +++ b/YACReaderLibrary/export_library_dialog.h @@ -6,11 +6,11 @@ #include #include #include +#include #include #include #include #include -#include class ExportLibraryDialog : public QDialog, protected Themable { diff --git a/YACReaderLibrary/folder_content_view.cpp b/YACReaderLibrary/folder_content_view.cpp index ec01ab003..ec6a5d27b 100644 --- a/YACReaderLibrary/folder_content_view.cpp +++ b/YACReaderLibrary/folder_content_view.cpp @@ -1,13 +1,12 @@ #include "folder_content_view.h" +#include "QsLog.h" +#include "comic.h" +#include "comic_files_manager.h" #include "folder_model.h" #include "grid_comics_view.h" #include "yacreader_global_gui.h" #include "yacreader_tool_bar_stretch.h" -#include "comic.h" -#include "comic_files_manager.h" - -#include "QsLog.h" #include #include diff --git a/YACReaderLibrary/folder_content_view.h b/YACReaderLibrary/folder_content_view.h index 3e15797a9..22d124779 100644 --- a/YACReaderLibrary/folder_content_view.h +++ b/YACReaderLibrary/folder_content_view.h @@ -1,17 +1,16 @@ #ifndef FOLDERCONTENTVIEW_H #define FOLDERCONTENTVIEW_H +#include "comic_db.h" +#include "comic_model.h" +#include "folder.h" +#include "themable.h" + #include #include #include #include -#include "comic_model.h" -#include "themable.h" - -#include "folder.h" -#include "comic_db.h" - class FolderModel; class ComicModel; class YACReaderToolBarStretch; diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index 601d9df52..804891e93 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -1,5 +1,14 @@ #include "grid_comics_view.h" +#include "QsLog.h" +#include "comic.h" +#include "comic_db.h" +#include "comic_files_manager.h" +#include "current_comic_view_helper.h" +#include "yacreader_comic_info_helper.h" +#include "yacreader_comics_selection_helper.h" +#include "yacreader_global_gui.h" + #include #include #include @@ -10,15 +19,6 @@ #include #include -#include "yacreader_global_gui.h" -#include "comic.h" -#include "comic_files_manager.h" -#include "QsLog.h" -#include "comic_db.h" -#include "yacreader_comics_selection_helper.h" -#include "yacreader_comic_info_helper.h" -#include "current_comic_view_helper.h" - GridComicsView::GridComicsView(QWidget *parent) : ComicsView(parent), filterEnabled(false), smallZoomLabel(nullptr), bigZoomLabel(nullptr) { diff --git a/YACReaderLibrary/grid_comics_view.h b/YACReaderLibrary/grid_comics_view.h index 9f60201d9..b3b674fff 100644 --- a/YACReaderLibrary/grid_comics_view.h +++ b/YACReaderLibrary/grid_comics_view.h @@ -1,14 +1,13 @@ #ifndef GRID_COMICS_VIEW_H #define GRID_COMICS_VIEW_H +#include "comic_db.h" #include "comics_view.h" #include "themable.h" #include #include -#include "comic_db.h" - class QAbstractListModel; class QItemSelectionModel; class QQuickWidget; diff --git a/YACReaderLibrary/import_comics_info_dialog.cpp b/YACReaderLibrary/import_comics_info_dialog.cpp index 3018c5721..0f7c7f793 100644 --- a/YACReaderLibrary/import_comics_info_dialog.cpp +++ b/YACReaderLibrary/import_comics_info_dialog.cpp @@ -1,11 +1,11 @@ #include "import_comics_info_dialog.h" -#include -#include +#include "data_base_management.h" + #include +#include #include - -#include "data_base_management.h" +#include ImportComicsInfoDialog::ImportComicsInfoDialog(QWidget *parent) : QDialog(parent) diff --git a/YACReaderLibrary/import_comics_info_dialog.h b/YACReaderLibrary/import_comics_info_dialog.h index 37d7d8e91..c0cf42221 100644 --- a/YACReaderLibrary/import_comics_info_dialog.h +++ b/YACReaderLibrary/import_comics_info_dialog.h @@ -3,12 +3,11 @@ #include "themable.h" -#include #include #include #include -#include #include +#include #include class Importer : public QThread diff --git a/YACReaderLibrary/import_library_dialog.cpp b/YACReaderLibrary/import_library_dialog.cpp index aad7b8231..944cbb283 100644 --- a/YACReaderLibrary/import_library_dialog.cpp +++ b/YACReaderLibrary/import_library_dialog.cpp @@ -1,10 +1,10 @@ #include "import_library_dialog.h" -#include -#include +#include #include #include -#include +#include +#include ImportLibraryDialog::ImportLibraryDialog(QWidget *parent) : QDialog(parent), progressCount(0) diff --git a/YACReaderLibrary/import_library_dialog.h b/YACReaderLibrary/import_library_dialog.h index de1cceed4..87462aa70 100644 --- a/YACReaderLibrary/import_library_dialog.h +++ b/YACReaderLibrary/import_library_dialog.h @@ -1,14 +1,14 @@ #ifndef IMPORT_LIBRARY_DIALOG_H #define IMPORT_LIBRARY_DIALOG_H -#include "yacreader_libraries.h" #include "themable.h" +#include "yacreader_libraries.h" #include #include #include +#include #include #include -#include class ImportLibraryDialog : public QDialog, protected Themable { diff --git a/YACReaderLibrary/import_widget.cpp b/YACReaderLibrary/import_widget.cpp index f899353fd..9c3935814 100644 --- a/YACReaderLibrary/import_widget.cpp +++ b/YACReaderLibrary/import_widget.cpp @@ -1,24 +1,23 @@ #include "import_widget.h" -#include -#include +#include +#include +#include +#include #include +#include #include -#include -#include -#include #include -#include #include +#include // TODO: is QGLWidget needed here??? // #include -#include #include -#include -#include - -#include #include +#include +#include +#include +#include class YACReaderActivityIndicatorWidget : public QWidget { diff --git a/YACReaderLibrary/import_widget.h b/YACReaderLibrary/import_widget.h index 9e54ba5ec..945b38aae 100644 --- a/YACReaderLibrary/import_widget.h +++ b/YACReaderLibrary/import_widget.h @@ -1,6 +1,8 @@ #ifndef IMPORT_WIDGET_H #define IMPORT_WIDGET_H +#include "themable.h" + #include #include #include @@ -9,10 +11,9 @@ #include #include #include +#include #include -#include "themable.h" - class ImportWidget : public QWidget, protected Themable { Q_OBJECT diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp index b801b6d5a..47d118cba 100644 --- a/YACReaderLibrary/info_comics_view.cpp +++ b/YACReaderLibrary/info_comics_view.cpp @@ -1,18 +1,17 @@ #include "info_comics_view.h" -#include -#include -#include -#include -#include - +#include "QsLog.h" #include "comic.h" #include "comic_files_manager.h" #include "comic_model.h" #include "yacreader_comic_info_helper.h" #include "yacreader_comics_selection_helper.h" -#include "QsLog.h" +#include +#include +#include +#include +#include InfoComicsView::InfoComicsView(QWidget *parent) : ComicsView(parent), flow(nullptr), list(nullptr) diff --git a/YACReaderLibrary/info_comics_view.h b/YACReaderLibrary/info_comics_view.h index 596b60c43..d898cee4e 100644 --- a/YACReaderLibrary/info_comics_view.h +++ b/YACReaderLibrary/info_comics_view.h @@ -2,9 +2,10 @@ #define INFOCOMICSVIEW_H #include "comics_view.h" -#include #include "themable.h" +#include + class QQuickView; class YACReaderComicsSelectionHelper; diff --git a/YACReaderLibrary/initial_comic_info_extractor.cpp b/YACReaderLibrary/initial_comic_info_extractor.cpp index 23f96ef02..9cdef9189 100644 --- a/YACReaderLibrary/initial_comic_info_extractor.cpp +++ b/YACReaderLibrary/initial_comic_info_extractor.cpp @@ -1,11 +1,12 @@ #include "initial_comic_info_extractor.h" -#include -#include "pdf_comic.h" #include "comic.h" #include "compressed_archive.h" -#include "qnaturalsorting.h" #include "cover_utils.h" +#include "pdf_comic.h" +#include "qnaturalsorting.h" + +#include using namespace YACReader; diff --git a/YACReaderLibrary/ip_config_helper.cpp b/YACReaderLibrary/ip_config_helper.cpp index 38c58188c..8f33e4779 100644 --- a/YACReaderLibrary/ip_config_helper.cpp +++ b/YACReaderLibrary/ip_config_helper.cpp @@ -1,7 +1,9 @@ -#include #include "ip_config_helper.h" + #include "qnaturalsorting.h" +#include + // 192.168 (most comon local subnet for ips are always put first) // IPs are sorted using natoral sorting diff --git a/YACReaderLibrary/ip_config_helper.h b/YACReaderLibrary/ip_config_helper.h index 8cabe1d34..b5fac6edd 100644 --- a/YACReaderLibrary/ip_config_helper.h +++ b/YACReaderLibrary/ip_config_helper.h @@ -1,4 +1,8 @@ #ifndef YR_IP_CONFIG_HELPER #define YR_IP_CONFIG_HELPER + +#include +#include + QList getIpAddresses(); #endif diff --git a/YACReaderLibrary/libraries_update_coordinator.cpp b/YACReaderLibrary/libraries_update_coordinator.cpp index 703b5d963..9743aef3e 100644 --- a/YACReaderLibrary/libraries_update_coordinator.cpp +++ b/YACReaderLibrary/libraries_update_coordinator.cpp @@ -2,8 +2,8 @@ #include "libraries_update_coordinator.h" #include "library_creator.h" -#include "yacreader_libraries.h" #include "yacreader_global.h" +#include "yacreader_libraries.h" using namespace YACReader; diff --git a/YACReaderLibrary/library_creator.cpp b/YACReaderLibrary/library_creator.cpp index 139dea240..4bfdfffb9 100644 --- a/YACReaderLibrary/library_creator.cpp +++ b/YACReaderLibrary/library_creator.cpp @@ -1,24 +1,22 @@ #include "library_creator.h" -#include -#include -#include -#include -#include -#include -#include - +#include "QsLog.h" +#include "comic.h" #include "data_base_management.h" -#include "qnaturalsorting.h" #include "db_helper.h" - #include "initial_comic_info_extractor.h" -#include "xml_info_parser.h" -#include "comic.h" #include "pdf_comic.h" +#include "qnaturalsorting.h" +#include "xml_info_parser.h" #include "yacreader_global.h" -#include "QsLog.h" +#include +#include +#include +#include +#include +#include +#include #include diff --git a/YACReaderLibrary/library_creator.h b/YACReaderLibrary/library_creator.h index 401e08cd9..cdba5aece 100644 --- a/YACReaderLibrary/library_creator.h +++ b/YACReaderLibrary/library_creator.h @@ -1,19 +1,20 @@ #ifndef __LIBRARY_CREATOR_H #define __LIBRARY_CREATOR_H -#include -#include +#include "comic_db.h" +#include "folder.h" + +#include #include #include -#include -#include -#include -#include #include -#include +#include +#include +#include #include -#include "folder.h" -#include "comic_db.h" +#include +#include +#include class LibraryCreator : public QThread { diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index d1689ede2..8e455b950 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -5,105 +5,85 @@ #include #include +#include +#include +#include #include +#include #include -#include +#include #include +#include #include +#include #include +#include #include #include #include -#include #include #include -#include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include #include #include #ifdef Q_OS_WIN #include + #include #endif -#include "folder_item.h" -#include "data_base_management.h" -#include "no_libraries_widget.h" -#include "import_widget.h" - -#include "yacreader_search_line_edit.h" +#include "QsLog.h" +#include "add_label_dialog.h" +#include "add_library_dialog.h" +#include "api_key_dialog.h" #include "comic_db.h" -#include "library_creator.h" -#include "package_manager.h" -#include "xml_info_library_scanner.h" +#include "comic_files_manager.h" +#include "comic_model.h" +#include "comic_vine_dialog.h" +#include "comics_remover.h" +#include "comics_view.h" +#include "cover_utils.h" #include "create_library_dialog.h" -#include "rename_library_dialog.h" -#include "properties_dialog.h" -#include "export_library_dialog.h" -#include "import_library_dialog.h" +#include "data_base_management.h" +#include "db_helper.h" +#include "edit_shortcuts_dialog.h" #include "export_comics_info_dialog.h" +#include "export_library_dialog.h" +#include "folder_content_view.h" +#include "folder_item.h" +#include "help_about_dialog.h" #include "import_comics_info_dialog.h" -#include "add_library_dialog.h" +#include "import_library_dialog.h" +#include "import_widget.h" +#include "library_comic_opener.h" +#include "library_creator.h" +#include "no_libraries_widget.h" #include "options_dialog.h" -#include "help_about_dialog.h" +#include "package_manager.h" +#include "properties_dialog.h" +#include "reading_list_item.h" +#include "reading_list_model.h" +#include "recent_visibility_coordinator.h" +#include "rename_library_dialog.h" #include "server_config_dialog.h" -#include "comic_model.h" -#include "yacreader_tool_bar_stretch.h" - -#include "yacreader_titled_toolbar.h" -#include "yacreader_main_toolbar.h" - -#include "yacreader_sidebar.h" - -#include "comics_remover.h" -#include "yacreader_library_list_widget.h" -#include "yacreader_folders_view.h" -#include "yacreader_reading_lists_view.h" - -#include "comic_vine_dialog.h" -#include "api_key_dialog.h" - -#include "comics_view.h" - -#include "edit_shortcuts_dialog.h" #include "shortcuts_manager.h" - -#include "comic_files_manager.h" - -#include "reading_list_model.h" -#include "add_label_dialog.h" - -#include "yacreader_history_controller.h" -#include "db_helper.h" - -#include "reading_list_item.h" - -#include "yacreader_content_views_manager.h" -#include "folder_content_view.h" - #include "trayicon_controller.h" - #include "whats_new_controller.h" - -#include "library_comic_opener.h" - -#include "recent_visibility_coordinator.h" - -#include "cover_utils.h" - -#include "QsLog.h" - +#include "xml_info_library_scanner.h" +#include "yacreader_content_views_manager.h" +#include "yacreader_folders_view.h" +#include "yacreader_history_controller.h" #include "yacreader_http_server.h" +#include "yacreader_library_list_widget.h" +#include "yacreader_main_toolbar.h" +#include "yacreader_reading_lists_view.h" +#include "yacreader_search_line_edit.h" +#include "yacreader_sidebar.h" +#include "yacreader_titled_toolbar.h" +#include "yacreader_tool_bar_stretch.h" extern YACReaderHttpServer *httpServer; #include diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index 4e5e0a885..ec25b09c6 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -1,25 +1,22 @@ #ifndef __LIBRARYWINDOW_H #define __LIBRARYWINDOW_H -#include -#include -#include -#include - +#include "comic_db.h" +#include "comic_model.h" +#include "comic_query_result_processor.h" +#include "folder.h" +#include "folder_query_result_processor.h" +#include "libraries_update_coordinator.h" #include "library_window_actions.h" +#include "themable.h" #include "yacreader_global.h" #include "yacreader_libraries.h" -#include "libraries_update_coordinator.h" - #include "yacreader_navigation_controller.h" -#include "comic_query_result_processor.h" -#include "folder_query_result_processor.h" -#include "themable.h" - -#include "comic_model.h" -#include "comic_db.h" -#include "folder.h" +#include +#include +#include +#include #include #include diff --git a/YACReaderLibrary/library_window_actions.cpp b/YACReaderLibrary/library_window_actions.cpp index 4c6edbded..76957dcbd 100644 --- a/YACReaderLibrary/library_window_actions.cpp +++ b/YACReaderLibrary/library_window_actions.cpp @@ -1,18 +1,17 @@ #include "library_window_actions.h" #include "edit_shortcuts_dialog.h" +#include "export_library_dialog.h" +#include "help_about_dialog.h" #include "library_window.h" -#include "shortcuts_manager.h" -#include "yacreader_history_controller.h" #include "recent_visibility_coordinator.h" - -#include "help_about_dialog.h" -#include "export_library_dialog.h" -#include "yacreader_content_views_manager.h" #include "server_config_dialog.h" +#include "shortcuts_manager.h" +#include "theme_manager.h" +#include "yacreader_content_views_manager.h" #include "yacreader_folders_view.h" +#include "yacreader_history_controller.h" #include "yacreader_options_dialog.h" -#include "theme_manager.h" #include diff --git a/YACReaderLibrary/library_window_actions.h b/YACReaderLibrary/library_window_actions.h index 583595a42..0cffabdbb 100644 --- a/YACReaderLibrary/library_window_actions.h +++ b/YACReaderLibrary/library_window_actions.h @@ -1,11 +1,11 @@ #ifndef LIBRARY_WINDOW_ACTIONS_H #define LIBRARY_WINDOW_ACTIONS_H +#include "qaction.h" + #include #include -#include "qaction.h" - class LibraryWindow; class YACReaderHistoryController; class EditShortcutsDialog; diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index 141b6561c..b14bd4636 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -1,29 +1,29 @@ #include "library_window.h" #include -#include -#include #include -#include #include +#include +#include +#include #if !defined use_unarr && !defined use_libarchive #include #endif -#include -#include - -#include "yacreader_global.h" -#include "yacreader_http_server.h" -#include "yacreader_local_server.h" +#include "app_language_utils.h" +#include "appearance_configuration.h" #include "comic_db.h" #include "data_base_management.h" #include "db_helper.h" -#include "yacreader_libraries.h" #include "exit_check.h" -#include "appearance_configuration.h" #include "theme_manager.h" #include "theme_repository.h" -#include "app_language_utils.h" +#include "yacreader_global.h" +#include "yacreader_http_server.h" +#include "yacreader_libraries.h" +#include "yacreader_local_server.h" + +#include +#include #ifdef Q_OS_MACOS #include "trayhandler.h" #endif diff --git a/YACReaderLibrary/no_libraries_widget.cpp b/YACReaderLibrary/no_libraries_widget.cpp index 7603db7fb..ec5865a00 100644 --- a/YACReaderLibrary/no_libraries_widget.cpp +++ b/YACReaderLibrary/no_libraries_widget.cpp @@ -1,9 +1,9 @@ #include "no_libraries_widget.h" -#include -#include #include +#include #include +#include NoLibrariesWidget::NoLibrariesWidget(QWidget *parent) : QWidget(parent) diff --git a/YACReaderLibrary/no_libraries_widget.h b/YACReaderLibrary/no_libraries_widget.h index 9ccfb751b..4e0ea74f6 100644 --- a/YACReaderLibrary/no_libraries_widget.h +++ b/YACReaderLibrary/no_libraries_widget.h @@ -1,10 +1,10 @@ #ifndef NO_LIBRARIES_WIDGET_H #define NO_LIBRARIES_WIDGET_H -#include - #include "themable.h" +#include + class QLabel; class NoLibrariesWidget : public QWidget, protected Themable diff --git a/YACReaderLibrary/options_dialog.cpp b/YACReaderLibrary/options_dialog.cpp index 288b162b2..ff37d8859 100644 --- a/YACReaderLibrary/options_dialog.cpp +++ b/YACReaderLibrary/options_dialog.cpp @@ -1,13 +1,12 @@ #include "options_dialog.h" -#include "yacreader_3d_flow_config_widget.h" #include "api_key_dialog.h" +#include "app_language_utils.h" #include "appearance_tab_widget.h" #include "theme_factory.h" #include "theme_manager.h" - +#include "yacreader_3d_flow_config_widget.h" #include "yacreader_global_gui.h" -#include "app_language_utils.h" #include #include diff --git a/YACReaderLibrary/options_dialog.h b/YACReaderLibrary/options_dialog.h index af878bfa9..017a3ced1 100644 --- a/YACReaderLibrary/options_dialog.h +++ b/YACReaderLibrary/options_dialog.h @@ -1,6 +1,9 @@ #ifndef __OPTIONS_DIALOG_H #define __OPTIONS_DIALOG_H +#include "yacreader_global.h" +#include "yacreader_options_dialog.h" + #include #include #include @@ -10,9 +13,6 @@ #include #include -#include "yacreader_global.h" -#include "yacreader_options_dialog.h" - using namespace YACReader; class OptionsDialog : public YACReaderOptionsDialog diff --git a/YACReaderLibrary/package_manager.cpp b/YACReaderLibrary/package_manager.cpp index 38200f5c1..2c8278d84 100644 --- a/YACReaderLibrary/package_manager.cpp +++ b/YACReaderLibrary/package_manager.cpp @@ -1,4 +1,5 @@ #include "package_manager.h" + #include PackageManager::PackageManager() diff --git a/YACReaderLibrary/properties_dialog.cpp b/YACReaderLibrary/properties_dialog.cpp index b23d5dd8c..4b43cd42c 100644 --- a/YACReaderLibrary/properties_dialog.cpp +++ b/YACReaderLibrary/properties_dialog.cpp @@ -1,29 +1,28 @@ #include "properties_dialog.h" -#include "yacreader_global_gui.h" - #include "cover_utils.h" #include "data_base_management.h" +#include "db_helper.h" #include "initial_comic_info_extractor.h" +#include "yacreader_cover_label.h" #include "yacreader_field_edit.h" #include "yacreader_field_plain_text_edit.h" -#include "db_helper.h" -#include "yacreader_cover_label.h" +#include "yacreader_global_gui.h" -#include -#include #include -#include -#include #include -#include -#include +#include +#include #include +#include +#include +#include #include -#include -#include -#include #include +#include +#include +#include +#include using namespace YACReader; diff --git a/YACReaderLibrary/properties_dialog.h b/YACReaderLibrary/properties_dialog.h index f4dcdd96b..c4f9e3455 100644 --- a/YACReaderLibrary/properties_dialog.h +++ b/YACReaderLibrary/properties_dialog.h @@ -2,7 +2,6 @@ #define __PROPERTIES_DIALOG_H #include - #include class QGridLayout; diff --git a/YACReaderLibrary/recent_visibility_coordinator.h b/YACReaderLibrary/recent_visibility_coordinator.h index 518c9c17b..b6e917ceb 100644 --- a/YACReaderLibrary/recent_visibility_coordinator.h +++ b/YACReaderLibrary/recent_visibility_coordinator.h @@ -2,9 +2,9 @@ #ifndef RECENT_VISIBILITY_COORDINATOR_H #define RECENT_VISIBILITY_COORDINATOR_H -#include "folder_model.h" #include "comic_model.h" #include "folder_content_view.h" +#include "folder_model.h" class RecentVisibilityCoordinator : public QObject { diff --git a/YACReaderLibrary/rename_library_dialog.cpp b/YACReaderLibrary/rename_library_dialog.cpp index 724dfd342..0439aeac5 100644 --- a/YACReaderLibrary/rename_library_dialog.cpp +++ b/YACReaderLibrary/rename_library_dialog.cpp @@ -1,8 +1,8 @@ #include "rename_library_dialog.h" +#include #include #include -#include RenameLibraryDialog::RenameLibraryDialog(QWidget *parent) : QDialog(parent) diff --git a/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.cpp index 816ac19eb..7c71efc0d 100644 --- a/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.cpp @@ -1,17 +1,13 @@ #include "comiccontroller_v2.h" -#include "db_helper.h" -#include "yacreader_libraries.h" -#include "yacreader_http_session.h" - #include "../static.h" - -#include "comic_db.h" +#include "QsLog.h" #include "comic.h" - +#include "comic_db.h" +#include "db_helper.h" #include "qnaturalsorting.h" - -#include "QsLog.h" +#include "yacreader_http_session.h" +#include "yacreader_libraries.h" using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.h b/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.h index f22aa6317..7197e6269 100644 --- a/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/comiccontroller_v2.h @@ -2,8 +2,8 @@ #define COMICCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class ComicControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/comiccontrollerinreadinglist_v2.cpp b/YACReaderLibrary/server/controllers/v2/comiccontrollerinreadinglist_v2.cpp index 82b54030c..bd026624f 100644 --- a/YACReaderLibrary/server/controllers/v2/comiccontrollerinreadinglist_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/comiccontrollerinreadinglist_v2.cpp @@ -1,15 +1,12 @@ #include "comiccontrollerinreadinglist_v2.h" -#include "db_helper.h" -#include "yacreader_libraries.h" -#include "yacreader_http_session.h" - #include "../static.h" - -#include "comic_db.h" -#include "comic.h" - #include "QsLog.h" +#include "comic.h" +#include "comic_db.h" +#include "db_helper.h" +#include "yacreader_http_session.h" +#include "yacreader_libraries.h" using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/comiccontrollerinreadinglist_v2.h b/YACReaderLibrary/server/controllers/v2/comiccontrollerinreadinglist_v2.h index 424fcbf74..3f697abfd 100644 --- a/YACReaderLibrary/server/controllers/v2/comiccontrollerinreadinglist_v2.h +++ b/YACReaderLibrary/server/controllers/v2/comiccontrollerinreadinglist_v2.h @@ -2,8 +2,8 @@ #define COMICCONTROLLERINREADINGLISTV2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class ComicControllerInReadingListV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/comicdownloadinfocontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/comicdownloadinfocontroller_v2.cpp index 903fa9aea..ef414872f 100644 --- a/YACReaderLibrary/server/controllers/v2/comicdownloadinfocontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/comicdownloadinfocontroller_v2.cpp @@ -1,10 +1,9 @@ #include "comicdownloadinfocontroller_v2.h" -#include - +#include "comic_db.h" #include "db_helper.h" -#include "comic_db.h" +#include using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/comicdownloadinfocontroller_v2.h b/YACReaderLibrary/server/controllers/v2/comicdownloadinfocontroller_v2.h index a40f214dc..4e32ff196 100644 --- a/YACReaderLibrary/server/controllers/v2/comicdownloadinfocontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/comicdownloadinfocontroller_v2.h @@ -2,8 +2,8 @@ #define COMICDOWNLOADINFOCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class ComicDownloadInfoControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/comicfullinfocontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/comicfullinfocontroller_v2.cpp index 2f5af2fec..12dd01bca 100644 --- a/YACReaderLibrary/server/controllers/v2/comicfullinfocontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/comicfullinfocontroller_v2.cpp @@ -1,13 +1,12 @@ #include "comicfullinfocontroller_v2.h" -#include - -#include "db_helper.h" #include "comic_db.h" - +#include "db_helper.h" #include "yacreader_libraries.h" #include "yacreader_server_data_helper.h" +#include + using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; using namespace std; diff --git a/YACReaderLibrary/server/controllers/v2/comicfullinfocontroller_v2.h b/YACReaderLibrary/server/controllers/v2/comicfullinfocontroller_v2.h index 031232ee9..e7bae830b 100644 --- a/YACReaderLibrary/server/controllers/v2/comicfullinfocontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/comicfullinfocontroller_v2.h @@ -2,8 +2,8 @@ #define COMICFULLINFOCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class ComicFullinfoController_v2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/covercontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/covercontroller_v2.cpp index e0bb5a35e..aa3741497 100644 --- a/YACReaderLibrary/server/controllers/v2/covercontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/covercontroller_v2.cpp @@ -1,8 +1,10 @@ #include "covercontroller_v2.h" + #include "db_helper.h" //get libraries -#include -#include "yacreader_libraries.h" #include "yacreader_global.h" +#include "yacreader_libraries.h" + +#include using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/covercontroller_v2.h b/YACReaderLibrary/server/controllers/v2/covercontroller_v2.h index 7dc7d726d..2b47b1086 100644 --- a/YACReaderLibrary/server/controllers/v2/covercontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/covercontroller_v2.h @@ -2,8 +2,8 @@ #define COVERCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class CoverControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/errorcontroller_v2.h b/YACReaderLibrary/server/controllers/v2/errorcontroller_v2.h index 3b64416fb..eda826d18 100644 --- a/YACReaderLibrary/server/controllers/v2/errorcontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/errorcontroller_v2.h @@ -2,8 +2,8 @@ #define ERRORCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class ErrorControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/favoritescontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/favoritescontroller_v2.cpp index a7bc39fb4..b7e35dc50 100644 --- a/YACReaderLibrary/server/controllers/v2/favoritescontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/favoritescontroller_v2.cpp @@ -1,8 +1,7 @@ #include "favoritescontroller_v2.h" -#include "db_helper.h" #include "comic_db.h" - +#include "db_helper.h" #include "yacreader_libraries.h" #include "yacreader_server_data_helper.h" diff --git a/YACReaderLibrary/server/controllers/v2/favoritescontroller_v2.h b/YACReaderLibrary/server/controllers/v2/favoritescontroller_v2.h index 5ab08463f..d0de2944e 100644 --- a/YACReaderLibrary/server/controllers/v2/favoritescontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/favoritescontroller_v2.h @@ -2,8 +2,8 @@ #define FAVORITESCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class FavoritesControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp index 0ecc765d2..9a2f118ed 100644 --- a/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.cpp @@ -1,17 +1,14 @@ #include "foldercontentcontroller_v2.h" -#include - -#include "db_helper.h" +#include "QsLog.h" #include "comic_db.h" +#include "db_helper.h" #include "folder.h" - +#include "qnaturalsorting.h" #include "yacreader_libraries.h" #include "yacreader_server_data_helper.h" -#include "qnaturalsorting.h" - -#include "QsLog.h" +#include #include diff --git a/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.h b/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.h index b856fe7f2..d5eac13e2 100644 --- a/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/foldercontentcontroller_v2.h @@ -2,8 +2,8 @@ #define FOLDERCONTENTCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class FolderContentControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.cpp index 5b5c1e3db..ff17afca9 100644 --- a/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.cpp @@ -1,11 +1,10 @@ #include "folderinfocontroller_v2.h" -#include - +#include "comic_db.h" #include "db_helper.h" //get libraries - #include "folder.h" -#include "comic_db.h" + +#include using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.h b/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.h index 321fc4243..ddac5fe07 100644 --- a/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/folderinfocontroller_v2.h @@ -2,8 +2,8 @@ #define FOLDERINFOCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class FolderInfoControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/foldermetadatacontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/foldermetadatacontroller_v2.cpp index 8910dcc7d..7d8d34b83 100644 --- a/YACReaderLibrary/server/controllers/v2/foldermetadatacontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/foldermetadatacontroller_v2.cpp @@ -2,7 +2,6 @@ #include "db_helper.h" #include "folder.h" - #include "yacreader_libraries.h" #include "yacreader_server_data_helper.h" diff --git a/YACReaderLibrary/server/controllers/v2/foldermetadatacontroller_v2.h b/YACReaderLibrary/server/controllers/v2/foldermetadatacontroller_v2.h index 03980355c..0e2ba8926 100644 --- a/YACReaderLibrary/server/controllers/v2/foldermetadatacontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/foldermetadatacontroller_v2.h @@ -2,8 +2,8 @@ #define FOLDERMETADATACONTROLLERV2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class FolderMetadataControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/librariescontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/librariescontroller_v2.cpp index ea949499d..9eb737398 100644 --- a/YACReaderLibrary/server/controllers/v2/librariescontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/librariescontroller_v2.cpp @@ -1,4 +1,5 @@ #include "librariescontroller_v2.h" + #include "db_helper.h" //get libraries #include "yacreader_libraries.h" diff --git a/YACReaderLibrary/server/controllers/v2/librariescontroller_v2.h b/YACReaderLibrary/server/controllers/v2/librariescontroller_v2.h index 521492c4e..a09c7d369 100644 --- a/YACReaderLibrary/server/controllers/v2/librariescontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/librariescontroller_v2.h @@ -2,8 +2,8 @@ #define LIBRARIESCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" /** This controller displays a HTML form and dumps the submitted input. diff --git a/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.cpp index bf9585cbf..6755ccab4 100644 --- a/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.cpp @@ -1,13 +1,11 @@ #include "pagecontroller_v2.h" #include "../static.h" - #include "comic.h" #include "yacreader_http_session.h" #include #include - #include using stefanfrings::HttpRequest; diff --git a/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.h b/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.h index 4bd71ce6e..60806e5f3 100644 --- a/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/pagecontroller_v2.h @@ -2,8 +2,8 @@ #define PAGECONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class PageControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/readingcomicscontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/readingcomicscontroller_v2.cpp index a63b3d7cc..2b10a767c 100644 --- a/YACReaderLibrary/server/controllers/v2/readingcomicscontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/readingcomicscontroller_v2.cpp @@ -1,8 +1,7 @@ #include "readingcomicscontroller_v2.h" -#include "db_helper.h" #include "comic_db.h" - +#include "db_helper.h" #include "yacreader_libraries.h" #include "yacreader_server_data_helper.h" diff --git a/YACReaderLibrary/server/controllers/v2/readingcomicscontroller_v2.h b/YACReaderLibrary/server/controllers/v2/readingcomicscontroller_v2.h index 51c960613..5aa916c39 100644 --- a/YACReaderLibrary/server/controllers/v2/readingcomicscontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/readingcomicscontroller_v2.h @@ -2,8 +2,8 @@ #define READINGCOMICSCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class ReadingComicsControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/readinglistcontentcontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/readinglistcontentcontroller_v2.cpp index 0abb55fce..353324ac6 100644 --- a/YACReaderLibrary/server/controllers/v2/readinglistcontentcontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/readinglistcontentcontroller_v2.cpp @@ -1,8 +1,7 @@ #include "readinglistcontentcontroller_v2.h" -#include "db_helper.h" #include "comic_db.h" - +#include "db_helper.h" #include "yacreader_libraries.h" #include "yacreader_server_data_helper.h" diff --git a/YACReaderLibrary/server/controllers/v2/readinglistcontentcontroller_v2.h b/YACReaderLibrary/server/controllers/v2/readinglistcontentcontroller_v2.h index bdf482e12..40e6f7dcf 100644 --- a/YACReaderLibrary/server/controllers/v2/readinglistcontentcontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/readinglistcontentcontroller_v2.h @@ -2,8 +2,8 @@ #define READINGLISTCONTENTCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class ReadingListContentControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.cpp index 7468bb40d..51a48b168 100644 --- a/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.cpp @@ -1,10 +1,9 @@ #include "readinglistinfocontroller_v2.h" -#include - +#include "comic_db.h" #include "db_helper.h" -#include "comic_db.h" +#include using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.h b/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.h index 32f42b269..43de4e8f2 100644 --- a/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/readinglistinfocontroller_v2.h @@ -2,8 +2,8 @@ #define READINGLISTINFOCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class ReadingListInfoControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/readinglistscontroller_v2.h b/YACReaderLibrary/server/controllers/v2/readinglistscontroller_v2.h index d319982dc..ea156c15f 100644 --- a/YACReaderLibrary/server/controllers/v2/readinglistscontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/readinglistscontroller_v2.h @@ -2,8 +2,8 @@ #define READINGLISTSCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class ReadingListsControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/searchcontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/searchcontroller_v2.cpp index e4a0632a4..a84091327 100644 --- a/YACReaderLibrary/server/controllers/v2/searchcontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/searchcontroller_v2.cpp @@ -3,8 +3,8 @@ #include "data_base_management.h" #include "db_helper.h" -#include "yacreader_libraries.h" #include "search_query.h" +#include "yacreader_libraries.h" #include #include diff --git a/YACReaderLibrary/server/controllers/v2/searchcontroller_v2.h b/YACReaderLibrary/server/controllers/v2/searchcontroller_v2.h index 52c1e778b..8837aa5df 100644 --- a/YACReaderLibrary/server/controllers/v2/searchcontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/searchcontroller_v2.h @@ -3,8 +3,8 @@ #define SEARCHCONTROLLER_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" #include diff --git a/YACReaderLibrary/server/controllers/v2/synccontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/synccontroller_v2.cpp index a64a11823..edba69f9a 100644 --- a/YACReaderLibrary/server/controllers/v2/synccontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/synccontroller_v2.cpp @@ -1,13 +1,13 @@ #include "synccontroller_v2.h" #include "QsLog.h" -#include - #include "comic_db.h" #include "db_helper.h" #include "yacreader_libraries.h" #include "yacreader_server_data_helper.h" +#include + using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/synccontroller_v2.h b/YACReaderLibrary/server/controllers/v2/synccontroller_v2.h index ca7358c7e..715a01c7e 100644 --- a/YACReaderLibrary/server/controllers/v2/synccontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/synccontroller_v2.h @@ -1,11 +1,11 @@ #ifndef SYNCCONTROLLER_V2_H #define SYNCCONTROLLER_V2_H -#include - #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" + +#include class SyncControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/tagcontentcontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/tagcontentcontroller_v2.cpp index 8aca99cf7..301f665ef 100644 --- a/YACReaderLibrary/server/controllers/v2/tagcontentcontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/tagcontentcontroller_v2.cpp @@ -1,8 +1,7 @@ #include "tagcontentcontroller_v2.h" -#include "db_helper.h" #include "comic_db.h" - +#include "db_helper.h" #include "yacreader_libraries.h" #include "yacreader_server_data_helper.h" diff --git a/YACReaderLibrary/server/controllers/v2/tagcontentcontroller_v2.h b/YACReaderLibrary/server/controllers/v2/tagcontentcontroller_v2.h index 9d140479d..956439949 100644 --- a/YACReaderLibrary/server/controllers/v2/tagcontentcontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/tagcontentcontroller_v2.h @@ -2,8 +2,8 @@ #define TAGCONTENTCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class TagContentControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.cpp index 215930678..e7d3205ec 100644 --- a/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.cpp @@ -1,10 +1,9 @@ #include "taginfocontroller_v2.h" -#include - +#include "comic_db.h" #include "db_helper.h" -#include "comic_db.h" +#include using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.h b/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.h index 78232c921..7617b4d54 100644 --- a/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/taginfocontroller_v2.h @@ -2,8 +2,8 @@ #define TAGINFOCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class TagInfoControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/tagscontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/tagscontroller_v2.cpp index 28337ec74..a60e42387 100644 --- a/YACReaderLibrary/server/controllers/v2/tagscontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/tagscontroller_v2.cpp @@ -1,10 +1,8 @@ #include "tagscontroller_v2.h" #include "db_helper.h" -#include "yacreader_libraries.h" - #include "reading_list.h" - +#include "yacreader_libraries.h" #include "yacreader_server_data_helper.h" using stefanfrings::HttpRequest; diff --git a/YACReaderLibrary/server/controllers/v2/tagscontroller_v2.h b/YACReaderLibrary/server/controllers/v2/tagscontroller_v2.h index 4748f82df..4a8e1f4b6 100644 --- a/YACReaderLibrary/server/controllers/v2/tagscontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/tagscontroller_v2.h @@ -2,8 +2,8 @@ #define TAGSCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class TagsControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp index 03401063d..7e4979749 100644 --- a/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.cpp @@ -1,12 +1,10 @@ #include "updatecomiccontroller_v2.h" -#include - -#include "db_helper.h" - +#include "QsLog.h" #include "comic_db.h" +#include "db_helper.h" -#include "QsLog.h" +#include using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; diff --git a/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.h b/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.h index 90a15b6fa..59912d379 100644 --- a/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.h +++ b/YACReaderLibrary/server/controllers/v2/updatecomiccontroller_v2.h @@ -2,8 +2,8 @@ #define UPDATECOMICCONTROLLER_V2_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class UpdateComicControllerV2 : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/controllers/versioncontroller.h b/YACReaderLibrary/server/controllers/versioncontroller.h index 9824ed34d..f38586a88 100644 --- a/YACReaderLibrary/server/controllers/versioncontroller.h +++ b/YACReaderLibrary/server/controllers/versioncontroller.h @@ -2,8 +2,8 @@ #define VERSIONCONTROLLER_H #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" #include diff --git a/YACReaderLibrary/server/controllers/webui/statuspagecontroller.cpp b/YACReaderLibrary/server/controllers/webui/statuspagecontroller.cpp index 8312bb88f..fadf99110 100644 --- a/YACReaderLibrary/server/controllers/webui/statuspagecontroller.cpp +++ b/YACReaderLibrary/server/controllers/webui/statuspagecontroller.cpp @@ -1,8 +1,8 @@ #include "statuspagecontroller.h" +#include "db_helper.h" #include "template.h" #include "yacreader_global.h" -#include "db_helper.h" #include "yacreader_libraries.h" #include diff --git a/YACReaderLibrary/server/controllers/webui/statuspagecontroller.h b/YACReaderLibrary/server/controllers/webui/statuspagecontroller.h index 22dae09fa..4eccd086c 100644 --- a/YACReaderLibrary/server/controllers/webui/statuspagecontroller.h +++ b/YACReaderLibrary/server/controllers/webui/statuspagecontroller.h @@ -2,8 +2,8 @@ #define STATUSPAGE_CONTROLLER #include "httprequest.h" -#include "httpresponse.h" #include "httprequesthandler.h" +#include "httpresponse.h" class StatusPageController : public stefanfrings::HttpRequestHandler { diff --git a/YACReaderLibrary/server/requestmapper.cpp b/YACReaderLibrary/server/requestmapper.cpp index 7e181c639..10f3d2e33 100644 --- a/YACReaderLibrary/server/requestmapper.cpp +++ b/YACReaderLibrary/server/requestmapper.cpp @@ -1,39 +1,34 @@ #include "requestmapper.h" -#include "static.h" -#include "staticfilecontroller.h" - -#include "controllers/versioncontroller.h" -#include "controllers/v2/librariescontroller_v2.h" -#include "controllers/v2/covercontroller_v2.h" +#include "QsLog.h" #include "controllers/v2/comiccontroller_v2.h" -#include "controllers/v2/folderinfocontroller_v2.h" -#include "controllers/v2/pagecontroller_v2.h" -#include "controllers/v2/updatecomiccontroller_v2.h" +#include "controllers/v2/comiccontrollerinreadinglist_v2.h" #include "controllers/v2/comicdownloadinfocontroller_v2.h" -#include "controllers/v2/synccontroller_v2.h" -#include "controllers/v2/foldercontentcontroller_v2.h" -#include "controllers/v2/tagscontroller_v2.h" -#include "controllers/v2/tagcontentcontroller_v2.h" -#include "controllers/v2/taginfocontroller_v2.h" +#include "controllers/v2/comicfullinfocontroller_v2.h" +#include "controllers/v2/covercontroller_v2.h" #include "controllers/v2/favoritescontroller_v2.h" +#include "controllers/v2/foldercontentcontroller_v2.h" +#include "controllers/v2/folderinfocontroller_v2.h" +#include "controllers/v2/foldermetadatacontroller_v2.h" +#include "controllers/v2/librariescontroller_v2.h" +#include "controllers/v2/pagecontroller_v2.h" #include "controllers/v2/readingcomicscontroller_v2.h" -#include "controllers/v2/readinglistscontroller_v2.h" #include "controllers/v2/readinglistcontentcontroller_v2.h" #include "controllers/v2/readinglistinfocontroller_v2.h" -#include "controllers/v2/comicfullinfocontroller_v2.h" -#include "controllers/v2/comiccontrollerinreadinglist_v2.h" +#include "controllers/v2/readinglistscontroller_v2.h" #include "controllers/v2/searchcontroller_v2.h" -#include "controllers/v2/foldermetadatacontroller_v2.h" - +#include "controllers/v2/synccontroller_v2.h" +#include "controllers/v2/tagcontentcontroller_v2.h" +#include "controllers/v2/taginfocontroller_v2.h" +#include "controllers/v2/tagscontroller_v2.h" +#include "controllers/v2/updatecomiccontroller_v2.h" +#include "controllers/versioncontroller.h" #include "controllers/webui/statuspagecontroller.h" - #include "db_helper.h" -#include "yacreader_libraries.h" - +#include "static.h" +#include "staticfilecontroller.h" #include "yacreader_http_session.h" - -#include "QsLog.h" +#include "yacreader_libraries.h" #include diff --git a/YACReaderLibrary/server/requestmapper.h b/YACReaderLibrary/server/requestmapper.h index 1767639ee..3598b1e96 100644 --- a/YACReaderLibrary/server/requestmapper.h +++ b/YACReaderLibrary/server/requestmapper.h @@ -2,6 +2,7 @@ #define REQUESTMAPPER_H #include "httprequesthandler.h" + #include class RequestMapper : public stefanfrings::HttpRequestHandler diff --git a/YACReaderLibrary/server/static.cpp b/YACReaderLibrary/server/static.cpp index 509a04672..fd8a563af 100644 --- a/YACReaderLibrary/server/static.cpp +++ b/YACReaderLibrary/server/static.cpp @@ -4,6 +4,7 @@ */ #include "static.h" + #include #include #include diff --git a/YACReaderLibrary/server/static.h b/YACReaderLibrary/server/static.h index d97eef0ea..48bf1d654 100644 --- a/YACReaderLibrary/server/static.h +++ b/YACReaderLibrary/server/static.h @@ -6,11 +6,11 @@ #ifndef STATIC_H #define STATIC_H -#include #include "staticfilecontroller.h" - #include "yacreader_http_session_store.h" +#include + /** This class contains some static resources that are used by the application. */ diff --git a/YACReaderLibrary/server/yacreader_http_server.cpp b/YACReaderLibrary/server/yacreader_http_server.cpp index 55f1bc3cf..cf59e681e 100644 --- a/YACReaderLibrary/server/yacreader_http_server.cpp +++ b/YACReaderLibrary/server/yacreader_http_server.cpp @@ -3,17 +3,17 @@ @author Stefan Frings */ -#include "static.h" #include "yacreader_http_server.h" + +#include "static.h" // #include "dualfilelogger.h" #include "httplistener.h" #include "requestmapper.h" #include "staticfilecontroller.h" - #include "yacreader_global.h" -#include #include +#include /** Name of this application */ #define APPNAME "YACReaderLibrary" diff --git a/YACReaderLibrary/server/yacreader_http_session.h b/YACReaderLibrary/server/yacreader_http_session.h index 995753e30..e1691aee8 100644 --- a/YACReaderLibrary/server/yacreader_http_session.h +++ b/YACReaderLibrary/server/yacreader_http_session.h @@ -1,10 +1,10 @@ #ifndef YACREADERHTTPSESSION_H #define YACREADERHTTPSESSION_H -#include - #include "comic.h" +#include + class YACReaderHttpSession : public QObject { Q_OBJECT diff --git a/YACReaderLibrary/server/yacreader_http_session_store.cpp b/YACReaderLibrary/server/yacreader_http_session_store.cpp index b8fa889a7..0fe827cc1 100644 --- a/YACReaderLibrary/server/yacreader_http_session_store.cpp +++ b/YACReaderLibrary/server/yacreader_http_session_store.cpp @@ -1,9 +1,9 @@ #include "yacreader_http_session_store.h" -#include - #include "yacreader_http_session.h" +#include + YACReaderHttpSessionStore::YACReaderHttpSessionStore(QObject *parent) : QObject(parent) { diff --git a/YACReaderLibrary/server/yacreader_server_data_helper.h b/YACReaderLibrary/server/yacreader_server_data_helper.h index d495898e9..f755bf0ae 100644 --- a/YACReaderLibrary/server/yacreader_server_data_helper.h +++ b/YACReaderLibrary/server/yacreader_server_data_helper.h @@ -1,11 +1,12 @@ #ifndef YACREADERSERVERDATAHELPER_H #define YACREADERSERVERDATAHELPER_H -#include -#include "folder.h" #include "comic_db.h" +#include "folder.h" #include "reading_list.h" +#include + class YACReaderServerDataHelper { public: diff --git a/YACReaderLibrary/server_config_dialog.cpp b/YACReaderLibrary/server_config_dialog.cpp index 924349d2f..21a361469 100644 --- a/YACReaderLibrary/server_config_dialog.cpp +++ b/YACReaderLibrary/server_config_dialog.cpp @@ -1,16 +1,16 @@ -#include -#include -#include -#include -#include -#include - #include "server_config_dialog.h" -#include "yacreader_http_server.h" -#include "yacreader_global_gui.h" #include "ip_config_helper.h" #include "qrcodegen.hpp" +#include "yacreader_global_gui.h" +#include "yacreader_http_server.h" + +#include +#include +#include +#include +#include +#include extern YACReaderHttpServer *httpServer; diff --git a/YACReaderLibrary/server_config_dialog.h b/YACReaderLibrary/server_config_dialog.h index 0345d381e..67014af44 100644 --- a/YACReaderLibrary/server_config_dialog.h +++ b/YACReaderLibrary/server_config_dialog.h @@ -1,14 +1,14 @@ #ifndef __SERVER_CONFIG_DIALOG_H #define __SERVER_CONFIG_DIALOG_H +#include "themable.h" + +#include +#include #include #include #include #include -#include -#include - -#include "themable.h" class ServerConfigDialog : public QDialog, protected Themable { diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index 6c208d699..9ade45fa7 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -1,12 +1,12 @@ #ifndef THEME_H #define THEME_H -#include - -#include "yacreader_icon.h" #include "help_about_dialog_theme.h" -#include "whats_new_dialog_theme.h" #include "theme_meta.h" +#include "whats_new_dialog_theme.h" +#include "yacreader_icon.h" + +#include struct MetadataScraperDialogThemeTemplates { QString defaultLabelQSS = "QLabel {color:%1; font-size:12px;font-family:Arial;}"; diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index e7bcc688a..a65359dc7 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -1,13 +1,13 @@ #include "theme_factory.h" +#include "icon_utils.h" +#include "yacreader_global.h" + #include #include #include #include -#include "icon_utils.h" -#include "yacreader_global.h" - struct MetadataScraperDialogParams { MetadataScraperDialogThemeTemplates t; diff --git a/YACReaderLibrary/trayhandler.mm b/YACReaderLibrary/trayhandler.mm index 05eb65028..cf1dbdae1 100644 --- a/YACReaderLibrary/trayhandler.mm +++ b/YACReaderLibrary/trayhandler.mm @@ -2,9 +2,10 @@ #include #undef __OBJC_BOOL_IS_BOOL -#import #include "trayhandler.h" +#import + void OSXShowDockIcon() { [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; diff --git a/YACReaderLibrary/trayicon_controller.cpp b/YACReaderLibrary/trayicon_controller.cpp index 2fbda2e0c..4a9ae8098 100644 --- a/YACReaderLibrary/trayicon_controller.cpp +++ b/YACReaderLibrary/trayicon_controller.cpp @@ -1,8 +1,7 @@ #include "trayicon_controller.h" -#include "yacreader_global_gui.h" - #include "library_window.h" +#include "yacreader_global_gui.h" #include #include diff --git a/YACReaderLibrary/xml_info_library_scanner.cpp b/YACReaderLibrary/xml_info_library_scanner.cpp index 20cadfbd3..40855e363 100644 --- a/YACReaderLibrary/xml_info_library_scanner.cpp +++ b/YACReaderLibrary/xml_info_library_scanner.cpp @@ -1,16 +1,15 @@ #include "xml_info_library_scanner.h" -#include - +#include "QsLog.h" #include "comic_db.h" #include "data_base_management.h" #include "db_helper.h" +#include "folder_item.h" #include "initial_comic_info_extractor.h" #include "xml_info_parser.h" #include "yacreader_global.h" -#include "folder_item.h" -#include "QsLog.h" +#include using namespace YACReader; diff --git a/YACReaderLibrary/xml_info_library_scanner.h b/YACReaderLibrary/xml_info_library_scanner.h index b752a2e18..f0676ad7f 100644 --- a/YACReaderLibrary/xml_info_library_scanner.h +++ b/YACReaderLibrary/xml_info_library_scanner.h @@ -1,8 +1,8 @@ #ifndef XMLINFOLIBRARYSCANNER_H #define XMLINFOLIBRARYSCANNER_H -#include #include +#include namespace YACReader { diff --git a/YACReaderLibrary/yacreader_content_views_manager.cpp b/YACReaderLibrary/yacreader_content_views_manager.cpp index 8d56c1ea1..0d505a8dc 100644 --- a/YACReaderLibrary/yacreader_content_views_manager.cpp +++ b/YACReaderLibrary/yacreader_content_views_manager.cpp @@ -1,22 +1,19 @@ #include "yacreader_content_views_manager.h" -#include "library_window.h" - #include "classic_comics_view.h" -#include "grid_comics_view.h" -#include "folder_content_view.h" - -#include "yacreader_sidebar.h" - -#include "info_comics_view.h" #include "comics_view_transition.h" +#include "empty_folder_widget.h" #include "empty_label_widget.h" -#include "empty_special_list.h" #include "empty_reading_list_widget.h" -#include "empty_folder_widget.h" +#include "empty_special_list.h" +#include "folder_content_view.h" +#include "grid_comics_view.h" +#include "info_comics_view.h" +#include "library_window.h" #include "no_search_results_widget.h" -#include "yacreader_options_dialog.h" #include "options_dialog.h" +#include "yacreader_options_dialog.h" +#include "yacreader_sidebar.h" //-- #include "yacreader_search_line_edit.h" diff --git a/YACReaderLibrary/yacreader_content_views_manager.h b/YACReaderLibrary/yacreader_content_views_manager.h index ed03b2d8c..e78a1f62f 100644 --- a/YACReaderLibrary/yacreader_content_views_manager.h +++ b/YACReaderLibrary/yacreader_content_views_manager.h @@ -1,12 +1,12 @@ #ifndef YACREADERCONTENTVIEWSMANAGER_H #define YACREADERCONTENTVIEWSMANAGER_H +#include "themable.h" +#include "yacreader_global_gui.h" + #include #include -#include "yacreader_global_gui.h" -#include "themable.h" - class LibraryWindow; class ComicsView; diff --git a/YACReaderLibrary/yacreader_folders_view.cpp b/YACReaderLibrary/yacreader_folders_view.cpp index 546a06952..54d413be9 100644 --- a/YACReaderLibrary/yacreader_folders_view.cpp +++ b/YACReaderLibrary/yacreader_folders_view.cpp @@ -1,13 +1,10 @@ #include "yacreader_folders_view.h" -#include "yacreader_treeview.h" - -#include "folder_model.h" - +#include "QsLog.h" #include "comic.h" #include "comic_files_manager.h" - -#include "QsLog.h" +#include "folder_model.h" +#include "yacreader_treeview.h" YACReaderFoldersView::YACReaderFoldersView(QWidget *parent) : YACReaderTreeView(parent) diff --git a/YACReaderLibrary/yacreader_folders_view.h b/YACReaderLibrary/yacreader_folders_view.h index 534859dba..30ac57c9f 100644 --- a/YACReaderLibrary/yacreader_folders_view.h +++ b/YACReaderLibrary/yacreader_folders_view.h @@ -1,12 +1,12 @@ #ifndef YACREADER_FOLDERS_VIEW_H #define YACREADER_FOLDERS_VIEW_H +#include "theme.h" +#include "yacreader_treeview.h" + #include -#include #include - -#include "yacreader_treeview.h" -#include "theme.h" +#include class YACReaderFoldersView : public YACReaderTreeView { diff --git a/YACReaderLibrary/yacreader_history_controller.h b/YACReaderLibrary/yacreader_history_controller.h index b51ecb8ee..8bf539d6b 100644 --- a/YACReaderLibrary/yacreader_history_controller.h +++ b/YACReaderLibrary/yacreader_history_controller.h @@ -1,9 +1,8 @@ #ifndef YACREADER_HISTORY_CONTROLLER_H #define YACREADER_HISTORY_CONTROLLER_H -#include - #include +#include class YACReaderHistoryController; diff --git a/YACReaderLibrary/yacreader_libraries.cpp b/YACReaderLibrary/yacreader_libraries.cpp index 2ac86ff34..54fea2fe7 100644 --- a/YACReaderLibrary/yacreader_libraries.cpp +++ b/YACReaderLibrary/yacreader_libraries.cpp @@ -1,4 +1,5 @@ #include "yacreader_libraries.h" + #include "qnaturalsorting.h" #include "yacreader_global.h" diff --git a/YACReaderLibrary/yacreader_local_server.cpp b/YACReaderLibrary/yacreader_local_server.cpp index b506260d1..f367eae5c 100644 --- a/YACReaderLibrary/yacreader_local_server.cpp +++ b/YACReaderLibrary/yacreader_local_server.cpp @@ -1,16 +1,14 @@ #include "yacreader_local_server.h" +#include "QsLog.h" +#include "comic_db.h" +#include "db_helper.h" +#include "yacreader_global.h" + #include #include #include -#include "yacreader_global.h" -#include "db_helper.h" - -#include "comic_db.h" - -#include "QsLog.h" - using namespace YACReader; QMutex YACReaderClientConnectionWorker::dbMutex; diff --git a/YACReaderLibrary/yacreader_local_server.h b/YACReaderLibrary/yacreader_local_server.h index bb935c59c..8a0432e40 100644 --- a/YACReaderLibrary/yacreader_local_server.h +++ b/YACReaderLibrary/yacreader_local_server.h @@ -1,9 +1,9 @@ #ifndef YACREADER_LOCAL_SERVER_H #define YACREADER_LOCAL_SERVER_H +#include #include #include -#include class QLocalServer; class QLocalSocket; diff --git a/YACReaderLibrary/yacreader_main_toolbar.cpp b/YACReaderLibrary/yacreader_main_toolbar.cpp index 93a76a10b..c074d41fc 100644 --- a/YACReaderLibrary/yacreader_main_toolbar.cpp +++ b/YACReaderLibrary/yacreader_main_toolbar.cpp @@ -1,12 +1,12 @@ #include "yacreader_main_toolbar.h" -#include +#include #include -#include #include -#include #include -#include +#include +#include +#include YACReaderMainToolBar::YACReaderMainToolBar(QWidget *parent) : QWidget(parent) diff --git a/YACReaderLibrary/yacreader_main_toolbar.h b/YACReaderLibrary/yacreader_main_toolbar.h index 06d490431..9526f2ec1 100644 --- a/YACReaderLibrary/yacreader_main_toolbar.h +++ b/YACReaderLibrary/yacreader_main_toolbar.h @@ -1,10 +1,10 @@ #ifndef YACREADER_MAIN_TOOLBAR_H #define YACREADER_MAIN_TOOLBAR_H -#include - #include "themable.h" +#include + class QToolButton; class QLabel; class QResizeEvent; diff --git a/YACReaderLibrary/yacreader_navigation_controller.cpp b/YACReaderLibrary/yacreader_navigation_controller.cpp index 0fb74f3cd..56b7623af 100644 --- a/YACReaderLibrary/yacreader_navigation_controller.cpp +++ b/YACReaderLibrary/yacreader_navigation_controller.cpp @@ -1,23 +1,22 @@ #include "yacreader_navigation_controller.h" -#include - -#include "library_window.h" -#include "folder_item.h" -#include "yacreader_history_controller.h" +#include "QsLog.h" #include "comic_model.h" -#include "folder_model.h" -#include "reading_list_model.h" #include "comics_view.h" -#include "folder_content_view.h" -#include "yacreader_global.h" #include "empty_label_widget.h" #include "empty_special_list.h" +#include "folder_content_view.h" +#include "folder_item.h" +#include "folder_model.h" +#include "library_window.h" +#include "reading_list_model.h" #include "yacreader_content_views_manager.h" #include "yacreader_folders_view.h" +#include "yacreader_global.h" +#include "yacreader_history_controller.h" #include "yacreader_reading_lists_view.h" -#include "QsLog.h" +#include YACReaderNavigationController::YACReaderNavigationController(LibraryWindow *parent, YACReaderContentViewsManager *contentViewsManager) : QObject(parent), libraryWindow(parent), contentViewsManager(contentViewsManager) diff --git a/YACReaderLibrary/yacreader_reading_lists_view.h b/YACReaderLibrary/yacreader_reading_lists_view.h index 566ab45e7..9ad883450 100644 --- a/YACReaderLibrary/yacreader_reading_lists_view.h +++ b/YACReaderLibrary/yacreader_reading_lists_view.h @@ -1,11 +1,11 @@ #ifndef YACREADER_READING_LISTS_VIEW_H #define YACREADER_READING_LISTS_VIEW_H +#include "yacreader_treeview.h" + #include -#include #include - -#include "yacreader_treeview.h" +#include class YACReaderReadingListsView : public YACReaderTreeView { diff --git a/YACReaderLibraryServer/console_ui_library_creator.cpp b/YACReaderLibraryServer/console_ui_library_creator.cpp index 9fa3d33ff..e4f6a2517 100644 --- a/YACReaderLibraryServer/console_ui_library_creator.cpp +++ b/YACReaderLibraryServer/console_ui_library_creator.cpp @@ -1,10 +1,10 @@ #include "console_ui_library_creator.h" -#include - #include "library_creator.h" -#include "yacreader_libraries.h" #include "xml_info_library_scanner.h" +#include "yacreader_libraries.h" + +#include using namespace YACReader; diff --git a/YACReaderLibraryServer/libraries_updater.cpp b/YACReaderLibraryServer/libraries_updater.cpp index e39ef326f..a2c1d625c 100644 --- a/YACReaderLibraryServer/libraries_updater.cpp +++ b/YACReaderLibraryServer/libraries_updater.cpp @@ -1,8 +1,8 @@ #include "libraries_updater.h" +#include "data_base_management.h" #include "yacreader_global.h" #include "yacreader_libraries.h" -#include "data_base_management.h" LibrariesUpdater::LibrariesUpdater() { diff --git a/YACReaderLibraryServer/main.cpp b/YACReaderLibraryServer/main.cpp index acd064e44..a774e4268 100644 --- a/YACReaderLibraryServer/main.cpp +++ b/YACReaderLibraryServer/main.cpp @@ -1,28 +1,24 @@ -#include -#include -#include -#include -#include - +#include "QsLog.h" +#include "QsLogDest.h" #include "comic_db.h" +#include "console_ui_library_creator.h" #include "data_base_management.h" #include "db_helper.h" -#include "yacreader_http_server.h" -#include "yacreader_global.h" -#include "yacreader_libraries.h" -#include "yacreader_local_server.h" #include "global_info_provider.h" - +#include "ip_config_helper.h" #include "libraries_update_coordinator.h" - #include "libraries_updater.h" - -#include "console_ui_library_creator.h" - -#include "QsLog.h" -#include "QsLogDest.h" #include "qrcodegen.hpp" -#include "ip_config_helper.h" +#include "yacreader_global.h" +#include "yacreader_http_server.h" +#include "yacreader_libraries.h" +#include "yacreader_local_server.h" + +#include +#include +#include +#include +#include using namespace QsLogging; diff --git a/common/app_language_utils.h b/common/app_language_utils.h index d76c63b9e..e74968263 100644 --- a/common/app_language_utils.h +++ b/common/app_language_utils.h @@ -9,6 +9,7 @@ #include #include #include + #include namespace YACReader::UiLanguage { diff --git a/common/bookmarks.cpp b/common/bookmarks.cpp index 872c4cc28..83bad65e1 100644 --- a/common/bookmarks.cpp +++ b/common/bookmarks.cpp @@ -1,13 +1,13 @@ #include "bookmarks.h" -#include -#include + +#include "yacreader_global.h" + #include +#include +#include #include - #include -#include "yacreader_global.h" - Bookmarks::Bookmarks() : lastPageIndex(0) { diff --git a/common/bookmarks.h b/common/bookmarks.h index 6c4226596..3f36e40d3 100644 --- a/common/bookmarks.h +++ b/common/bookmarks.h @@ -1,12 +1,11 @@ #ifndef BOOKMARKS_H #define BOOKMARKS_H -#include -#include +#include #include -#include #include -#include +#include +#include class BookmarksList { public: diff --git a/common/check_new_version.cpp b/common/check_new_version.cpp index bb7738636..18646a5cc 100644 --- a/common/check_new_version.cpp +++ b/common/check_new_version.cpp @@ -2,16 +2,15 @@ #include "yacreader_global.h" -#include -#include -#include - -#include #include -#include -#include +#include #include +#include #include +#include +#include +#include +#include #define PREVIOUS_VERSION_TESTING "6.0.0" diff --git a/common/comic.cpp b/common/comic.cpp index 0be6a3a00..7351bd14b 100644 --- a/common/comic.cpp +++ b/common/comic.cpp @@ -1,20 +1,20 @@ #include "comic.h" +#include "QsLog.h" +#include "bookmarks.h" //TODO desacoplar la dependencia con bookmarks +#include "comic_db.h" +#include "compressed_archive.h" +#include "qnaturalsorting.h" + +#include +#include +#include #include #include #include #include -#include -#include -#include -#include - -#include "bookmarks.h" //TODO desacoplar la dependencia con bookmarks -#include "qnaturalsorting.h" -#include "compressed_archive.h" -#include "comic_db.h" -#include "QsLog.h" +#include enum YACReaderPageSortingMode { YACReaderNumericalSorting, diff --git a/common/comic.h b/common/comic.h index 91952e6f3..6543ee11a 100644 --- a/common/comic.h +++ b/common/comic.h @@ -1,12 +1,12 @@ #ifndef __COMIC_H #define __COMIC_H -#include -#include +#include "bookmarks.h" +#include "extract_delegate.h" + #include +#include #include - -#include "extract_delegate.h" -#include "bookmarks.h" +#include #ifndef NO_PDF #include "pdf_comic.h" #endif // NO_PDF diff --git a/common/comic_db.cpp b/common/comic_db.cpp index 9fa6edb3b..04a494712 100644 --- a/common/comic_db.cpp +++ b/common/comic_db.cpp @@ -2,8 +2,8 @@ #include "yacreader_global.h" -#include #include +#include //----------------------------------------------------------------------------- // COMIC------------------------------------------------------------------------ diff --git a/common/comic_db.h b/common/comic_db.h index 9f3b70d6d..c72a01ce3 100644 --- a/common/comic_db.h +++ b/common/comic_db.h @@ -2,11 +2,12 @@ #define __COMICDB_H #include "library_item.h" -#include -#include -#include + #include +#include #include +#include +#include class ComicInfo : public QObject { diff --git a/common/concurrent_queue.h b/common/concurrent_queue.h index 380f6d5d5..9d0d9f651 100644 --- a/common/concurrent_queue.h +++ b/common/concurrent_queue.h @@ -1,11 +1,12 @@ #ifndef CONCURRENT_QUEUE_H #define CONCURRENT_QUEUE_H -#include -#include -#include -#include #include + +#include +#include +#include +#include #include namespace YACReader { diff --git a/common/global_info_provider.cpp b/common/global_info_provider.cpp index 8ef36cc53..22828992c 100644 --- a/common/global_info_provider.cpp +++ b/common/global_info_provider.cpp @@ -1,8 +1,8 @@ #include "global_info_provider.h" -#include #include #include +#include #ifdef YACREADER_LIBRARY #include diff --git a/common/http_worker.cpp b/common/http_worker.cpp index 3ab184bec..a0737be80 100644 --- a/common/http_worker.cpp +++ b/common/http_worker.cpp @@ -1,14 +1,13 @@ #include "http_worker.h" -#include -#include -#include - -#include #include -#include -#include +#include #include +#include +#include +#include +#include +#include #define PREVIOUS_VERSION "6.0.0" diff --git a/common/pdf_comic.cpp b/common/pdf_comic.cpp index 9cdcd41c9..6c309b1c3 100644 --- a/common/pdf_comic.cpp +++ b/common/pdf_comic.cpp @@ -1,6 +1,7 @@ -#include "comic.h" #include "pdf_comic.h" +#include "comic.h" + #if defined USE_PDFIUM && !defined NO_PDF int pdfRead(void *param, diff --git a/common/pdf_comic.h b/common/pdf_comic.h index cc47d0cde..950602701 100644 --- a/common/pdf_comic.h +++ b/common/pdf_comic.h @@ -1,10 +1,10 @@ #if !defined PDF_COMIC_H && !defined NO_PDF #define PDF_COMIC_H -#include -#include #include +#include #include +#include #include #if defined Q_OS_MACOS && defined USE_PDFKIT diff --git a/common/pdf_comic.mm b/common/pdf_comic.mm index c242169ad..b878707e2 100644 --- a/common/pdf_comic.mm +++ b/common/pdf_comic.mm @@ -2,13 +2,13 @@ #undef __OBJC_BOOL_IS_BOOL -#import -#import -#import - #include "QsLog.h" #include "QsLogDest.h" +#import +#import +#import + MacOSXPDFComic::MacOSXPDFComic() { } diff --git a/common/qnaturalsorting.h b/common/qnaturalsorting.h index 3dfc393bb..ac3f217c7 100644 --- a/common/qnaturalsorting.h +++ b/common/qnaturalsorting.h @@ -3,10 +3,11 @@ #ifndef __QNATURALSORTING_H #define __QNATURALSORTING_H -#include -#include #include "library_item.h" +#include +#include + int naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity caseSensitivity); bool naturalSortLessThanCS(const QString &left, const QString &right); bool naturalSortLessThanCI(const QString &left, const QString &right); diff --git a/common/rhi/yacreader_comic_flow_rhi.cpp b/common/rhi/yacreader_comic_flow_rhi.cpp index c57d38e99..abf3ab587 100644 --- a/common/rhi/yacreader_comic_flow_rhi.cpp +++ b/common/rhi/yacreader_comic_flow_rhi.cpp @@ -1,4 +1,5 @@ #include "yacreader_comic_flow_rhi.h" + #include // YACReaderComicFlow3D implementation diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index 3cf29c0da..5d1a74052 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -1,4 +1,5 @@ #include "yacreader_flow_rhi.h" + #include #include #if defined(YACREADER_RHI_PERF) diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index 89a479c75..ca7184dd0 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -7,12 +7,13 @@ #if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) -#include -#include - #include "flow_types.h" -#include "yacreader_global.h" #include "scroll_management.h" +#include "yacreader_global.h" + +#include + +#include // the image/texture info struct struct YACReader3DImageRHI { diff --git a/common/rhi/yacreader_page_flow_rhi.cpp b/common/rhi/yacreader_page_flow_rhi.cpp index d32200716..f4af58d91 100644 --- a/common/rhi/yacreader_page_flow_rhi.cpp +++ b/common/rhi/yacreader_page_flow_rhi.cpp @@ -1,4 +1,5 @@ #include "yacreader_page_flow_rhi.h" + #include // YACReaderPageFlow3D implementation diff --git a/common/scroll_management.cpp b/common/scroll_management.cpp index ddef42dc9..f8e2683ef 100644 --- a/common/scroll_management.cpp +++ b/common/scroll_management.cpp @@ -1,4 +1,5 @@ #include "scroll_management.h" + #include ScrollManagement::ScrollManagement() diff --git a/common/themes/appearance_tab_widget.h b/common/themes/appearance_tab_widget.h index 981950581..720827ce2 100644 --- a/common/themes/appearance_tab_widget.h +++ b/common/themes/appearance_tab_widget.h @@ -6,6 +6,7 @@ #include #include #include + #include #include diff --git a/common/themes/icon_utils.cpp b/common/themes/icon_utils.cpp index 9430dae9b..a0f01c103 100644 --- a/common/themes/icon_utils.cpp +++ b/common/themes/icon_utils.cpp @@ -1,10 +1,10 @@ #include "icon_utils.h" +#include "yacreader_global.h" + #include #include -#include "yacreader_global.h" - QPixmap renderSvgToPixmap(const QString &svgPath, int logicalSize, qreal devicePixelRatio) { return renderSvgToPixmap(svgPath, logicalSize, logicalSize, devicePixelRatio); diff --git a/common/themes/theme_editor_dialog.cpp b/common/themes/theme_editor_dialog.cpp index 459f9b5bd..c969aa29b 100644 --- a/common/themes/theme_editor_dialog.cpp +++ b/common/themes/theme_editor_dialog.cpp @@ -1,27 +1,28 @@ #include "theme_editor_dialog.h" -#include +#include +#include #include +#include +#include #include #include -#include -#include -#include -#include -#include #include -#include #include -#include +#include #include #include -#include -#include -#include -#include +#include #include #include +#include +#include +#include +#include #include +#include + +#include // Role used to store the JSON path (QStringList) on each leaf item. static const int PathRole = Qt::UserRole; diff --git a/common/worker_thread.h b/common/worker_thread.h index dc1db19af..8b846d973 100644 --- a/common/worker_thread.h +++ b/common/worker_thread.h @@ -4,11 +4,11 @@ #include "release_acquire_atomic.h" #include -#include +#include #include #include -#include #include +#include //! Usage: //! 1. call performTask(); diff --git a/common/yacreader_global.cpp b/common/yacreader_global.cpp index f4da42d98..1054070f1 100644 --- a/common/yacreader_global.cpp +++ b/common/yacreader_global.cpp @@ -1,9 +1,9 @@ #include "yacreader_global.h" -#include -#include -#include #include +#include +#include +#include using namespace YACReader; diff --git a/common/yacreader_global.h b/common/yacreader_global.h index c4718d77b..b2a44e91d 100644 --- a/common/yacreader_global.h +++ b/common/yacreader_global.h @@ -1,11 +1,11 @@ #ifndef __YACREADER_GLOBAL_H #define __YACREADER_GLOBAL_H -#include -#include -#include #include +#include #include +#include +#include class QLibrary; diff --git a/common/yacreader_global_gui.cpp b/common/yacreader_global_gui.cpp index ccce5861d..f86dc449d 100644 --- a/common/yacreader_global_gui.cpp +++ b/common/yacreader_global_gui.cpp @@ -1,9 +1,9 @@ #include "yacreader_global_gui.h" -#include #include -#include #include +#include +#include using namespace YACReader; diff --git a/common/yacreader_global_gui.h b/common/yacreader_global_gui.h index 88d53a004..e8e1c4199 100644 --- a/common/yacreader_global_gui.h +++ b/common/yacreader_global_gui.h @@ -3,8 +3,8 @@ #include "yacreader_global.h" -#include #include +#include #define PATH "PATH" #define UI_LANGUAGE "UI_LANGUAGE" diff --git a/compressed_archive/7z_includes.h b/compressed_archive/7z_includes.h index 34668e43f..59be0178d 100644 --- a/compressed_archive/7z_includes.h +++ b/compressed_archive/7z_includes.h @@ -1,6 +1,9 @@ #ifndef _7Z_INCLUDES_H #define _7Z_INCLUDES_H +// clang-format off +// Umbrella header for 7zip. Include order is load-bearing: +// MyInitGuid.h must precede all interface headers that use DEFINE_GUID. extern "C" { #include "lib7zip/C/Alloc.h" #include "lib7zip/C/7zTypes.h" @@ -30,4 +33,6 @@ extern "C" { #include "lib7zip/CPP/7zip/Common/StreamObjects.h" #include "lib7zip/CPP/7zip/Common/StreamUtils.h" +// clang-format on + #endif // _7Z_INCLUDES_H diff --git a/compressed_archive/StdAfx.h b/compressed_archive/StdAfx.h index b23436e93..76d067d29 100644 --- a/compressed_archive/StdAfx.h +++ b/compressed_archive/StdAfx.h @@ -3,7 +3,7 @@ #ifndef __STDAFX_H #define __STDAFX_H -#include #include +#include #endif diff --git a/compressed_archive/compressed_archive.cpp b/compressed_archive/compressed_archive.cpp index 0926e14e4..65aff55fa 100644 --- a/compressed_archive/compressed_archive.cpp +++ b/compressed_archive/compressed_archive.cpp @@ -1,18 +1,16 @@ -#include - #include "compressed_archive.h" + +#include "QsLog.h" +#include "extract_callbacks.h" #include "extract_delegate.h" +#include "open_callbacks.h" #include "yacreader_global.h" -#include -#include -#include #include - -#include "open_callbacks.h" -#include "extract_callbacks.h" - -#include "QsLog.h" +#include +#include +#include +#include #define _MY_WINAPI WINAPI diff --git a/compressed_archive/compressed_archive.h b/compressed_archive/compressed_archive.h index b691527e3..90634f813 100644 --- a/compressed_archive/compressed_archive.h +++ b/compressed_archive/compressed_archive.h @@ -6,9 +6,9 @@ class ExtractDelegate; class QLibrary; -#include #include #include +#include struct SevenZipInterface; diff --git a/compressed_archive/extract_callbacks.h b/compressed_archive/extract_callbacks.h index 7acb50c9d..54e251cb9 100644 --- a/compressed_archive/extract_callbacks.h +++ b/compressed_archive/extract_callbacks.h @@ -3,6 +3,7 @@ #include "7z_includes.h" #include "extract_delegate.h" + #include using namespace NWindows; diff --git a/compressed_archive/libarchive/compressed_archive.h b/compressed_archive/libarchive/compressed_archive.h index d7accc4fd..2df1fb9f5 100644 --- a/compressed_archive/libarchive/compressed_archive.h +++ b/compressed_archive/libarchive/compressed_archive.h @@ -3,8 +3,8 @@ #include "extract_delegate.h" -#include #include +#include extern "C" { #include diff --git a/compressed_archive/open_callbacks.h b/compressed_archive/open_callbacks.h index 0e46c1de7..1c607b3a1 100644 --- a/compressed_archive/open_callbacks.h +++ b/compressed_archive/open_callbacks.h @@ -2,6 +2,7 @@ #define OPEN_CALLBACKS_H #include "7z_includes.h" + #include ////////////////////////////////////////////////////////////// // Archive Open callback class diff --git a/compressed_archive/unarr/compressed_archive.cpp b/compressed_archive/unarr/compressed_archive.cpp index 4dfdce909..1e074e6d9 100644 --- a/compressed_archive/unarr/compressed_archive.cpp +++ b/compressed_archive/unarr/compressed_archive.cpp @@ -1,9 +1,10 @@ #include "compressed_archive.h" -#include +#include "extract_delegate.h" + #include +#include -#include "extract_delegate.h" #include CompressedArchive::CompressedArchive(const QString &filePath, QObject *parent) diff --git a/compressed_archive/unarr/compressed_archive.h b/compressed_archive/unarr/compressed_archive.h index a16e07e46..07bd1c40f 100644 --- a/compressed_archive/unarr/compressed_archive.h +++ b/compressed_archive/unarr/compressed_archive.h @@ -1,8 +1,9 @@ #ifndef COMPRESSED_ARCHIVE_H #define COMPRESSED_ARCHIVE_H -#include #include "extract_delegate.h" + +#include extern "C" { #include } diff --git a/custom_widgets/help_about_dialog.cpp b/custom_widgets/help_about_dialog.cpp index 2b8de003f..7c5817356 100644 --- a/custom_widgets/help_about_dialog.cpp +++ b/custom_widgets/help_about_dialog.cpp @@ -1,17 +1,16 @@ #include "help_about_dialog.h" #include "global_info_provider.h" +#include "yacreader_global.h" -#include -#include -#include -#include #include #include -#include #include - -#include "yacreader_global.h" +#include +#include +#include +#include +#include HelpAboutDialog::HelpAboutDialog(QWidget *parent) : QDialog(parent) diff --git a/custom_widgets/help_about_dialog.h b/custom_widgets/help_about_dialog.h index 2bf69160b..c9310108b 100644 --- a/custom_widgets/help_about_dialog.h +++ b/custom_widgets/help_about_dialog.h @@ -1,10 +1,10 @@ #ifndef HELP_ABOUT_DIALOG_H #define HELP_ABOUT_DIALOG_H -#include - #include "themable.h" +#include + class QTabWidget; class QTextBrowser; diff --git a/custom_widgets/whats_new_dialog.cpp b/custom_widgets/whats_new_dialog.cpp index 8f6aa98f4..0378bab58 100644 --- a/custom_widgets/whats_new_dialog.cpp +++ b/custom_widgets/whats_new_dialog.cpp @@ -1,5 +1,7 @@ #include "whats_new_dialog.h" +#include "yacreader_global.h" + #include #include #include @@ -8,8 +10,6 @@ #include #include -#include "yacreader_global.h" - YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent) : RoundedCornersDialog(parent) { diff --git a/custom_widgets/yacreader_3d_flow_config_widget.cpp b/custom_widgets/yacreader_3d_flow_config_widget.cpp index a3db5fefc..a1bb4fe1a 100644 --- a/custom_widgets/yacreader_3d_flow_config_widget.cpp +++ b/custom_widgets/yacreader_3d_flow_config_widget.cpp @@ -2,13 +2,13 @@ #include "yacreader_spin_slider_widget.h" -#include -#include +#include #include -#include #include #include -#include +#include +#include +#include YACReader3DFlowConfigWidget::YACReader3DFlowConfigWidget(QWidget *parent /* = 0 */) : QWidget(parent) diff --git a/custom_widgets/yacreader_3d_flow_config_widget.h b/custom_widgets/yacreader_3d_flow_config_widget.h index cdf855f95..692913f0a 100644 --- a/custom_widgets/yacreader_3d_flow_config_widget.h +++ b/custom_widgets/yacreader_3d_flow_config_widget.h @@ -2,6 +2,7 @@ #define YACREADER_3D_FLOW_CONFIG_WIDGET_H #include "flow_types.h" //TODO + #include class QRadioButton; diff --git a/custom_widgets/yacreader_busy_widget.cpp b/custom_widgets/yacreader_busy_widget.cpp index 0ef081b30..67198bf83 100644 --- a/custom_widgets/yacreader_busy_widget.cpp +++ b/custom_widgets/yacreader_busy_widget.cpp @@ -1,9 +1,9 @@ #include "yacreader_busy_widget.h" #include +#include #include #include -#include YACReaderBusyWidget::YACReaderBusyWidget(QWidget *parent) : QWidget(parent) diff --git a/custom_widgets/yacreader_cover_label.cpp b/custom_widgets/yacreader_cover_label.cpp index 63a2db7a7..791b5831e 100644 --- a/custom_widgets/yacreader_cover_label.cpp +++ b/custom_widgets/yacreader_cover_label.cpp @@ -1,4 +1,5 @@ #include "yacreader_cover_label.h" + #include "yacreader_global_gui.h" YACReader::CoverLabel::CoverLabel(QWidget *parent) diff --git a/custom_widgets/yacreader_cover_label.h b/custom_widgets/yacreader_cover_label.h index 8d570c9f4..6328087a2 100644 --- a/custom_widgets/yacreader_cover_label.h +++ b/custom_widgets/yacreader_cover_label.h @@ -1,9 +1,9 @@ #ifndef DROP_LABEL_H #define DROP_LABEL_H -#include #include #include +#include #include namespace YACReader { diff --git a/custom_widgets/yacreader_dark_menu.cpp b/custom_widgets/yacreader_dark_menu.cpp index 15c7f7029..ce7e1fe6f 100644 --- a/custom_widgets/yacreader_dark_menu.cpp +++ b/custom_widgets/yacreader_dark_menu.cpp @@ -1,8 +1,8 @@ #include "yacreader_dark_menu.h" +#include #include #include -#include YACReaderDarkMenu::YACReaderDarkMenu(QWidget *parent) : QMenu(parent) diff --git a/custom_widgets/yacreader_library_item_widget.cpp b/custom_widgets/yacreader_library_item_widget.cpp index 0bd5d2c51..1446a28a8 100644 --- a/custom_widgets/yacreader_library_item_widget.cpp +++ b/custom_widgets/yacreader_library_item_widget.cpp @@ -1,11 +1,11 @@ #include "yacreader_library_item_widget.h" -#include - #include "yacreader_global.h" + +#include #include -#include #include +#include using namespace YACReader; diff --git a/custom_widgets/yacreader_library_item_widget.h b/custom_widgets/yacreader_library_item_widget.h index 33462b566..117f09bc6 100644 --- a/custom_widgets/yacreader_library_item_widget.h +++ b/custom_widgets/yacreader_library_item_widget.h @@ -1,11 +1,11 @@ #ifndef YACREADER_LIBRARY_ITEM_WIDGET_H #define YACREADER_LIBRARY_ITEM_WIDGET_H -#include -#include - #include "themable.h" +#include +#include + class QLabel; class QToolButton; class QMouseEvent; diff --git a/custom_widgets/yacreader_library_list_widget.cpp b/custom_widgets/yacreader_library_list_widget.cpp index 679024bfe..a267a6f53 100644 --- a/custom_widgets/yacreader_library_list_widget.cpp +++ b/custom_widgets/yacreader_library_list_widget.cpp @@ -1,10 +1,11 @@ #include "yacreader_library_list_widget.h" +#include "qnaturalsorting.h" #include "yacreader_library_item_widget.h" -#include -#include + #include -#include "qnaturalsorting.h" +#include +#include YACReaderLibraryListWidget::YACReaderLibraryListWidget(QWidget *parent) : QWidget(parent), currentLibraryIndex(-1) diff --git a/custom_widgets/yacreader_macosx_toolbar.h b/custom_widgets/yacreader_macosx_toolbar.h index f07de90cc..d383865b6 100644 --- a/custom_widgets/yacreader_macosx_toolbar.h +++ b/custom_widgets/yacreader_macosx_toolbar.h @@ -5,6 +5,7 @@ #include "yacreader_main_toolbar.h" #include "yacreader_search_line_edit.h" + #include class YACReaderMacOSXSearchLineEdit : public YACReaderSearchLineEdit diff --git a/custom_widgets/yacreader_macosx_toolbar.mm b/custom_widgets/yacreader_macosx_toolbar.mm index 487bc90ff..2338eb30b 100644 --- a/custom_widgets/yacreader_macosx_toolbar.mm +++ b/custom_widgets/yacreader_macosx_toolbar.mm @@ -1,11 +1,12 @@ #include "yacreader_macosx_toolbar.h" + #include "QtWidgets/qmainwindow.h" #include #import -#import #import +#import NSImage *QIconToNSImage(const QIcon &icon, const QSize &size, const QColor &color = QColor()) { diff --git a/custom_widgets/yacreader_options_dialog.cpp b/custom_widgets/yacreader_options_dialog.cpp index 72f45ce8a..99c214cdd 100644 --- a/custom_widgets/yacreader_options_dialog.cpp +++ b/custom_widgets/yacreader_options_dialog.cpp @@ -4,12 +4,12 @@ #include "yacreader_global_gui.h" #include "yacreader_spin_slider_widget.h" -#include #include +#include +#include #include -#include #include -#include +#include #include YACReaderOptionsDialog::YACReaderOptionsDialog(QWidget *parent) diff --git a/custom_widgets/yacreader_search_line_edit.cpp b/custom_widgets/yacreader_search_line_edit.cpp index 7c2b08f26..8090f2e01 100644 --- a/custom_widgets/yacreader_search_line_edit.cpp +++ b/custom_widgets/yacreader_search_line_edit.cpp @@ -1,8 +1,8 @@ #include "yacreader_search_line_edit.h" -#include -#include #include +#include +#include YACReaderSearchLineEdit::YACReaderSearchLineEdit(QWidget *parent) : QLineEdit(parent), paddingLeft(0), paddingRight(0) diff --git a/custom_widgets/yacreader_search_line_edit.h b/custom_widgets/yacreader_search_line_edit.h index dbaeebd29..bca2b9a42 100644 --- a/custom_widgets/yacreader_search_line_edit.h +++ b/custom_widgets/yacreader_search_line_edit.h @@ -1,11 +1,11 @@ #ifndef YACREADER_SEARCH_LINE_EDIT_H #define YACREADER_SEARCH_LINE_EDIT_H -#include -#include - #include "themable.h" +#include +#include + class QToolButton; class QLabel; diff --git a/custom_widgets/yacreader_sidebar.cpp b/custom_widgets/yacreader_sidebar.cpp index ade0550e7..a4cd113d9 100644 --- a/custom_widgets/yacreader_sidebar.cpp +++ b/custom_widgets/yacreader_sidebar.cpp @@ -1,15 +1,14 @@ #include "yacreader_sidebar.h" -#include -#include - #include "yacreader_folders_view.h" -#include "yacreader_reading_lists_view.h" +#include "yacreader_global.h" +#include "yacreader_global_gui.h" #include "yacreader_library_list_widget.h" +#include "yacreader_reading_lists_view.h" #include "yacreader_titled_toolbar.h" -#include "yacreader_global.h" -#include "yacreader_global_gui.h" +#include +#include YACReaderSideBar::YACReaderSideBar(QWidget *parent) : QWidget(parent) diff --git a/custom_widgets/yacreader_sidebar.h b/custom_widgets/yacreader_sidebar.h index 0d05c5a3b..82e6933e2 100644 --- a/custom_widgets/yacreader_sidebar.h +++ b/custom_widgets/yacreader_sidebar.h @@ -1,6 +1,8 @@ #ifndef YACREADER_SIDEBAR_H #define YACREADER_SIDEBAR_H +#include "themable.h" + #include #include #include @@ -9,8 +11,6 @@ #include #include -#include "themable.h" - class YACReaderFoldersView; class YACReaderLibraryListWidget; class YACReaderSearchLineEdit; diff --git a/custom_widgets/yacreader_social_dialog.cpp b/custom_widgets/yacreader_social_dialog.cpp index a42abaa7d..8c0edf054 100644 --- a/custom_widgets/yacreader_social_dialog.cpp +++ b/custom_widgets/yacreader_social_dialog.cpp @@ -1,16 +1,16 @@ #include "yacreader_social_dialog.h" -#include +#include "comic_db.h" + +#include #include -#include -#include #include #include -#include #include -#include - -#include "comic_db.h" +#include +#include +#include +#include YACReaderSocialDialog::YACReaderSocialDialog(QWidget *parent) : QWidget(parent) diff --git a/custom_widgets/yacreader_spin_slider_widget.cpp b/custom_widgets/yacreader_spin_slider_widget.cpp index 708dfd01f..092fc0e59 100644 --- a/custom_widgets/yacreader_spin_slider_widget.cpp +++ b/custom_widgets/yacreader_spin_slider_widget.cpp @@ -2,8 +2,8 @@ #include #include -#include #include +#include YACReaderSpinSliderWidget::YACReaderSpinSliderWidget(QWidget *parent, bool strechableSlider) : QWidget(parent), tracking(true) diff --git a/custom_widgets/yacreader_table_view.cpp b/custom_widgets/yacreader_table_view.cpp index 08b671560..d434fb47d 100644 --- a/custom_widgets/yacreader_table_view.cpp +++ b/custom_widgets/yacreader_table_view.cpp @@ -1,19 +1,17 @@ #include "yacreader_table_view.h" +#include "QsLog.h" +#include "comic_item.h" +#include "comic_model.h" #include "yacreader_global_gui.h" -#include -#include -#include -#include -#include #include #include - -#include "QsLog.h" - -#include "comic_item.h" -#include "comic_model.h" +#include +#include +#include +#include +#include YACReaderTableView::YACReaderTableView(QWidget *parent) : QTableView(parent), editing(false), myeditor(0) diff --git a/custom_widgets/yacreader_table_view.h b/custom_widgets/yacreader_table_view.h index f455854a4..88d20b313 100644 --- a/custom_widgets/yacreader_table_view.h +++ b/custom_widgets/yacreader_table_view.h @@ -1,11 +1,11 @@ #ifndef YACREADER_TABLE_VIEW_H #define YACREADER_TABLE_VIEW_H -#include -#include - #include "themable.h" +#include +#include + class QResizeEvent; class YACReaderTableView : public QTableView, protected Themable diff --git a/custom_widgets/yacreader_titled_toolbar.h b/custom_widgets/yacreader_titled_toolbar.h index 6856394a0..2ab45f5fe 100644 --- a/custom_widgets/yacreader_titled_toolbar.h +++ b/custom_widgets/yacreader_titled_toolbar.h @@ -1,13 +1,13 @@ #ifndef YACREADER_TITLED_TOOLBAR_H #define YACREADER_TITLED_TOOLBAR_H -#include +#include "themable.h" + #include #include #include #include - -#include "themable.h" +#include class QIcon; class BusyIndicator; diff --git a/custom_widgets/yacreader_tool_bar_stretch.h b/custom_widgets/yacreader_tool_bar_stretch.h index a200575a8..8ddd47723 100644 --- a/custom_widgets/yacreader_tool_bar_stretch.h +++ b/custom_widgets/yacreader_tool_bar_stretch.h @@ -1,8 +1,8 @@ #ifndef YACREADER_TOOL_BAR_STRETCH_H #define YACREADER_TOOL_BAR_STRETCH_H -#include #include +#include class YACReaderToolBarStretch : public QWidget { diff --git a/custom_widgets/yacreader_treeview.h b/custom_widgets/yacreader_treeview.h index a2d76daae..eb869cbd9 100644 --- a/custom_widgets/yacreader_treeview.h +++ b/custom_widgets/yacreader_treeview.h @@ -1,6 +1,8 @@ #ifndef YACREADER_TREEVIEW_H #define YACREADER_TREEVIEW_H +#include "themable.h" + #include #include #include @@ -10,8 +12,6 @@ #include #include -#include "themable.h" - class YACReaderTreeView : public QTreeView, protected Themable { Q_OBJECT diff --git a/image_processing/lancir.h b/image_processing/lancir.h index eb3019942..be2d8314b 100644 --- a/image_processing/lancir.h +++ b/image_processing/lancir.h @@ -46,8 +46,8 @@ #ifndef AVIR_CLANCIR_INCLUDED #define AVIR_CLANCIR_INCLUDED -#include #include +#include #if __cplusplus >= 201103L diff --git a/shortcuts_management/actions_shortcuts_model.cpp b/shortcuts_management/actions_shortcuts_model.cpp index baf50c16c..71528288f 100644 --- a/shortcuts_management/actions_shortcuts_model.cpp +++ b/shortcuts_management/actions_shortcuts_model.cpp @@ -1,4 +1,5 @@ #include "actions_shortcuts_model.h" + #include "shortcuts_manager.h" #include diff --git a/shortcuts_management/edit_shortcut_item_delegate.h b/shortcuts_management/edit_shortcut_item_delegate.h index cc6f0500d..7293514ab 100644 --- a/shortcuts_management/edit_shortcut_item_delegate.h +++ b/shortcuts_management/edit_shortcut_item_delegate.h @@ -2,9 +2,9 @@ #define EDIT_SHORTCUT_ITEM_DELEGATE_H #include -#include #include #include +#include #include class KeySequenceLineEdit : public QLineEdit diff --git a/shortcuts_management/edit_shortcuts_dialog.cpp b/shortcuts_management/edit_shortcuts_dialog.cpp index 50d7f5efb..149c940bb 100644 --- a/shortcuts_management/edit_shortcuts_dialog.cpp +++ b/shortcuts_management/edit_shortcuts_dialog.cpp @@ -4,14 +4,14 @@ #include "actions_shortcuts_model.h" #include "edit_shortcut_item_delegate.h" -#include -#include -#include -#include -#include #include #include +#include #include +#include +#include +#include +#include EditShortcutsDialog::EditShortcutsDialog(QWidget *parent) : QDialog(parent) diff --git a/shortcuts_management/edit_shortcuts_dialog.h b/shortcuts_management/edit_shortcuts_dialog.h index 08f26ee9e..39c0b7326 100644 --- a/shortcuts_management/edit_shortcuts_dialog.h +++ b/shortcuts_management/edit_shortcuts_dialog.h @@ -1,11 +1,11 @@ #ifndef EDIT_SHORTCUTS_DIALOG_H #define EDIT_SHORTCUTS_DIALOG_H +#include "themable.h" + #include #include -#include "themable.h" - class QListView; class QTableView; diff --git a/shortcuts_management/shortcuts_manager.cpp b/shortcuts_management/shortcuts_manager.cpp index 8dc5c7b20..6ca75c216 100644 --- a/shortcuts_management/shortcuts_manager.cpp +++ b/shortcuts_management/shortcuts_manager.cpp @@ -1,9 +1,10 @@ #include "shortcuts_manager.h" -#include -#include #include "yacreader_global.h" +#include +#include + ShortcutsManager::ShortcutsManager() { initDefaultShorcuts(); diff --git a/shortcuts_management/shortcuts_manager.h b/shortcuts_management/shortcuts_manager.h index 5cf01bdf8..b8c6b90af 100644 --- a/shortcuts_management/shortcuts_manager.h +++ b/shortcuts_management/shortcuts_manager.h @@ -1,10 +1,10 @@ #ifndef SHORTCUTS_MANAGER_H #define SHORTCUTS_MANAGER_H -#include #include -#include #include +#include +#include class QAction; diff --git a/tests/compressed_archive_test/main.cpp b/tests/compressed_archive_test/main.cpp index f5b1e7ebe..4f681c9fa 100644 --- a/tests/compressed_archive_test/main.cpp +++ b/tests/compressed_archive_test/main.cpp @@ -1,9 +1,9 @@ -#include +#include "compressed_archive.h" + #include #include - -#include "compressed_archive.h" +#include #include From 754ea0c2f680ee8de126307055162b1ea49e87f5 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 14 Mar 2026 09:23:20 +0100 Subject: [PATCH 152/187] Add support for loading image plugins through the settings folder of the apps. --- CHANGELOG.md | 3 +++ YACReader/main.cpp | 1 + YACReaderLibrary/main.cpp | 1 + YACReaderLibraryServer/main.cpp | 1 + common/global_info_provider.cpp | 3 +++ common/yacreader_global.cpp | 34 +++++++++++++++++++++++++ common/yacreader_global.h | 5 ++++ custom_widgets/whats_new_controller.cpp | 4 +-- custom_widgets/whats_new_dialog.cpp | 3 +++ 9 files changed, 52 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 968ce1bec..d1cb487f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ Version counting is based on semantic versioning (Major.Feature.Patch) * Add a theme editor and support for custom themes. * Add an application language setting with a system default option in YACReader and YACReaderLibrary. +### All apps +* Add support for user-installed Qt image format plugins via the shared `plugins/imageformats` folder in the YACReader settings directory. + ## 9.16.4 ### YACReaderLibrary diff --git a/YACReader/main.cpp b/YACReader/main.cpp index 4a554d85a..c4485b6c6 100644 --- a/YACReader/main.cpp +++ b/YACReader/main.cpp @@ -114,6 +114,7 @@ int main(int argc, char *argv[]) app.setApplicationName("YACReader"); app.setOrganizationName("YACReader"); + YACReader::initializeSharedPluginPaths(); auto *appearanceConfig = new AppearanceConfiguration( YACReader::getSettingsPath() + "/YACReader.ini", qApp); diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index b14bd4636..2494fc6d9 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -140,6 +140,7 @@ int main(int argc, char **argv) app.setApplicationName("YACReaderLibrary"); app.setOrganizationName("YACReader"); app.setApplicationVersion(VERSION); + YACReader::initializeSharedPluginPaths(); // Theme initialization auto *appearanceConfig = new AppearanceConfiguration( diff --git a/YACReaderLibraryServer/main.cpp b/YACReaderLibraryServer/main.cpp index a774e4268..fc988ec7e 100644 --- a/YACReaderLibraryServer/main.cpp +++ b/YACReaderLibraryServer/main.cpp @@ -48,6 +48,7 @@ int main(int argc, char **argv) app.setApplicationName("YACReaderLibrary"); app.setOrganizationName("YACReader"); + YACReader::initializeSharedPluginPaths(); QString buildNumber = ".0"; diff --git a/common/global_info_provider.cpp b/common/global_info_provider.cpp index 22828992c..b3ca5a93d 100644 --- a/common/global_info_provider.cpp +++ b/common/global_info_provider.cpp @@ -1,5 +1,7 @@ #include "global_info_provider.h" +#include "yacreader_global.h" + #include #include #include @@ -24,6 +26,7 @@ QString YACReader::getGlobalInfo() text.append("\nAPP INFORMATION\n"); QString supportedImageFormats = QImageReader::supportedImageFormats().join(", "); text.append(QString("Image formats supported: %1\n").arg(supportedImageFormats)); + text.append(QString("User image plugin folder: %1\n").arg(YACReader::getImageFormatsPluginsPath())); // append if sqlite driver is available #ifdef YACREADER_LIBRARY text.append(QString("SQLite driver available: %1\n").arg(QSqlDatabase::isDriverAvailable("QSQLITE") ? "yes" : "no")); diff --git a/common/yacreader_global.cpp b/common/yacreader_global.cpp index 1054070f1..5d89304ba 100644 --- a/common/yacreader_global.cpp +++ b/common/yacreader_global.cpp @@ -12,6 +12,40 @@ QString YACReader::getSettingsPath() return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); } +QString YACReader::getCommonSettingsPath() +{ + const auto organizationName = QCoreApplication::organizationName().trimmed(); + const auto basePath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); + + if (organizationName.isEmpty()) + return basePath; + + return QDir(basePath).filePath(organizationName); +} + +QString YACReader::getCommonSettingsFilePath() +{ + return QDir(getCommonSettingsPath()).filePath("YACReaderCommon.ini"); +} + +QString YACReader::getPluginsPath() +{ + return QDir(getCommonSettingsPath()).filePath("plugins"); +} + +QString YACReader::getImageFormatsPluginsPath() +{ + return QDir(getPluginsPath()).filePath("imageformats"); +} + +void YACReader::initializeSharedPluginPaths() +{ + QDir().mkpath(getImageFormatsPluginsPath()); + + const QString pluginsPath = QDir(getPluginsPath()).absolutePath(); + QCoreApplication::addLibraryPath(pluginsPath); +} + QString YACReader::colorToName(LabelColors colors) { switch (colors) { diff --git a/common/yacreader_global.h b/common/yacreader_global.h index b2a44e91d..750e6c9a2 100644 --- a/common/yacreader_global.h +++ b/common/yacreader_global.h @@ -103,6 +103,11 @@ QDataStream &operator<<(QDataStream &stream, const OpenComicSource &source); QDataStream &operator>>(QDataStream &stream, OpenComicSource &source); QString getSettingsPath(); +QString getCommonSettingsPath(); +QString getCommonSettingsFilePath(); +QString getPluginsPath(); +QString getImageFormatsPluginsPath(); +void initializeSharedPluginPaths(); QString colorToName(LabelColors colors); QString labelColorToRGBString(LabelColors color); QLibrary *load7zLibrary(); diff --git a/custom_widgets/whats_new_controller.cpp b/custom_widgets/whats_new_controller.cpp index 8e4b38048..c5c696a05 100644 --- a/custom_widgets/whats_new_controller.cpp +++ b/custom_widgets/whats_new_controller.cpp @@ -7,9 +7,7 @@ YACReader::WhatsNewController::WhatsNewController() { } void YACReader::WhatsNewController::showWhatsNewIfNeeded(QWidget *fromParent) { - QSettings commonSettings(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + - "/YACReader/YACReaderCommon.ini", - QSettings::IniFormat); + QSettings commonSettings(YACReader::getCommonSettingsFilePath(), QSettings::IniFormat); if (commonSettings.value("LAST_VERSION_INSTALLED").toString() != VERSION) { showWhatsNew(fromParent); diff --git a/custom_widgets/whats_new_dialog.cpp b/custom_widgets/whats_new_dialog.cpp index 0378bab58..7fd3be6b1 100644 --- a/custom_widgets/whats_new_dialog.cpp +++ b/custom_widgets/whats_new_dialog.cpp @@ -57,6 +57,9 @@ YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent) " • Add a theme editor and support for custom themes
" " • Add an application language setting with a system default option in YACReader and YACReaderLibrary
" "
" + "All apps
" + " • Add support for user-installed Qt image format plugins via the shared plugins/imageformats folder in the YACReader settings directory
" + "
" "I hope you enjoy the new update. Please, if you like YACReader consider to become a patron in Patreon " "or donate some money using Pay-Pal and help keeping the project alive. " "Remember that there is an iOS version available in the Apple App Store, " From b49446c2468663f6f203955bba48abf32a8eb922 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 15 Mar 2026 11:03:12 +0100 Subject: [PATCH 153/187] Replace old apps icons with new ones TODO: replace them with svg versions, I am not sure if all the places these icons are used support svg. --- images/YACReader.png | Bin 4957 -> 1483 bytes images/YACReaderLibrary.png | Bin 5324 -> 1868 bytes images/icon.png | Bin 20829 -> 4298 bytes images/iconLibrary.png | Bin 26640 -> 5894 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/images/YACReader.png b/images/YACReader.png index 32e007a355fc6c160f375b85f9e9e8fbf20cde2c..ddb21839accf3b1f7621d6ba681024ec26a4933d 100644 GIT binary patch delta 1465 zcmV;q1xEVaCd&(uB!3BTNLh0L01FZT01FZU(%pXi000GjNkl^Z;xxqS1TGowU= z>d|`(z$V}^=7zQa&w00gF{~;--ctY$1B+V>HBXXX84mp%GD)19#5IfCvPkP^lW6 zg-?@PxE{yrnjvs~RY!m4bnjENyMtuX7S=Q-ROP_(hJOu2MkrSebUsYSl4r5()aCNl zkucEv66xw*avA%QCRF*m+ov_~U#~~qv@hL6dfv^=q^;K~zwLjKjK7!cB}T#;j~jK1 zh~NhimGnA_t9D)`cmTzsyWU{L@1hn&b@{9~_9YiFLe-C`c=yqB`YgM8>)!5JiU4Sj6>fwzmvE zmZD?H^Z33&OyUS68>rO`s^<}Gx2=WnvGUigpNSt{6IRda~8*0C;T+ zsrrT}Y;Xj^z)&hjxS3+B*#Xc_7QbeQqN%Kj$$wlJ8nTNYZ2@Yslw~8vASMEtoG496 z=7c!MNf%dKMZ^YlA=RC9J24wIk&troSBb0<#qetUccP{mka!AROZ%L_AH`DAxPfbm z9w?6tkaECMi3X-FVr>aZT{|X*e%nXJ1zX9K&P@!XmJ)_ee9|J^izS>n_&RA9EE2=$ zWPeABc)#io^|yxiBAp%hmiDY7iS#1U|8Avk*=j=L?DaD4Bx7 z*Bt%eZWa|S3R#7=>cb;~D({(p$?gq8C{+x9jTnk6-=^o52eGx+bnu`$!tuQ?Ab;+n zD{qnY6m|m#T&nzW_q6jPGEl7vrHXLAEL41& zQ>zeE&oeae6@UJ)8Af{PXjA0U3fEE7o(Ekpu)EmM1Q)=V_;@8W5Qg!YXJjCZAQ-<6 zLa6w{9Zwu3mFr2a%Y+=8KF? zJ^TWH_;?)y!cTiPk`H?6>{hrsK7R|1dwk}>LW`OG>9iUz7cM|62(^%&cVogogd;nj z!1;RzodtzA;psZt{ITH?XjB4FxEm*XaqkQLJ2s#PcTk)+0sb=8^cNhpn$U6o){E{6 zM|NyL4{oPBuSnO)Yi6US8VDoEtl5q2Uf9i5N6&ER{dIKclN9rcwA(y*Xn&#sBcN}4 zmsHPcAdWP@eDe;22VP-8!J?2;q;zxPp^2}UY5_R9gTZ6FIs5CE{N1;ijyAZVsK|JN zwuM;+noCNJeUxoVmDK=-OG2qCIJTla1DTY<(KP%}nvI$^g}@`wKcI<#GU Tj5AW}00000NkvXXu0mjf(6hq- literal 4957 zcmV-j6Qb;iP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x00(qQO+^Ra3>6L+8Rq>@ssI2IVM#XR$AV@wY2#^@a2g3#u zBZi$e})xX!-3dCR<|-|OzX)N=Bn`wicWITU53fWp1E zZ`G;)|D1oFs(bqiKW5ptdlxqrm-zU@578TxOpJ995k!RJM-K7aUw+RXI8WOAy$h-gs)|8bQsg<#dCp(C`jN($kJRb|%Hae1sp^{DJ9m&K2}Pc>yt-Pn zi((IO$Xa_igm_4m-Nu+{U{XXAMHI9~Syk2ZQF%)>z8iwSeC5Xc>cbBl)4FMR_3WEG zc;paoU%2%DkHC1R!y^wIWuxDxmFLV%O|rDII-MrTV+x-Ep4P~5&^aSo6uFvKA+!o` zA)%@>vQ$wuC>B&v4Zf_y#-MZ;Mf6n>`EHEyyLp-}u5WCD!1bGpZ1($qcLMu%?_zp# z0v`fnoepQ;c~?#xJ$l?&^AAzJpvt2nakAYK=61I^a%hGJj_v3E`zF}6Yl_bJP8y%H z*@sSE6MT(tHfhQp^`OVq>ubDxdWAD@ud&&y9O#QN#()2Vvv2;z#~wPaX_62^;Pjhs z|L6qv?cT-lBZpY;Zm@sP9L8Ms_SShP&q==e~B3S)cuOOU(=K|o9mHt7h8P$`^x2chbl{|@wXc1{#%+P zn?JaRq&}3uLq`weoM(1=imI+>5^KK#{6 z5&b%<4X6U3Ky+Pf_7o<6iowd)(NHni?9-GDA`qOT>TYoHQp58vrkp;XQ8mVa{$Y&q z-)32M{_2f+@+{-xwd+5ez=>l=Zb#tO>e>?`^6$pRCw}gcM<26a_=RUUaXe#o;wovn zK#XfB^{A(!K~Z$1aRrnZBf&xN5Pct4JF3l+rtw1{qs-;2lBFA6UU?0^`}!Cwn+d=R zF@~>YX?pq-k3GV(&;25Kb*?aN2mRXmH0r!YwkHU~2UGJ%*$f?Fl{KEVfkuKNBjV;4m!3Dq>e9;U-zISU@co1k z`Ng06EX%i6|FMYt_ES$kGxJY>=@7d9b+V2lYtH~3Ou8SF>;y7gwL;Th#5WDDa`@WO zR5dY1K=Cf%Yext@&>l(J!k96PokZ+7${5Zi40;XTIlS|Due3TD;!4ze7P>7$G`ria z;{PPptn~&ZjdOPrIDB9~?N-6XtJj_ok^ed~yJPM*e*N=I%kNW+3nnQrb`NR$VT_$X z)ecjlbGT}S;5@;3TaEdKj=FRV zdJQ2c{Y^&*U~ES84QXnq>pd>Ydjj2-bO<`@Q4wDSBw>WQ_<8BF$qzXG_%-5=wu!vN>F+D z^w#kRLAP3nKH&+xs!mkxDXyv*f%%r*)z9;ro0T&qL_G` z!P+Z?dK2#=!AD|P#)x22OKbc9-mT%QH4w|@T17Re8En=#7YIJ$ng|G4ZV5psON)x3 zzc~PuL@eG5&KsOJL{fs8!o{291&qkUp!wd}gjPFeurW`X zEB)2ihMA*TBLqdG5+m3IR1Hxr(JM$!@HI`{FxaeVs$p*TK4Od^Ne!-nZdVDKqhUb5 z+mL1!D#67Tia~M1IY5E0OElIb+w!G=%4i9`9f3T{sOtKFk-*OB7S`58@uTH`K-M`- zU2fo-64wO0i`c}FB!b5C7;8Wy-USA|nyU1Kp!g<`qzN`nscNBdDNYNBeOy^$tih%U zF1CRLW6W?1Vp~Hw`I-nPIMb&qNpoj=bVi03#d`{Wq*sO&%tHipCcY!3e z1lj~zXlzg*NP)2(q8eh%At=EX#3&&2@;qCY?Ggf*93M+mwIx7ZImAMmTLzmAuJ**J zxW+T+dq8M+3Mjsn57ju_FG)&>1sVkv zi;{uOQ7q9ncqa%2W!>NdpgJEy=x%M|ZWCyn3nJn|RMxtI7$S)kLeOC-qf(7DZAak) z2w^xu>(Wz~9z_siao*qqG>u@b5c+F~Q4~A8Uj`6MlnzQtP*9TF3to%?uYsTj^|02n zM2!G%z4qqY8~f*W18^J3mww^rgNSUX8X6DYJ5T`y?;>>>aCIDB`-pRqy7H8LPdV_^ zb-?>!YHS*%te|!&HX9?#7?R|~pr|ASZ4vDRwzY#m3m1eC1VIP^q6!)!F(!x@27|!j zY9uNVc=?HsJ*r8P+!=v4-hKxWR)QLQG=#@DB(T&`r5l==zq##D6EGxiL_Q7Q1 zU~|&e1R)AGiNlApC`65D5J)nDYlzx_O-b8hs3e%ExVjlRAW{zoEOu-96@Y%ftn2fM zeLtrr05=ww*uQ5EBXV9u21{M-+*&p4ngr2^cai?UQ2UHQKVZb-qL4NPd6D3pqj4>q z2bF>%+l?e`8s88@Lz;K6**HeQ)dQlhASNX3NeC%f$lUH6Gs-?+t3e{vUfeVHb9&?G}NVr`8|hMJUM z+QfVsn?st{WTqf3#!<=9Sku%F$r9AcaPOYvr0ogFB3Utpnu5CVB-Rn#fT&kF)H20;JXIrqGCp1r$vGQYHZCxKpnz=@+r7OyWX{7=N5{Oi+;_JP9> zG1+#cQ*C@zkeZa#MM6^!b!u9u&1p^SLL`zTEkX!XcGtTcJNf{16Nw7Orbs$THntNxb`Z&D!DM8uX*yH)fn=0T zK#CohdKe?)2aA+8bAB zoC5kk%Bud)Ax3{=VUg8tcl);D{qosoK1F{};=FQugj@!-dfws`uJ$BEh{8=s|^ zI)JeSKBg!J?-iR^lB`XP0VDyF4Bw@Q!N@QzihwnSsKf1tu?5B^2$3XfBQ~QN^tt-( zIZnU)67RfoiMk1h@EzyeuNrHwq)Ebyr(fR=`F#liT${g1jLJ`a>XR>=KKItY!Px(F z=0Z7D*6;D?@x6?Bh)E!CLt5lubF5mxVv>w3%Mp`dlHqY|Vu~b55rH(z>2$_PlHq4>bkLO3tjrP<<{aVtGCu5X%k$;R|A@=#8oBb#tPNOGIej2=o_*$ zB6v)alVojL?G6(Y6SVRcF-F!mdMqz5bNbYG_{(oS%UkbWXMM8)C_%r`IQK8pG`;Z3 znX}C8nB~$a_iryB{9fpRqaec4%8DG=v*)u$<9`>jEylUtH~@)o)VFt0Zxj@VO5<5 zIzWEgm<$c7Mt<_+WBmG8f1akf!JB7Zrs z{^XAcAuRh4zIOWDTh9W1+k8|YepFn^M{T$j#^u$uzje-aLQduYj3tj@$wtfCi{W=RZDy zyD^VEW?=YG^VWrndh*0WUruc}{`t>+imY7_XFkpBu4lM(Wr;ufz5mW@FP|cWxLP&M zZ@zo+@;65|WLwp3W3)#kx})QdMZk;lG=KH-B`%%6h^q$J z#P*!?udH^v-|P>{72qgPkEAi!CZ8?MZvp>E3FgBZCBOloH8NTNM@D_>k%aaEyW6eS z=kDJ>`}oXc!F!ii@jm*fu@_^!;zRh(pse0iRX?&DMs@4jjfkuPOF(%Swg9Yfk9qK6 z5y(b$duT1t8+mF1xDS}|-j7|py1aQlYHf`4RCUdHzYt?w1U5!(bp*zZ`o|F{Whl=u zBC$naYuxQp{gDXhUEnL=Ca@P6A9?5+uD0mf8yazr`+i@+`5Iz#!DBd>2oKt`VL zGnAx`BFkOl`VS-UVG=SUuw&bdMuw7_V>q!}qrvT{wzfsB91-Y_Je-U?UXSkEQFPph z&@Eu|F30&%oBCcLf7nFH8BXHXHp4pVmyLdJjoKBX<5t!%+uCoX%q8f zL`R^TQM+pN`#sA?ndvDo#W4G9eXy}zpIaae?=Ns$A9vhd>_%<lyG`cVnotJrO%WJDy{76o%x`|VQP zl1a%Ak;=Ww{{tENMqaZ1`Xm4V03~!qSaf7zbY(hYa%Ew3WdJfTF*hwRGc7YPR4_C; zGBY|bIV&(SIxsM!A6c#d001R)MObuXVRU6WZEs|0W_bWIFflbPF)}SOF;p=#Ix;gl bGBqnOF*-0X5Ebl~00000NkvXXu0mjf_g8T_ diff --git a/images/YACReaderLibrary.png b/images/YACReaderLibrary.png index f52e5dea709713c2d8ef4ee3f2e97a92366bc7d6..855bb865c69d6af412b950203f08514d7aa24bab 100644 GIT binary patch delta 1853 zcmV-D2g3NwDa;O#B!3BTNLh0L01FZT01FZU(%pXi000L5Nkl+`TjXuwbxvZGT_eYg_(nN4mS3o%8?S zGv~~l8KIQolP{#pP@F=DN)`cRe`kjp`f$sc{k2y_{Sm7S)Fr@JXkycWiucE5@8wkn z%07isi;6sea0k4?UvSDm+KXb^-rc)I&2)Hy#!X_mV_h`@Vz9ilKDY^&JyxnQ>c8{cIL_=u$ zw5^KGhkMklXiJ;Tr5c+nT&ykijUhT6oVzl>iS`jrUbGR00XXxH*!=6R83<7L4au(6 zZuYE=5b)%08F}-)J`SC}!R0}hBaetphd!8=0A*WzrGM7Po{vZKO8ia?##21ia+Q|L z8k#w|M-7ziY*eLK5s@5dh*4b}$OFxZ5%jt^__<2De*YG&{lQ5^Xeh~4O{G&bl&3ko z`>r`BedJCRmmLT*zEkXD>+Whoxpxq^V#oHz0SL7$t(8W-uo>mcn31W3t5 zO<74+hku7T_=Q#TO8icIdHWg?z5hifM{;tU*aOnW8tUcXeN_ua9w6xVvbo%iofrg_ z?S%;!GCLKgp;BX6EHtTsreiH2VDHWbUOfIP-+AJhn=7pYD0up@2ifzPEt7VuD)R8J zo*Njxa8_zHl+2NZl)@V7l{#@CZtVzq#u<|fj;)-F4c_!h3veq2{>pbB|LwGPnNL6Zb@qIA z>wlzu28M<~S}18To^N(NpcFD0N2WcF2z;#Oc8WDTAsTk>Mrh8q7)nV@-_)*dJ>LOR zfl`d;n-v2}N|cpA*_tB~_f(dSJ~wXLK;yOzj{Y|t3=9n;bR)ArRZ|E+Nu-?u>C6N3 zfwSk@&`l3QXxReB7xkmx9nRyX=92*Iy?<{9O|P`@y~lq8P74#IGBL1o+oauE&c1^l ztpQDAJl`x22o#!O(*9nTBM!R9&#mIa^oEI6*G;(v9_4SRG5nLqK-;^QxHhC%@{tHa z%i)1sMZKoG=(;}Wh{Wz4^`p;o5d+U1{S%%@35F+#P-F?vGW(0MP16l7boKK=*MGIV zl9?{fyzv&zr(5wviqQ>M7EhF&dm+mXdV25&(ry6K*@ViX(q9iQ-2LMe%z7$V+#mEoQaRxEY1dq+K+)~{jp-T5nYu6B0Q z)O?cXoBxLGEyQ0`i7Qly?wWcr6&t^QZ1Q6jrLe68*6Fb+D~2Wy*bA^@#<+F*!L4W z;UZjt0$jlYT)`NoH<&3{rhl=Ub$m7|gg|$B&`mc=MN!Jm6#h!y4k|m1l4(-IeVl*4 zC#Qhc_KQ6HE%E3)N@C< zo-_!T*5HX0W4L`}f`2qWHUY$jhmOqZg5ws_iD7CAHAeo|$vbWBB&3OV$uc~VVqE?R zn&HZanJnb*l26*adA004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x00(qQO+^Ra3>6L+8Rq>@ssI2J&`Cr=RA}DinQ4q<*Lj|w zyVkyUExqqO)3b_A4#|wTh_tCt3#FJ)Y}1Y+!4eG1f^7&vfc!}E%SqrMu#6~{4I_dO zNe-mYkRh9rOoF6DYQhm`IGh>I*3)}WcTIP7*Isq2>Tc)cNB7WVhReuOk{>z1!L3`k z2lsux@4N50=N^rpqaBc+-!=DvC;s4zj}YrUPx0y%8Wn}Hxra#RRow0_Zm*8p>(H&2 zXz#A!cI$)!4uxEpnaMZ@hjseHj+#_Exvr}`v@;%IeuifQmav^)qimSlcOU@ zDUnhZblv#M@#8c9^h>|{5DEV!wihl@D|N_E9UwEP<2!9^tA^X_AbcIW)yC;`@OnLb zr-u|>kR3ushkV+l5cf!FuD;vWr`w)>+0^xOj_a|#TYgVX`ke@mMIy{jP2jpNuIHt6 zUH_wlvooLiozH)exHv^==@M4G%kYsy#QI`*b^{?K!t+t}47Sz4>Gp2HgQ|d{AUq$} z_7J`RO(UEdCK~m2ow{|lT5r(p_TE?99RUmv6zJJDp67>y0rTG+oSpq=zy0|SlhseL zvwVr>Zkx>L7_n>uue*!qI4G)tqQ(%y#O-%yhMO;|C+4%aY z-wW-uIz48_$KDs zv|Q?}1$0#k-^Fp=pB>=f>`oWo^Y^3c;d=rpB*GU6A&^qydjeHcP*jCZS7W`{hb(-M!t5~)96n65ys77` zE0dK}jQgAJ6e|I?i6X_~K0n-xWCBz5k>DyJt`=r0>eEU#U>M9aE;W`4&ESe*{dcE`{Z z`7h?CGxz_-lXKLrf0Oe1Ce@NhVdeyZprG5VA$$kdX(Pp+MT%SE0VxH(>jM%!V4#I^ z)H;KR?4u+mj?+IhOf-?_#+9FNQ+&j^ak{q3ak74&=%9kK*+jT>0UDp;hZbatcR_kxo?Txk;kQ82WbcO1*Af z@q8a$)9wtw7lM=12Ip49_`&foSI?YfWg|w=%n}N8XtX4X$YN?1y4pk2Yz$K%eH+;G zdExs=DKSGaf~hgetsH9R1l6`rZn&Sq&^SnsH~#idDb6pTBxbNec_M)wcFHYKv)Em6 z-m%@M!y&Vas&aE@_s(2MQ&s-s@7L%H`vJXIq1H~a`o;yW&o8r5(wJY9bc{oY)!~4Lt=7tgu#67&Hwbu)|aee-`hsTCLTCG~<;>tRG>ExZ2 zkdP9vy|NW6udLSSAMQh%K?3PPl9@b(!BLcZ9-!4|&}`JOtS${dLO4?(R*?9;CcWA! zZCv^Weu+!h)~VN<-23n^5lQB_ap^3VpZN`(DVSO z|L1dT?`(jo(rLLN;hWa6+41i$trl+sxUGZ^Opb$;Ol0+8Pbhc!Mwp79z=*~PDmA>7 z=UH!@#hN_9!1R4YbF;(}Swf*GiFA-aFhaOd11Twm6HH9c;<`Sk|HoGt8A=kFe3cQWjaJ!1ifB&=x7ccVd-Kfu+NkHzvmG@O z4t+71G9UQ#=bqx`%@r}8!uJ`9d87|K#Pv&8DQ?XZ8$Uv;sj+uJkU?O(|ubO-c~|mLjy!YAyicxGfn>8M?U^w`mx79gsxYKMLpJ6 z7je}%c6bUeeuS1BzzAlDsdZX6&#|^}ilr;BP~0ry`YOfZO)kH7nz59__^}6BUtDGB z$|-VlkK%b@>f76l9)FN-V1$PsIm!JG+(RroOtqzAwFRzY`<`PvhNiVtybV>6ek>ZL zRIa`=Kr|etFO|l2oR3dU4}SKkPk%~XTDry?mli4QR8Z9b**=YKdy`J5O}i)QlEMv) zk}Mo%d~$~VJ`K0I!2IRcSf4*jUSH$BN1tSMt;vNKzD@cA4-)H}Vry-UqbEPi#kC$I z{Yl0~GnA?pT|a;p$q`JC5YLSVFp|d{PyIN;)^>J^uh^~>jaK`eODGZ!G1Q;p`ieDk z^!Tj4u=EBOFK?k}VN4^1)VoxhT~tGo2v`Wef#2JrTuO0cEleWS&)CQ`gA;f2=wWah zix`?@yP|XUnQvkYOp}|qhs$TqaOBikCW-4b zu&oNd+eK5mNMGf~$||diCWaoNP#7c{jneB_ES&l}sZ^ZF`#;L1Gp{mp=qQ^llTN43 ziN8*H{(q_V?g`^PbKmv*a!)vBSJ9bCtvQQcs5 z=`yic0^2c3&YWQGeB@@x{eUET7K{%S?LmzsC zUav!Wx5UE2B37$SFr6cl%aiJ}@mve5T_&0+VfPwns=~nVeT+@b@q@qq4gpPP{OC!( z`}|eX$q@Bck51RY_XW1?;duhj7igM_@AMez3-RP*hgo005qtGg^|w@Kt9F0%^uIj6 zd04(<33Yo8Gqa9pHq|rd&t3oZM;{*}7LTAQ8Y3gaxUPq;2N|23W%|G|T+gLZt5Dk6 zWxG_wFoT41lO)pVfA!3(n40XFYOi^H736m*s^^TzKsq zAO7T1TrUYWi@RiVDVmnOA9WugB)%_jU7ut;L_QVf-a}dDj?eJJ7ccVaYge&b>(8t$ zocq`PgOi=puU~v;8*Q}Ol*$!umUe7S)vI>Ty)PI}Bs9&SW7XK+TIc5GI+_BJNE8$m zR2^M62?m42V@cBKJlRZ!fqaHsCQiM)gBr}xKYbSq3mb$2CXJ4ZFZKl6wu|d}xSmfe z5?~;kWTFt{#IbSKigmvCgIDl6<;KeOSO2)tw9aqumVN&%GxBZkLQ+ZhH9f@=1(szUVZ(Kfos5RABf&*O{@SC=mLJXXK!w7tbh0B&CRvN>(@>kz3arl z#MB{84;WNhU4#}Qm4Nk)*ST`#Cn$)iD?*Aw^j*<1B{Lo_~_#w1VzVn zJ$5Q}HcB1J)jF=-!EJ0ab7GF4oW4S()}gYs*uHx4r{4xH0Ihvpw?+G%0D^!Im_P<- zNhz!KT6JfAWkI`H+%R3oGZZbT1wt9jaDi-Liovl-vV|1LI@jmV@$!#fVtILyN@^W0Am9QhOtChye()G^b{AK0F+KN^wSJa)Is^Yl15{?a$A3Dt7$U!C! z%+i;Slj#fKxeAqPgK`TN*2`?|RH;{Yv2B}BD1`7Fws&gGFYh3g0MGu-cdnGT7rzFa z0UGb3^IZW1VC<*N-tVFP^V(i5O6j^zt5(_VZLBSOTQ@f;mA15v^>wAVv8A{!BvSoE z69a^!11!v6=Hl5GX;!!VfT{Sd>#MfVmEDHT@@9pl<#jI2uTdDD;kh6Dz?#4C($nC- zxF3E0-2mQekIVofZ#kxb!2XyBFbzxrx&4yMYnqmh#^Ql+Bo+>sX50*zhM^m(5Wcci zTvvo}+O4*|q-lCLo=D|~M#i%T4d(ZZ)n_mWA1?umi z@qIV>ZaI>%pMl6*Aar1OAHV|gz}WtnK26i|QlbgrdkQ$ZuKS+vZ%Zk+fHE)$#0|sj zkHzDCp05UK!H!UzTEi*7w zFf=+cGdeIiD=;!TFfgMZS*`#803~!qSaf7zbY(hiZ)9m^c>ppnF*PkQGA%MOR53F; eGBY|dH7hVNIxsL073`M)0000RCt{2ookRB)pdZs+wYm#hgJ_HK*GWnU?LI;J#g_zz)oVv z;KV?M*!dF+J5@<4F{aA)pA^I@%65K*B5|BlIaRWRiEMDxoQ(|2Qb=+ zl4W#^6Tl{K^`rMTzd20-Lg9bAv*pU@FgJRuAKeBL$9~4diYrTth?6>r5wV6!#gTyG>$=@VO&;9O7U|&~@lhG~CwLsn6?NVfP zjhhX0kSAj>xynMREW$UqtTDP>f{gBB!R%uJ8U2ry$$zlPnt%Z(YXSzGtO*!!G7B)^ zWIn)vWAPp-VHy38)$IawlUCiIYh4gx=JWZ)Kv;n2C)WRleveYq|EE;rf35!)q9J5~ znD$=%XnMc-Z!gn#7GNe}*M+MlP0%q_<% zoR4AVL6~hQOn|H%BPbo9`p%Z3O%af$~qHw`R8y( z*JFBTwWnsMf+8rrN$J2h364LkmBHw~BJ{ihw6@)WR7iUng_U2#Ua$ef8t!%x=Zy4E zQGDZD_=moWWp-B)MCs|?Q-G+pM?&`lg&!yiAGj4~(G{5P;_enOC8U3f$ydLQJoa$c z6hV}pUf)v+&|KU7K;fIq7&-qooCRxp*t{pBcIss&U-}}Ze-O)R_z0b#XB41S@D$cE zblzsH{BocNyrp)d0w!O-1OM=LY)fDW-Fs*^qV)51T~&anjSr+Ekh;bXpMM+9*m?#+ z@GX>&{Dk65U&66Py$jh+x~c$Ct@nMX`HI}CTgjhwErTfdX8htfCx7wDjwpdBK6P=& z6`Qb?)r14*SSsfsgLbopcC&iDv}Zt`ct%CErtz^znk zl0ZuIOzw0KqZ9I1QXjsrs8$t>ew4+R-k;U_)1Ywn^%!FxrB>4wNJ&zajVSJ1(^elK zYVT`-qFPhrR(*w`<=2tb`qM`R6^`uKi02wuX1Y#cTYZ3L;a4h>!iBdpwETK9;m-|W zx{R*fLe*FG!LPJvTS7=Ad_NTa*rg9(=U24ly9NPw;d)Mpr3Aqt3_zq*b=zVAnuTAk zN)~3qPXWQm>aXc;GwE4@)O!I+>7y1%%2mn8+AUa_@KeECv;k=>4ZDRs+6#!h{YpiV zJ8v`I!j0{HDg%WexAL#?Q|u9>+5|-7^;KVCjD3vZ71yVE`wU>{>`&kajl9OB7}GK) z6C6q^l#o5^*4o; zoA85%9FvgB+`#7ezHcrgw|GP1duGgzJGO>Xfka9JBVh(nDzk%?gdl)wMX_+hKa!dL z_F{QU@O|wEV34Q|C+-F+rI1Qe^CdNN8Tlod*WU@8r61P=L?r7HCiVezHV;&*im}yy zPgeUogSY51f&ipUX2KJNg6rvAzNA`{44?JkM1{#XeXPPc$Uvf`k*G7D*aGM=esGq3 z9MPv)yS<3J;6ef!8uA22AW<(MO6K%^$>_>Ik6((6IU@`kDRo4U1obXaFF+{>0^R-d z7F-zrMj3O)FugDwtWZkCuE()0fS!=4>Iz^wBk@X*5gRG>$Y2sH9@__KOv6?TzyC9_ z3y=|?MnpIM@NoPlK?dHBTV}9Rjx8u|$Q)h)HW;F9r#mz(%gWVHe_kdqzT%TYyA?pePQI1%SFk8q>w% zg@QxRQ%adQ7M&3frF24oKqWE+u`ECoevB4p%IG|@Hr2F7Vf@LXiG2W-uno$HM|E-> z(}!9N+)LPW=7> zNAbqvU%<7&GNUbNl50Th1tJ96fiQ)@HU-tG!yR}CgUiXcb|NZo;aCF8XbS%(w*c{| zJAtOw$Ww=Y8T-d&{3aA{JoW{0j=&C`zqEQ@iJAaIXyH2+OzixJl!}zm$~*fW#H_uE z=YVac+_CMX@>-~OjDVEC1jj6d=@@~*(O1(qRFasEia&4h`*)e>!UgMq*x1et)sVxM7M)XorKu|bgcb(9en6$BC|5%TsA?ss z)Zl%W-ohCde3JawO8P&uPz(N*|NT2ed4im)1z+%Vt+&I?pgL9aBig0_FkK01fuiO^ zxvG_*Tvb$SS~+SyoW1U^ShDJB3JX_Zd83$?*REo96eWF*y#5gT9=ioq8pm@4IY;Qh z9Y=%-9wPCg&v6mOAD_`S1&D~6gdkj0vgYe$9omjr6URu z5h+5nvxpxqGF9`#^FR@V!Vdy{O|%wq^Jk-N<`w$&k`G>olV6Gg#+F}(?JYn7BTFwr zLEDuj@XHjBzRIaXyE*j2cbPi46Wi3LT?<~wqGXAsMu)}0c z%hW=4EP-um1+XlzP3k*=cgx(*geczEc?F1w6d^j7^|fzRU69Snf@&7>^lO@h9w|zs zR5f2ws=~TW&yZViZd#>h_ubb}J@Qn&`(~Sw5;SVL)g<^{sPV0&vSUbGqN!y-XsR3M z5mC&de%|uFn(dCJ7vx=VZKeD0 z;Uv9Qf%p33?HLP@2CWZY0EDY(7zPZVby=eOmyYk_&}gM!30BjF|Ey?@4|6h8HZ6kJVf}w)W&9_aVXXZj*)SbR^0-K3K$bJB0zxSOv4?UNT?Pb^2 zbqwVMBYBewQcWm$TOzHI`cFtBu2P&nu6IeoTtd@sAVUCeM^XEf!*+One|J%>q$;2a{*NLq;J%Z=j+UzG?lC2l%I|~qb{WV|VUi1~r z-06D$iWl$uEad|~V6*^3xiH9MiN37)5q;+aD8QExI4fBE+c%%qXDXA2cy9Yguxk^H zTxM&I-L;<3H_>h4cqRP;oQf+xs3;5wo{n%B=YKcX)zKqCtoa_hf=v+#Fj zz1A@sWFF3ZSFTL8Y&faXy`(A)TxBKGk>t_^xW%3|z?7W>r&;A>p4P!&P zU+>vqhhg2w%O3=j-^#p>14M&8K>+x0{KajU!|z8bIP%JUyz|PB2&N|R99TF6o~@@| z*;d2DpC-^kmGvUUcs);BZn zeE<>W;Mo@Blupf(O222Bx;tluiz`N3tYm_3Ft3|{$XhoBIN|IX&k9qs4Ds#+O`0MD z^Z0kC$-H+04FMvo*=ExohN5Y_KCAJwV*tCmU5KOz(MZRR4ns7KO!%|1!$PS?fi>MO zNgBLM&hy*2b%I@D>Ym(6U|+XOlF=2;HS#wU_k-F-n-(F;j-EZXnN*WEzHX5d=j zy+=?o`h^p~W&jb*3@YB^Z34dCwIXG7lI!w+R=yXS6ab)jccugbz>WD&mA6JOMC;tZ z;@$4Gz*e&6px-zFY|4MCa&PmS@0uADUa%I})}exBw4ZIj+E(Gi3>Ki7;`f}Dz|Cld sxUyZP%V-NbfL*{H`A=8(&vw!O1A%SH^Rv*yWdHyG07*qoM6N<$f`{Nx1poj5 literal 20829 zcmV*UKwH0wP)r^rSF2ly z!Q47oFEd_5yomVy?r-`2zQ6n6Z^z$`za4)&{&xKTbcj#&1$-*TxM}2M)SL$H0M3j@ z&Guw8+5v6?P66kDF;D=StDlnx4A26P0T+SGz{T?yF8=XsvHZ*VavA>W?&jHzztIXX zZW=WiHD`fa&z;?S74T^!;l2pC1yIlNM@Hab;KRVfv&G_1=8NU~f&0&2ytI6dKkGRe zf1?y&5csE!N6jlHqtWL9Ukp4Ske}j9TLJHyEf&8uUo1a3TP*)*zFhX7;%fr_1}MO} zy)%2`QS+L~X!KU#)ub8z*L@rS@1HFeKRaJ6fBXE!OCSGKUC4is3UF@k%+2S{?!A>X z!#@wmp2_hsrdRLN?^;8aMYhM0x{L?`SB?Z%W&$D7Ly|JRhDiD)lKzY94JSuBC`O0~ zqyX{cPdWg93cUTUd+-0r`Eq&mOz!2`j{jg3;N0GsGviV7<&)9q>wwpg0<;?%5eOc9 zfN>MK^?8BkoeA82OXT(!!gOS5N=KGyq*4&Ug)#f97x9Ph-9i9g_V;?6_n6KTf(J69 z+#|4!w;dsPymNSGu>BloJA(5Z%@@4=PgZ>3BNq??wAN2`sgKPTi~sWO`yTk2XZ5h2 z!T4*f07JC?%5!J;z7_aNVCzPXi^IeW5w<6h=ie0gk6-4v{e^)S-O|vEM(A<}p(}(e z$j6_9DqciZzZjYA03c+65Kk#A0D@l-gN5h`z9o1|3?8B*_>O)xqiYT4FC1~#M=$V; zzwm23^2noT{iN|{1b+Iid+-0g`Eq&rh91`iF_Z)3+94z^p8$bAxvXcpvE6!0gatY{M=8(YNr94>*45SAU=R z>rNcthi_l>&^LrZ{)@%vVoFqwfc9d%FF-hY(9%wZ+LKAchq&%)lQI;}QsX`%&ET4+vqO;ARAS1Vm!! zAxiLIT0``PCy#oVx3=E&_Ycub(fM7oVd?z8Rl#1-SF} zTfby78vPLPil^GoIhc+;f9KVfFaHN;c+pEflVbZ#sQPmevfk_$V~=nD2)lecq5lwq z4x~cp>9Jp5rvX3|Cw>osWV=1C{W$m@LPV9Xpt|WN5o!d$<$JygDQ8Gs9G@zJw-#p& zwlhNp0E9>!c5=O;JvyXcbt$6=k;6mJAG~+OL;I(B@R1qD$tTMg9+@o`-+uRf5B&Nw zea25UK4l7UZtu)3=g#i^DDc%!b{#QBLI~V``wMvE7dE`^4X{=&qjzm?Gsjn z{zG{4K?pOvc`w8(NId~rLEPkQz#xp13J}Ba>EbxG10dkr3%LFY_1PaMpS*7PJj2n) zzYP)g)A_>j5vFVDmn|VggcJzG#u7vZ1&d%-EvthAymbTww)fm~pW-j>n{dy=fuq%v zX0-%WFq zzUm9E+9!q;!Q6xI-iMw2pCCG9wuR8A5Hd#$iF%BY7#%VALGb=+8E<}%2q~{h)+1>O zN7Et8S5Qpf0%A;iKCDnB*&asg2g z<2ntCNr)i~=*`t~PdajqCalf&0PrOIAVr$C?*KWxznVxY_WLV-S<6k_a`oq zzd{AL^Y&Z6Ycd-BFfcma8u305Lg4Ga@tgRzw|xgyeeBQe>VtIqKZlw9d$ewmIzwis z5cw3TYJ`-@ghxe;mISJ$^KO7Te!;uw6g`KkIWAPAw)j>K+f-faKfzB zPo@NyW{bs}@4oMWcRh27T=PgiS!3KZ+b_N2wtr3nas;Gj?2O_0FMJ`df8!hZ;@7`{ z+wXW0F&Mfl|1aH@e~UMd5&RVdpz@kxd>WaJ5ke7S00KgkL_oy;7?NGP@&UJvA)ffu z6ED}y{$wrIY7mcw?}l8HwZTXN4IvVIn(@v!;-F{V`ScT#k_pM?y|u!uKU*NsnL=qr z2!VFKU~%~nYXbA5Kn(EE*{%o=Mhj-uiz#o4i^7*7Hz`4CMFFtp6 z?^j4=SRk4D7vFg&U-i{r%NySKM#`!p#(-Vk#nFR5j5qH=$sCZVtU*=V$h<*idU)^w zqCjOk#JB=_AV;bf5X?P8N+*tkt`mkoZmjl+(4FI%ycTdAgd0*`xS8?ZID801ABjF) zOYq@%c5|!%2{H~yC6MxjFW;8x5Y z`!yDi{S3aphoUMFN}%!)S#=7jiUhpGkcu)wfUHp2^N9W-MDz%~gRWnPS^P3YbL?M3 z7~+C-JxR9LMt_6HUkf87ceL^EF#tKb`gEke17ySD$Nw3Gb+8(bm1=mg#$r2GcrFzbRR`Tfht~tEItD>|HbsdC(P^mZ#c1Sg2-Ps&djt3X@fYLz4y0J0kimNpL&S6z@57M)pU^oW z&^jrA5b5vrKHdea@q`emnhc#uypQZZ@;IxRWp?CI3Kp&AH{QF$#iQ%j!Dfra58i#> z1K`dqxE{2?W@Vx}G`m>0kCD^-A`OW0bD-m)BGylaQ&|2To;P>N+$Um+Fx)h*!>xeN0 zT1u*`Ab{g60Bmou-3o*xMnx2RnAJl=#qb)}g1}ji>yw+%Um@!qrl@Z%g_vFu-Vgb-Vg#W{q#@g2Y&cRhjr=+1&u<u6s{LGTbx2Ae~?5Mre7 z9No$$p?fygAr9F}7%~W@5|E@bg*OK8!C8pTF&+snFLGM*1f1Zu*<$&xjkPxv3p^(Z zaOdr}e$`|&`Zt^qeh7gd{L%lBSA5nhx$x0n=JH2>n8|jHl!9zDX0&?_AyR%Dog+HG z0a*kQAxo-LZ=qlO9!l>K>|^NaWq_nV`c1qYW_uKb7&d`lTu0`|9)$I*jxnWm&bm!5 zzK#h}To7=^)2$3K#PslUg%Ap%1X4x>5-9~j$c+iMy(4&^P{$!&3DFb0gBWn$VLC&< z>M@!i;p-LsVd1M`{lI?&=h(0vC9XC z@4FG%Jw4;$X~wy|Gq0SCM*s5UHt#*J|B{s7FZS=|{QJI_@lFi_ipeR;>GlwHd!q43 zT_LgwQfMGm=0 z6Qbv=+u#K{Q$t3WYWB`}#1KSgxjH^Jl46o;{5g1}9)s9s)a;Vgx1h7rsk(?t0HlvY zgrCkEe9!#y-5g#12&>tn^vivMlN413h)paL1sp!ULMXv_l1k5cow0Rhgtv2Ilo(?; z)fi4s4UfOQPf9&cxD6pS0)dnU zfoF93OOV;~FztC%uBjxq z=Pz7*!TF1qo|aMctSrDw@3`$JuNA&?j<5MgZ)JCPmj~YcV~j_aL1@aYGh|hR5CUgR z626oWBi`)ey1OXGuR!W4-O=yiyZi9wVVX1F!s6opiZe5Wz8TlPn`ZYbIeO%$fEpny zqU#7ztexm)7NwYAov#m5Scnq=CkSK;xP(r#mgM)>Q$G3OY``HT&F-6-@Bb0~>{p3V z3><=(G63uGE?_!`^Pb=%LPVsDIG6JM!%H9J%3~i$c!T%c{E{!@bHD0W_{cl{8``7$ zhymK=kV-BDrVETFNdZmkDQZbkX`HuAox#S8TnC)LicnIGN6pu8k)L`x8GgbR;Lh7` z{oKiD^bW4!+?Qp}umAS%l8YJl{PyQkl!|J5hhnsa(izV7R{GR-?T>`PRrEGN$$gh1Y8EDn1nJ0&p;!JvwG7s(1u-#RWnct~#|^Dg7v z5A5*3rRv&P;FsV1fe*d;>E!qcS%7iV6ocQtO8CxM-u4~e$z(F+fj|3ElnjWhK@~NK zi1#L?Y{ULBc(VEqs@*qZ+XoS9hvnn{J5uG0&VCzac|XqPnE9U(F-*>V3yX`thO>q> zH#>$@X^VoC0dxl2^~4A&&(e$+g1pSgiX4?mq|OPH5G^qXf)51e5iugQLT4F4jEJ!( zI16%%=rsM&JBJEkO4Skrh#}=n{>Pt4^G*tX{nITSATWIjM2k`*wIBwE4{T<7mZ?n; z>ukWZj(U<4fxOb>Wrp{bLOJ%fEcai0f&zTrxM_-~Ye4yg6yV(1Gye#<^W?S|;p}e7 z8~@>(SsmWX(Z_$DJkO}Mc92RA0E|x+JW_t2*Dt2rc{67I5rTb`80M7I*HKPiOMCPe zbhG#2`tt|`lbha3d*x5)+lzoqC0~+R_Riz2!5Pn*i=Wj+O4l+)mT83aBb%4Pgi#y-SMG zE=}SMMom4+H*RT-c`X-~@g%2Pnl$?XBJ{l@y1-VM(RUsKlugERZqN!Ql|{-S_&FYD zCZp!o`EvP`<>F_o0OO_^4-~GeNA!HtH+%)nWQTj-^@B)hDYy2JA~9o}^LQUn2#_H2 zvuxk`{VX5V(;>~4ZEZ8~qCi>N51n*JB9Y}SGtbRUG=;CEx9GoG+1K2EHeX8X!ieDQH&)p#*VAd2;E=RmAwKO~826yn>57w+e9X?3uR!XRnfdgj>#Z zyy45gfqwZIm+${2w)RHovP5c`(jn{81q&bwLVw7mk9-^6A0W_#SaAA9KY&?$jKlN) z7cneB1ay9ua{Ki>`jXGnb2QtxaQ?&pir_8f zWC}7x$aX;0q#R(^7zm-myE(y0Y;QPq>-S+6ALHPWpC*Qm7$q@InV$Q09{JD@W4a!h zog#RHvxauIB1XaDu*JJbzp|)ICA=ZloPNm#1D~(>0A=72?#0hK449tZ#{XT5K>@GayNOY2|l7SwSkcf z?XNC&rtxV{*mAAxo{0iXM$H!kFF(00MEJCum%Qv1uZIYiAACFIWJ(AEEfitk#cvuQ zL<*wT4>3m1*7Lpr(>}z($Nvq26fZ!{={vrY^B?{ZOt+%mdI{bf;`%wJx2P;*IqTBQ zcb@T9MLAMb)6b^bdJUKF`*EtVKxuu<<^jNi5Oha>hUxw>#&w8jiGGzXE(WaAtcC`U z;32jh!MmZL1WFHB!2sRH5b2hNE06bNnL=f1xY0DjdXr3hS?fXgiDTk@s(9MoQ^qLwz2)!FEgz*j`WV%CL=36S*)8qHRR$li#-$>QPi5Zm**76o$-zVag6I>h zYWtq;7k(3u-Tl8|&64r%s|n7~Eicix2BkHtqZX+oN(;u@B}EBaH-80LbvyeH{4WTZ zC|XIGQm`dR-94!&GsCVv2If(4bAk^TBUmglW=EQ?4JmjtbAs`4F*I z(zl9wT;hCEt{5TL*Ol?9$*37Wl}vBg0*sp`Cw1d)MvQRlUdye|*GzAE74u6UqMD>) zPcmy3?>r*UQWb1{ph&s<_|$(wIer-zKl+0>12H;?B4Oluf-cTdPF}{*#os4*i)jri z%UI1*E?w4|vMKTXl2f;R7ya@<<`;eeq$UK5&J}2dRC4&(2&B&-N@7U4zw0fFxnR{- zL%No#k=R49`vb4^7-p0TT<IjjYa~r9k9@(YPgs1rX8liT0nw$9O*Qq#egM ztN`cEo_Pas=H#{z;ngpilUEb+>NNWg{|?n;lFB(g;(S17Dm{jH954;A8h!g9v%CKg zXV=V{h;xYs_0ao&WT0lfmk6=tUky603 zpY~s|eEj!V9esdQ+)M!!hy=-+lo=$yJSdqBEN3mN`M}{9f)G2r?@}Lm@F_D`*XbiT zA!wI9b*&j~)d^u7Am*d}79j*W%aVj+Nbs@`v`b4-s*M{wsT`}hWi-ifHV!<3NN*%Q zYNUj&6O1OB5F#dy$@7v_<&{80XNtTO_&!`)3phEdr;_UpDZsdC1n}7>w}l9wer|!a zf!$l*NN^pdyBjHze*@5&px%BJd2>4lAOCrXYr1sATfe63C;#dKA*6hMZOqp9)J#jt zaY=i$K;;?Ud88CqdX`Zkak66-vs?GVvZ77}AT>iRAKuA<>TaokW4I2kp2 zz)MeV(-O{%S_Gccw|xmm7v6z4`vVLblA8^lQ@4HxySIHex;Vpzdllml$tLto3c2Zy zRa%l|=|@OGHOk0x$zp#-L=s#;N=05bY~A!l99?)j2^maE#0g)m^%hc%HU%4NJgbFS z!~H3RTO)b#STNqjjrndDiRdw&Rw$Lgm=Gd_h_#;CQ6#JC)OV-`!shUKvqOuNYC{@1 z*+#ZnSjt)xqF^<*Ly9TzA!(O2o-9k(>BShOHSNk$R2px3x@8YBP!x%wl&L2T^q+F| zlpA#ccW@1PWL#Nt=@{>v*9t;k*NDa zauy;|2*NP!z4M7utt0`+>%o%6WM#*@e}|(Bze@-w*c59>S2rLO)*Jz0Q<$;ln8_Ok zdbb}u5)3){5b&*LmJlP;of0YK3G0x~qoiOt7eulo%uz`c8P2qHOGCGE%x8|WR-gn$ zp*G(IE?ED48kYEh+4bW>yD?K zI~&N$V`kBS zfTNTqhMc0(7!y-hJP_K0WC4@jK!NH^NNGa8jd&}X@Q$Z*ZFxE5I48lL@ z0@hf32q{mOQZn8yH;Xh#DTYWtRUBOuSQDAgJU$4V35<6tI$M!d8fR8SH$y2w-=^6+ zp5{Yu$}#WUhMdtfCocrcg=gnXg%pD5WiHyh001BWNklf|4}j#S#Clw|wnm-E;?{}QP*S)KwO z>r=T@#*~i57%`ovUma3!y_BtUZ{hI=ehw*AGQESDjXqVrHgM@+;&h&fn8Zj{B)**( z`ZACy@()ARaqVUx&2G~r!8?|~h`dGxORycGOX~%6tsgAjKr>q#U;#pxv_~0}t(?AdDO-wy5Cw}PM^#DsHjw24 zk4Ed%H_>;2akE4KrV9x$3Shk_BG7q`DyAvEdZGzfJu3w`w|AxhrYE;eDvOeVqMA@o z&oRIJA&N2^ShgupK_(w7<$>oJ|9?;WlmSi{7Ds6m=_B(TMFiOH)oNzqhDoq>?7drDVr z3>F`ALWs00Pc}`|F;Q%h=Ob*)L0p&nvHz?TfV60Gv;HFj zbw03H25pnVk~cY7E)!nP8uCmgy<6F#4Ll;GN?JcmV<83{z=L%O&kZ!958tA zBAdFBhj^VBHxlW4N8g?xZv^mb>KG9pl9{h+O(dnCsrPW*C?W_*+Ew83$2un4W$I4O zMo1Hh!D3fO=;A146E0wFBr6q*BTF-uMAi#MR0L78S~{jX#gKLivMjlV#mq6DDqGa^;IzK-#e27TJ22HcZ4VEA&jZ~lpVMLK`E-6YNcrln}juUH+ zfg{s9+SR}i@@qtI9qkXXgdEN}GM07x{L&+6 zu^6(7fYOq_br|odMhX5VMgj#wHngii)o5ab*`c9s1m0V`&(K9e_PS0WvJpYnI61OT?u3DL6W#t`!r&rSlgrJ?k{^2~eVv$)7G3Jt26M2C3wb z_KD$jFzd#%USKy4Od3D%@^Vrx|I449L7f=z`Xa81F~~0oO0M^61BD$`)&nn>|z} zHx|Zro+2Okk3J&vF`!s2995mxH&`v)U--@Tcu5 zn-b^1bdfxlsfd>Us)r-_r^AMxfv)?Bi^}nd8Nlg=AB5P0v;gKubc+fDII9kkk!(pbZhA9jUf<8)wi|6q%10~QDoNDqts6r2`=^99bIWLtw#(Oy}6>{m}`aa zT@r}t2R6+>4-e5}dLW8~y?2K!9={(gS^|>!%u-LYRP2hWs8d&p`H>+nCC(3Ur7V(* z@R2M_vCnE5sm2AWI>l^RP>(8vQ20O!Zl#8y-@v)VVX#ACt!ooEKq)Xr5XeAk+AyYf zPZZ^BvG~KM6Yh;zfF}S6t2Xl3MaOuo)58|W0ilq|0tgbIlWtxPW;j*q*2}i626Rk_ zWDVBiq#m!+y)|HSydeq54^*sf<*sEr1-&@K%PSkeh36Jjt)YqljMr!!8!sKTv^0nHIl3EdA?Zw>C*}KMl8VL zwHrcAz(d~;Rh9K(i$ne^H%Q!Z@V9Q=3PU<)Oc*qK2qd}lPReXGDl?)MLgg7!YgVh6NU{;yRiv)f#u_F(L?>Kd z3cA))S1!dV1JL7aYFLfPfj5xu^~x+>uN>@vd!J6YH(~(}hDW)n;P_#-+JPY(y&sbD zVMi%9T`^)Efys5ym7vvbHocY zUA`_G=s9Z-Uy$(Rt+k+R7{HmBQjp*cM8$ehCMo5n=AJY=ap;BCq( z`nE@?oXPYQBKG+H0MkcC(*$riCs27#3=tP<(8*;i4-DJ86+*2So|bg2r)qSflbfNo zAOwq(p&U2Kj0@;m%czk!mr<6H5K?t9uOuRZ?E=Ar$N~p*f%TxSaptqd z;#Y4(0iHGnIDhey0cIz+bv|3m0f;zbH~e%M6o52~1xdq~b3^c9;K&W!de3II#t`u~ zZmMRcOVPPMQPf$3M#;Lw!QBkDW0?7e`!?b6B6ak7+talkV3noOS(={HCdv+4?aE$NfZ+2l6CYhA&<*N%Jr>H zLG1dP(}EQST{H-WjEkh7!$~HxxqAMM~SqWDZv95xSs#NbpFDn-+N9J zU>H}SNuA5FUXo=g;`h!EHT<+{2VxE0tWBj$rpre9-ltx;xTZxV7`1Q1U?CXR;A692 zQmXa&7$T;)i7ix?8Yfl@i#48lTp^VrddqTdF-B2O$0>(4p5?p;JoQ+klmmKJvjw(a zqE(N#9nm{N%+Q%mM9|iwg-QP254o>Ube*86a@M^;j;b1P{*ZjPQiA0oP}eDP zN972W6R64Z^(r695@`j-4s{D)G51te5>*I-c9qss)(RfozitWmkLJszxe>wMXf^Nx zCmKRR6d14B%4}Lz#b!ghRI2E$eQF4i)zTpcfT(Me8;}Elw}xizn%iEe4QjW}_Y()7 zVXa+>^ALp^(uuS}ryvzZLV(?y>Xb_hSj>7Nn%*c>Z&8^b(}I2(m~4*_F`)(4Kv8PC zl})AR;0G$VMkv8*>1eiUyxv0OQ(PyhcOv)|%f+1Cy=-uGg2g=1yVn55(G^ECl5|}p zFOuM8HX5!yAgd8F8i+j*=~_oM8DX7fybaMV@s4y|2>K3u$fzp8<3~N0XZm{P|Np*0 zx!$k^_|UZ*j!c7+j&8Y63{!0HHUbSHksb+2af29^sj*Iwl{GS-60@7gCg&2c;~mlUX%S1kOS5|pRqo(rgZGlI4V1Oq z06-x`bS4w5JDwo(2{ER{u!Js%C<0lkO{k10M`U@0_n>4!6eIE?xfdZ6hli=Nsj4&& zToTta{}<0+xb&OPsREq8aPg||tq}qq@6)m*hZpW4Z(cy(rVg2YWmzryM8g^`ZoL{- zrUiMS249|{*$^T~jZ`IpocWPWwSkkqA26=Oi!!awC5OV0D3~1>bgt-HkIXbt6m*@( z`H1zBW?H63&#cCW4C6AgvOtt)5XClKm(adQPCnX2WFt)6W^(2nBAd_~jVj8`mrbk| zmOPIHx1{eaWnJOL2%#q!cBm%P#3g_s;FBzu&}?m|Rn0?Mdsqlf6axVz8dNqWiUdaW zolA5yq3DgKo^B(vFH!H$YSBCx2A-CF~GBtvQk)IC&J{? zQjZcXJh;emW>A^L_MT>|L@G_&dKR-pv+jDRMm4HDg^-%Ijb!DV=F}cSJibR^9lsC%NC_#0-MGeMCjT;-6Un0%~C8>H<}OKyQH`B2^Qe| zg^NFZqr!hC3h;3fB)q`_e3V?6)j*_gCFXENHEm8fZz!uIkfAt=bDpCsJuonzP zLU1d*ix?9jdZP2RD?!zyh855_HRaR`zu2GLV~WZ$?7Rl);OmiI{bQ}NncToCLl5(rGF|P6Xh7=GRmq#$SnDAos-v7^6?8$ zm^iYf)CZ41??09mkTE6QffXq@wx z4>|hlP(5dh#g9GHZx_4ag(8P<-@fXLojRXUu0F`~o_`a&FL)If@B4kSvPje}Ro`$Tdi7^E)!AB1EElrcsf}<;rt9cqgbvIY$Sc@pgsO1<0J` zTrk>hXjhRuPY<$dBh9F!D0A9n;MCcjlwYe1V=}7o7@1Y*qQW~z+j`2nr0qxz8bQ!^ zlB(9YZk4_%MC6opjZ|rA7NsCKgVZ^W38U#2DlchQie_Apl{=`cq3Z%VFYzIxtQA5^ zq{@+UD4r>u;A?L|q&16TRP=pB>WcB{b7Z4ETo^N&)+`p1zU`?>u)*{D@4j+9-~ZtK z4?psq#@bJg0*pt^vdHtdUc0@u89VMhe9l+?1Rwj;pQaiqgp#-cAMXvctJL>yV?$Zz z5Cu}EuTE>~L?G!}Pc@#Pv_=lh+PX=LDYVOw-pj|dt)!lgK#efIrkYGakMOaetSgKy z8SR`RZ%&a_Q}SwuVzi4Yrj$*A>yI#Pmlk}M*|0SI7$0hMQKRx2p$oeC96?W3ju5KG z`5dJIl_8|2TRG}cK_nxqw;As|50#Gy-m#n;>PZbUBQJ+?TBL(P< zedzSg_E!VD>uo~7tk0?9C2qUz77ztj9{CV?mEpW5X1mxpLS$pS*9cXTWhnz#&eO^l zc@c?G(sr6=l5qOP%u&^ek=yrB)HS-^!G;mK9HH}^u1geZWCCNV@tCaH!^>Toozv)I zLSBsVA*U!4!$*XD1fCEJs_8byk13lHp>nL13D6M=Av1bkp;eD<7Z@uks}hw}LkUd;r&~EDTMfG2L5Pgie1^yxP!&~OAYvexSxWnmn@Xm0sU1!V5V}TG=crG;kY>6= zR@MY^e9T!c1Gb&f>_oJ=^a@XF})|t1ww>Pwvw!rz^-O=i#g?JO0)e!%F!wMK6T?1&1uTX8LH71QWYRI z%T`i06`;{t65N6qJjZ>}0v{w1g;Y7kc#rzjZA3LeXE|kEC2GAD^qs?+mfT{c_3KV)4C?UcB^-g1=|1006zQA3nXa{gs@w0zhvSmoHx6wXc0Sr=I^x?tkyU zqnMsXa9JpdMBlkdbRPQ1JJ~wB zi^#TEElGR;8|YVUDzFUg+^L03q4EM7$Ba(jjI7Qg%Uyaup{fg3tB6(}DFOtCk0a`F zjgmQ8SwnOfBdJGI%4!TkvYfAQ{o|>|t{RHb*8kVtnFm>Rm52Rz?)vU~_r2binVvy2 z8i7Wj1(1-fG6XQT3sc6Vu%dFHoVd!EN+pgBaXD2aEQyl>l28@mK#EknkYce>9IzEY z0tu%q5T=J=mB6Y{@GBU039KSc(I<&owAasITFP5!ISxXY zI0X-P_z<=AWoj#H*sg;xOqEimi%G>Xrt9NY_TrYuG3+9yzu5*BI&HB z`Hr16mOv@rM1}F}WAxsz39mFn< zAdND@a!Haj|1Yh%Cxk&FO@wJ-+77X_a9jsLf?XWNEDTYvbr{~WpF(*LcA-cpZE7oL z2|F#~L=}jzErHH?Ff13hJdRTwNpk>IQEJmPaEleZ@`%y_giwJawGQixXNj827$V}K z?>tMrd8yKu!hd_=JvghD=-NnllIJ4x#yi9qETzG zc;+}54$Y>dShBjYgT%y9h_GA?!$eBeQ%6dH=~PG(T?bE4toWFA8OyDx#U$E9__&^r zX%!H{!?GO^CbilcOLM0wluB6seuOiE1cmC0#)n05h?_Kq_Q6R@z{ z66N8&xTQgaVG^_>3`23PmHBCc`VtWGH{W}fwe@B{GG5ww(3^z^v+6u0yVMMLb zSTFmfIoEOCo&8-1Sgtu(M#RkDeVI4D>t8WHx5Dz-7b%tu#qxA`un@Fb241;D7zzr- z0>V(u8BC{05ZaignO4YBC1#_@#3>FSg-6(4M+h(r1B8)57`9klnx)?8;8gZv`+JEJ zN9Fv*q$-$Fz7P(EUBvN9SdMb$AS~k8P{|ik#ViULk%X;o2z#hJoIxibY_F*1Q5aZ` zMKms z!ou-fWmg*(5`!Reu}h;^mcU38A(ggl(hh74)4_2~m83yJr=8#yOu|57yJ}@oSU$pZ z)N-mYh++%JQHoR;sQCFXR0}AeDtsVRY=WI~1Pzg1c9p6|ff1`71`>gg39VMF?$uDC z*-|E|!Pa>eMIy260-isNX&2I(L~2Xom{u!f>Fg<%&K!dzWNmGYNB{3L zDn+bM)u(E`{=pYcp8E9F;7-F;5kR?AD&KO`jgQl#aJ1*dyl(#mUVZZ|y!pP5@#X*e z`}hMc!{b8~D;|g$2Jv1RK9HF(RyRS^Kd)WrB}rzR&JCYM4kB^2G5SB)<7`q$pg z&%FJ&dE|jVp}KaK;mJ|P_8*`yxKCvS83hp5#p9Zd1h1$=R{(G%1EwAN_I&33vRxM~6bIDF{feHGvTO8$2#l{h#!u)?9K z0q*&w_cAzfkgxv9zoRrX#rTbf85kMFEx6bP7sGUrm;@bF4GW|y$%;c98)=zVT_3<8 z2nAlzRy6=)RW(!y6^jolK+`a-lv|icsiJBMo=0V17{g2pI3Y;lSh3{<3?Z=`RU62% zY}|r}X{aKOTvTG!t81yoPHDOdaiWqoNxyg6O%~>6XgAxeEiW;D>~WS)KSR)3CyDB; zMJ0|-Hwl7ZE98In=!xmyt2G+&W;<9q>96ogL0~O!@&;2ek?l&2+E^zqOxAN9s z`yC$m!l&?t_T!X>DR?$+!BH*QOo441cmtC-UKwFIgdwTiRcYli3W#Ds7#b-7SO~+$ zvX$nZNY#*82(=I+(rB7k3Jk-fGB}LuD(ze^^$MY^4nwH+a0beha~zw3>!eH3iomji zCer!^06`eh)1CGS+3Z+NbPEa?0ijPl_F-@cB+M^ z$TN&Caxc1CQv$FoT-(Al4Ar_N4etik^36!?eT0gI3Boiz4Txe%5GI^Hb%N#dXIMP* zEOW{N8ccF%F>N?mKS#7r-akq&{6Dl|lCE z+iv9zciqX!pFD;P)+i5-QXU#*WZzA=MZcSIb}@!thlPuj6&u8{krs_s`G?|S0I8Xl zcTJl_VUxt93Z#iw8o+iuB^ofXEC*qlYBka@FV^?-JdaXQRq8SgRjS6whye*iX^?-d z(W2h$5QHH?5E6zV=jUgcKlL07$B*#BQ;&0Q%^^<2R)`09e(wCjug@(kUJ{SFld$6i z0C4!w!FQ#NB!{-zSEWR&Tz|(laUFy4$uaidu#b_EGOlf6ix?vbR7>}yn*pdwuE)qE zLM9Q-)pTXYooD*T5Ax#kFR-|p5X&uR zJg6+J&m285{oz`pv1x&)oq$~-0D!59@f)TlCq4(f{c?}(mS*qD{!-DRXdAeWfny2$ zqDiS>;d?^Gjgt_yB1le&000pTNklyob|Gve zl5^*w(e|nwr=I-xNG#UtC6-o;7`CrcuMYd#Fs5XH=pF6+shjR;ySG=NkHE`9vgSP{< zMx*n>$y1*PK0h@verRfP;x~ae0{5Vr8tf>fNjYTe=O$9H)F?8%r^LjbnDW@`7(4I| z+Km}($Dkef7^bbFeo~Xq9lDWXVT`aHV!9=4Z;1NpIpuJ23z(+h*_kD(9p_?n&o-eA z{N>#Fg?~G@u()Lo|8BxHA%HB*Ei9g#TUh)Ez|_R}AaHnUa^g+E+kivBUQ}hWod=oV z-}F9ifBQXLIQ2DT(jke~iKPo>flentWvm)l{vNE-MB2|l;#T$o(5QvVJ7^fxt2O@L z-#vA)()l*vRJC6J@3ng4&*l~u7kA|uFB7gg0c2rrVQ~#OGPkgJ1o%$?QxoGpD%Rk@ z)a1lI;O6xEepL4hmn#%qNfL4MYu`m>@>Zmb5N46u(sxKig*X<}t076W0`4GYVMHZ} z#xagRf$a@aueC88A0ufagyf-be5+doqd&BPFU*}^_={@2@x99p+um(>NeQ4A%q=X| zfhT|`<`%k>q+BYAieDf zt=@QWZeelLYMn17Tz3S}4{D8utTh^SRKbcl02VIYFBL1dm;F*DU7xrpP7DJ)7Zd|A z2osalg^&wN9l{_ci4zQO468Usarh>N54@4e-~^84GC6eXI|bcu2)VPaS<=ro%a?ZlODVA$cL9H0ZdJdPXZgdoH$||6SmmL9=OQoTFgX@t>#5;ceFavw;p}BsR zndiQSH{jC>ZOqDHDpNnh(AbR(3=C6nlwT@}6Xxb;`Q(RwpBIlEQ|a9o&zQ#hB`i*# zoxQi&YR_?Lrgg8G-_Ksuzgy{6NG}qhyoF76i4b0P1TZx@{(ds6kVyi+a`y#pdCTVk zn11Td!FIvhLsB?QW%N!4#tu@djHNYuC9N>vZy$Yx&wl))bUK}$GCz@W@zmL~_txr- zlWdNBJ;U?J&m**#$Z$~0>K>|M>yC?vmlXj_O-_tfeE(nT?^43S$qskE{Y+V#yQ22&(@7rcIzO7p_+VP-QmMgIjDIK>b-}-X#!uuJeH;Ny?B0 zg&6P)cdT>E&wmntV^2STcf&8@jlLdX4}(yhx(!p%YDY|;oaHNj{70O5@p(+M_t3;~ za_Yp)nR{F9_Bps%{3I*i^GMFV=Q)9Xp3MkI?{5ObsFHo#Dgn10cqs`$vp20Vo2cFd z!*sip$bO$w$XxZm?4bkY(&~FGKDteB&R?N@dF~%)#`7lWm@$8d- zNhDp8j)QBN$T(qjy~F9#XZY>|U*YJFk6dK=I;<=k0NQM|zdb!W`%j`M4!M*Ib12{Kl3e?njy zChN7@|CpJZ|Cp3AD~|H_k%eAjU^~!@uzLMpK-F))YRh1^3BU#>QC-LKEYm<~>-pf( ztlZ49xvc!mK6p4eHu?d9^b!f91A?EsV}SSl?!RGl@2$M}+;^FtIe}4m4b=wBEiH3) z<_u3f@(q^HpH;a5Jr;CSBTKnHJAdvE)@$`2pp>uX7 zIs9|K$CKawkNnyFk8y6@XL)so^Jk}NHL7WTzFOQ-X;_t^No~ z+b*Z~pb;-K-?huOjq1+XNcSnR(R9_v7<5^;CaA3-&oQz@u_IQ%P6ve!q1gUbZqPv# zvb9xEV56wWg8uHIkUs>B3$TU<2k$csQ85ho>-+zRVXw-g-}nrl`tk~EbyPEpBu?}2 zyU7?rsDu&2FtIHQDU*7&-gsoaR(~jt<64jV*8`q?&-?EI*6C{JS|rFGTL`r1&E>X( zlMq-V`sFy zhcW5#TVAOX>9hDKLQPOJyhRu335v+;nQf~@o?Z%|Opm*yo7}AxrWw=`QVdP_1`5D1vTpF1U7x>-n!P<6{q})g2*2*E06lZI0||{YFihwgx%0Vd;CrM;1r3?}&>q(NdrIY~*xmpR+KJ*wh__fUc zy=>_$;w^%Uv{wuu)!64>d_zY$T$spqDRX$3n|@N(V52gQ$ny z&N&_6Ce-Ycs6kmpAxI;wgi;j8QLMB;*Z$XR)H z5%JJPWR?iBgpt(`G{U3Y{#x|ebWOl2DyCU0ff}-wfb8+E?`f^au~!5;#Q_q!4JEeY z?P{a?5Y3dsub^ydZD*fL-|HyFv6AkqXOx!NWqPNhYhuw{pq9RO(sLe9ueTS) zbyiUb(u8KyI~gUv1l;SHvs^1k@7+WZdOrmA(ucAlDP{+kgLl#j7(pdx==1g?guHz9 zfg4e5(#`Cn*=%;UX4$rOyJ~rAp}0lXWYot*z&r}EnvEwY0+>n957Xuz26eb_o4Th;ZpXWw=jA+fb>1@SO)P<5`YaHU~63vd3sxnoM;PJ04}>2iVm`8S(E`m>8-;{_BE_;lUB`E`XnA=z|w z1pR-K+h2>SH54*>+4XvzBJZ8loFvMe*T|f+n*L|z?l(jsZiTL{k%v5S_Zl1B!S(vA z5|%mNUV8fkwqwp{1eEBm3ur~Jka^EW67^dg$;akv`I(KW%M)c@)7Ex<9z?lb}DbM9xOOSKo0HX{fO$geR-N zW(lUB*vsy-YqEX2a4iTxgNq^ppRUJnJ7Qof4f$%Hq1QcZhco2A_hQ@q2sfs?F!Ykb zwIqNnxO7b|&7ym0+*`>}xc1M`i#YR3#+&W0ZTah>RLo070KGsHK=xgO4hM7D$kMkf z%XbpCLVDh}KxY3MO5R^La6J*gc0i!a!mRn1jgZ}nAoBiua^L%zt-VY@`uwlov(Bdm zFR`re2S05D&krT=($*0h_1P9^j3p$p8QV07*qoM6N<$g7s?itpET3 diff --git a/images/iconLibrary.png b/images/iconLibrary.png index 4c4d8a69491ce879311c9bb83e3d82b526cf57af..07799e119737d8e9354eb52a0a146138dcde0e6b 100644 GIT binary patch literal 5894 zcmV+h7y0OkP)L5>*&1w;@Oub8NbQRB6n z#Q2E@a+!4#QG(fBSJ2JjdL$7OMTM}si3#G0N1{fF5g~|j7z`+v2RDc^3^RSc_iF#B z*FD3f(&tQ1f1#nfU-x^}@As=;RsHH$zYH*r6B9wq1kr>L{v&>{OqWB(_C;lM z-#Qs>xo*jiMlU|n=fvR@;EcJ+iNIWh7?jUKmMIKQ%eGCjeb3cP{%y=5ig1VmoG~}~ z5bzB^6sUY<3W1%J_MVNmFPV1Yk2=47fC9L}pH%3wl_?zd?sc=5{BXqN)a$eYobj7P zS@=B!d-uB8OQxML8C(T8V{T$1QZAxw_In0)QrbJ$p0VUV#w|7gka8|kmWAI_&Ae)L^kTS(V_$r$W={RK% zUr)ss_8U+(|2-L_-2V4$$`+u9Q?>v-9Ie;|C{tX@7NCby?gR92$_miKDK`N!q^S_1OSa-oFeff6?T1v-#;((OuZ7D%I>X?-7XCz0ojIPjy z&_L4=2oRc522FF1xr)&Zl%n)3fRuF9W(kg?o=XSm*h;{Tt)4qJ(y@?^!%)7Eu?MX*hzW^VMs5NAq`%}45*{2Z%EbX zJTYcaEn^OPZ^fn$dFkyBS+uc*U2Phg=~GIfn+RR+qzJ`T1~Kv89o<9&q}xU-bMDwl zq?JV433>%3qZ|E$kV^)T*64`;S)I9TUy;qnX}xQ&CKdAST|s zy=yCglt^hK9S3PAk#-U%8E0^f#sw!-F=jwzPRw|rc>47%Jg{ghyQ3z$H;88Xlp<(G zQ4~Q;oY@r>z^(0W8}3*MoMeoKfXxLbRB_Qsz3EdOD0U&U;;Gl(rBmC!=25{E!UPUNN z*WxoH`_r#B$hT&%A{LW*R{{;!V_L9>;~*^yClSMn?BmqF4o`jmq_Xfk(bQPO1K${h zFS!>hx*wTLAZ;fv@+hDM=v3@?07rJg)Q#9@9m2Y8dzrUtFPg6W1DbB;)K8$P>Cikr z95ut{B%)Z67S11P^1$TLW#NBHrd=_PL17Ck(uz#Rk&c~H`Dl4<@TG&4HcnCr{~P10 znSRBIg#4aD-otLs)Gv*|ihP6}Z$mmsNX0DV;E}&!pgX>IlB%MHr-s5-33zMS?2a@+@Sg`bRJMfY*V=r9+KD+@nYTzk>USdkX& zL?mZ@f!y{1WXDi%WG}(gOGf7I+-2xjU&-J)gZJYRbkmO%+4luSee6f@hJnb<83%r9Hb3oX9aTB2avXnOvbUJ`?=-P=JHT4PnoiSXq;XPX0qD2hBmQ;oU z96vaJ{hogHRSfCn=ly6DX@`)ynU!PE__%E0pBB~ei(^Gw`PSz~XMMiI(b^W_iXYs; zTkr289P)A34PWEDi6^CxPx;ww9)IZ#G>;#xNbz+lt|7^|=0^T-=MVCBos$RE@y?39 z*!~2<@MaZVoP)W5RPB#2s-K6kO?|RF-{G16=cR1?Fp0l@07>caqp3y&{+oy*P{o0n^iZR*3LuWmzHaisJkq?WP4%X$=$ zp5%$O@tyNVWp%EPL+BpNP%UP#8l;2niFF(k8fKshPq-cOm6*%`r%K4RuqUk0= z&tD&C*s%>b@d%EUK-xBF4w?G&vK$3CAXO+=uYkkY=6+fJv?Fu*XU8(^*g8N`5%BQu zU;k|S*s$aJap{>SxUX{Q*U0QKwy6)7o|V5LaKDCXf~G{;32-dZ%is#`2S~;8C8C@; zvM!t7^odjieLV4BSMmB=TWCJEfr^0lfa5>??ge~(^9QuWtb#?<9*zp1K~w+yM=v+^ ztK`i+DUYB78K!#9Y7`(PZdg~0iznpI{C8&Tup^H!nvbb3NEx~U{c1w2-qqHj0Av<2 zmPIE}c9{QQ&${_tfxfjtq_fv;0vtq!a?HF5aGgJn6=zISb!O)%lQF4K`m_abWJV)_ zj5~o+I!GspOvX8RaDLnWGKbPwU!_(=OWS>?(4D|k2QV3 zV}q7icP_&|fCOo$*Y7nS+mO-4%VdL_AK`#0;iD(B96=JKBaya6?{NMSFC5JDdmdr- z;|rNEs+sBk@)eFB(&2M|>`#lBasT7ACqNkPD%*mh`a~h0#x)n6&h=McT!2fa@+FXQ zUp_kv;8^snD@-zm$DUiv|2(?_Z%sc|zTe8N4?Mx|?@<2stvmNH^`6J@glh3uhLtNg zM=^6pgJWAH6H$KsA9GbUlZQb<|9kR>H0%Y*TRKg`INuTP%gm-WIU>}}P z4MwmEq-4X+w)C;ByFbDctifB^3nN&KZu*Mg3{tC`?RW&u@bLEgyYs35+ji|m2u*eT zQ`5T{kdXzDsTcrh)3-L1(S?teE6$t1?-p$!Cj3b0aLu_LvyS6W9Ln*78+o@yLpQx> z9&d4)0Cz|hs0?%2IVb1$azY$5<5^G(AXO$VJLQGSKm8hNSn!i;Sg`ml#tv&_Y;)rQ z#~-=nDi$n$oA#tonKp_L4Dbi5Sp8i5;C5= z%zP9;r?jeN3d*)!AJP`L@rMl+_mJ)j9K9?InMo(m{nG_ApY{k|UA;l2k1^CrVI{!= zJA%}stO3Pf*_-d68D4~D9@qqAK<3lI0uX|2ds;L5ewmDU?XAsdW)+%lxEac!;KM*6 zB|-?ce^59Dc<$w8JoNiNGGWXJzWL<~2!}eHP;1t|%U!eQvp<^X$kbh6q;v=eyiB^{ zJSLnpJTKQ+yKyr+_Qvqnc~vJ+UAYLZV4-s6?~lbk`QtfY>8iDSd&Yz4-T*7!S;V$I zt=xUnWI%T zSER`xwKyi({t=HaT+a8eJU{1GS@`;TbYBg+JKrG$Sq;TAvjC|LF*FUK>1^A*mwpZT zjS8ADdKmXVyBgge0>|Ov)0)%Ah7UfL>gp=uW&p!qQJl#jsa(NA*Kw>kmw)b*oL}P4 zi&wH^Uz|XLU!|T`($DIgnQs{*1w!a(x>*nfIOW74{OX3wdE|vR8Q0v%Rp)oi1ylt6 zJTl`N?t5xE5!*x<9*QzXl@38O%vaAkGcWgJ&J!N+pZXvmS|M+y@XT3!s}U zTk|gCMjV$_K|T%VjBVzevCW4));ypOzx>w=^InExv2@j1map4Rpy4=lkFUf0XKw*A zJ%K=II+||q`deGGDnyx2<`)k?gW;<{_XgZ8XxwnlEEOR0l|ilr&~%gK>vyofJ(^WP z${d-ctJbo7{dSCiQUJ{`I<^1VJu=P@p!`4@n&Ck=ef)Xp>O$X_9>Z<-&&Lc@WB4mo z`!96V*gyM6R%-*50+{ID01N(FR)Bmk`?2TQu%it#ScU1YKr>B*)_L+LTMLjeYVSOu zo9G@t%Qx=gtxa1pKV6wa*t+urX8!&K%uscQe?v3KfhHD{6>``ch8y6iVeFk zL)EJD=WZ&c$lmmKGyz#^kU&Gz4Rmh+!yo3RU;KgnZIJ@rs?y{6mzQzxqc7qK)#3?M zVR!`$;Wqs*GEGOiF(Z>(Y#U)CX=U;w}Z{2bqaV>;5T#qMIi{T4( zn(@o40(^CPu1+R26(bnUdsJ(#;6n#aw*nuqXLE8$nv zqWeN_ufG5rM~L-|!-IokC1$>x~n?GCikf6ezRh28(E#j?fMEx5t?Gr@yj!%T|UD zIhJrm&)qZVp+}$QdozB`mc2=QmA&wU>+uAuFnmFD!&5Nf1BmfId@8pVAcY$t5|I|H$UZJT=VYc#x`M_&Jtw)u(iLwq<;VB2qa}tJtWx9rP>pKuO+T7Z znEiq~lRpIjKy4T2SV^^URID8<+DbCoiWP0einY<)zn)V@4(0qa$1%L=xC0`6ONDt) zFXZQQ9%uXB2&TURBT$JMsKN|Xy24Lw9iQJ0-{BDBr#_iS1yH0jTGxnIx|Ow9v;H0CJ@XRtpZ^;X zOJI0I7=bW`FNEQ*P|?e#&+X}Jc^l_{5(U{fQV4-C45Y3jbRFH}!|{bMtprXYik*z% zBx5*Mf{&~ud$zRm#(S%A>|{C>TIa`vQO!u{(AcY%#y<5RCBugfOs9}9h9%j$V>f?W z@g_@Gy~VQC>)F0%zjBZJY6?p4#P}PZDDaityf%)5 zbSxa#GB|cpr9HEfIF8*RcsqHB0(3l5%Hd`#ksZ%*Y@~D;KeCyMfQK1VCgt3Mw6?W# z*8`6-|Jfz9CG2!?jOOtv|GmeD;SDOGn_e{Cqr$m#y(s4XaES3Y{$Fua52^l2N3Ak; z-2dIqV=4nyTEMPwQ=dCP5u{3$mU^Ck-?nk=Bu+BM(8d~`o%55Nm440oclf98-AcsP zF#KV3uU`q@@S>Ssm8rz=C=+jZR1l}ubp)THNZZG|2;4k30(6~pvWZj*noeO)2Ru(H zN2k})Nxhd+9Cz1JD~TO%XXCED>~D`y5j=FKk)x%xt(_ZxGK;t#z!z4*8oJk=vC|DS z-B2}M(^dPfX$J|ui1+*;GG7;vQ-u4k=y)mQf%QZ}dMSG+MUk#0am~pgiXv?b%k+Z- zYd3A>lpG{(nmp|eHtg7sx3ZyQ7-zVPQG}LWv)|Fai>@T|11PQqI2uG}1?i|shZxg? z6h+z=AhCS`RU5Np%5C?uV#5x+mA#bk17UZehVIUVxP?8qP+gS#?Hyc14zMJeo?gP1 z?NIBnKfc71FaI5HWiPy;8ccr}&G4aVoji9k{ZF@``&fXCNi_)$<3?m2pYYf-e_`4$ zeuppIfTyAsBM^3b_BvT*XecrzX#qNLM-;Zj*`o$#e3p4nzsR(^9>!PI2T!O5(-%@c z`&5)pH@=4%bYuUN@I4iE zc-=sabZE8^-L9wqag?M5kkY}i6WECew@$k3sJ?ssj9;?grIq-qdgH06=@7o@DXE&D zq695~boVlh@y*YVqHlfGr}|cFTRW4c{*;yLci^k)g(q08eEc3aP@}|Zeu|Q_0LuNF zU{J3B-@WYgPxYOpD^@f4raOp9FW$;}SNIj^rcX`TmSD|KQBtFTl;87`n)O@eKCuupScNZKhbLIwDJs{UuP=e#{*fph3y_LIOvae4%DU%GrX zQ*N8d&X$;()CpFp_C6JlpU%MpC3BAsLy7bOIySMK{P~ewbjArs{N&c{ySU}92Y7Mm zn;3yGzRF&hfiQ-z0>hVDg6;bDOR&v9m=dr6Zs4h%;DWIO`1U2I9`;jPx9{Z6`yb)) z=a*mxD)Cjhf=|Wg8QxA&x$3+(%70FbT>#-1!$To z$G*_WcDJokq1*QX5W-z+;74dW(y>(H5;qD+=%%|qQST)9(sk?{E#2G#xT4f_bRp0* zgY-UzA{ChF3OyC8*8_%jM}r}J;i!!5E6fJKc|r+TQ+p>!H%)xHY0rLl&5}jR76V^+ zos71W-j0j%kSAphMmq0l!e4b=vCC1WNJx2|kWw+w##dErC$?)8(3S*kLHLjG*otZRP+ofH64O0cf1 z1f|XFWwWlGoO&S+-v0g6oB#4td(Xyc<>sK|kRWbf_JFGSDGpHpfKz8Io+#V)%yssa zJBB5J5SxIjm(99%@gau}rvNEVoxW(IjI_*@iS_}q{liZeU0J4UAVdp@_YmT`WwX9} ch~QKFKbsj5{s$*w3IG5A07*qoM6N<$g1~i%bpQYW literal 26640 zcmV*$KsmpOP)ihrygy*dQ zo{IcjCjEk3HuFosOM&E5eJ&8-`yfdm$q?0i(%}|{>eKWT7U~gvac)=+1K*lo%HIt< zGM_Khp2^?zT;TaEfOF{hQ0r^8wFG0pv1ic|KnV z047F1TOhGLG_-7Y+fO2EIMNl>gFvzVOI1{hOaDJTC=s<&JHky$7GLCq{>V zK5m*{0o3*Pf*>H*-_QT^{y!pYKZ3XXMM6=H!1M7Ok9x7r@^p#9Oqq_{CWdz1h}T%g zF8!Dw5Y$$i;Q8!38|7O^I-bfBJQ)G7AGmXVDgVuC-8%Ao@*AF)0+<*b)`1tVksn%r z-Sd0~1_$}OPrM&*>96p;3J7S{YLw;{sTQhO+ zrOB_+s?Jg?)cEXoLrg8}G+hZHBm&WP7{yN>HUXTf*6V*;t6QI+&lif%!f-q-D9`l? z{GVWCpnrQv*S`rw)?f2|k2k;djr`FEewEh32WeLFxXlKog(X&}7IB*nR@p`bJ{zum z5yN}_6R!0DAv1zz^rA-x2qy-Krp7R02^1yIhVC*~jx^XYXcLbFlfG^zD2twS~_Tjwgv_UyQ7nG>YG+S-c-v zOJH>DAklXVs%qi4@)(LkPqf9Bt}3Z;OHyQLxGI_~kR?GNBm$&$DJZnVP6N1dO$cMa zLd~)ko}*#=iFjTKAQp{gHjRyZ8yJJOISz*nKJyQsV|=86Rk)qn(ljemvs72g_^yu# z1l8pREz2W4zLU)O4JgV9G$TYj_d4v_AzIY~1ip(^T%x{o5Wjg6Ns&knzlqMl%hB{A z&DtsmBtx|5(d%r;v_Ms8dI|}{C9b(NJ*B-&oEHOt4(y7X<}c^6nO(pVu;93^|6GjW zlkvRq0bu$vx6atni7 zd+6J74Ft=ClUGw){3>pv3PKS09)Sq(9S7fakYpJ>5+&Yq3(?GNc&$9uh3`;ZI>z*4 z`zS4};5j}*F^DHs0>|g%oXUfs03-qERX1wOp#p6#~zvUTRXWxM&Lz{|{iZrc+0t_Oi2@Y`8NU~T$H$g+eatN2cfTHz?w#m8w? z&R|6AbY>-*wJN?BqHAaeUelpZoyE|R7h6$H1SpaOAzdFybtbO^4%IAc`PmxdpIQN2 zxntX3hIIYi&?bL;<0d}x;ol+EC1b7JMS1pHSgWfjs!Dyeis!gADlICjZSn^vOm@8d z?bMdOkD_|Wii+v*<}(`eu}Tga+{s%gkd7f2>fPN$V3G5wwYyFU${1>x6S&7=Z7$t%dLTRF`W+k`X{ck}O({DWd(ul%JSn zTdWY2+yTk<6$v=B_uvzM`^=B>dHkDo^5+7%Z2Gr>cfvaP1N_Mc-bON7Ml%wWr@u_2 zSi*H20^g&)Qp0XI*bNWYg^83?q5e1(pY*n(X>h9q~Qg?sQ_8{a9T zg%j-%Ffh^09MAC-A=YPi``iLwaK4XZ4WfO35S)u51Q2*WK@cEG?f2@d7U5V3 z!_+at0-+k@c3w*&J0yFk5;MpD`5J*Bo zR%HAjKmhfUMYJPC&5F^GH?p)WA)CF(Y8c?~{8Hgd&&ohwfS(!xOpFe{JZ_qQ2`E7j zFgP^C8{Y6*x;k8v+1-?9K2M{#g4=B2Hf>zn!zxlEYA?QReaY$2+{5V@D%iD50V_lS~*0d`#S1{<7*zibWx1tyZ%Kc9xm=A zf_8}NuO;|`Kp?9UzSp)SiXzddc^tZb1+{ZC)lwPRvzT19aqT9+WX-aw&*T_C6@DrN zFfls3D{h)!0E{3A=pPv1&2N1Ry}1}qgjK3ymFg(EN_DwP(`qMB(nH-O z(h1D;ODN6Ui4ZQ5+@5_x2%JWfwwV?Lu7@Pc_>N6Dxe2?Tr%^mZJoiGH15cucGmn5m}2Lxc4Ap!w2ry5ilr&e{*WEV%#IkpraMDRJF z@GK7bIXveAh()6#anrmLh>IYgufLzSzvDOP@9$>QxJGsElhg`}RPrm-SF41g2Gv4^ zR?Q~x0-~L9ItPL2|N$q_3>=~0@E+rkAtA?5Q_G)(0*Saf;QppdqLm@L=pxf2spa0 zL__LF4aW#+0aZWDNq>ZTwfvEVeBr%3M_fFo0*FPU=}luJ-vb7P5Tw!>-uCuiXP~c# z@gbk;{AZ};7pN6hXjU!4@d$zE)2i9D8ZOaJlia2>;lwUHdlkEO2H^(~v_mz!Zs9pL zK_F0d4LuSj@Ewef%cNbO<>R_cKxyE1n0;VB3L88 zO}y{=_`Wz-fC@aHSSpI|`kdOo!b-CbBauN3#h7#ZC?>C9e){Ye_a1!Ww`q4J-}PK@ z@SNoV)`~m#09)2yd(ZoRkD=il16d0z|9NVK1!{!?jdC4T)6gS2)s-5Re$UgwP0DRx)cYp79*}7$z zu1-N^=F>z{ucco45mxyWzAuP&hG|xtl$UC>8iMgXS@cL6qhl+@v)^cU?07bw;}ZA* z2+{V<*ZKo}*C*1oo66iHc+Pq{w}BAgITlW1q3s*E{@Ul(ZUpV(?gh3o@CA~5K|Wu! zWBwozc#cmZ9b z--klF{?_&98#is?ci;7P;&FrO>_=!+R>&X!0jpDw;MoC&X&}oog{dNy6^D^sY2ukQ z;p9##GvCE&x)20-cDszbPC6nu7oiDXV6C1d@XmYl7lv~p5NjbL1m5}2twUO4yX_20 zNEal7d@sQF0zAhj-fhyX+8lY@r|fhQ?#vO1ci?I%vcuz?$d@^D_(ANJ8;L~XZ_j13 zS=tf6$}>0OKN-)u4=^!0{Ht-(eCPUe&vkkI>u)0zPEeWq2(8)*rP&!8r96)1fdqO) zr?yg~veKfnH%h!ahLPAzZSg)@mJK4HRcipO&Fu5+3EGaEYujt3-)|GRbf!ep z3fOw%AhGl?PCZYnT02Mn`g(nCX0I&)>!F+QMLRlZA9l{1x5NE4VO&_>x!A`$7t+a! ze6CGg(NuiT$7wpm(wZ68?~h`<5UmRweipK>?Xy@2WZuucGzWml$RSUFW6l6qG6K#8>km%@mz;i)xvWw zo+Q54Zp~aLc)fgkE{+e*$MbDrv}^tA*5lmran3Jjulc^?g9M7Ew6l7u0+K|t+9aNi zAp)2@9#Cz>@Z|`R&K!Pxh_2D?6s$UZogN#u>>-^_6OP8HIVy^xF*|jZp@>B|rqH3b zh8<&KpNT}|BG&YDgXU_|ATt|pQ+7%g-G|$ zAqm0i*}G^~+o@X5@v$2oD~mRpuga1h--flagzq{u%TMmIUW?5E&-L(JkHGcYvAOH7 z5g(jS-3oDTNmz$;L7FcJ&PNWe?GXe4veGX1%Bq4S%QPx$ONcIw=6T3)ddXSV5-RT}O=?oJSLqsAvOL?F9SqDW2lLjyCnL?JtZ%&L3 zU-66*vxa9h42(siiA`f8{{jp^oBW$zcnkmI1AmNNJwRpdi`142sL@j_pZ*c6QwIrx z^?~;(%(v*w7!2;(Om$%a&#|ydHMDR7Ndn(#3t`=xmkHe@!HpiU<_urveJAVVpq2NR1Irj}YtMLe;V82)kT< z-Oa>1dI?412-!haWL(D~9#v3P4c!Q_VOJm1Cl*O0TBvf1PQ%s$Vg5xd8olwE?hty$ zmVj6^s%#n?`6_TNfFA^G-n@km{nba&WO>Uch9%UpPu6CJsW8GQFPU#S*x*HQ#jp95g-jZj&oq(MOwA?#tz@9a`wSLrZ{ys0=eC-v+n3!c*%#0V*Rx|{d#g}{g?|N0)f-=aM#Fh zA0kjx1&MZz-)*``k|1PuQ(cvrpM|EaVWc+@&TOQ6WDAjWipt77qa*zwn{*^Q@jM?@ zQE4`toIQ1vmBT+mJNXcMMv~};juiMbN<~&G5~oBTZg7s4(PxUEbvz>im>3=YmAGmC z5kL^YrqOOb`l&Ayi6*Gd{{z*f{Zy6;1a7---mJC=-1f}N&o)prnJriMliT)sYKsry zwR}9srQK;Iv3mA<7nNeg+L|q0RGVLayq?Q{icMVWM+tFm-G_6Q9!Zi=)bAbQCKFflrO{aRCp8wjM4UV{&P^skA; zvpDsGl%~E$HNUdv!3&zT7M|%?I3xUM=t}KIBzLDhsqoT?liS zuAxo%VH4k)V{B{~Hwa^d6R4pG;ZO+QZBlF4oY;R4$9{Ydot*~po&oB0AJ1B4dU6#n zk)j&g(oSQqA(zeEmdm6sfBLNaWL#1K#G+9>Zkm4sM1>&K6>jl6Z@H07{}uwTOyT&S zQJP!8ZQ6jqwp{FngYO2^N)F9N!1#_dTVDF-6i$AVdZ|pSYMsBB&r_Ifac<^be4Q60 zX{|VOzK8GPdj9$KqTLyM@lGvOQ;=i{r|BZeg4EcJ)bb}-TnJcQmFXD1oFLp!XKolj znxK?F!p#Q$XJ z=mBi2y_P#ohw4fl*A7@+Y*H<`Y}nPsuGf5y{E<&lSzKthVzX9^xhR3NUYB31zYD3| znp>pAo_wi=-7M49?IMJ5h2UIkc-%BUJ~2A{%a@X?bzCw5LJR=Gi=Vo_VQC@$0pe8JR-I>lv&!A(ha|Kgo2JaGqw(+BarHJ6?9 zS-T6pdT2Xo=Vx_0RqOlhX3X;yz4iAlwh|%`IJVbr^t`}$tcQHQ8(_p#Qe!WoUOI!N zUq!JTrepjDBI$9$$sS}g&gALC?Add9I{_uDBzs1Yg^lOBctXZ$RXF_h4`38elj!bX zsnLTGlJPx(AMU1V4&sN?l$Yn(dHDdk(PDg~WJIH6E*M@TZknICa>up@bD8wurQ!@O zVICl6MsEX>fq<>aBIEs0w!Q4X<2KH+aNsXcG@WFx(JsHbK5nzc)Zt~8^Dg6C;#~gf zzoI;UKa+cJN0L>HsQwc+SGFBC#D!kJSlbMGp=a3k_}Aof!RMuR%eUkIn-#xEB0;kM zTB^&3sQTMkS++=yUrVfS2R<5s9Ab9%G~2gMU>F8SGRdA%G+E%eK9XusFBNE=`Ws4z z?nBcJhz;Xb1YHT4m4<;Ej-#bgEKD8Yva7pr?GpX{8z`4&h;`UVvO&XA5dstV+Wb=f z&#HCnlD3XrG6BR*^A!Lw-Q&u>Rrb8@{Rr^e z$>91o{yvHdN51_h*iC^fxv08|s<*#eoU6^ZXR*Y2bAHY;JS8s9@wc;k?b7YJBi14S zNur(YlOPg{(KT`t#hH7kOM6&dmNAk!I{LSvnrX`ADkn}JWarLpM59q;Ss~ihhb%mV zq#$HyH9aVPork~pc~n)w>>X!rMIoCCv9#(U#S^r`z1YPP*WJ*G=eHYGovic&2jwrqg-+IHAJE&iY(LFJC2M%l2jyFA@Bo~=Dj@p*^eL`n^^A#3e^bR zogtbnhaeooGy4!y7_apR@x&mS7NyZ>(r7g4?%Bb(l%QUz$feZ<)_&;hrQqtxxFiCI znbDU3nuK8Y7L$ov-cPH1kn)1T;_=Ti^Tcm6b$o_!SP(TOBJl{P&!)%>+at5 z&$|lgjjy1xct0zR%c)m=jLtNY*-zKt78a*w*#Gc%*>c6T=(<5T93|e}3zCAsN0z}4 z1a5PYeP8$s3R5Ne#&Q(xE)-nMc!J4=I!bpAk?7;}1K;NA>$|Y5CZUi|JRYUxN6F`F zSeA#T#ZXk8z-cWXJAL-Umx8M&m)wG>W&okC@d!d#iIksZjfK2pQm z$&|YP>HuEDr)O}8 z)uM%z=tfRWFmvoNcJGOx>nb2P^2BK(@f1p^n@ZI}xEAHQgy%W{`I=>&x)fYJ8BbdP zxlB3)3}&$4{_K2FbVz>!l3p`&(72vb7~dHChiWO6o{J_!PW=Qk+K zO(6-7<#~v8LTA6n}99)kGo+8n+cH7SF)9&S8 zKSpZr?A41n9U83v2R=eCqc;$*#*yM0A|;GMHwVX2YQ_MF{7%F|)8pS4V+(qJvOK zOspgE5$%Sf#XzUvSO9oK=?f=AeFP%iApZxqoD zfh23hyAznnI7ZAQ@NHVP8m(FrRcmMb8dba934CEL^#WhuNvZ%KoJcWv`E8te@FOg@ zuI9|XN9o&rD@OM?!`rW7>evy!_4j|xHLrdh!y_Yjo=?<_W4k_j$VF9jnk@%Z9XJ0C zzW4`!NpDsrIk=U{Y0y=PXtJM$Qk8K3Cd#fxtMVutc4Y{ML!3D?%luNEa4d%;gWa^y zWQBU&z^YIGXdz#CSuUHo zU#B>CnpiSPI@d#2-ypH{1ZMw@M3W|}?9wbwQ=Q(2U0GObt(K7GByzkH4*`M8(n1S= zvVyJ^h{P1437t?lLJ&xJjzcmVBk&yRw-i&6001BWNkl za)z#a1;_6BFe}Z=nLKcSp&Q;nc5EBT+!(VbkMXT9e2NV>+(6&p07wd*scxFKL!vW- z2s}K`MbhKAEBEsCKl@{Z*J5SWJM6_$gy0mVh(Pn>4tc#0L-pEv?rnl?9!Zc|55H zv;#?qmOIQ!Ur1c6U&WuCLgju4B-Np^J+jwJ|1V{~M)jO@9E^i@~mRZmksb3aaX z9()%e)-J%NsOYf>QXE`IQ1=9_l8aJmfNxPRR&iSn9hpv&*-kooBh*$_u}Wop?|d}S z4k-lvJ8ofk&ntQCpWe%=yPeZ}_p|HO@1SqXHR$0uXAeHax4(2d$~!|L}LBK;t5<&B@huhx(1nP`U4S+XX3Z9+{mnaV)X=>o2 zXgby96=WlWYQ$+aYSi+RB%?lxDsfs)@yqZ0uc)fYU;WPyp`3Yw&agp8BF@6G1N3jZ zlASO4MMiJFhH7Dw+WdZ;(j=|&41ry1d-Sr5rs*InIJOLmfvP8o<$Um4c#SFxC*}x+ zWxD%&8Qis%z^!1{S6Q7e;5Kc#$8KWux;L`-_P0>6H*)sy5jMT}EsXAdF`8j;eBXV1 z`GfC8+qjFD-grF{kmFVyKT&!^V@M8}y6qb*z zkM4ZFP`NZb{cAk!hLBt)J<<`2yr(ZxmACBLgK0{X%OHiaREkydC->tt>L5v!wGKM_ zwlKDF3s+o!Bhmg5YKltP3z(mrq42~$rXIbUN~KIB*+mf^l1AK>s4GeqM3 zn28R;krsrQE*)yyV*dG%Q*Ei zie{k4x(HfjuF5t!e(Eeg|C(Q*VOivI1Kj$Om*5MiRZEno_Hq2-d-&YfzKQznd)cx3 z8g^fG1G(M|5j7w_I!=1)t=Q!`YD>qd&L6_9FQe-+fq+(101B#>K#KGbSb2QUqcmTl zyjaGFsw6UcY!xa(>_kDn`|MeXty9_q$-i0F~$nic3)2GQ@elv2ik9~U|BP1=b^YS6~ z?mf@Yn;8BQNvAk>kgwpygRyZ}gaCg4yli5kyx+ikBvQdAUG zU908Ggw1ZE-NOv+xSki>`~sxF=J4Z>aA5C`C=|;yMHt)mY1Qf|YM4ZBE8QEe$LQ>9 zZ_@N^WLcnS3ZAE+8gb-s3e+%?9tS0i>qt~rDpYHoDA}8_N~@&DcGI03qFFEV!_WLN z-+cH8uYTh%&^IuS5l!NG9^JhofP^G`0!cxObTE1Ur}@SQKZxr|T=}y*h;-*@(L<|N zLF*nT+Be1{d-pSa{2^|8^%nL&ew=*4MGu(-QV1iOBogVQe{dMbkSeLYF`?t2VD zfT~I|C=(%Fe@!l%>8#eRhaA_v7S1U-8j22E{MB;4Ryq%k0bSt~BxQs+Z zqE()v*|M;;1aq?slxEN3*)FotMZEtqI*0cV=^jCnRV2}BH;l*%N+^zOBv8VgsAd*D z-UnKo%+{A+W;ZjmX*-pbWe(o;RX+B~+xfXSzJ-Y`yHGWQa3q2fN)U}D2)q`G7DA77 zGJE(({L}k>1L3=Dzj`CxgCkVDKJW#Wh?3s8od+J;%M*Kl#BHzM#Ni_+DHJ?ZEsUfX zgp5w2@iYU2!?>PIed!ooT}gCZ=jhSnfIwCpI+8BFrxFD6o>XV@wJ|fg9Mbj4nq^(G zsNhmGg%-LxJKt=1TD)IfBtKi>hS&WHlgE!?*NT*vW|0+@nwg>!gt_sio7u8uEB8O} z0QI^>-@q`jM1oi>j;`w{Qh?`qNNN}}k)ku*M{oZy{X-it%^0o96468lt96Ux2lmpK zJwwvYAb8AYbO#g6f$g z#1axCm*33t>?Ez?JWbbQrlF&nDSqwOex2@AiiwE{kR*;BJIc)T4E=+H#N!<(s)i8` z(~(G^X&PF{z=$L;qA}vhZnC)nVrG<>87AGELDp45)_z3&6n3LYqi*8|5~|UGq;(Rg zDYV!qa;O8zh|$opn4>>S&%g!(S>w(xe}Ox`^cix4!`$}rTQNc*^pHWZ>M*u(Gx!dw zrX%Z7<|a>Z=lkA>)GUzgPqFQW?Wmnsv$!f~v^>%yn>lsr2zPz=TkP7MqoYe^X4XP8 zBKSh3JKawxoT9IP6eDENTs^~$*I!F_cb1->UY3hhGCcz5Hjp@}W@ z_Vp7p!+?w#PcYEmPpZ3{{rmS*ELZ8t^%Dt4a2y9sRZx|79Y9qT!r?ICNDRYF5KpFv zCDWLRBud8!p^#0;-cL+EiBnyqR$QUp@M)p+p_ulcf1O@JcSuE*md(|bPT_MnI)B) zWz#b{!P4AGzVnT*k?Kt{Hes?t2g#MhSeMLdE8W zpM5cQy@;x*XyF7c$K#{#cpb|80Zdb6%eA}Mc-<>GH7QYRIHZThY1RsS_s%bY5oXWz zS(X-?RBA2(Dm{JUn29Xe>@cbB6#E~(mzTce1*Fn_^!4@O23mXhQ#Gu5m9C`0!Gj0! z{099)X{=fkUj%e^8yF!4*A87H!FOwxwfJqD>L~K87M3nTv0581d zg*^0k??q8;GMhJ0s(b9631dqUdV8~6b=4L8%uO#KoXE0%nYB{6%H;GcLn9kWXELag zk1B&KEA4Dv;6vczI5wW=;@B-(troUz<9Qy;@e(Ny}U>)o&-h5N9FJT@V~Hf-#?O!No>1zH#=YUCQhAg zP;dBzQzN*I6~6c7|HXVm=BAfyq_9$@RCe)<C37iLPGK*&#M<80YbQ4|465TL_2a zbfwaSLSbCj!w)=ab(6UO^pHiEO4&e?xO4Bp zCtmqmQdnAIDZk9mz5bVIR#yl|qDY#7 ztVj6r$3DQ^_dbJZz%{r2EE{ip6|+k%nk_*jGmhIRao<-z%5>T1`dhZqXf>%d0)$XV zbPvDI8CWv%vQGrOHY-j*|iGi)O8g-ud z&L=prP+{i{I}uWYc4B2FNO!rc$q0 znO|7o&|~*=*IjoaNgf-vY{K&dLJ};^O;Rp4h(%L0o65S`R%>-OH{bj2 zT|9LEkJ_^}*@YU?Q5A(mB0<~?qiYI&AX9e)?dBhWuInT^ItfRjG_3~nb91y>4KkS? zqR}X>>t3*dB%n|z(AAY>dS-!<;SqLT^J1*>65+6cFR3Vcl<)k@o$USO`^bc9Y~Qnk zt6%?HoIN{7-RYovWDAu_oyiCPiL*x@BX`9v;z^&Sf(x=r&%jnf;Vv>g1B{Jt;ON19 zyzm8=qiP0{q!RDw#upOda2VgSSy;$(^610-%QtVw4;(ga-GZivaXi8D;xzL!%cQ!~ z1VJaBZLgQRMXhdqux34Z*UY~UmrMW?qrdwSgLKbk6s?1v-a&?jM%jD+y_ky4+-!lRg*@|f^Awhgq`Hzs!#dT5%ZVfV z`Nr42K&@V6WNZjk@1SM-ShW>SpO_>bPtcX#gjKWfU3XmoPs}eBKIXVjaZQ_l2QE!d zU^JRu+Y#ggh9tp`ok{-SkG{Y=-~KiZKXHics6-|=h#!&}$jP+oRZ6R?R2+kBm&wX% zp4F8Gol|$yKbGKyI|gw5Fs^hzg~LZU_)r%ey}KD3A1Be#K_sjrycUY0AKkrk|K9IWEG?4GB#0)mRI4piU1IX| zB;inmOwT49ThMA)NRs3OUpjXB?C)HP|2K3=qJS%RZ2MopuS5IC4Gsxj{L-6w>#uy6 zX0ys4zVGead-p*ST^Tm-xPoloAjz19;y0-^9OloQKq{V~M_EF{!M0ucM+_3#6mEGA zBdn1b+sLtb!QNBdR2y*Ro-4WfnrrAzXJ~g0ODL*}CmG1Hf}slV9Yo-@uk9ntJow-P z96fxPLVl5}ufB>%ERG~842*8({zncFip06=j!z*@exJ=f8n61DKjh@m(^N%Z z?qTuNAr9T~r!2Q1cik2O*<^LK#kMPNq1o^VM-o`Y5X{efx(8AQL zfR->(WkG~xgl8iw3W_4=PQ|c&nM^K0qhYf+J&B?vNhAkYnLC5yx_7J;OMg1Ilz;3} z@CKJa0J%)MCzs8f0m4E+S1MrRM4b2k$v23_yE%30n>_r`w<)exIes+HnNwAaXb%%R zb~8LO1c8U;fGi2hi&Id`V>n9~_7a9+&^0tlGLt}VoFL39k)+9qqo^Ua z@7%%FS6|J*KtGYF36es93X+5>%P2C)_#gsSmlyb_uiinTBaRk|ux0yYG+c$_lZzA= zC;8!>pJK$c_|r@_kVZ5fCv2z~^&<$oT`oW0)GDEc zG#t;RBRj_A(Z`V`@$r+B)4xf3H;pRQJ05N<0I5pYxH$4vth7F-@qWI*}=^89N+xr|J&Z1$H{h9_1@n-@0zQ+x_X|6 z(`O!%oD5_<1Of>+qQol*j(~{B^{V)aFQ|A`oN%}(cvTcpK|qFtDG3=c_Y6>sjmTeB1ACWjmp0j9kTGVfrFZef96@3_85yz3;&_ ztCUOyIowOMYn16z&vE8~kK))>#KApuZQo5cmt$zlep*w5lnMp@^{e+&D&%n-m!Evc zJGtvEKSkEn$&@^vIXcDse1^BY^={t#?t8iCwKot;hVeq}l=C?RQN(lX#x4jy*;VkM zR@^|9C8JO(-(NTD(~jfT@Kv|ptmrD~ssIoPg_KlF;;(=(KxdE5?matr^N+qC+pchF z;wxBIot~a{qLBbCElDDg0I`@(AW&mwYMh1XB{tS`lnQxV&m|O&(%IcdINpLI2C2vi zs%jfmSEp!b2>K8;ZHm5UdN{_)Y6(;9pnY%~%hOYw zzWat^}#`{0`DMDd|LjE*{VPV@Iwp}9> zic_hSnVz}C{a^SRbF&+C_QZL|JKo1b$;}RZe(b% zh5pVYb1NCL#VXl?!PbFxb`JM(ab}4pk6h%r=f}xq^GJ3PSqo!sOd=Yq2sG**<7XzA zwmp9S($s;vX=jX`fJ*tLIB;G@7dk4XA1U!#qs-uzj zFQO<4X1&JX$S8@hMo<+I1OdBV!7{Qq#YqC3LSqVk#GfXiUotthf)MB-&^pHA)D-6)`yA;r52J+?)Zhl!7D@ zopkq(aQyH=9{9(<#c^HU_x@kw+B**L;M3sYo&JRG7W7G@=#$F(d>qk?5xT$ovAd2tD2eGa*v#`J;ay9K*#`J z7@wT})l#KWxe^{;@iH(H3I%}s0Ce5sn(MA%*PeUW*tp2V#BnAr9_94u3oI?pQ7BYN zCSz#2il!;dOy=n5>Sp`)8##04NwOO@(S*pra0Ih%Gc!HG_{p#S(Vo2q4-^c+zQxw#~40dzSe{iziQqn7%Z} z`nrjl2r!g#x%+yDT?gL5-0U*(zWu1tUM9|*~WN8PlTU0&zh(OxrfCw6LFQzH{fYHb$gxG;0*Wm z&LRsP*p+z-D|sSO2V9Z$f{q)A5=acPG&955gHJO4tuGUi%b1ZUS!sythDVT<2qU9A z+1SYP#ZUb;^;(VB-E$9bf6sgQ^1mKqZYjs=T9NEVkzzK-yMOFHa+M)4vhdfj?3%szMJ;WZlX)@_7>C7aVBbG=} zF6CL6zDO~bWodDNM6#99kzu-ew&K|q`L!tutCN^@0X5V~Yv&FetAb%)#1S3_)uC1u z5#!tG9KHp^s55c=2oq0#9jBBgI2`Aak>I8`y&g@EvTfV7tfe#j)5rdlYBQ6ZnNu(q_qfdkj#NghV6PEglbP8TpOU-YZ0L`YLfuU9CQYJQQc zMr}i>VVVnqVQDRW@_PyZzyy$GkFjmr z$Yf?Xar_~cR;pCZc0@@g)iq2!kt7@rA&3Im^(AVCh38hVttzstAP7#Qs)t|iuUxUI z8hN5oi=~yPsa3Ot!$E?90Fg+XJ$s@A0vawl^9$?bvvpD(z371;i?fqVj-Te_k!Kj* zx|3~Nw=%Y67hcaciW?auSw;_qFl%KTrH(rEPHI{h$5rUxwjDJP;qg!W1!fy_5E?es=HP&&uiw|MGYLi}dm$V_UcJj$iy0j*U-q;`|cDa-H>!GWl$g z*Sz)`Zn}1q>7@(Qe*)GLcAtWJ{cD_a!)UdY-8ZOC(xTB$6rWwHgy=PcU)zB(X%2Yp%b69Xods ziv%bYi_~3}MCT}qrlRN}qR}YDVu>&O@dufF>Z>Sjg+QlH+0&?nhPnB`oov~%i^b(d z9{%#@nYlPlYilb%`p$Qu210!6;5fx{jn%aRt)b zBplEwRH}ZBBFphx8+smALj`y*)I;*HZ3m~Z<=t^yWLaQ-dY10KZZxq@sg(YrAP9@! za{xrc;RJX{at+IJD3`NT426)Q(bhRYHoeB-r@zVU*#?ff+%9v z>y!

T(rHDia7gI4ecwC+7)8+tIWz9^kqTOLJ3PI)4%n*tPds_U^v{Rnt)v0Zk8) zOlq7t^$cJ9`;U>IKTD5ZL5nE32%Jj?`Ke$2Nw#g<%fiwePe1-mP9A!eU@*wrfA;6t zvH?mbwb*qlk3B!Z%36_1)g+TC(Vhx&`>VFIlx{Sy5=1iD3SuJ`5DV+9Z4~HejkB_*mBrC4Ty6-o;I~-_GO5Cpd9-1xXT^U&x{HeGCjXedrOpj(ZI4?jGBpMIev}gM)xsM6dKjfJWSKUvTPEGASVu@u&*xk|o!wBB1VsVSx@3@r71wc4Gz~$JFf9i`5K*-Nfl!1{Btk5q5ek;kbw6D0Is(Cf zhO9``YZkh$VHh=R+rjljTtNan)@w2wPL#L&{0F%HrdybpoZyR}{x}y;ofU2^RE|SexNoPwK zb&E>XfBp-_t1lx#5O7_WTFoLF(U~|ij%#G;>_{>+*u}!dL%61KeQ!tGK(SmoV_Mb~ zHJ!X-2_OjGtq3lXC{iru2?i5b*$SF2QY%-fl=Aq6oLywauep2j%mll4ZRfuG-o#yZ zy_V_eDJs=k?W3+XQP^)#&-M5oKK&P0`Fgtae z^vWg7S`|T*8reTCwq+uU0*WdlNE%uoie;{lYO`o-m;A($SPEV5rMtV2V4#C?wZO#W zBB!1|itBc9+gR<+TO`(dX0y_`p=v?@*F`u#_qlQ_>s5$I5X=xTw7*kwLr2Z z$eGjgjE|6SxJLgqq8H<@Nh3-Ax%$LlJjTJc1U{rd&h>QH_@id2@e2UTSd${JtJJ_~!4}qYHWmbu|baPApHXPexb$N=p=~EQ)Yj~dT zKX-weVS*r_C?WK4JJnJK*QsNgb;{)uf*`QGyu#36FTKMzux-x>Gm|B5yXQW(Zrx5W z7^YY%aO9bXc;dlt5Dg`%*J`};-R~w_GdXf*p5teh(NvjY(ZIC~cJCZuVKqm-P^D^E zXqsR8#q&JsrcJ$WH!OVN1xDBFFJ8L4u8SmzG@DT?ia@u})Iq8aH2e zEoaVN;JM@(*32FZ$LdN2r~bUVgT)I|Gxxt7E?&6`Xm5Y7AiAyLh|Sh*uR_;7PM?{g zrL~7@)nIjL7R#z5%L?(hMyU{_r6s{V_q+iF5mA)?MvLd6J3qr!Z{+K?+i>*2rZyuq>Nsyp549*U~q%3rSL`)vCCz<8LTYRXlw4 zqla41^e9>&j;coxB@NTESYBQMrJKds9MNQe!Qt(U42@DXYMeQBkdOV*?-B_l@m!a? z@BIN@bMG5@^zb>(O{Ce_D5D1yE}Wg=jsv@qWtoj!nPRE#J9GrUe4XPsSeDb!?>^&g z+j&9sH_5VnJ3x{|6h+3Yn}kCev*Q!Av_#pvYmh|PvTheV`|n>)n%LFY0Ph8%H4+iY<|@4U&exI4m#Etkm2!c_xk+5xMwCRtkqEA< z6Hl~|NW|&s=|PrcL|H))1S*vh^{RoaswjE{MbYT%8{m!uujY>1Z)J3-7pt0~R$4<* zRV-I!X6GD(MjLnF1mWQ5Q!ymJr~=mH?A6A2 zfk3%5gQg|9>-9g#x$%qCj4~VPRm{49ss;#$lT^wEKmHRxLESVtdGa)>rqSNfi5>_O z3WW&-Lx_Th=UO()@xzpgStLor zL&k9+5NM&jbAK9-m{hr;A6PJPL>|=H@iy}(cu8Zq#F5i6XezX0o zKe#1G8FT=Z*oc+cQK@TY#Z~9s;2lwrTRX#8wiA2$rthzvT2Hi zbwn|Y=ZZw5t-R}9@1VbbfGu0LkjZ3t=9y=x83tY5J%qwxe|@fMM59q6;V^=vpy@%> zV9ZYp4Tb6I?xC}z1HrBmkX^dk+o+aHEX|#!m|wwh#D>SMG4tgh!C)(b7)F$We&&s9 z;kYiIr*h!+Z)I%DHbg<<@S($e_LG0f#nUHAM5EZ2&0qZ0Uz4*X9y>I_BL^=qerbhT z&17YMk$dmGnS8m%dbZ3DzxG;APb}gzdJ{I8?fRw(j`LzO-}CT`MmjDa_yx2amuOhW zt{H5sZLo8DKl}HMk_`bTkgC+J4O-h$eB{qQ!8ad2!kLp#Fh6+`#3Yg!;GOUM8E(7v zHe^-D_3+cRWSNciEXPlrU}$KVt=qOCiXzo&1+!Ko7z+6_#|2T6@mxO=Xw)qXqe{J2 z#i$gh2I61!9ScVFX zt|TtDeR(T7e|;~Cmsc(K&l!flDo_*&NfOajnP^z!;+YF<9qnV^?jeG5i5Mkcwo?~Wa4jhBFR11PAB8f7AfX={RKbBeN#F_JW zqC#tH8-YNuVJwQsvY*!{i87MlAxjX@RDz)((O80LEQX?}1oRekHBPyZ#;z|Bi`Y1( zNqS|K`Pq3cO-zzWud%wa!u;GU(~}d-Oigm?*g;M_{}gL0X%qxR0q*_bxAN|Hzmo@^ zIL4_9s~Cn!E?;3|EyLKB9`@}X;?%_@>UBSj%dcSS>-Wv(6U{orLZeo(4+z)wFiq

4DTHr6?H_8hT98;YtS%aRWQNkLH* zWJ$tr@#}zN;@Wit!9|f}0>JXb}(u zY}-bb6^UV_7EEN(G~4__|d9vujgSAqFYv2>_9a%+MJi>3 z^|f_YmzMd&pTCb!f8_|3S{+SOUl<2}_IsBZe4DZT=9U1*ajDhp7p#9t5(xxUwvBXB zC{)09*}r#`wdHBHbjo!1bko{1h9XPYw#9G!-d}U({4$BCzdDHoEXGehUc7YS++P5H z+5mtBe8*kMuSNohK+v=-F<&Yk*ERhv%d{ilAS)V<>ryB>?7#kYPMCx)tBdRT z8$>PJ@;8kl5RSwMha-eSArwWyb)1F@kx^BZNGygZN+_yEC>$jki&LuBvFZ+me1TIZ z&rni__`MJPH|E#VxY%qNOj0hDId}XN@B43WV`4tTnG1`JdIf63W$Wv7KWNizP9ZeZ zfxjwnYzNbHUI_O#y?r zNhKbS)6w3JSu10dOVmsU8{dDRDl&?yp=dgy07kV!K9{3jHwgwqw6?Y($uf@PH+>QS zNs_`t9K1%sno5CsS*B5kQ44?pmanR>nUIPk>=QdDJRVQn69{UOWty~g4N*5OT&GSn8mCw^2m}+juFdM|8XgsF zdx2<7;M)B+VOt_kJn;l4Pn;kgj}eVVQB)NH4^7kj(lDU_sv=XjTnxL>70h)SrDa0I zVsQeY5Nm6zWY$*kJdb25MKBP=buVit1FWvD5DErS6`4Z^k5aNUe({%oj=#VEAb<6# z$2fg@lC@l&m2`o{(UB$bg>7G!ZBuWo>s{A2fJMlv8Joc|A=}9PDyKjuKksiM^d}|lMaG3R6g>1IOMz+fGT8>iDpjNG- zs4~eGzjjeDAQ22GxE_rbwBCyh!ymYFFYDO?6K5xQ>znVUyQ__V{?sRU(;IH2y}bij z520y65EVZ4nQ!o|Zylw(w~w}jO0u<$`AbLKBhNg(0Q?hhs=;)t0Rr>oF!D-`z&M+M zq$tpVk2(!Nk>x~hSI0+WRT^$d^)R}9FP`htl8htZ8)~_Yb*y@UWUGj26sc6pL}NOG z{jKy54EmD75wJ{)dR?Ms$aHmYWpr!{@s=c#C?ZP&2!0Pgis1Oh>3XBOFU^P8Anx4|^gggTFW{VV99IGx>n z^bhuvYHz2fua{i0#@X>%YNqd5ltd9c58Jju6tFEDqg+B!Wl|ljL?S^d)jH`+fje*7 z&RRCdsbk~3?MLon&+e`K@_+v&-uSv}c-4*95Q(P0})<#UO*xqO*OSZ8RUjh#DsIC%IH zuRCxJx7@sszx}($SI_>p|kJ-B^~%TGrq_KldAq?%GRFXDb3GeSO`0<`aKV zuT)Bh@n`=!U^HG<snhk~YQ*p|i0N|8jzP7-aSSgy>{!UFB75IwyzHN)WI zg*hI3>~YSXK25z=f5Gw>@DM!{!E>-Z0n_obYeh-+mt&qsZ*L!gK#+51PqS^?7>@1m z@WcN~-;nJvRT zY~MP>{%dzIG|+{rsu(p3)3gDXNF;>gxRgpY78cjp$QfL-YlK^G+`;KHm$?5kALnP^ z@fO0NFtJoGg5V;mVcz%4zeA~Pvj3)6A-iRI`Um;U-~6tZSzDd}o&lc4pX~*F1F*o$ z(EV2nfTjURbfMPpNwr-kf%eL)}%$hMfbs@aEx*{Vgw4^#vH4RZx7}~NE zJ=99g3Lwf!WF<~+eT}u1IVu&GRPS!IaDvsPS=u{-3=RfKCEF2@Id$?B|MG<|^38`H z=EC?n0=h~l6d(IrMX!U zWdgFntM9mh;n6L`A|blFJGtYw>$vOHH`5wZ$gWJVu{uY!S|O9p(3Xs||C%j~jr7pj z(drL~?0Y<;(J-lGj30dc^<>g(eDwD}z|X(yEu>Pd=&^P}0UbS*;6uOp#~eO7&fP!q zW|DfHmbNY){L-hG96z1`jsRZ+azGJZ?^l5rsd%gM3fR(mdNt_GR3k$taS^; zvP;bk6!`Xp%(Pm0PE`}7sroNudk78h0g9U{e3MA^mh=A1Syw` z96NTLFMatd9Dn|K=I7?obrnUH5Cs=m(dh5*V}5p;O3fm(IL)I^O>p0RujkU#3YEed z*X37K>yu83Mr=Ey*OBBBQDr;b@%Jwhr1lIvE`qWTZ>Qu?*%{3al(l zVVCAvTf9hib()!}alZNJL3-PCUVY$J@@13lyY`}LDho>)e*Wh_#I`-xaMxY8Q?C{% zmrcI-kAH4kX5}=#v*+vhv%Sgm99OYR_)1m*5-%3{O=`ynfq=gn*oF_3v%mllW79@x z2d)8BK@i#k0lj-@%T6^Ej*v*E2!+E84vx^)(TS`m0O)#vKp^mfBS+I^qR}9dBrrR9 zj%@lOx%DYRL66p?MkEqMRa7ji#>~_z$B%EYv{Iy6t)Xc;-CbP_4-FxTFf`c9^Ut5; z)QNK#UYy-G+`{g?*YM|`_y&Wm1_`aqefPbQTW`OWcp^!@P-0;@&A`Ag@n{%X@+*nk zRt?*#W0@x9atXtzQY;p6YzNn~F${z3MwW%eWrjyaNvGF2@P_}2=sDPe%3I&^E~=)^ z&%XC(sFVwYgE}An;BQdOo?Z1k?;P+6;2b{lZTv}fMVmsKbR_@~@BtuQ_IL9**f=V{ z4t#InDSU*s07Gm_2pPBz9}KE2OFiL8OmFY(3HA++ifx@;1Oh=^$DyZh09lc7ESo?u z2%d*y+l+1BPBWi{B9_4O4YIYBEYBUC;?$`{N+o~NM5AFU zl``2}5kZh?Ywg03l5E?xo2ub3F}Kc+T{{Wc)6^;(?7Lv7zjTDIUn;-lw9)A1` zzw&GUol>R7Ku?mt`PRDF?=UcsquLVF5Bqtd$5W?*mb>Xt!5NAGHa!U*(nxgr_}lBOXAAX0*j0DMeF zd%96&UklovgexdWvWl*$jl6yn+p*C#4MmZeo0(>Ea)ujkzY9(A%j19gAO3;Qed!tA z|EupIS8*5_O!3T9M|te)|6;h-#zB0;?*zUIH5%iWiw3{Zarl#d{ck zhHuB07H;DuH;&7V>zk5f3!7jG;H!|RAP6z=B7tC7O|^GQEv@ZBXIBqB{X;m8?`)A} zg+#KINF++CEyd9AFl}uuc(@dbS&VAg&rlA>kwgL0EMQdDs8!P7*0E}NvKtxZ=2lQ; z69JpWC7tsZ4LbX`pehn|)1zuw6bykHI^BKUj15E(?F!xPF}4h}G1%WjvNeUS>v)3V zuQ&u3MR0K)i{+(7sz#Yd9)5`7;Ssv~h7hzUQ}Y>q`!|1|*WCR^lAXPDceOG?cKv$|v#@>%k^tYDd@5KFWOs;+bC!Z|LUKMkTxp-^Hi zy^f-2w70dBNVEbX8|%yDa%rj+6HQN%Y#${OA3)Sn*sg^v*>rZcvAn!WvTF;y1H&Bp z*26e%jiJ$D#H4Rr( z@eql{;v|!;808`>OG~tNbg`DV`Q}%@OkZy|d#}G4RS$q;@F#!pmsE0>mK?i$61W6h z02c9?UuulaD?(Qj4t8j`et9tn?91+};_IvozK^;M-+-wA{rDg%;7f!ozDsi*UoB{C ziaQfufF=b$p|*S>miIJxqL5M}ZN1)evK|9GZODbDH-H;)6>Jh9Y9J ztzApCb&P7asQ>^6vq?ljRO(&by>c)V_7gy?8kS`ejV5UC=wj>69qik;k3>91sa(SK zpja$n)T(6Ci%618OG_&o=`^uOm~>`?FMr|FoIi7dYNdoxt)T~EY}v7ov28mU8rg!T z>y(NGthz-g+Cnth%|^aTdLxgbir`kksWLxxiPG8}k$^;BZzlkcKXHhf6X19L@K4B; z1v*x82*uDjt?T(|!^hK7e4Mw&%SB1R^Y!M1H&+v4ECLwxq1{+8LvGia)x z@8`H4*<20Fa@DyomSr?erEhSUXf%nW>a6F=6w76*^*Y6J zh1rPn)=1$+U2VyxqCKzM@ zQ51z}G#*TKbjhJ`I3Nn5*nE^(GstJxaXpXj-U0UCbSvdb1=q3bEyTk?1P$RdX2vAUimo6BMu74E#{dRCX``5zznP4YznBm4ZKgd?#~G!_pA1EHwrxsq*})M{0XYL%K%X%uDz1OeCaotB~`;W&Qk zRwN|j;ZZ8vPOWZU!WYG{#&eqfjf5mg;Y2c}4GfPdsrF7KnQRqm)hg{B9o%@!9SjVO zV$^K}K_HVYBZ?w@U2!UNchZg8}B_; z)AVpSng|2}ao6)i%QQu!QWhP@5(PnY1VK=|=9Zx*H5v{(u3NDzYs&Myd3;sXG=49a zMv=x#4TQpSXIF1*Xk<(YhC)KMTt-zD#8cjkv`-X376buR(;Yz&0`;1qd!8o)jvxqi0VD)L1RPCO zx?I=GTedyzy6zG_ph}JZp}A@qz*lk6#xt9auq2=eg5X4=v0x+;4+n$6kYQBR+(rh= zGCe^M1kV$ZCBYMwglE@2@q^S-Pg}b{uELvh6c$ z0?2E;uK>py*Y@BuyRGr;I-63Vl})fqf*=GmT~|EUQ%tk2&{)rFs+y>q<`bUhO*g*# zDE>1bf3XS_8!58^;z6(pfZ%40C`}lvCT>L?6&Wxt_(8afG zbNB-o!PlcN1;e+K3{6ANX}s!`49&H_z`vCQO)2p02B>LU==h@fT72d;vu0NDLFeMf zA3E9etFP&rmJ0;}dpGj=huJhVR~diWxDADa?o34iw0@PROZAE;_d zqI1ATBoy3TF^mhY>p8qwWi{{HR4q+W|59p#yLnv%UjkIv1oY+M^X7X4->7`WnnHi4 z^uIFz{yl2W%I5KMz2DT?yYY4K9DXpR8K456F`f8E<0`%gZ| Date: Tue, 17 Mar 2026 19:35:30 +0100 Subject: [PATCH 154/187] Replace goto.png with a themeable svg image --- YACReader/goto_dialog.cpp | 10 +++++++--- YACReader/goto_dialog.h | 8 +++++++- YACReader/themes/builtin_classic.json | 3 +++ YACReader/themes/builtin_dark.json | 3 +++ YACReader/themes/builtin_light.json | 3 +++ YACReader/themes/theme.h | 1 + YACReader/themes/theme_factory.cpp | 10 ++++++++++ YACReader/yacreader_images.qrc | 2 +- images/goto.png | Bin 908 -> 0 bytes images/goto.svg | 11 +++++++++++ 10 files changed, 46 insertions(+), 5 deletions(-) delete mode 100644 images/goto.png create mode 100644 images/goto.svg diff --git a/YACReader/goto_dialog.cpp b/YACReader/goto_dialog.cpp index f442b93b3..d0c5b12ed 100644 --- a/YACReader/goto_dialog.cpp +++ b/YACReader/goto_dialog.cpp @@ -8,6 +8,7 @@ GoToDialog::GoToDialog(QWidget *parent) : QDialog(parent) { setupUI(); + initTheme(this); } void GoToDialog::setupUI() @@ -42,9 +43,7 @@ void GoToDialog::setupUI() mainLayout->addLayout(bottomLayout); auto imgMainLayout = new QHBoxLayout; - auto imgLabel = new QLabel(); - QPixmap p(":/images/goto.png"); - imgLabel->setPixmap(p); + imgLabel = new QLabel(); imgMainLayout->addWidget(imgLabel); imgMainLayout->addLayout(mainLayout); @@ -78,3 +77,8 @@ void GoToDialog::open() pageNumber->setFocus(); QDialog::open(); } + +void GoToDialog::applyTheme(const Theme &theme) +{ + imgLabel->setPixmap(theme.dialogIcons.goToDialogIcon); +} diff --git a/YACReader/goto_dialog.h b/YACReader/goto_dialog.h index e62f8d2d4..339104d17 100644 --- a/YACReader/goto_dialog.h +++ b/YACReader/goto_dialog.h @@ -1,21 +1,27 @@ #ifndef __GOTODIALOG_H #define __GOTODIALOG_H +#include "themable.h" + #include #include #include #include #include -class GoToDialog : public QDialog +class GoToDialog : public QDialog, protected Themable { Q_OBJECT public: GoToDialog(QWidget *parent = nullptr); +protected: + void applyTheme(const Theme &theme) override; + private: QLabel *numPagesLabel; QLabel *textLabel; + QLabel *imgLabel; QLineEdit *pageNumber; QIntValidator *v; QPushButton *accept; diff --git a/YACReader/themes/builtin_classic.json b/YACReader/themes/builtin_classic.json index fcac45c7f..3b0b217ed 100644 --- a/YACReader/themes/builtin_classic.json +++ b/YACReader/themes/builtin_classic.json @@ -1,4 +1,7 @@ { + "dialogIcons": { + "iconColor": "#404040" + }, "goToFlowWidget": { "editBackgroundColor": "#55000000", "editBorderColor": "#77000000", diff --git a/YACReader/themes/builtin_dark.json b/YACReader/themes/builtin_dark.json index 7efd26aeb..3dc7b9d3d 100644 --- a/YACReader/themes/builtin_dark.json +++ b/YACReader/themes/builtin_dark.json @@ -1,4 +1,7 @@ { + "dialogIcons": { + "iconColor": "#cccccc" + }, "goToFlowWidget": { "editBackgroundColor": "#55000000", "editBorderColor": "#77000000", diff --git a/YACReader/themes/builtin_light.json b/YACReader/themes/builtin_light.json index dc9209f78..274788b81 100644 --- a/YACReader/themes/builtin_light.json +++ b/YACReader/themes/builtin_light.json @@ -1,4 +1,7 @@ { + "dialogIcons": { + "iconColor": "#404040" + }, "goToFlowWidget": { "editBackgroundColor": "#22000000", "editBorderColor": "#33000000", diff --git a/YACReader/themes/theme.h b/YACReader/themes/theme.h index f5c073518..1355dfbeb 100644 --- a/YACReader/themes/theme.h +++ b/YACReader/themes/theme.h @@ -182,6 +182,7 @@ struct ShortcutsIconsTheme { struct DialogIconsTheme { QIcon findFolderIcon; + QPixmap goToDialogIcon; }; struct Theme { diff --git a/YACReader/themes/theme_factory.cpp b/YACReader/themes/theme_factory.cpp index deb855175..42f07fe80 100644 --- a/YACReader/themes/theme_factory.cpp +++ b/YACReader/themes/theme_factory.cpp @@ -56,6 +56,10 @@ struct ShortcutsIconsParams { QColor iconColor; // Main icon color (replaces #f0f) }; +struct DialogIconsParams { + QColor iconColor; // Main icon color (replaces #f0f) +}; + struct TranslatorParams { TranslatorThemeTemplates t; @@ -79,6 +83,7 @@ struct ThemeParams { HelpAboutDialogTheme helpAboutDialogParams; WhatsNewDialogParams whatsNewDialogParams; ShortcutsIconsParams shortcutsIconsParams; + DialogIconsParams dialogIconsParams; TranslatorParams translatorParams; }; @@ -340,6 +345,11 @@ Theme makeTheme(const QJsonObject &json) p.shortcutsIconsParams.iconColor = colorFromJson(s, "iconColor", p.shortcutsIconsParams.iconColor); } + if (json.contains("dialogIcons")) { + const auto o = json["dialogIcons"].toObject(); + p.dialogIconsParams.iconColor = colorFromJson(o, "iconColor", p.dialogIconsParams.iconColor); + } + if (json.contains("translator")) { const auto t = json["translator"].toObject(); auto &tp = p.translatorParams; diff --git a/YACReader/yacreader_images.qrc b/YACReader/yacreader_images.qrc index a5b011eda..a573b9fb3 100644 --- a/YACReader/yacreader_images.qrc +++ b/YACReader/yacreader_images.qrc @@ -1,7 +1,7 @@ ../images/icon-new.svg - ../images/goto.png + ../images/goto.svg ../images/find_folder.svg ../images/flow1.png ../images/flow2.png diff --git a/images/goto.png b/images/goto.png deleted file mode 100644 index d99a3d013cf6269179d60d2d77d95e5b0cc44750..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 908 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+nDsne978H@y}7e7NW@X#*vF@R2R=9*`pRoyTzpn#_k}ac z#?9so^BF3cOqw|=n2t^8c+7d{f`F0H3%%tZPBm$Zq?IlE{eSf=D~~C&|L#gJ&-*?L zq_a})}GSy#Rf(57;S$@HN~zM-tcG-^BuiER?|01I?cGu_=2s3pw3(*54r=R74Z_uSAJj-@ zjhtaod{^Om>H`(OJKH8!8eirOVtugj^m5yoTa1;xn>zC*XfY(-3|-VS->T3^t%P|t zpr1kGzhVOa4}DvAaGyev|NzJ5Sfoiajz#y)pjZN0mbB zG8S9+85eoA-ZT8a$SU`WOWnwC=`263R}7)0%~u#NZ2sFF@$mdo#UBgT>u>c*;W$uh zK4pL9^;m{SD%sihs~^^H>%Y3RamMKheyU$sN?y}X zz6}>RuO+L`n9yjn%kf$@)8pAS^4Bv&Hsl+eux%`9D%y2Wp`7(H=c$)$&G$ro)Ft*w z^Zbf&s3~4Q`}lkL1=1?-*j#PI1-^5ZY%e%gc>Xr;G1WcRchx5pYF$5i{nKmqzVdyw z&5PuCC%4p3oo=qf`LoCSceBdF{VFfr&%T#Eyj^C|Z`A~6t|u3sSRR;E-0TPjn%doi0HKk-t$?SAa4t(=^B|CdP{7r&Bad$9g9 zbFA31kiCZ)Y&MwqXxq9=e0iK;d|yDQT-cOlzE+eR+kV?KPr{EJS+^juBK(C=;2GV- z8utl@SH*9+bs+YtFvIgue}*~Xwu}XFUs(=RQY3&q=>oG>)E!O(2F;X+lgoMK%t5L= MUHx3vIVCg!0Fcgu5dZ)H diff --git a/images/goto.svg b/images/goto.svg new file mode 100644 index 000000000..89ccb8106 --- /dev/null +++ b/images/goto.svg @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file From 4f500eecb69d7ab567332706a795cbc94e25dcb6 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 21 Mar 2026 17:10:04 +0100 Subject: [PATCH 155/187] Remove unused images --- YACReaderLibrary/images.qrc | 4 ---- images/sidebar/collapsed_branch_osx.png | Bin 162 -> 0 bytes images/sidebar/collapsed_branch_selected.png | Bin 139 -> 0 bytes images/sidebar/expanded_branch_osx.png | Bin 169 -> 0 bytes images/sidebar/expanded_branch_selected.png | Bin 133 -> 0 bytes 5 files changed, 4 deletions(-) delete mode 100644 images/sidebar/collapsed_branch_osx.png delete mode 100644 images/sidebar/collapsed_branch_selected.png delete mode 100644 images/sidebar/expanded_branch_osx.png delete mode 100644 images/sidebar/expanded_branch_selected.png diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index 788d45d96..1f898934b 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -103,10 +103,6 @@ ../images/sidebar/renameListIcon.svg ../images/sidebar/branch-closed.svg ../images/sidebar/branch-open.svg - ../images/sidebar/collapsed_branch_osx.png - ../images/sidebar/collapsed_branch_selected.png - ../images/sidebar/expanded_branch_osx.png - ../images/sidebar/expanded_branch_selected.png ../images/sidebar/folder.svg ../images/sidebar/folder_finished.svg ../images/sidebar/folder_read_overlay.svg diff --git a/images/sidebar/collapsed_branch_osx.png b/images/sidebar/collapsed_branch_osx.png deleted file mode 100644 index 873c70482b79620d74222df64244f7aa52124099..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^96-#;!3HGxgLCzOlw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6JlA{S2=$B>F!Nk9Jo|Ie&Y#*oC8BjIx30GmSCf#nP=b_|8g zcB}>r+oyfBkC616&~d(nAttQhjzYs(UiN~YOnEY9JOT*}&F>%F;&>Gt2Q-ht)78&q Iol`;+0JC8+lK=n! diff --git a/images/sidebar/collapsed_branch_selected.png b/images/sidebar/collapsed_branch_selected.png deleted file mode 100644 index 9c6c6a6dffafaff1dd0f2ef34caa9cc97963fb55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b`!3HGn8ON~#DajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MY^6Yjv*Ddl79UE|DQ=Atszn1qkN=*8iROBqC-Q4z`-L8 kd>6JRn2H>YYG7by__;jrhF;{UnLv#Up00i_>zopr0PWu@zW@LL diff --git a/images/sidebar/expanded_branch_osx.png b/images/sidebar/expanded_branch_osx.png deleted file mode 100644 index bc812fc7b1b0b8a8e1dd08ff33b8293c10bd6784..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRM!3HF?&tBaMq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6?uEQIEGZ*O8W8t|NrLyKMpdpDF`|^1TuICa>yT8$e?nL zA$UoH^F*diN&Jn3W)uxnFF@n=!!UaZaZkfp@1fq|L9^wA$4&hDmF QKw}v^UHx3vIVCg!03IJS(EtDd diff --git a/images/sidebar/expanded_branch_selected.png b/images/sidebar/expanded_branch_selected.png deleted file mode 100644 index 896697624e2dfd819143bbf9036d3b0fb2506227..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^Y#_`5A|IT2?*XJFOI#yLg7ec#$`gxH85~pclTsBt za}(23gHjVyDhp4h+5i=)d%8G=RNPAX^Z&m+v)G0PMwP}k@ju5^f5=aNP#@FuzmT(u d!J&bX!B8hZ?AGtQJAhgkJYD@<);T3K0RXDsD?tDN From 5fbd5bc185592cbec0ae1e244fa279dfa6a3f6ee Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 21 Mar 2026 20:14:14 +0100 Subject: [PATCH 156/187] Remove no longer needed patch --- compressed_archive/libp7zip.patch | 305 ------------------------------ 1 file changed, 305 deletions(-) delete mode 100644 compressed_archive/libp7zip.patch diff --git a/compressed_archive/libp7zip.patch b/compressed_archive/libp7zip.patch deleted file mode 100644 index 872b8d76c..000000000 --- a/compressed_archive/libp7zip.patch +++ /dev/null @@ -1,305 +0,0 @@ -previous patch ---- libp7zip/CPP/include_windows/windows.h -+++ libp7zip/CPP/include_windows/windows.h -@@ -36,7 +36,7 @@ - #define WINAPI - - #undef BOOL --typedef int BOOL; -+typedef signed char BOOL; - - - #define CREATE_NEW 1 - -fix linux build ---- libp7zip/CPP/myWindows/StdAfx.h -+++ libp7zip/CPP/myWindows/StdAfx.h -@@ -206,8 +206,6 @@ - - #if defined( __x86_64__ ) - --#define _WIN64 1 -- - #endif - - #endif - -CVE-2016-9296 ---- libp7zip/CPP/7zip/Archive/7z/7zIn.cpp -+++ libp7zip/CPP/7zip/Archive/7z/7zIn.cpp -@@ -1097,7 +1097,8 @@ - if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i]) - ThrowIncorrect(); - } -- HeadersSize += folders.PackPositions[folders.NumPackStreams]; -+ if (folders.PackPositions) -+ HeadersSize += folders.PackPositions[folders.NumPackStreams]; - return S_OK; - } - -CVE-2017-17969 ---- libp7zip/CPP/7zip/Compress/ShrinkDecoder.cpp -+++ libp7zip/CPP/7zip/Compress/ShrinkDecoder.cpp -@@ -121,8 +121,13 @@ - { - _stack[i++] = _suffixes[cur]; - cur = _parents[cur]; -+ if (cur >= kNumItems || i >= kNumItems) -+ break; - } -- -+ -+ if (cur >= kNumItems || i >= kNumItems) -+ break; -+ - _stack[i++] = (Byte)cur; - lastChar2 = (Byte)cur; - - - - -CVE-2018-5996 ---- libp7zip/CPP/7zip/Compress/Rar1Decoder.cpp -+++ libp7zip/CPP/7zip/Compress/Rar1Decoder.cpp -@@ -29,7 +29,7 @@ public: - }; - */ - --CDecoder::CDecoder(): m_IsSolid(false) { } -+CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { } - - void CDecoder::InitStructures() - { -@@ -406,9 +406,14 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * - InitData(); - if (!m_IsSolid) - { -+ _errorMode = false; - InitStructures(); - InitHuff(); - } -+ -+ if (_errorMode) -+ return S_FALSE; -+ - if (m_UnpackSize > 0) - { - GetFlagsBuf(); -@@ -477,9 +482,9 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) - { - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } -- catch(const CInBufferException &e) { return e.ErrorCode; } -- catch(const CLzOutWindowException &e) { return e.ErrorCode; } -- catch(...) { return S_FALSE; } -+ catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; } -+ catch(const CLzOutWindowException &e) { _errorMode = true; return e.ErrorCode; } -+ catch(...) { _errorMode = true; return S_FALSE; } - } - - STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) - -CVE-2018-5996 ---- libp7zip/CPP/7zip/Compress/Rar1Decoder.h -+++ libp7zip/CPP/7zip/Compress/Rar1Decoder.h -@@ -39,6 +39,7 @@ public: - - Int64 m_UnpackSize; - bool m_IsSolid; -+ bool _errorMode; - - UInt32 ReadBits(int numBits); - HRESULT CopyBlock(UInt32 distance, UInt32 len); - -CVE-2018-5996 ---- libp7zip/CPP/7zip/Compress/Rar2Decoder.cpp -+++ blibp7zip/CPP/7zip/Compress/Rar2Decoder.cpp -@@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20; - static const UInt32 kWindowReservSize = (1 << 22) + 256; - - CDecoder::CDecoder(): -- m_IsSolid(false) -+ m_IsSolid(false), -+ m_TablesOK(false) - { - } - -@@ -100,6 +101,8 @@ UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numB - - bool CDecoder::ReadTables(void) - { -+ m_TablesOK = false; -+ - Byte levelLevels[kLevelTableSize]; - Byte newLevels[kMaxTableSize]; - m_AudioMode = (ReadBits(1) == 1); -@@ -170,6 +173,8 @@ bool CDecoder::ReadTables(void) - } - - memcpy(m_LastLevels, newLevels, kMaxTableSize); -+ m_TablesOK = true; -+ - return true; - } - -@@ -344,6 +349,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream * - return S_FALSE; - } - -+ if (!m_TablesOK) -+ return S_FALSE; -+ - UInt64 startPos = m_OutWindowStream.GetProcessedSize(); - while (pos < unPackSize) - { - -CVE-2018-5996 ---- libp7zip/CPP/7zip/Compress/Rar2Decoder.h -+++ libp7zip/CPP/7zip/Compress/Rar2Decoder.h -@@ -139,6 +139,7 @@ class CDecoder : - - UInt64 m_PackSize; - bool m_IsSolid; -+ bool m_TablesOK; - - void InitStructures(); - UInt32 ReadBits(unsigned numBits); - -CVE-2018-5996 ---- libp7zip/CPP/7zip/Compress/Rar3Decoder.cpp -+++ libp7zip/CPP/7zip/Compress/Rar3Decoder.cpp -@@ -92,7 +92,8 @@ CDecoder::CDecoder(): - _writtenFileSize(0), - _vmData(0), - _vmCode(0), -- m_IsSolid(false) -+ m_IsSolid(false), -+ _errorMode(false) - { - Ppmd7_Construct(&_ppmd); - } -@@ -545,6 +546,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) - return InitPPM(); - } - -+ TablesRead = false; -+ TablesOK = false; -+ - _lzMode = true; - PrevAlignBits = 0; - PrevAlignCount = 0; -@@ -606,6 +610,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) - } - } - } -+ if (InputEofError()) -+ return S_FALSE; -+ - TablesRead = true; - - // original code has check here: -@@ -623,6 +630,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing) - RIF(m_LenDecoder.Build(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize])); - - memcpy(m_LastLevels, newLevels, kTablesSizesSum); -+ -+ TablesOK = true; -+ - return S_OK; - } - -@@ -824,7 +834,12 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) - PpmEscChar = 2; - PpmError = true; - InitFilters(); -+ _errorMode = false; - } -+ -+ if (_errorMode) -+ return S_FALSE; -+ - if (!m_IsSolid || !TablesRead) - { - bool keepDecompressing; -@@ -838,6 +853,8 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress) - bool keepDecompressing; - if (_lzMode) - { -+ if (!TablesOK) -+ return S_FALSE; - RINOK(DecodeLZ(keepDecompressing)) - } - else - - -@@ -901,8 +918,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream - _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1; - return CodeReal(progress); - } -- catch(const CInBufferException &e) { return e.ErrorCode; } -- catch(...) { return S_FALSE; } -+ catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; } -+ catch(...) { _errorMode = true; return S_FALSE; } - // CNewException is possible here. But probably CNewException is caused - // by error in data stream. - } - -CVE-2018-5996 ---- libp7zip/CPP/7zip/Compress/Rar3Decoder.h -+++ libp7zip/CPP/7zip/Compress/Rar3Decoder.h -@@ -192,6 +192,7 @@ class CDecoder: - UInt32 _lastFilter; - - bool m_IsSolid; -+ bool _errorMode; - - bool _lzMode; - bool _unsupportedFilter; -@@ -200,6 +201,7 @@ class CDecoder: - UInt32 PrevAlignCount; - - bool TablesRead; -+ bool TablesOK; - - CPpmd7 _ppmd; - int PpmEscChar; - -CVE-2021-3465 ---- libp7zip/CPP/7zip/Common/StreamObjects.cpp -+++ libp7zip/CPP/7zip/Common/StreamObjects.cpp -@@ -157,6 +157,8 @@ STDMETHODIMP CDynBufSeqOutStream::Write( - - STDMETHODIMP CBufPtrSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) - { -+ if(_buffer == nullptr || _size == _pos) -+ return E_FAIL; - size_t rem = _size - _pos; - if (rem > size) - rem = (size_t)size; - -GCC10 warning fix ---- libp7zip/CPP/Windows/ErrorMsg.cpp 2015-01-18 11:20:28.000000000 -0700 -+++ libp7zip/CPP/Windows/ErrorMsg.cpp 2019-09-24 13:01:18.887289152 -0600 -@@ -14,14 +14,14 @@ UString MyFormatMessage(DWORD errorCode) - AString msg; - - switch(errorCode) { -- case ERROR_NO_MORE_FILES : txt = "No more files"; break ; -- case E_NOTIMPL : txt = "E_NOTIMPL"; break ; -- case E_NOINTERFACE : txt = "E_NOINTERFACE"; break ; -- case E_ABORT : txt = "E_ABORT"; break ; -- case E_FAIL : txt = "E_FAIL"; break ; -- case STG_E_INVALIDFUNCTION : txt = "STG_E_INVALIDFUNCTION"; break ; -- case E_OUTOFMEMORY : txt = "E_OUTOFMEMORY"; break ; -- case E_INVALIDARG : txt = "E_INVALIDARG"; break ; -+ case unsigned (ERROR_NO_MORE_FILES) : txt = "No more files"; break ; -+ case unsigned (E_NOTIMPL) : txt = "E_NOTIMPL"; break ; -+ case unsigned (E_NOINTERFACE) : txt = "E_NOINTERFACE"; break ; -+ case unsigned (E_ABORT) : txt = "E_ABORT"; break ; -+ case unsigned (E_FAIL) : txt = "E_FAIL"; break ; -+ case unsigned (STG_E_INVALIDFUNCTION) : txt = "STG_E_INVALIDFUNCTION"; break ; -+ case unsigned (E_OUTOFMEMORY) : txt = "E_OUTOFMEMORY"; break ; -+ case unsigned (E_INVALIDARG) : txt = "E_INVALIDARG"; break ; - case ERROR_DIRECTORY : txt = "Error Directory"; break ; - default: - txt = strerror(errorCode); From f65fd08e6511d90a9827fcbcb9f58c03824a1982 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 21 Mar 2026 20:45:23 +0100 Subject: [PATCH 157/187] Make flow ribbons themeable --- YACReaderLibrary/comic_flow_widget.cpp | 1 + YACReaderLibrary/images.qrc | 4 +- YACReaderLibrary/themes/builtin_classic.json | 3 + YACReaderLibrary/themes/builtin_dark.json | 3 + YACReaderLibrary/themes/builtin_light.json | 3 + YACReaderLibrary/themes/theme.h | 6 +- YACReaderLibrary/themes/theme_factory.cpp | 31 ++++- common/rhi/yacreader_flow_rhi.cpp | 130 +++++++++++++++---- common/rhi/yacreader_flow_rhi.h | 9 ++ images/readRibbon.png | Bin 2382 -> 0 bytes images/readRibbon.svg | 24 ++++ images/readingRibbon.png | Bin 2181 -> 0 bytes images/readingRibbon.svg | 19 +++ 13 files changed, 201 insertions(+), 32 deletions(-) delete mode 100644 images/readRibbon.png create mode 100644 images/readRibbon.svg delete mode 100644 images/readingRibbon.png create mode 100644 images/readingRibbon.svg diff --git a/YACReaderLibrary/comic_flow_widget.cpp b/YACReaderLibrary/comic_flow_widget.cpp index b75fdb527..0c2b603ed 100644 --- a/YACReaderLibrary/comic_flow_widget.cpp +++ b/YACReaderLibrary/comic_flow_widget.cpp @@ -24,6 +24,7 @@ void ComicFlowWidget::applyTheme(const Theme &theme) { setBackgroundColor(theme.comicFlow.backgroundColor); setTextColor(theme.comicFlow.textColor); + flow->setRibbonImages(theme.comicFlow.readPixmap.toImage(), theme.comicFlow.readingPixmap.toImage()); } void ComicFlowWidget::setBackgroundColor(const QColor &color) diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index 1f898934b..b221181ea 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -78,8 +78,8 @@ ../images/notCover.png ../images/library_dialogs/openLibrary.svg ../images/metadata_dialog/previousCoverPage.svg - ../images/readingRibbon.png - ../images/readRibbon.png + ../images/readingRibbon.svg + ../images/readRibbon.svg ../images/metadata_dialog/resetCover.svg ../images/search_result.svg ../images/serverConfigBackground.svg diff --git a/YACReaderLibrary/themes/builtin_classic.json b/YACReaderLibrary/themes/builtin_classic.json index e3dc64ac5..10c301cd5 100644 --- a/YACReaderLibrary/themes/builtin_classic.json +++ b/YACReaderLibrary/themes/builtin_classic.json @@ -1,6 +1,9 @@ { "comicFlow": { "backgroundColor": "#000000", + "readMainColor": "#db4725", + "readTickColor": "#8a2c17", + "readingColor": "#e6b90f", "textColor": "#4c4c4c" }, "comicsViewTable": { diff --git a/YACReaderLibrary/themes/builtin_dark.json b/YACReaderLibrary/themes/builtin_dark.json index b625814d9..2f5a4f41f 100644 --- a/YACReaderLibrary/themes/builtin_dark.json +++ b/YACReaderLibrary/themes/builtin_dark.json @@ -1,6 +1,9 @@ { "comicFlow": { "backgroundColor": "#111111", + "readMainColor": "#db4725", + "readTickColor": "#8a2c17", + "readingColor": "#e6b90f", "textColor": "#888888" }, "comicsViewTable": { diff --git a/YACReaderLibrary/themes/builtin_light.json b/YACReaderLibrary/themes/builtin_light.json index cf6916ea8..25d88e86f 100644 --- a/YACReaderLibrary/themes/builtin_light.json +++ b/YACReaderLibrary/themes/builtin_light.json @@ -1,6 +1,9 @@ { "comicFlow": { "backgroundColor": "#dcdcdc", + "readMainColor": "#db4725", + "readTickColor": "#8a2c17", + "readingColor": "#e6b90f", "textColor": "#303030" }, "comicsViewTable": { diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index 9ade45fa7..54ba16ad5 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -92,9 +92,11 @@ struct MetadataScraperDialogThemeTemplates { QSize rowIconSize = QSize(8, 7); }; -struct ComicFlowColors { +struct ComicFlowTheme { QColor backgroundColor; QColor textColor; + QPixmap readPixmap; + QPixmap readingPixmap; }; struct ComicsViewTableThemeTemplates { @@ -484,7 +486,7 @@ struct Theme { ThemeMeta meta; QJsonObject sourceJson; - ComicFlowColors comicFlow; + ComicFlowTheme comicFlow; MetadataScraperDialogTheme metadataScraperDialog; HelpAboutDialogTheme helpAboutDialog; WhatsNewDialogTheme whatsNewDialog; diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index a65359dc7..22f216119 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -330,10 +330,18 @@ struct WhatsNewDialogParams { QColor headerDecorationColor; }; +struct ComicFlowParams { + QColor backgroundColor; + QColor textColor; + QColor readMainColor; // Main ribbon color for read state (#f0f in readRibbon.svg) + QColor readTickColor; // Tick color for read state (#0ff in readRibbon.svg) + QColor readingColor; // Main ribbon color for reading state (#f0f in readingRibbon.svg) +}; + struct ThemeParams { ThemeMeta meta; - ComicFlowColors comicFlowColors; + ComicFlowParams comicFlowParams; MetadataScraperDialogParams metadataScraperDialogParams; HelpAboutDialogTheme helpAboutDialogParams; EmptyContainerParams emptyContainerParams; @@ -361,10 +369,22 @@ Theme makeTheme(const ThemeParams ¶ms) Theme theme; // Comic Flow - const auto &cf = params.comicFlowColors; + const auto &cf = params.comicFlowParams; theme.comicFlow.backgroundColor = cf.backgroundColor; theme.comicFlow.textColor = cf.textColor; + { + const qreal dpr = qApp->devicePixelRatio(); + // readRibbon: #f0f (main) + #0ff (tick) + theme.comicFlow.readPixmap = renderSvgToPixmap( + recoloredSvgToThemeFile(":/images/readRibbon.svg", cf.readMainColor, cf.readTickColor, params.meta.id), + 100, 136, dpr); + // readingRibbon: #f0f (main) + theme.comicFlow.readingPixmap = renderSvgToPixmap( + recoloredSvgToThemeFile(":/images/readingRibbon.svg", cf.readingColor, params.meta.id), + 100, 136, dpr); + } + // MetadataScraperDialog const auto &msd = params.metadataScraperDialogParams; const auto &t = msd.t; @@ -918,8 +938,11 @@ Theme makeTheme(const QJsonObject &json) if (json.contains("comicFlow")) { const auto o = json["comicFlow"].toObject(); - p.comicFlowColors.backgroundColor = colorFromJson(o, "backgroundColor", p.comicFlowColors.backgroundColor); - p.comicFlowColors.textColor = colorFromJson(o, "textColor", p.comicFlowColors.textColor); + p.comicFlowParams.backgroundColor = colorFromJson(o, "backgroundColor", p.comicFlowParams.backgroundColor); + p.comicFlowParams.textColor = colorFromJson(o, "textColor", p.comicFlowParams.textColor); + p.comicFlowParams.readMainColor = colorFromJson(o, "readMainColor", p.comicFlowParams.readMainColor); + p.comicFlowParams.readTickColor = colorFromJson(o, "readTickColor", p.comicFlowParams.readTickColor); + p.comicFlowParams.readingColor = colorFromJson(o, "readingColor", p.comicFlowParams.readingColor); } if (json.contains("metadataScraperDialog")) { diff --git a/common/rhi/yacreader_flow_rhi.cpp b/common/rhi/yacreader_flow_rhi.cpp index 5d1a74052..7db946660 100644 --- a/common/rhi/yacreader_flow_rhi.cpp +++ b/common/rhi/yacreader_flow_rhi.cpp @@ -138,28 +138,8 @@ void YACReaderFlow3D::initialize(QRhiCommandBuffer *cb) qDebug() << "YACReaderFlow3D: Created defaultTexture" << defaultImage.size(); } -#ifdef YACREADER_LIBRARY - // Initialize mark textures - if (!scene.markTexture) { - QImage markImage = QImage(":/images/readRibbon.png").convertToFormat(QImage::Format_RGBA8888); - if (!markImage.isNull()) { - scene.markTexture.reset(m_rhi->newTexture(QRhiTexture::RGBA8, markImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips)); - scene.markTexture->create(); - getResourceBatch()->uploadTexture(scene.markTexture.get(), markImage); - getResourceBatch()->generateMips(scene.markTexture.get()); - } - } - - if (!scene.readingTexture) { - QImage readingImage = QImage(":/images/readingRibbon.png").convertToFormat(QImage::Format_RGBA8888); - if (!readingImage.isNull()) { - scene.readingTexture.reset(m_rhi->newTexture(QRhiTexture::RGBA8, readingImage.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips)); - scene.readingTexture->create(); - getResourceBatch()->uploadTexture(scene.readingTexture.get(), readingImage); - getResourceBatch()->generateMips(scene.readingTexture.get()); - } - } -#endif + if (ribbonTexturesDirty || (!readRibbonImage.isNull() && !scene.markTexture) || (!readingRibbonImage.isNull() && !scene.readingTexture)) + syncRibbonTextures(getResourceBatch()); // Create vertex buffer (quad geometry) if (!scene.vertexBuffer) { @@ -373,8 +353,34 @@ void YACReaderFlow3D::ensurePipeline() void YACReaderFlow3D::render(QRhiCommandBuffer *cb) { - if (!m_rhi || numObjects == 0) + if (!m_rhi) + return; + + QRhiResourceUpdateBatch *batch = scene.resourceUpdates; + scene.resourceUpdates = nullptr; + + auto ensureBatch = [this, &batch]() { + if (!batch) + batch = m_rhi->nextResourceUpdateBatch(); + return batch; + }; + auto deferBatch = [this, &batch]() { + if (batch) + scene.resourceUpdates = batch; + }; + +#ifdef YACREADER_LIBRARY + if (ribbonTexturesDirty || (!readRibbonImage.isNull() && !scene.markTexture) || (!readingRibbonImage.isNull() && !scene.readingTexture)) + syncRibbonTextures(ensureBatch()); +#endif + + // Even without draw calls, pending uploads still have to reach the GPU. + // Otherwise recreated ribbon textures would exist but never receive pixels. + if (numObjects == 0) { + if (batch) + cb->resourceUpdate(batch); return; + } const QSize outputSize = renderTarget()->pixelSize(); const QColor clearColor = backgroundColor; @@ -552,6 +558,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) ensureUniformBufferCapacity(draws.size()); if (!scene.uniformBuffer) { + deferBatch(); qWarning() << "YACReaderFlow3D: No uniform buffer available for rendering"; return; } @@ -560,6 +567,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) ensurePipeline(); if (!scene.pipeline) { + deferBatch(); qWarning() << "YACReaderFlow3D: No pipeline available for rendering"; return; } @@ -569,6 +577,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) if (!scene.instanceBuffer || scene.instanceBuffer->size() < requiredInstanceSize) { scene.instanceBuffer.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::VertexBuffer, requiredInstanceSize)); if (!scene.instanceBuffer->create()) { + deferBatch(); qWarning() << "YACReaderFlow3D: Failed to create instance buffer of size" << requiredInstanceSize; return; } @@ -576,7 +585,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) // === PHASE 1: PREPARE (BEFORE PASS) === // Update ALL uniform and instance data for ALL draws in one batch - QRhiResourceUpdateBatch *batch = m_rhi->nextResourceUpdateBatch(); + batch = ensureBatch(); // Process pending texture uploads if (!pendingTextureUploads.isEmpty()) { @@ -603,6 +612,7 @@ void YACReaderFlow3D::render(QRhiCommandBuffer *cb) // === PHASE 2: RENDER (DURING PASS) === cb->beginPass(renderTarget(), clearColor, { 1.0f, 0 }, batch); + batch = nullptr; cb->setGraphicsPipeline(scene.pipeline.get()); cb->setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height())); @@ -762,6 +772,65 @@ void YACReaderFlow3D::executeDrawWithOffset(QRhiCommandBuffer *cb, QRhiTexture * cb->draw(6); } +void YACReaderFlow3D::removeCachedShaderBindings(QRhiTexture *texture) +{ + if (!texture) + return; + + auto it = scene.shaderBindingsCache.find(texture); + if (it != scene.shaderBindingsCache.end()) { + delete it.value(); + scene.shaderBindingsCache.erase(it); + } +} + +void YACReaderFlow3D::syncRibbonTextures(QRhiResourceUpdateBatch *batch) +{ +#ifndef YACREADER_LIBRARY + Q_UNUSED(batch); + ribbonTexturesDirty = false; +#else + if (!m_rhi || !batch) + return; + + bool allTexturesReady = true; + + auto syncTexture = [this, batch, &allTexturesReady](std::unique_ptr &texture, const QImage &image, const char *name) { + if (image.isNull()) { + if (texture) { + removeCachedShaderBindings(texture.get()); + texture.reset(); + } + return; + } + + if (texture && !ribbonTexturesDirty) + return; + + if (texture) { + removeCachedShaderBindings(texture.get()); + texture.reset(); + } + + std::unique_ptr newTexture(m_rhi->newTexture(QRhiTexture::RGBA8, image.size(), 1, QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips)); + if (!newTexture->create()) { + qWarning() << "YACReaderFlow3D: Failed to create" << name << "ribbon texture"; + allTexturesReady = false; + return; + } + + batch->uploadTexture(newTexture.get(), image); + batch->generateMips(newTexture.get()); + texture = std::move(newTexture); + }; + + syncTexture(scene.markTexture, readRibbonImage, "read"); + syncTexture(scene.readingTexture, readingRibbonImage, "reading"); + + ribbonTexturesDirty = !allTexturesReady; +#endif +} + void YACReaderFlow3D::releaseResources() { scene.reset(); @@ -1278,6 +1347,19 @@ void YACReaderFlow3D::setTextColor(const QColor &color) update(); } +void YACReaderFlow3D::setRibbonImages(const QImage &readImage, const QImage &readingImage) +{ + readRibbonImage = readImage.convertToFormat(QImage::Format_RGBA8888); + readingRibbonImage = readingImage.convertToFormat(QImage::Format_RGBA8888); +#ifdef YACREADER_LIBRARY + ribbonTexturesDirty = true; +#else + ribbonTexturesDirty = false; +#endif + + update(); +} + // Event handlers void YACReaderFlow3D::wheelEvent(QWheelEvent *event) { diff --git a/common/rhi/yacreader_flow_rhi.h b/common/rhi/yacreader_flow_rhi.h index ca7184dd0..a1062bbb3 100644 --- a/common/rhi/yacreader_flow_rhi.h +++ b/common/rhi/yacreader_flow_rhi.h @@ -179,6 +179,10 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement QColor backgroundColor; QColor textColor; + QImage readRibbonImage; + QImage readingRibbonImage; + bool ribbonTexturesDirty = false; + /*** System info ***/ float viewRotate; @@ -202,6 +206,8 @@ class YACReaderFlow3D : public QRhiWidget, public ScrollManagement // Helper methods QRhiTexture *createTextureFromImage(QRhiCommandBuffer *cb, const QImage &image); + void removeCachedShaderBindings(QRhiTexture *texture); + void syncRibbonTextures(QRhiResourceUpdateBatch *batch); void updateUniformBuffer(QRhiCommandBuffer *cb, const UniformData &data); void prepareMarkInstanceData(const YACReader3DImageRHI &image, QVector &data); void ensureUniformBufferCapacity(int requiredSlots); @@ -260,6 +266,9 @@ public slots: void setBackgroundColor(const QColor &color); void setTextColor(const QColor &color); + // Ribbon image setters (for themed SVG rasterized images) + void setRibbonImages(const QImage &readImage, const QImage &readingImage); + virtual void updateImageData() = 0; void reset(); diff --git a/images/readRibbon.png b/images/readRibbon.png deleted file mode 100644 index 4dcd32e214e95372050a17ef1c07097110d18222..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2382 zcmV-U39iBuAOSP&pW?9uO9Sow&?60x=GVLOn%aSx8erG!Qa{vEa4at7>0g zUe#P8OAlcjjkCC-p8R6K|LmTApNFg_C>T|*M9CCT3Gvbk>sS0xYM0hw2#vRBNI#HI&CZ{U)`cooL@lBMbl z>(TOP4xJ2{bR<&P3_(L6Xb1#>pdkpdksV1^VYj4Km~sr9u>oG5z>Wt|)hZF!Ag zQ07I+;$g5*It43V@_dCMDinD>!w?aQJl|oU>=h8kEoBRYY3@a*vH-?l4lqPHU!fmz z(CT`oSMMZ@NER?k35-goP*Iir1)horU+&T8Un$lj)ob6K+q5f z_7F785CnpTK(L2k55WvU%OyiFMKD9qilK+}hvPjbJmEH2USC^r|B8x|RmEAdEMVWb z0*80^c~9Bs-+$jf;BR~9j+zIbs;hh&f#lKRiW>R+AK!tm2LoMX75=Y{q;@_8&>usQ zgy)Ur)tgIXsT50A9$lZT^H3{_xJ)ZB~O~sV5hG z@zn69_Th%XNa7k<9itxRfK(7q5MVuBf#~)x?_2g(b%}i$sw{);@_4+9!f=z-QQ}@; zM17RHwho_-!gt{}@LL38p!Eb}tsBm`_K*M%Gl3ta8KRY~ak@Oleg}R7zlCjJ4>7>L z9SSz@>h=Ck7K6kCG~fXm{0V3)n#!WhU7?4s()Z!L#Pe-K``%qy)A!`fi=RW4m1Fb% zX(V)n!1#>=5v17=VPL4tb)>nX!JywukZrX{IFlhM`rXOw+1cwoel8GoiK@Vao67WdF+@!wm$+Wd??yma1_&2uv_A zRPNGIx&D!$zZs|7nA#@n1NH^`EX27Aud;eVvDU{=UD?GbDKC8u=#;71&Wnc6tsuW2*f$&lmMr2& zhl7W<{p~(X#|<9pJ}xt|g)tKpHdChU4~_wjrO+j-U@8lgR6QuEt63?jT%?A|H2bs) zjL72S=f|S1?FCd|1pxv|>a%{|K?=i9uhvYJlx>bs(kU>N9#i9+E2>{CgaUIE0>);d zZd{SXRZdCi^$XQzoB(IHlj6Xz`vEB3UBOtxfwlRcn9OSr=?=zPDGWE08M!K{xqwNh zz~GqtaEx%QaLh$1dppJ=f4vERybxj_M(!#M~8yVTRTS% z8Z2w`0cG+y;n?9E3On0tKuADI?Hd?vIy@L?&tQTupD^^AeKOs|Gp$8VMz>EItgkhU2M;_g9)Hi%kInN@`2zbxO)iS!*Pev=fu$ z0_(mIjBRgPV~zqdyobQ;QVPSJ;{;(Lp=2~M3FijqXvVE!LuD^a(miw5wZ~=51Yx1U zq@9?AbA)q+bIz0O&2AUp4F{Sxwi`Y{SV$-tDKI!^ICrCv%(;g^^ZwZ#KJsawFOyrX zR)CSU0wd?%BH1M6k);)LzBN3jha3RL&R%b0i}*^)bOlCa@$vJ4sO!CzHFHv6IcEqc zsT~(Rd)srn)oQaSl(Y(rT$tV7c&dKKU9~yi8qP^&jYO0EWc1q5p8Ks68 zrak@pk4pnI@D}ek6lRH-90s zKqLyJgt+tJ+VZ7QMGZ9#_?yT$;}TOR(>3q;1cQg7>Oj$ynXP|3KGqkGx876ftoFo` zXX<;sKhRPaW5zj?8`ECx6bAhJiY3Hrh?mp%3ccbZ6hNHrM3Z>q^Qd{}+E-FK^CT&n2~N5mr7=#hS;P+v zwI6D#L1jMIba%|6(;$VOZqXXQ_Lt3)HvOmfrvlEZh6J+_yKVZvvq&P0oTgi}xZ3Gw z)23b6lJC&jSc-X-7*GnAUI-)e=@ukD*HIP*c{0J36WZzS4OjVI)i>V{c zM$}9OGH6+WnKh=4Oh@WyhJrC>E(^_k`&WPg0HX#fUvSPh0{{R307*qoM6N<$f^*ML AfdBvi diff --git a/images/readRibbon.svg b/images/readRibbon.svg new file mode 100644 index 000000000..7eced57ee --- /dev/null +++ b/images/readRibbon.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/readingRibbon.png b/images/readingRibbon.png deleted file mode 100644 index 476912ef207b7d9f8963558d66f11fe3fa8ddcdb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2181 zcmV;02zvL4P)RCwC#U0rMxRTQ56X}2v{OoYUk zm>6G7j1QVQ6x`!l<XI=eu{dsU!i8f-A}6 zKxUzv4|vBQ!X+38$~*zOi45I}5Rn8AGq+$MBy)sl+*JN4k~B<+L4=!=QLti(Z^nux zMRmSHX(s%bImn9C@a0~4@zy<&Ubd@nVsxt%<>mwxGAq7vr1Vg6k?SeAF!Kn@`q>9& z56)$q5oS?=6y0k zvK@tjc#_P7NEXBZ_QE4X$EXO=O_EH5zp^qZA2pqDTTE6!NDfy?ykksU)X|fAAR92J zEZt&S59ELl$$}Wb0fYcKhIgzJ2oXdG07CL8Wg%xFLI4l~LI4l~LI9{NLNpoSo20U!i~05;SR6cI!S0NINO0Wc3iga9A} zDGNY^fDi!l5D)@Jkg@;}f|LayLZGq$q%5Q?0E8fAA!Q*#01%SzvKJ`}5dwe^s4M^x z0zv?&EJO$ZLZGq$LiI)Rp5WrYTIJDzStVrRl`{do#N27kW8(|hR`ojo1d9_>bUA@rvrmsLMM#{1oQAWl`yCd5V z{jRjJ-CN9th$DX5$7~8Cs=4o$e!KF`q7{XCMoM0#tlj~=>*Wohs;k{v58LhMcH2bA zRAvezto8gQwQT?Tl2tRNx$cAP%`h%q*ZiD}8*I0aS%BG1ZhhR0eLB}i*V1?ByZKLu z?i{;tS#5gZgP|SF!Civm`*?&HX={jY_lwuicj&ux4=430X+oUR?z$67-HU5OU$f01 zANc|9@Ig*Ogr_W-Zx8WveZuuYx(D6M;e0r^s8jL&@i*nb`s&CpYYrcZPSKX;nLTnli{3{QDQ`j zv8^$pTY7?8#kS?e%bljc997gid$jh2pN6U!8J7hzf;?3j^+FNIFsEekm=PI9T^SJX zNzb5X(KAuhE$l*v+VtG}LzRM(GK%+rMVh)(Z8Vc23#9Z3vbc+$NzZmlQFp{VtN@~sbOi48)rKD2Pe!5WX6DzPiOo3feJ2$lM&>jb-YSSN|TgC3QUg=5MA2-;X>cC={ZnfS&tARV^Kw@>S~YH zZBkNJ^+K02HzN}7qnd~jpQE#Z(sKSEwW_|XWL36F$!ZPpUsjtIZHkj|Lx_x2l~g*! zBvN41rXaPE+UmD!4J_9xtFcWz{n96)Z%nc_T_u%nv?Nksaal}lrnXP02-$m5se5%x zs3ya*HXEeG+evMwKIBwoWx^w*q_!QDcU2#Yo*TykVK&LID)zBN3zOwPM2@jE7FapY z_qLr1%(nm1Mr4%LM7AG38?#&1W|EYIvX~95=9>drsA8FYve=dyLP~1Rx=iZ`8-UAf&xZ^S@FVuDbTWl1g@gFqfo^YhjZ5Mt!8d zW{nWaSjn2dLu;C|HnfA~+Dt4E=9-wq3zMvm)K}_rD!#H^W!0Zj>gI3E_yVDmQkbOz zqdrsL9kZ52#rt4`a$rN9Jf2sr`9Ma}3XJtV{%UyM%=BLkd($Q3Te@E&$gxXs#VHUQWCxzCI!~hAFkN?M$z)=rKzofrKGa1 z2ekIZpM|R!8L7T%%|}wkrNGE1Y(bQ&O9E9aS2ITxtB2^R}s8Oa?MUxJ-gY6BO9+;5_A5uXhHt zmS-OEKH+go1$1m6q#wS}5ns(1F_1+bE}sIlAj$L#$26lZlG= zWFo^%if%!Qq0FRI)5FQ2zpuEP*>q-8 z`0*%@hylLfX6LKcd?rTBG~~+?W_K~0#;lYdQ~6*H2y?dK-za-cc~RpdKFkS-@`o4_ zZ)g$~?^NrGYN4rA9tlN!Kf-;ih*4yo7#d$RRD&*@H*~k0r^_I@UT!f8e*wQPCRzV_ zf7s!oYEXomcm$$i!ps|FB)8mR_|?PDjaYUOQ@+b02O4?MEu7Z`(?Q0#Yl>v@r`uE> zG_x3XCAf*pVulJL(j(@MK6TyUCRRlYNRJr!6aZ4je*z2uy9!eNKIi)C00000NkvXX Hu0mjf3A6ob diff --git a/images/readingRibbon.svg b/images/readingRibbon.svg new file mode 100644 index 000000000..1cd07eaac --- /dev/null +++ b/images/readingRibbon.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + \ No newline at end of file From 2560174a8422eed28ed00be7738f2d841f7ce962 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sat, 21 Mar 2026 20:55:23 +0100 Subject: [PATCH 158/187] Extract noLibrariesWidget theme and use themed line assets --- YACReaderLibrary/images.qrc | 6 +- YACReaderLibrary/import_widget.cpp | 26 ++++--- YACReaderLibrary/import_widget.h | 3 + YACReaderLibrary/no_libraries_widget.cpp | 15 ++-- YACReaderLibrary/no_libraries_widget.h | 1 + YACReaderLibrary/themes/builtin_classic.json | 12 ++- YACReaderLibrary/themes/builtin_dark.json | 12 ++- YACReaderLibrary/themes/builtin_light.json | 12 ++- YACReaderLibrary/themes/theme.h | 15 ++-- YACReaderLibrary/themes/theme_factory.cpp | 62 +++++++++++---- images/glowLine.png | Bin 460 -> 0 bytes images/glowLine.svg | 75 +++++++++++++++++++ images/noLibrariesLine.png | Bin 238 -> 0 bytes images/noLibrariesLine.svg | 43 +++++++++++ 14 files changed, 228 insertions(+), 54 deletions(-) delete mode 100644 images/glowLine.png create mode 100644 images/glowLine.svg delete mode 100644 images/noLibrariesLine.png create mode 100644 images/noLibrariesLine.svg diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index b221181ea..86783e830 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -42,7 +42,7 @@ ../images/flow3.png ../images/flow4.png ../images/flow5.png - ../images/glowLine.png + ../images/glowLine.svg ../images/metadata_dialog/loadCustomCover.svg ../images/import/coversToggle.svg ../images/icon-new.svg @@ -74,7 +74,7 @@ ../images/library_dialogs/new.svg ../images/metadata_dialog/nextCoverPage.svg ../images/noLibrariesIcon.svg - ../images/noLibrariesLine.png + ../images/noLibrariesLine.svg ../images/notCover.png ../images/library_dialogs/openLibrary.svg ../images/metadata_dialog/previousCoverPage.svg @@ -111,13 +111,11 @@ ../images/import/updatingIcon.svg ../images/custom_dialog/custom_close_button.svg ../images/whats_new/whatsnew_header.svg - ../images/lists/default_0.svg ../images/lists/default_1.svg ../images/lists/default_2.svg ../images/lists/label_template.svg ../images/lists/list.svg - ../images/clearSearchNew.svg ../images/iconSearchNew.svg diff --git a/YACReaderLibrary/import_widget.cpp b/YACReaderLibrary/import_widget.cpp index 9c3935814..9dafa3958 100644 --- a/YACReaderLibrary/import_widget.cpp +++ b/YACReaderLibrary/import_widget.cpp @@ -23,6 +23,8 @@ class YACReaderActivityIndicatorWidget : public QWidget { public: YACReaderActivityIndicatorWidget(QWidget *parent = 0); + void setPixmaps(const QPixmap &normalLine, const QPixmap &glowLine); + public slots: private: @@ -31,16 +33,11 @@ public slots: }; YACReaderActivityIndicatorWidget::YACReaderActivityIndicatorWidget(QWidget *parent) - : QWidget(parent) + : QWidget(parent), normal(nullptr), glow(nullptr) { - QPixmap line(":/images/noLibrariesLine.png"); - QPixmap glowLine(":/images/glowLine.png"); normal = new QLabel(this); glow = new QLabel(this); - normal->setPixmap(line); - glow->setPixmap(glowLine); - auto layout = new QHBoxLayout(); layout->addWidget(normal, 0, Qt::AlignVCenter); @@ -50,11 +47,6 @@ YACReaderActivityIndicatorWidget::YACReaderActivityIndicatorWidget(QWidget *pare layout->setContentsMargins(4, 4, 4, 4); layout->setSpacing(0); - // setFixedHeight(3); - // resize(579,3); - glow->setGeometry(4, 4, glowLine.width(), glowLine.height()); - // normal->setGeometry(0,1,579,1); - auto effect = new QGraphicsOpacityEffect(); // effect->setOpacity(1.0); @@ -80,6 +72,13 @@ YACReaderActivityIndicatorWidget::YACReaderActivityIndicatorWidget(QWidget *pare animation->start(); } +void YACReaderActivityIndicatorWidget::setPixmaps(const QPixmap &normalLine, const QPixmap &glowLine) +{ + normal->setPixmap(normalLine); + glow->setPixmap(glowLine); + glow->setGeometry(4, 4, glowLine.width(), glowLine.height()); +} + ImportWidget::ImportWidget(QWidget *parent) : QWidget(parent) { @@ -88,7 +87,7 @@ ImportWidget::ImportWidget(QWidget *parent) iconLabel = new QLabel(); - auto activityIndicator = new YACReaderActivityIndicatorWidget(); + activityIndicator = new YACReaderActivityIndicatorWidget(); text = new QLabel(); textDescription = new QLabel(); @@ -399,6 +398,9 @@ void ImportWidget::applyTheme(const Theme &theme) bottomDecorator->setPixmap(importTheme.bottomCoversDecoration); bottomDecorator->setFixedHeight(importTheme.bottomCoversDecoration.height()); + const auto &noLibrariesWidget = theme.noLibrariesWidget; + activityIndicator->setPixmaps(noLibrariesWidget.noLibrariesLinePixmap, importTheme.glowLinePixmap); + // Apply text colors updateTextColors(); } diff --git a/YACReaderLibrary/import_widget.h b/YACReaderLibrary/import_widget.h index 945b38aae..9da45b84f 100644 --- a/YACReaderLibrary/import_widget.h +++ b/YACReaderLibrary/import_widget.h @@ -14,6 +14,8 @@ #include #include +class YACReaderActivityIndicatorWidget; + class ImportWidget : public QWidget, protected Themable { Q_OBJECT @@ -57,6 +59,7 @@ public slots: QToolButton *hideButton; QLabel *topDecorator; QLabel *bottomDecorator; + YACReaderActivityIndicatorWidget *activityIndicator; void resizeEvent(QResizeEvent *event) override; void updateTextColors(); diff --git a/YACReaderLibrary/no_libraries_widget.cpp b/YACReaderLibrary/no_libraries_widget.cpp index ec5865a00..8a539601b 100644 --- a/YACReaderLibrary/no_libraries_widget.cpp +++ b/YACReaderLibrary/no_libraries_widget.cpp @@ -13,9 +13,7 @@ NoLibrariesWidget::NoLibrariesWidget(QWidget *parent) iconLabel = new QLabel(); - QPixmap line(":/images/noLibrariesLine.png"); - QLabel *lineLabel = new QLabel(); - lineLabel->setPixmap(line); + lineLabel = new QLabel(); text = new QLabel(tr("You don't have any libraries yet")); text->setStyleSheet("QLabel {font-size:25px;font-weight:bold;}"); @@ -75,19 +73,20 @@ NoLibrariesWidget::NoLibrariesWidget(QWidget *parent) void NoLibrariesWidget::applyTheme(const Theme &theme) { - auto emptyTheme = theme.emptyContainer; + auto nlwTheme = theme.noLibrariesWidget; QPalette p(palette()); - p.setColor(QPalette::Window, emptyTheme.backgroundColor); + p.setColor(QPalette::Window, nlwTheme.backgroundColor); setPalette(p); QPalette textPalette = text->palette(); - textPalette.setColor(QPalette::WindowText, emptyTheme.textColor); + textPalette.setColor(QPalette::WindowText, nlwTheme.textColor); text->setPalette(textPalette); QPalette descPalette = textDescription->palette(); - descPalette.setColor(QPalette::WindowText, emptyTheme.descriptionTextColor); + descPalette.setColor(QPalette::WindowText, nlwTheme.descriptionTextColor); textDescription->setPalette(descPalette); - iconLabel->setPixmap(emptyTheme.noLibrariesIcon); + iconLabel->setPixmap(nlwTheme.noLibrariesIcon); + lineLabel->setPixmap(nlwTheme.noLibrariesLinePixmap); } diff --git a/YACReaderLibrary/no_libraries_widget.h b/YACReaderLibrary/no_libraries_widget.h index 4e0ea74f6..19967071d 100644 --- a/YACReaderLibrary/no_libraries_widget.h +++ b/YACReaderLibrary/no_libraries_widget.h @@ -25,6 +25,7 @@ public slots: QLabel *iconLabel; QLabel *text; QLabel *textDescription; + QLabel *lineLabel; }; #endif // NO_LIBRARIES_WIDGET_H diff --git a/YACReaderLibrary/themes/builtin_classic.json b/YACReaderLibrary/themes/builtin_classic.json index 10c301cd5..9afcec68e 100644 --- a/YACReaderLibrary/themes/builtin_classic.json +++ b/YACReaderLibrary/themes/builtin_classic.json @@ -39,9 +39,7 @@ }, "emptyContainer": { "backgroundColor": "#2a2a2a", - "descriptionTextColor": "#aaaaaa", - "searchIconColor": "#4c4c4c", - "textColor": "#cccccc", + "iconColor": "#4c4c4c", "titleTextColor": "#cccccc" }, "gridAndInfoView": { @@ -97,6 +95,7 @@ "coversViewBackgroundColor": "#3a3a3a", "currentComicTextColor": "#aaaaaa", "descriptionTextColor": "#aaaaaa", + "glowLineColor": "#ffe100", "iconCheckedColor": "#aaaaaa", "iconColor": "#cccccc", "modeIconColor": "#4a4a4a", @@ -179,6 +178,13 @@ "selectionBackgroundColor": "#2e2e2e", "textColor": "#dddfdf" }, + "noLibrariesWidget": { + "backgroundColor": "#2a2a2a", + "descriptionTextColor": "#aaaaaa", + "iconColor": "#4c4c4c", + "noLibrariesLineColor": "#a8a8a8", + "textColor": "#cccccc" + }, "readingListIcons": { "currentlyReadingMainColor": "#ffcc00", "currentlyReadingMainSelectedColor": "#ffcc00", diff --git a/YACReaderLibrary/themes/builtin_dark.json b/YACReaderLibrary/themes/builtin_dark.json index 2f5a4f41f..7a26d484e 100644 --- a/YACReaderLibrary/themes/builtin_dark.json +++ b/YACReaderLibrary/themes/builtin_dark.json @@ -39,9 +39,7 @@ }, "emptyContainer": { "backgroundColor": "#2a2a2a", - "descriptionTextColor": "#aaaaaa", - "searchIconColor": "#4c4c4c", - "textColor": "#cccccc", + "iconColor": "#4c4c4c", "titleTextColor": "#cccccc" }, "gridAndInfoView": { @@ -97,6 +95,7 @@ "coversViewBackgroundColor": "#3a3a3a", "currentComicTextColor": "#aaaaaa", "descriptionTextColor": "#aaaaaa", + "glowLineColor": "#ffe100", "iconCheckedColor": "#aaaaaa", "iconColor": "#cccccc", "modeIconColor": "#4a4a4a", @@ -179,6 +178,13 @@ "selectionBackgroundColor": "#2e2e2e", "textColor": "#dddfdf" }, + "noLibrariesWidget": { + "backgroundColor": "#2a2a2a", + "descriptionTextColor": "#aaaaaa", + "iconColor": "#4c4c4c", + "noLibrariesLineColor": "#a8a8a8", + "textColor": "#cccccc" + }, "readingListIcons": { "currentlyReadingMainColor": "#ffcc00", "currentlyReadingMainSelectedColor": "#ffcc00", diff --git a/YACReaderLibrary/themes/builtin_light.json b/YACReaderLibrary/themes/builtin_light.json index 25d88e86f..9742b606f 100644 --- a/YACReaderLibrary/themes/builtin_light.json +++ b/YACReaderLibrary/themes/builtin_light.json @@ -39,9 +39,7 @@ }, "emptyContainer": { "backgroundColor": "#ffffff", - "descriptionTextColor": "#565959", - "searchIconColor": "#cccccc", - "textColor": "#495252", + "iconColor": "#cccccc", "titleTextColor": "#888888" }, "gridAndInfoView": { @@ -97,6 +95,7 @@ "coversViewBackgroundColor": "#e6e6e6", "currentComicTextColor": "#565959", "descriptionTextColor": "#565959", + "glowLineColor": "#ffe100", "iconCheckedColor": "#565959", "iconColor": "#495252", "modeIconColor": "#e6e6e6", @@ -179,6 +178,13 @@ "selectionBackgroundColor": "#333133", "textColor": "#000000" }, + "noLibrariesWidget": { + "backgroundColor": "#ffffff", + "descriptionTextColor": "#565959", + "iconColor": "#cccccc", + "noLibrariesLineColor": "#a8a8a8", + "textColor": "#495252" + }, "readingListIcons": { "currentlyReadingMainColor": "#ffcc00", "currentlyReadingMainSelectedColor": "#ffcc00", diff --git a/YACReaderLibrary/themes/theme.h b/YACReaderLibrary/themes/theme.h index 54ba16ad5..6117dd4fd 100644 --- a/YACReaderLibrary/themes/theme.h +++ b/YACReaderLibrary/themes/theme.h @@ -122,11 +122,6 @@ struct EmptyContainerTheme { QColor backgroundColor; QString titleLabelQSS; - // For NoLibrariesWidget - QColor textColor; - QColor descriptionTextColor; - QPixmap noLibrariesIcon; - // Search-related icons (themed from search_result.svg) QPixmap searchingIcon; // For ClassicComicsView searching state QPixmap noSearchResultsIcon; // For NoSearchResultsWidget empty state @@ -139,6 +134,14 @@ struct EmptyContainerTheme { QMap emptyLabelIcons; // Keyed by YACReader::LabelColors enum value }; +struct NoLibrariesWidgetTheme { + QColor backgroundColor; // Background of the widget + QColor textColor; // Main title text color + QColor descriptionTextColor; // Description text color + QPixmap noLibrariesIcon; // Icon displayed in the widget + QPixmap noLibrariesLinePixmap; // Themed horizontal line separator +}; + struct SidebarTheme { QColor backgroundColor; QColor separatorColor; @@ -172,6 +175,7 @@ struct ImportWidgetTheme { QPixmap importingIcon; QPixmap updatingIcon; QIcon coversToggleIcon; + QPixmap glowLinePixmap; // Themed glow line animation }; struct NavigationTreeThemeTemplates { @@ -491,6 +495,7 @@ struct Theme { HelpAboutDialogTheme helpAboutDialog; WhatsNewDialogTheme whatsNewDialog; EmptyContainerTheme emptyContainer; + NoLibrariesWidgetTheme noLibrariesWidget; SidebarTheme sidebar; SidebarIconsTheme sidebarIcons; LibraryItemTheme libraryItem; diff --git a/YACReaderLibrary/themes/theme_factory.cpp b/YACReaderLibrary/themes/theme_factory.cpp index 22f216119..9ecf3e6db 100644 --- a/YACReaderLibrary/themes/theme_factory.cpp +++ b/YACReaderLibrary/themes/theme_factory.cpp @@ -60,11 +60,15 @@ struct EmptyContainerParams { QColor backgroundColor; QColor titleTextColor; - // For NoLibrariesWidget + QColor iconColor; +}; + +struct NoLibrariesWidgetParams { + QColor backgroundColor; QColor textColor; QColor descriptionTextColor; - - QColor searchIconColor; // Color for search-related icons (replaces #f0f in search_result.svg) + QColor iconColor; + QColor noLibrariesLineColor; }; struct SidebarParams { @@ -94,6 +98,7 @@ struct ImportWidgetParams { QColor modeIconColor; QColor iconColor; QColor iconCheckedColor; + QColor glowLineColor; }; struct NavigationTreeParams { @@ -345,6 +350,7 @@ struct ThemeParams { MetadataScraperDialogParams metadataScraperDialogParams; HelpAboutDialogTheme helpAboutDialogParams; EmptyContainerParams emptyContainerParams; + NoLibrariesWidgetParams noLibrariesWidgetParams; SidebarParams sidebarParams; SidebarIconsParams sidebarIconsParams; LibraryItemParams libraryItemParams; @@ -457,21 +463,19 @@ Theme makeTheme(const ThemeParams ¶ms) theme.emptyContainer.backgroundColor = ec.backgroundColor; theme.emptyContainer.titleLabelQSS = ect.titleLabelQSS.arg(ec.titleTextColor.name()); - theme.emptyContainer.textColor = ec.textColor; - theme.emptyContainer.descriptionTextColor = ec.descriptionTextColor; - theme.emptyContainer.noLibrariesIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/noLibrariesIcon.svg", ec.searchIconColor, params.meta.id), 165, 160, qApp->devicePixelRatio()); { const qreal dpr = qApp->devicePixelRatio(); - theme.emptyContainer.searchingIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/search_result.svg", ec.searchIconColor, params.meta.id, { .suffix = "_searching" }), 97, dpr); - theme.emptyContainer.noSearchResultsIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/search_result.svg", ec.searchIconColor, params.meta.id, { .suffix = "_no_results" }), 239, dpr); + const auto &rli = params.readingListIconsParams; + + theme.emptyContainer.searchingIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/search_result.svg", ec.iconColor, params.meta.id, { .suffix = "_searching" }), 97, dpr); + theme.emptyContainer.noSearchResultsIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/search_result.svg", ec.iconColor, params.meta.id, { .suffix = "_no_results" }), 239, dpr); - theme.emptyContainer.emptyFolderIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_folder.svg", ec.searchIconColor, params.meta.id), 319, 243, dpr); - theme.emptyContainer.emptyFavoritesIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_favorites.svg", QColor(0xe84853), params.meta.id), 238, 223, dpr); - theme.emptyContainer.emptyCurrentReadingsIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_current_readings.svg", ec.searchIconColor, params.meta.id), 167, 214, dpr); - theme.emptyContainer.emptyReadingListIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_reading_list.svg", ec.searchIconColor, params.meta.id), 248, 187, dpr); + theme.emptyContainer.emptyFolderIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_folder.svg", ec.iconColor, params.meta.id), 319, 243, dpr); + theme.emptyContainer.emptyFavoritesIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_favorites.svg", rli.favoritesMainColor, params.meta.id), 238, 223, dpr); + theme.emptyContainer.emptyCurrentReadingsIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_current_readings.svg", ec.iconColor, params.meta.id), 167, 214, dpr); + theme.emptyContainer.emptyReadingListIcon = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/empty_container/empty_reading_list.svg", ec.iconColor, params.meta.id), 248, 187, dpr); // Generate empty label icons for each label color - const auto &rli = params.readingListIconsParams; for (int c = YACReader::YRed; c <= YACReader::YDark; ++c) { auto labelColor = static_cast(c); auto colorName = YACReader::colorToName(labelColor); @@ -484,6 +488,21 @@ Theme makeTheme(const ThemeParams ¶ms) } // end EmptyContainer + // NoLibrariesWidget + const auto &nlw = params.noLibrariesWidgetParams; + const qreal dprNLW = qApp->devicePixelRatio(); + + theme.noLibrariesWidget.backgroundColor = nlw.backgroundColor; + theme.noLibrariesWidget.textColor = nlw.textColor; + theme.noLibrariesWidget.descriptionTextColor = nlw.descriptionTextColor; + theme.noLibrariesWidget.noLibrariesIcon = renderSvgToPixmap( + recoloredSvgToThemeFile(":/images/noLibrariesIcon.svg", nlw.iconColor, params.meta.id), + 165, 160, dprNLW); + theme.noLibrariesWidget.noLibrariesLinePixmap = renderSvgToPixmap( + recoloredSvgToThemeFile(":/images/noLibrariesLine.svg", nlw.noLibrariesLineColor, params.meta.id), + 579, 1, dprNLW); + // end NoLibrariesWidget + // Sidebar const auto &sb = params.sidebarParams; theme.sidebar.backgroundColor = sb.backgroundColor; @@ -508,6 +527,8 @@ Theme makeTheme(const ThemeParams ¶ms) theme.importWidget.bottomCoversDecoration = QPixmap(recoloredSvgToThemeFile(":/images/import/importBottomCoversDecoration.svg", iw.coversDecorationBgColor, iw.coversDecorationShadowColor, params.meta.id)); theme.importWidget.importingIcon = QPixmap(recoloredSvgToThemeFile(":/images/import/importingIcon.svg", iw.modeIconColor, params.meta.id)); theme.importWidget.updatingIcon = QPixmap(recoloredSvgToThemeFile(":/images/import/updatingIcon.svg", iw.modeIconColor, params.meta.id)); + // glowLine: 579x5 glow line animation + theme.importWidget.glowLinePixmap = renderSvgToPixmap(recoloredSvgToThemeFile(":/images/glowLine.svg", iw.glowLineColor, params.meta.id), 579, 5, qApp->devicePixelRatio()); { QIcon coversToggle; const QString normalPath = recoloredSvgToThemeFile(":/images/import/coversToggle.svg", iw.iconColor, params.meta.id); @@ -1005,9 +1026,17 @@ Theme makeTheme(const QJsonObject &json) auto &ec = p.emptyContainerParams; ec.backgroundColor = colorFromJson(o, "backgroundColor", ec.backgroundColor); ec.titleTextColor = colorFromJson(o, "titleTextColor", ec.titleTextColor); - ec.textColor = colorFromJson(o, "textColor", ec.textColor); - ec.descriptionTextColor = colorFromJson(o, "descriptionTextColor", ec.descriptionTextColor); - ec.searchIconColor = colorFromJson(o, "searchIconColor", ec.searchIconColor); + ec.iconColor = colorFromJson(o, "iconColor", ec.iconColor); + } + + if (json.contains("noLibrariesWidget")) { + const auto o = json["noLibrariesWidget"].toObject(); + auto &nlw = p.noLibrariesWidgetParams; + nlw.backgroundColor = colorFromJson(o, "backgroundColor", nlw.backgroundColor); + nlw.textColor = colorFromJson(o, "textColor", nlw.textColor); + nlw.descriptionTextColor = colorFromJson(o, "descriptionTextColor", nlw.descriptionTextColor); + nlw.iconColor = colorFromJson(o, "iconColor", nlw.iconColor); + nlw.noLibrariesLineColor = colorFromJson(o, "noLibrariesLineColor", nlw.noLibrariesLineColor); } if (json.contains("sidebar")) { @@ -1058,6 +1087,7 @@ Theme makeTheme(const QJsonObject &json) iw.modeIconColor = colorFromJson(o, "modeIconColor", iw.modeIconColor); iw.iconColor = colorFromJson(o, "iconColor", iw.iconColor); iw.iconCheckedColor = colorFromJson(o, "iconCheckedColor", iw.iconCheckedColor); + iw.glowLineColor = colorFromJson(o, "glowLineColor", iw.glowLineColor); } if (json.contains("serverConfigDialog")) { diff --git a/images/glowLine.png b/images/glowLine.png deleted file mode 100644 index 13ee7b3b8247d5a65504c02f8cd04a4607a23130..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 460 zcmV;-0W>0v!@e#&uBcplOCP)=tS)}XFeX^+xunc zn-``$&6SXptu2-+b%1ms{)S~rFA9?J7W)D1$ zV;}UR&)CAw#>;7md&3UeNN*?CUJKqPT-L6?Dmth}9BfoliF8opuj&k7aXpLlP~;*_ zg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/noLibrariesLine.png b/images/noLibrariesLine.png deleted file mode 100644 index 18599349aa0a339a3103bf9b8e24bd60359d17b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmVdPacM~bJNr1&!v^(qPh1_llrxyU`*)8^gzPL}r0fx_9~ z+-Wvby^s6p!`Y`h7M_*)LrXJeF_rtM{NG*9n#p7>dCBv#*8a%xz_XC$f$hd(XO9<} o1%{Q(qgmj;^tpJ)TbBR>02oK$`>R7ZzW@LL07*qoM6N<$f<;1Q9RL6T diff --git a/images/noLibrariesLine.svg b/images/noLibrariesLine.svg new file mode 100644 index 000000000..316f51f78 --- /dev/null +++ b/images/noLibrariesLine.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 0affbded6ee5290789c92a6345883d3c3a7a1804 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 22 Mar 2026 12:13:07 +0100 Subject: [PATCH 159/187] Normalize color strings so they are always upper case for better readability of the theme files and the values in the editor --- YACReader/themes/builtin_classic.json | 50 +-- YACReader/themes/builtin_dark.json | 56 ++-- YACReader/themes/builtin_light.json | 46 +-- YACReaderLibrary/themes/builtin_classic.json | 302 +++++++++---------- YACReaderLibrary/themes/builtin_dark.json | 302 +++++++++---------- YACReaderLibrary/themes/builtin_light.json | 266 ++++++++-------- common/CMakeLists.txt | 2 + common/themes/theme_editor_dialog.cpp | 23 +- common/themes/theme_json_utils.cpp | 50 +++ common/themes/theme_json_utils.h | 14 + common/themes/theme_repository.cpp | 3 +- 11 files changed, 587 insertions(+), 527 deletions(-) create mode 100644 common/themes/theme_json_utils.cpp create mode 100644 common/themes/theme_json_utils.h diff --git a/YACReader/themes/builtin_classic.json b/YACReader/themes/builtin_classic.json index 3b0b217ed..ac1bda11e 100644 --- a/YACReader/themes/builtin_classic.json +++ b/YACReader/themes/builtin_classic.json @@ -5,19 +5,19 @@ "goToFlowWidget": { "editBackgroundColor": "#55000000", "editBorderColor": "#77000000", - "editTextColor": "#ffffff", + "editTextColor": "#FFFFFF", "flowBackgroundColor": "#282828", - "flowTextColor": "#ffffff", - "iconColor": "#ffffff", - "labelTextColor": "#ffffff", - "sliderBorderColor": "#22ffffff", + "flowTextColor": "#FFFFFF", + "iconColor": "#FFFFFF", + "labelTextColor": "#FFFFFF", + "sliderBorderColor": "#22FFFFFF", "sliderGrooveColor": "#77000000", - "sliderHandleColor": "#55ffffff", + "sliderHandleColor": "#55FFFFFF", "toolbarBackgroundColor": "#99000000" }, "helpAboutDialog": { - "headingColor": "#302f2d", - "linkColor": "#c19441" + "headingColor": "#302F2D", + "linkColor": "#C19441" }, "meta": { "displayName": "Default Classic", @@ -32,36 +32,36 @@ "translator": { "backgroundColor": "#404040", "borderColor": "#212121", - "iconColor": "#cccccc", - "inputBackgroundColor": "#2a2a2a", + "iconColor": "#CCCCCC", + "inputBackgroundColor": "#2A2A2A", "inputDarkerBackgroundColor": "#272727", - "primaryTextColor": "#ffffff", - "scrollbarHandleColor": "#dddddd", - "secondaryTextColor": "#e3e3e3", + "primaryTextColor": "#FFFFFF", + "scrollbarHandleColor": "#DDDDDD", + "secondaryTextColor": "#E3E3E3", "selectionBackgroundColor": "#202020" }, "toolbar": { - "backgroundColor": "#f3f3f3", - "checkedButtonColor": "#cccccc", - "iconCheckedColor": "#5a5a5a", + "backgroundColor": "#F3F3F3", + "checkedButtonColor": "#CCCCCC", + "iconCheckedColor": "#5A5A5A", "iconColor": "#404040", "iconDisabledColor": "#858585", "menuIndicatorColor": "#404040", - "separatorColor": "#cccccc" + "separatorColor": "#CCCCCC" }, "viewer": { "defaultBackgroundColor": "#282828", - "defaultTextColor": "#ffffff", - "infoBackgroundColor": "#bb000000", - "infoTextColor": "#ffffff" + "defaultTextColor": "#FFFFFF", + "infoBackgroundColor": "#BB000000", + "infoTextColor": "#FFFFFF" }, "whatsNewDialog": { - "backgroundColor": "#ffffff", + "backgroundColor": "#FFFFFF", "closeButtonColor": "#444444", - "contentTextColor": "#0a0a0a", - "headerDecorationColor": "#e8b800", - "headerTextColor": "#0a0a0a", - "linkColor": "#e8b800", + "contentTextColor": "#0A0A0A", + "headerDecorationColor": "#E8B800", + "headerTextColor": "#0A0A0A", + "linkColor": "#E8B800", "versionTextColor": "#858585" } } diff --git a/YACReader/themes/builtin_dark.json b/YACReader/themes/builtin_dark.json index 3dc7b9d3d..40dc2dd2a 100644 --- a/YACReader/themes/builtin_dark.json +++ b/YACReader/themes/builtin_dark.json @@ -1,23 +1,23 @@ { "dialogIcons": { - "iconColor": "#cccccc" + "iconColor": "#CCCCCC" }, "goToFlowWidget": { "editBackgroundColor": "#55000000", "editBorderColor": "#77000000", - "editTextColor": "#ffffff", + "editTextColor": "#FFFFFF", "flowBackgroundColor": "#282828", - "flowTextColor": "#ffffff", - "iconColor": "#cccccc", - "labelTextColor": "#ffffff", - "sliderBorderColor": "#22ffffff", + "flowTextColor": "#FFFFFF", + "iconColor": "#CCCCCC", + "labelTextColor": "#FFFFFF", + "sliderBorderColor": "#22FFFFFF", "sliderGrooveColor": "#77000000", - "sliderHandleColor": "#55ffffff", + "sliderHandleColor": "#55FFFFFF", "toolbarBackgroundColor": "#99000000" }, "helpAboutDialog": { - "headingColor": "#e0e0e0", - "linkColor": "#d4a84b" + "headingColor": "#E0E0E0", + "linkColor": "#D4A84B" }, "meta": { "displayName": "Default Dark", @@ -27,41 +27,41 @@ "version": "10.0.0" }, "shortcutsIcons": { - "iconColor": "#d0d0d0" + "iconColor": "#D0D0D0" }, "translator": { "backgroundColor": "#404040", "borderColor": "#212121", - "iconColor": "#cccccc", - "inputBackgroundColor": "#2a2a2a", + "iconColor": "#CCCCCC", + "inputBackgroundColor": "#2A2A2A", "inputDarkerBackgroundColor": "#272727", - "primaryTextColor": "#ffffff", - "scrollbarHandleColor": "#dddddd", - "secondaryTextColor": "#e3e3e3", + "primaryTextColor": "#FFFFFF", + "scrollbarHandleColor": "#DDDDDD", + "secondaryTextColor": "#E3E3E3", "selectionBackgroundColor": "#202020" }, "toolbar": { "backgroundColor": "#202020", - "checkedButtonColor": "#3a3a3a", - "iconCheckedColor": "#dadada", - "iconColor": "#cccccc", + "checkedButtonColor": "#3A3A3A", + "iconCheckedColor": "#DADADA", + "iconColor": "#CCCCCC", "iconDisabledColor": "#444444", - "menuIndicatorColor": "#cccccc", + "menuIndicatorColor": "#CCCCCC", "separatorColor": "#444444" }, "viewer": { "defaultBackgroundColor": "#282828", - "defaultTextColor": "#ffffff", - "infoBackgroundColor": "#bb000000", - "infoTextColor": "#b0b0b0" + "defaultTextColor": "#FFFFFF", + "infoBackgroundColor": "#BB000000", + "infoTextColor": "#B0B0B0" }, "whatsNewDialog": { - "backgroundColor": "#2a2a2a", - "closeButtonColor": "#dddddd", - "contentTextColor": "#e0e0e0", - "headerDecorationColor": "#e8b800", - "headerTextColor": "#e0e0e0", - "linkColor": "#e8b800", + "backgroundColor": "#2A2A2A", + "closeButtonColor": "#DDDDDD", + "contentTextColor": "#E0E0E0", + "headerDecorationColor": "#E8B800", + "headerTextColor": "#E0E0E0", + "linkColor": "#E8B800", "versionTextColor": "#858585" } } diff --git a/YACReader/themes/builtin_light.json b/YACReader/themes/builtin_light.json index 274788b81..4027bc539 100644 --- a/YACReader/themes/builtin_light.json +++ b/YACReader/themes/builtin_light.json @@ -6,18 +6,18 @@ "editBackgroundColor": "#22000000", "editBorderColor": "#33000000", "editTextColor": "#202020", - "flowBackgroundColor": "#f6f6f6", + "flowBackgroundColor": "#F6F6F6", "flowTextColor": "#202020", "iconColor": "#404040", "labelTextColor": "#202020", "sliderBorderColor": "#22000000", "sliderGrooveColor": "#33000000", "sliderHandleColor": "#55000000", - "toolbarBackgroundColor": "#bbffffff" + "toolbarBackgroundColor": "#BBFFFFFF" }, "helpAboutDialog": { - "headingColor": "#302f2d", - "linkColor": "#c19441" + "headingColor": "#302F2D", + "linkColor": "#C19441" }, "meta": { "displayName": "Default Light", @@ -30,38 +30,38 @@ "iconColor": "#606060" }, "translator": { - "backgroundColor": "#e8e8e8", - "borderColor": "#cccccc", + "backgroundColor": "#E8E8E8", + "borderColor": "#CCCCCC", "iconColor": "#404040", - "inputBackgroundColor": "#f5f5f5", - "inputDarkerBackgroundColor": "#ebebeb", - "primaryTextColor": "#1a1a1a", + "inputBackgroundColor": "#F5F5F5", + "inputDarkerBackgroundColor": "#EBEBEB", + "primaryTextColor": "#1A1A1A", "scrollbarHandleColor": "#909090", - "secondaryTextColor": "#2a2a2a", - "selectionBackgroundColor": "#dcdcdc" + "secondaryTextColor": "#2A2A2A", + "selectionBackgroundColor": "#DCDCDC" }, "toolbar": { - "backgroundColor": "#f3f3f3", - "checkedButtonColor": "#cccccc", - "iconCheckedColor": "#5a5a5a", + "backgroundColor": "#F3F3F3", + "checkedButtonColor": "#CCCCCC", + "iconCheckedColor": "#5A5A5A", "iconColor": "#404040", - "iconDisabledColor": "#b0b0b0", + "iconDisabledColor": "#B0B0B0", "menuIndicatorColor": "#404040", - "separatorColor": "#cccccc" + "separatorColor": "#CCCCCC" }, "viewer": { - "defaultBackgroundColor": "#f6f6f6", + "defaultBackgroundColor": "#F6F6F6", "defaultTextColor": "#202020", - "infoBackgroundColor": "#bbffffff", + "infoBackgroundColor": "#BBFFFFFF", "infoTextColor": "#404040" }, "whatsNewDialog": { - "backgroundColor": "#ffffff", + "backgroundColor": "#FFFFFF", "closeButtonColor": "#444444", - "contentTextColor": "#0a0a0a", - "headerDecorationColor": "#e8b800", - "headerTextColor": "#0a0a0a", - "linkColor": "#e8b800", + "contentTextColor": "#0A0A0A", + "headerDecorationColor": "#E8B800", + "headerTextColor": "#0A0A0A", + "linkColor": "#E8B800", "versionTextColor": "#858585" } } diff --git a/YACReaderLibrary/themes/builtin_classic.json b/YACReaderLibrary/themes/builtin_classic.json index 9afcec68e..52ac1a37a 100644 --- a/YACReaderLibrary/themes/builtin_classic.json +++ b/YACReaderLibrary/themes/builtin_classic.json @@ -1,124 +1,124 @@ { "comicFlow": { "backgroundColor": "#000000", - "readMainColor": "#db4725", - "readTickColor": "#8a2c17", - "readingColor": "#e6b90f", - "textColor": "#4c4c4c" + "readMainColor": "#DB4725", + "readTickColor": "#8A2C17", + "readingColor": "#E6B90F", + "textColor": "#4C4C4C" }, "comicsViewTable": { - "alternateBackgroundColor": "#f2f2f2", - "backgroundColor": "#fafafa", - "headerBackgroundColor": "#f5f5f5", - "headerBorderColor": "#b8bdc4", - "headerGradientColor": "#d1d1d1", + "alternateBackgroundColor": "#F2F2F2", + "backgroundColor": "#FAFAFA", + "headerBackgroundColor": "#F5F5F5", + "headerBorderColor": "#B8BDC4", + "headerGradientColor": "#D1D1D1", "headerTextColor": "#313232", - "itemBorderBottomColor": "#dfdfdf", + "itemBorderBottomColor": "#DFDFDF", "itemBorderBottomWidth": 1, - "itemBorderTopColor": "#fefefe", + "itemBorderTopColor": "#FEFEFE", "itemBorderTopWidth": 1, "itemTextColor": "#252626", - "selectedColor": "#d4d4d4", + "selectedColor": "#D4D4D4", "selectedTextColor": "#252626", - "starRatingColor": "#e9be0f", - "starRatingSelectedColor": "#ffffff" + "starRatingColor": "#E9BE0F", + "starRatingSelectedColor": "#FFFFFF" }, "comicsViewToolbar": { - "backgroundColor": "#f0f0f0", - "checkedBackgroundColor": "#cccccc", + "backgroundColor": "#F0F0F0", + "checkedBackgroundColor": "#CCCCCC", "iconColor": "#404040", - "separatorColor": "#cccccc" + "separatorColor": "#CCCCCC" }, "contentSplitter": { - "handleColor": "#b8b8b8", + "handleColor": "#B8B8B8", "horizontalHandleHeight": 4, "verticalHandleWidth": 4 }, "dialogIcons": { - "iconColor": "#f7f7f7" + "iconColor": "#F7F7F7" }, "emptyContainer": { - "backgroundColor": "#2a2a2a", - "iconColor": "#4c4c4c", - "titleTextColor": "#cccccc" + "backgroundColor": "#2A2A2A", + "iconColor": "#4C4C4C", + "titleTextColor": "#CCCCCC" }, "gridAndInfoView": { - "backgroundBlurOverlayColor": "#2a2a2a", - "backgroundColor": "#2a2a2a", + "backgroundBlurOverlayColor": "#2A2A2A", + "backgroundColor": "#2A2A2A", "borderColor": "#121212", - "buttonColor": "#ffcc00", - "buttonShadowColor": "#aa000000", - "buttonTextColor": "#ffffff", + "buttonColor": "#FFCC00", + "buttonShadowColor": "#AA000000", + "buttonTextColor": "#FFFFFF", "cellColor": "#212121", "cellColorWithBackground": "#99212121", - "cellSelectedBorderColor": "#ffcc00", + "cellSelectedBorderColor": "#FFCC00", "cellSelectedColor": "#121212", - "comicCoverBorderColor": "#30ffffff", + "comicCoverBorderColor": "#30FFFFFF", "continueReadingBackgroundColor": "#88000000", - "continueReadingTextColor": "#ffffff", + "continueReadingTextColor": "#FFFFFF", "currentComicBackgroundColor": "#88000000", - "currentComicCoverShadowColor": "#ff000000", - "favCheckedColor": "#e84852", - "favUncheckedColor": "#1c1c1c", - "folderCoverBorderColor": "#20ffffff", - "infoBackgroundColor": "#2e2e2e", + "currentComicCoverShadowColor": "#FF000000", + "favCheckedColor": "#E84852", + "favUncheckedColor": "#1C1C1C", + "folderCoverBorderColor": "#20FFFFFF", + "infoBackgroundColor": "#2E2E2E", "infoBorderColor": "#404040", - "infoMetadataTextColor": "#b0b0b0", - "infoScrollbarColor": "#ff424246", + "infoMetadataTextColor": "#B0B0B0", + "infoScrollbarColor": "#FF424246", "infoShadowColor": "#000000", - "infoTextColor": "#ffffff", - "itemDetailsColor": "#a8a8a8", - "itemTitleColor": "#ffffff", - "linkColor": "#ffcc00", - "newItemColor": "#ffffcc00", - "placeholderFolder1BorderColor": "#20ffffff", + "infoTextColor": "#FFFFFF", + "itemDetailsColor": "#A8A8A8", + "itemTitleColor": "#FFFFFF", + "linkColor": "#FFCC00", + "newItemColor": "#FFFFCC00", + "placeholderFolder1BorderColor": "#20FFFFFF", "placeholderFolder1Color": "#20000000", - "placeholderFolder2BorderColor": "#20ffffff", + "placeholderFolder2BorderColor": "#20FFFFFF", "placeholderFolder2Color": "#88000000", - "ratingSelectedColor": "#ffffff", - "ratingUnselectedColor": "#1c1c1c", - "readTickCheckedColor": "#e84852", - "readTickUncheckedColor": "#1c1c1c", - "scrollbarBorderColor": "#aa313131", + "ratingSelectedColor": "#FFFFFF", + "ratingUnselectedColor": "#1C1C1C", + "readTickCheckedColor": "#E84852", + "readTickUncheckedColor": "#1C1C1C", + "scrollbarBorderColor": "#AA313131", "scrollbarColor": "#88424242", "showDropShadow": true }, "helpAboutDialog": { - "headingColor": "#302f2d", - "linkColor": "#c19441" + "headingColor": "#302F2D", + "linkColor": "#C19441" }, "importWidget": { - "backgroundColor": "#2a2a2a", - "coversDecorationBgColor": "#3a3a3a", - "coversDecorationShadowColor": "#1a1a1a", - "coversLabelColor": "#aaaaaa", - "coversViewBackgroundColor": "#3a3a3a", - "currentComicTextColor": "#aaaaaa", - "descriptionTextColor": "#aaaaaa", - "glowLineColor": "#ffe100", - "iconCheckedColor": "#aaaaaa", - "iconColor": "#cccccc", - "modeIconColor": "#4a4a4a", - "titleTextColor": "#cccccc" + "backgroundColor": "#2A2A2A", + "coversDecorationBgColor": "#3A3A3A", + "coversDecorationShadowColor": "#1A1A1A", + "coversLabelColor": "#AAAAAA", + "coversViewBackgroundColor": "#3A3A3A", + "currentComicTextColor": "#AAAAAA", + "descriptionTextColor": "#AAAAAA", + "glowLineColor": "#FFE100", + "iconCheckedColor": "#AAAAAA", + "iconColor": "#CCCCCC", + "modeIconColor": "#4A4A4A", + "titleTextColor": "#CCCCCC" }, "libraryItem": { - "libraryIconColor": "#dddfdf", - "libraryIconSelectedColor": "#ffffff", + "libraryIconColor": "#DDDFDF", + "libraryIconSelectedColor": "#FFFFFF", "libraryIconShadowColor": "#000000", - "libraryOptionsIconColor": "#ffffff", - "selectedBackgroundColor": "#2e2e2e", - "selectedTextColor": "#ffffff", - "textColor": "#dddfdf" + "libraryOptionsIconColor": "#FFFFFF", + "selectedBackgroundColor": "#2E2E2E", + "selectedTextColor": "#FFFFFF", + "textColor": "#DDDFDF" }, "mainToolbar": { - "backgroundColor": "#f0f0f0", - "dividerColor": "#b8bdc4", + "backgroundColor": "#F0F0F0", + "dividerColor": "#B8BDC4", "folderNameColor": "#404040", "iconColor": "#404040", - "iconDisabledColor": "#b0b0b0" + "iconDisabledColor": "#B0B0B0" }, "menuIcons": { - "iconColor": "#f7f7f7" + "iconColor": "#F7F7F7" }, "meta": { "displayName": "Default Classic", @@ -128,137 +128,137 @@ "version": "10.0.0" }, "metadataScraperDialog": { - "busyIndicatorColor": "#ffffff", - "buttonBackgroundColor": "#2e2e2e", + "busyIndicatorColor": "#FFFFFF", + "buttonBackgroundColor": "#2E2E2E", "buttonBorderColor": "#242424", - "buttonTextColor": "#ffffff", - "checkBoxTickColor": "#ffffff", - "contentAltBackgroundColor": "#2b2b2b", - "contentBackgroundColor": "#2b2b2b", - "contentTextColor": "#ffffff", + "buttonTextColor": "#FFFFFF", + "checkBoxTickColor": "#FFFFFF", + "contentAltBackgroundColor": "#2B2B2B", + "contentBackgroundColor": "#2B2B2B", + "contentTextColor": "#FFFFFF", "dialogBackgroundColor": "#404040", - "downArrowColor": "#9f9f9f", - "hyperlinkColor": "#ffcc00", - "labelBackgroundColor": "#2b2b2b", - "labelTextColor": "#ffffff", - "navIconColor": "#ffffff", - "radioCheckedBackgroundColor": "#e5e5e5", - "radioCheckedIndicatorColor": "#5f5f5f", - "radioUncheckedColor": "#e5e5e5", - "rowIconColor": "#e5e5e5", - "tableAltBackgroundColor": "#2e2e2e", - "tableBackgroundColor": "#2b2b2b", + "downArrowColor": "#9F9F9F", + "hyperlinkColor": "#FFCC00", + "labelBackgroundColor": "#2B2B2B", + "labelTextColor": "#FFFFFF", + "navIconColor": "#FFFFFF", + "radioCheckedBackgroundColor": "#E5E5E5", + "radioCheckedIndicatorColor": "#5F5F5F", + "radioUncheckedColor": "#E5E5E5", + "rowIconColor": "#E5E5E5", + "tableAltBackgroundColor": "#2E2E2E", + "tableBackgroundColor": "#2B2B2B", "tableBorderColor": "#242424", "tableHeaderBackgroundColor": "#292929", - "tableHeaderBorderColor": "#1f1f1f", + "tableHeaderBorderColor": "#1F1F1F", "tableHeaderGradientColor": "#292929", - "tableHeaderTextColor": "#ebebeb", + "tableHeaderTextColor": "#EBEBEB", "tableScrollBackgroundColor": "#404040", - "tableScrollHandleColor": "#dddddd", - "tableSectionBorderDark": "#dfdfdf", - "tableSectionBorderLight": "#fefefe", + "tableScrollHandleColor": "#DDDDDD", + "tableSectionBorderDark": "#DFDFDF", + "tableSectionBorderLight": "#FEFEFE", "tableSelectedColor": "#555555", "toolButtonAccentColor": "#282828", - "upArrowColor": "#9f9f9f" + "upArrowColor": "#9F9F9F" }, "navigationTree": { - "branchIndicatorColor": "#e0e0e0", - "branchIndicatorSelectedColor": "#ffffff", - "folderIconColor": "#e0e0e0", - "folderIconSelectedColor": "#e0e0e0", + "branchIndicatorColor": "#E0E0E0", + "branchIndicatorSelectedColor": "#FFFFFF", + "folderIconColor": "#E0E0E0", + "folderIconSelectedColor": "#E0E0E0", "folderIconSelectedShadowColor": "#000000", "folderIconShadowColor": "#000000", - "folderNotCompletedColor": "#edc518", + "folderNotCompletedColor": "#EDC518", "folderReadOverlayColor": "#464646", "folderReadOverlaySelectedColor": "#464646", - "newItemColor": "#edc518", + "newItemColor": "#EDC518", "scrollBackgroundColor": "#404040", - "scrollHandleColor": "#dddddd", - "selectedTextColor": "#ffffff", - "selectionBackgroundColor": "#2e2e2e", - "textColor": "#dddfdf" + "scrollHandleColor": "#DDDDDD", + "selectedTextColor": "#FFFFFF", + "selectionBackgroundColor": "#2E2E2E", + "textColor": "#DDDFDF" }, "noLibrariesWidget": { - "backgroundColor": "#2a2a2a", - "descriptionTextColor": "#aaaaaa", - "iconColor": "#4c4c4c", - "noLibrariesLineColor": "#a8a8a8", - "textColor": "#cccccc" + "backgroundColor": "#2A2A2A", + "descriptionTextColor": "#AAAAAA", + "iconColor": "#4C4C4C", + "noLibrariesLineColor": "#A8A8A8", + "textColor": "#CCCCCC" }, "readingListIcons": { - "currentlyReadingMainColor": "#ffcc00", - "currentlyReadingMainSelectedColor": "#ffcc00", + "currentlyReadingMainColor": "#FFCC00", + "currentlyReadingMainSelectedColor": "#FFCC00", "currentlyReadingOuterColor": "#000000", "currentlyReadingOuterSelectedColor": "#000000", - "favoritesMainColor": "#e15055", - "favoritesMainSelectedColor": "#e15055", + "favoritesMainColor": "#E15055", + "favoritesMainSelectedColor": "#E15055", "labelColors": { - "blue": "#82c7ff", - "cyan": "#a0fddb", - "dark": "#b7b7b7", - "green": "#ade738", - "light": "#cbcbcb", - "orange": "#f5c240", - "pink": "#fd9cda", - "purple": "#d692fc", - "red": "#f67a7b", - "violet": "#8f95ff", - "white": "#fcfcfc", - "yellow": "#f2e446" + "blue": "#82C7FF", + "cyan": "#A0FDDB", + "dark": "#B7B7B7", + "green": "#ADE738", + "light": "#CBCBCB", + "orange": "#F5C240", + "pink": "#FD9CDA", + "purple": "#D692FC", + "red": "#F67A7B", + "violet": "#8F95FF", + "white": "#FCFCFC", + "yellow": "#F2E446" }, "labelShadowColor": "#000000", "labelShadowSelectedColor": "#000000", "listDetailColor": "#464646", "listDetailSelectedColor": "#464646", - "listMainColor": "#e7e7e7", - "listMainSelectedColor": "#e7e7e7", + "listMainColor": "#E7E7E7", + "listMainSelectedColor": "#E7E7E7", "listShadowColor": "#000000", "listShadowSelectedColor": "#000000", - "readingListMainColor": "#e7e7e7", - "readingListMainSelectedColor": "#e7e7e7", + "readingListMainColor": "#E7E7E7", + "readingListMainSelectedColor": "#E7E7E7", "specialListShadowColor": "#000000", "specialListShadowSelectedColor": "#000000" }, "searchLineEdit": { "backgroundColor": "#404040", - "iconColor": "#f7f7f7", - "textColor": "#ababab" + "iconColor": "#F7F7F7", + "textColor": "#ABABAB" }, "serverConfigDialog": { - "backgroundColor": "#2a2a2a", + "backgroundColor": "#2A2A2A", "checkBoxTextColor": "#262626", - "decorationColor": "#f7f7f7", + "decorationColor": "#F7F7F7", "labelTextColor": "#575757", - "propagandaTextColor": "#4d4d4d", - "qrBackgroundColor": "#2a2a2a", - "qrForegroundColor": "#ffffff", - "qrMessageTextColor": "#a3a3a3", + "propagandaTextColor": "#4D4D4D", + "qrBackgroundColor": "#2A2A2A", + "qrForegroundColor": "#FFFFFF", + "qrMessageTextColor": "#A3A3A3", "titleTextColor": "#474747" }, "shortcutsIcons": { - "iconColor": "#f7f7f7" + "iconColor": "#F7F7F7" }, "sidebar": { "backgroundColor": "#454545", - "busyIndicatorColor": "#ffffff", + "busyIndicatorColor": "#FFFFFF", "sectionSeparatorColor": "#575757", - "separatorColor": "#bdbfbf", + "separatorColor": "#BDBFBF", "titleDropShadowColor": "#000000", - "titleTextColor": "#bdbfbf", + "titleTextColor": "#BDBFBF", "uppercaseLabels": true }, "sidebarIcons": { - "iconColor": "#e0e0e0", + "iconColor": "#E0E0E0", "shadowColor": "#000000", "useSystemFolderIcons": false }, "whatsNewDialog": { - "backgroundColor": "#2a2a2a", - "closeButtonColor": "#dddddd", - "contentTextColor": "#e0e0e0", - "headerDecorationColor": "#e8b800", - "headerTextColor": "#e0e0e0", - "linkColor": "#e8b800", + "backgroundColor": "#2A2A2A", + "closeButtonColor": "#DDDDDD", + "contentTextColor": "#E0E0E0", + "headerDecorationColor": "#E8B800", + "headerTextColor": "#E0E0E0", + "linkColor": "#E8B800", "versionTextColor": "#858585" } } diff --git a/YACReaderLibrary/themes/builtin_dark.json b/YACReaderLibrary/themes/builtin_dark.json index 7a26d484e..c43986486 100644 --- a/YACReaderLibrary/themes/builtin_dark.json +++ b/YACReaderLibrary/themes/builtin_dark.json @@ -1,124 +1,124 @@ { "comicFlow": { "backgroundColor": "#111111", - "readMainColor": "#db4725", - "readTickColor": "#8a2c17", - "readingColor": "#e6b90f", + "readMainColor": "#DB4725", + "readTickColor": "#8A2C17", + "readingColor": "#E6B90F", "textColor": "#888888" }, "comicsViewTable": { - "alternateBackgroundColor": "#2c2c2c", + "alternateBackgroundColor": "#2C2C2C", "backgroundColor": "#232323", - "headerBackgroundColor": "#2a2a2a", - "headerBorderColor": "#1f1f1f", + "headerBackgroundColor": "#2A2A2A", + "headerBorderColor": "#1F1F1F", "headerGradientColor": "#252525", - "headerTextColor": "#dddddd", - "itemBorderBottomColor": "#1f1f1f", + "headerTextColor": "#DDDDDD", + "itemBorderBottomColor": "#1F1F1F", "itemBorderBottomWidth": 0, "itemBorderTopColor": "#353535", "itemBorderTopWidth": 0, - "itemTextColor": "#dddddd", + "itemTextColor": "#DDDDDD", "selectedColor": "#555555", - "selectedTextColor": "#ffffff", - "starRatingColor": "#e9be0f", - "starRatingSelectedColor": "#ffffff" + "selectedTextColor": "#FFFFFF", + "starRatingColor": "#E9BE0F", + "starRatingSelectedColor": "#FFFFFF" }, "comicsViewToolbar": { - "backgroundColor": "#1f1f1f", + "backgroundColor": "#1F1F1F", "checkedBackgroundColor": "#555555", - "iconColor": "#dddddd", + "iconColor": "#DDDDDD", "separatorColor": "#444444" }, "contentSplitter": { - "handleColor": "#1f1f1f", + "handleColor": "#1F1F1F", "horizontalHandleHeight": 4, "verticalHandleWidth": 4 }, "dialogIcons": { - "iconColor": "#f7f7f7" + "iconColor": "#F7F7F7" }, "emptyContainer": { - "backgroundColor": "#2a2a2a", - "iconColor": "#4c4c4c", - "titleTextColor": "#cccccc" + "backgroundColor": "#2A2A2A", + "iconColor": "#4C4C4C", + "titleTextColor": "#CCCCCC" }, "gridAndInfoView": { - "backgroundBlurOverlayColor": "#2a2a2a", - "backgroundColor": "#2a2a2a", + "backgroundBlurOverlayColor": "#2A2A2A", + "backgroundColor": "#2A2A2A", "borderColor": "#121212", - "buttonColor": "#ffcc00", - "buttonShadowColor": "#aa000000", - "buttonTextColor": "#ffffff", + "buttonColor": "#FFCC00", + "buttonShadowColor": "#AA000000", + "buttonTextColor": "#FFFFFF", "cellColor": "#212121", "cellColorWithBackground": "#99212121", - "cellSelectedBorderColor": "#ffcc00", + "cellSelectedBorderColor": "#FFCC00", "cellSelectedColor": "#121212", - "comicCoverBorderColor": "#30ffffff", + "comicCoverBorderColor": "#30FFFFFF", "continueReadingBackgroundColor": "#88000000", - "continueReadingTextColor": "#ffffff", + "continueReadingTextColor": "#FFFFFF", "currentComicBackgroundColor": "#55000000", - "currentComicCoverShadowColor": "#ff000000", - "favCheckedColor": "#e84852", - "favUncheckedColor": "#1c1c1c", - "folderCoverBorderColor": "#20ffffff", - "infoBackgroundColor": "#2e2e2e", + "currentComicCoverShadowColor": "#FF000000", + "favCheckedColor": "#E84852", + "favUncheckedColor": "#1C1C1C", + "folderCoverBorderColor": "#20FFFFFF", + "infoBackgroundColor": "#2E2E2E", "infoBorderColor": "#404040", - "infoMetadataTextColor": "#b0b0b0", - "infoScrollbarColor": "#ff424246", + "infoMetadataTextColor": "#B0B0B0", + "infoScrollbarColor": "#FF424246", "infoShadowColor": "#000000", - "infoTextColor": "#ffffff", - "itemDetailsColor": "#a8a8a8", - "itemTitleColor": "#ffffff", - "linkColor": "#ffcc00", - "newItemColor": "#ffffcc00", - "placeholderFolder1BorderColor": "#20ffffff", + "infoTextColor": "#FFFFFF", + "itemDetailsColor": "#A8A8A8", + "itemTitleColor": "#FFFFFF", + "linkColor": "#FFCC00", + "newItemColor": "#FFFFCC00", + "placeholderFolder1BorderColor": "#20FFFFFF", "placeholderFolder1Color": "#20000000", - "placeholderFolder2BorderColor": "#20ffffff", + "placeholderFolder2BorderColor": "#20FFFFFF", "placeholderFolder2Color": "#88000000", - "ratingSelectedColor": "#ffffff", - "ratingUnselectedColor": "#1c1c1c", - "readTickCheckedColor": "#e84852", - "readTickUncheckedColor": "#1c1c1c", - "scrollbarBorderColor": "#aa313131", + "ratingSelectedColor": "#FFFFFF", + "ratingUnselectedColor": "#1C1C1C", + "readTickCheckedColor": "#E84852", + "readTickUncheckedColor": "#1C1C1C", + "scrollbarBorderColor": "#AA313131", "scrollbarColor": "#88424242", "showDropShadow": true }, "helpAboutDialog": { - "headingColor": "#e0e0e0", - "linkColor": "#d4a84b" + "headingColor": "#E0E0E0", + "linkColor": "#D4A84B" }, "importWidget": { - "backgroundColor": "#2a2a2a", - "coversDecorationBgColor": "#3a3a3a", - "coversDecorationShadowColor": "#1a1a1a", - "coversLabelColor": "#aaaaaa", - "coversViewBackgroundColor": "#3a3a3a", - "currentComicTextColor": "#aaaaaa", - "descriptionTextColor": "#aaaaaa", - "glowLineColor": "#ffe100", - "iconCheckedColor": "#aaaaaa", - "iconColor": "#cccccc", - "modeIconColor": "#4a4a4a", - "titleTextColor": "#cccccc" + "backgroundColor": "#2A2A2A", + "coversDecorationBgColor": "#3A3A3A", + "coversDecorationShadowColor": "#1A1A1A", + "coversLabelColor": "#AAAAAA", + "coversViewBackgroundColor": "#3A3A3A", + "currentComicTextColor": "#AAAAAA", + "descriptionTextColor": "#AAAAAA", + "glowLineColor": "#FFE100", + "iconCheckedColor": "#AAAAAA", + "iconColor": "#CCCCCC", + "modeIconColor": "#4A4A4A", + "titleTextColor": "#CCCCCC" }, "libraryItem": { - "libraryIconColor": "#dddfdf", - "libraryIconSelectedColor": "#ffffff", + "libraryIconColor": "#DDDFDF", + "libraryIconSelectedColor": "#FFFFFF", "libraryIconShadowColor": "#000000", - "libraryOptionsIconColor": "#ffffff", - "selectedBackgroundColor": "#2e2e2e", - "selectedTextColor": "#ffffff", - "textColor": "#dddfdf" + "libraryOptionsIconColor": "#FFFFFF", + "selectedBackgroundColor": "#2E2E2E", + "selectedTextColor": "#FFFFFF", + "textColor": "#DDDFDF" }, "mainToolbar": { - "backgroundColor": "#1f1f1f", + "backgroundColor": "#1F1F1F", "dividerColor": "#555555", - "folderNameColor": "#dddddd", - "iconColor": "#dddddd", + "folderNameColor": "#DDDDDD", + "iconColor": "#DDDDDD", "iconDisabledColor": "#666666" }, "menuIcons": { - "iconColor": "#f7f7f7" + "iconColor": "#F7F7F7" }, "meta": { "displayName": "Default Dark", @@ -128,137 +128,137 @@ "version": "10.0.0" }, "metadataScraperDialog": { - "busyIndicatorColor": "#ffffff", - "buttonBackgroundColor": "#2e2e2e", + "busyIndicatorColor": "#FFFFFF", + "buttonBackgroundColor": "#2E2E2E", "buttonBorderColor": "#242424", - "buttonTextColor": "#ffffff", - "checkBoxTickColor": "#ffffff", - "contentAltBackgroundColor": "#2e2e2e", - "contentBackgroundColor": "#2b2b2b", - "contentTextColor": "#ffffff", + "buttonTextColor": "#FFFFFF", + "checkBoxTickColor": "#FFFFFF", + "contentAltBackgroundColor": "#2E2E2E", + "contentBackgroundColor": "#2B2B2B", + "contentTextColor": "#FFFFFF", "dialogBackgroundColor": "#404040", - "downArrowColor": "#9f9f9f", - "hyperlinkColor": "#ffcc00", - "labelBackgroundColor": "#2b2b2b", - "labelTextColor": "#ffffff", - "navIconColor": "#ffffff", - "radioCheckedBackgroundColor": "#e5e5e5", - "radioCheckedIndicatorColor": "#5f5f5f", - "radioUncheckedColor": "#e5e5e5", - "rowIconColor": "#e5e5e5", - "tableAltBackgroundColor": "#2e2e2e", - "tableBackgroundColor": "#2b2b2b", + "downArrowColor": "#9F9F9F", + "hyperlinkColor": "#FFCC00", + "labelBackgroundColor": "#2B2B2B", + "labelTextColor": "#FFFFFF", + "navIconColor": "#FFFFFF", + "radioCheckedBackgroundColor": "#E5E5E5", + "radioCheckedIndicatorColor": "#5F5F5F", + "radioUncheckedColor": "#E5E5E5", + "rowIconColor": "#E5E5E5", + "tableAltBackgroundColor": "#2E2E2E", + "tableBackgroundColor": "#2B2B2B", "tableBorderColor": "#242424", "tableHeaderBackgroundColor": "#292929", - "tableHeaderBorderColor": "#1f1f1f", + "tableHeaderBorderColor": "#1F1F1F", "tableHeaderGradientColor": "#292929", - "tableHeaderTextColor": "#ebebeb", + "tableHeaderTextColor": "#EBEBEB", "tableScrollBackgroundColor": "#404040", - "tableScrollHandleColor": "#dddddd", - "tableSectionBorderDark": "#dfdfdf", - "tableSectionBorderLight": "#fefefe", + "tableScrollHandleColor": "#DDDDDD", + "tableSectionBorderDark": "#DFDFDF", + "tableSectionBorderLight": "#FEFEFE", "tableSelectedColor": "#555555", "toolButtonAccentColor": "#282828", - "upArrowColor": "#9f9f9f" + "upArrowColor": "#9F9F9F" }, "navigationTree": { - "branchIndicatorColor": "#e0e0e0", - "branchIndicatorSelectedColor": "#ffffff", - "folderIconColor": "#e0e0e0", - "folderIconSelectedColor": "#e0e0e0", + "branchIndicatorColor": "#E0E0E0", + "branchIndicatorSelectedColor": "#FFFFFF", + "folderIconColor": "#E0E0E0", + "folderIconSelectedColor": "#E0E0E0", "folderIconSelectedShadowColor": "#000000", "folderIconShadowColor": "#000000", - "folderNotCompletedColor": "#edc518", + "folderNotCompletedColor": "#EDC518", "folderReadOverlayColor": "#222222", "folderReadOverlaySelectedColor": "#222222", - "newItemColor": "#edc518", + "newItemColor": "#EDC518", "scrollBackgroundColor": "#404040", - "scrollHandleColor": "#dddddd", - "selectedTextColor": "#ffffff", - "selectionBackgroundColor": "#2e2e2e", - "textColor": "#dddfdf" + "scrollHandleColor": "#DDDDDD", + "selectedTextColor": "#FFFFFF", + "selectionBackgroundColor": "#2E2E2E", + "textColor": "#DDDFDF" }, "noLibrariesWidget": { - "backgroundColor": "#2a2a2a", - "descriptionTextColor": "#aaaaaa", - "iconColor": "#4c4c4c", - "noLibrariesLineColor": "#a8a8a8", - "textColor": "#cccccc" + "backgroundColor": "#2A2A2A", + "descriptionTextColor": "#AAAAAA", + "iconColor": "#4C4C4C", + "noLibrariesLineColor": "#A8A8A8", + "textColor": "#CCCCCC" }, "readingListIcons": { - "currentlyReadingMainColor": "#ffcc00", - "currentlyReadingMainSelectedColor": "#ffcc00", + "currentlyReadingMainColor": "#FFCC00", + "currentlyReadingMainSelectedColor": "#FFCC00", "currentlyReadingOuterColor": "#000000", "currentlyReadingOuterSelectedColor": "#000000", - "favoritesMainColor": "#e15055", - "favoritesMainSelectedColor": "#e15055", + "favoritesMainColor": "#E15055", + "favoritesMainSelectedColor": "#E15055", "labelColors": { - "blue": "#82c7ff", - "cyan": "#a0fddb", - "dark": "#b7b7b7", - "green": "#ade738", - "light": "#cbcbcb", - "orange": "#f5c240", - "pink": "#fd9cda", - "purple": "#d692fc", - "red": "#f67a7b", - "violet": "#8f95ff", - "white": "#fcfcfc", - "yellow": "#f2e446" + "blue": "#82C7FF", + "cyan": "#A0FDDB", + "dark": "#B7B7B7", + "green": "#ADE738", + "light": "#CBCBCB", + "orange": "#F5C240", + "pink": "#FD9CDA", + "purple": "#D692FC", + "red": "#F67A7B", + "violet": "#8F95FF", + "white": "#FCFCFC", + "yellow": "#F2E446" }, "labelShadowColor": "#000000", "labelShadowSelectedColor": "#000000", "listDetailColor": "#464646", "listDetailSelectedColor": "#464646", - "listMainColor": "#e7e7e7", - "listMainSelectedColor": "#e7e7e7", + "listMainColor": "#E7E7E7", + "listMainSelectedColor": "#E7E7E7", "listShadowColor": "#000000", "listShadowSelectedColor": "#000000", - "readingListMainColor": "#e7e7e7", - "readingListMainSelectedColor": "#e7e7e7", + "readingListMainColor": "#E7E7E7", + "readingListMainSelectedColor": "#E7E7E7", "specialListShadowColor": "#000000", "specialListShadowSelectedColor": "#000000" }, "searchLineEdit": { "backgroundColor": "#404040", - "iconColor": "#f7f7f7", - "textColor": "#ababab" + "iconColor": "#F7F7F7", + "textColor": "#ABABAB" }, "serverConfigDialog": { - "backgroundColor": "#2a2a2a", - "checkBoxTextColor": "#dddddd", - "decorationColor": "#f7f7f7", - "labelTextColor": "#c0c0c0", - "propagandaTextColor": "#b0b0b0", - "qrBackgroundColor": "#2a2a2a", - "qrForegroundColor": "#ffffff", - "qrMessageTextColor": "#a3a3a3", - "titleTextColor": "#d0d0d0" + "backgroundColor": "#2A2A2A", + "checkBoxTextColor": "#DDDDDD", + "decorationColor": "#F7F7F7", + "labelTextColor": "#C0C0C0", + "propagandaTextColor": "#B0B0B0", + "qrBackgroundColor": "#2A2A2A", + "qrForegroundColor": "#FFFFFF", + "qrMessageTextColor": "#A3A3A3", + "titleTextColor": "#D0D0D0" }, "shortcutsIcons": { - "iconColor": "#f7f7f7" + "iconColor": "#F7F7F7" }, "sidebar": { "backgroundColor": "#454545", - "busyIndicatorColor": "#ffffff", + "busyIndicatorColor": "#FFFFFF", "sectionSeparatorColor": "#575757", - "separatorColor": "#bdbfbf", + "separatorColor": "#BDBFBF", "titleDropShadowColor": "#000000", - "titleTextColor": "#bdbfbf", + "titleTextColor": "#BDBFBF", "uppercaseLabels": true }, "sidebarIcons": { - "iconColor": "#e0e0e0", + "iconColor": "#E0E0E0", "shadowColor": "#000000", "useSystemFolderIcons": false }, "whatsNewDialog": { - "backgroundColor": "#2a2a2a", - "closeButtonColor": "#dddddd", - "contentTextColor": "#e0e0e0", - "headerDecorationColor": "#e8b800", - "headerTextColor": "#e0e0e0", - "linkColor": "#e8b800", + "backgroundColor": "#2A2A2A", + "closeButtonColor": "#DDDDDD", + "contentTextColor": "#E0E0E0", + "headerDecorationColor": "#E8B800", + "headerTextColor": "#E0E0E0", + "linkColor": "#E8B800", "versionTextColor": "#858585" } } diff --git a/YACReaderLibrary/themes/builtin_light.json b/YACReaderLibrary/themes/builtin_light.json index 9742b606f..f6d252ac5 100644 --- a/YACReaderLibrary/themes/builtin_light.json +++ b/YACReaderLibrary/themes/builtin_light.json @@ -1,36 +1,36 @@ { "comicFlow": { - "backgroundColor": "#dcdcdc", - "readMainColor": "#db4725", - "readTickColor": "#8a2c17", - "readingColor": "#e6b90f", + "backgroundColor": "#DCDCDC", + "readMainColor": "#DB4725", + "readTickColor": "#8A2C17", + "readingColor": "#E6B90F", "textColor": "#303030" }, "comicsViewTable": { - "alternateBackgroundColor": "#f2f2f2", - "backgroundColor": "#fafafa", - "headerBackgroundColor": "#f5f5f5", - "headerBorderColor": "#b8bdc4", - "headerGradientColor": "#f5f5f5", + "alternateBackgroundColor": "#F2F2F2", + "backgroundColor": "#FAFAFA", + "headerBackgroundColor": "#F5F5F5", + "headerBorderColor": "#B8BDC4", + "headerGradientColor": "#F5F5F5", "headerTextColor": "#313232", - "itemBorderBottomColor": "#dfdfdf", + "itemBorderBottomColor": "#DFDFDF", "itemBorderBottomWidth": 0, - "itemBorderTopColor": "#fefefe", + "itemBorderTopColor": "#FEFEFE", "itemBorderTopWidth": 0, "itemTextColor": "#252626", "selectedColor": "#595959", - "selectedTextColor": "#ffffff", - "starRatingColor": "#e9be0f", - "starRatingSelectedColor": "#ffffff" + "selectedTextColor": "#FFFFFF", + "starRatingColor": "#E9BE0F", + "starRatingSelectedColor": "#FFFFFF" }, "comicsViewToolbar": { - "backgroundColor": "#f0f0f0", - "checkedBackgroundColor": "#cccccc", + "backgroundColor": "#F0F0F0", + "checkedBackgroundColor": "#CCCCCC", "iconColor": "#404040", - "separatorColor": "#cccccc" + "separatorColor": "#CCCCCC" }, "contentSplitter": { - "handleColor": "#f0f0f0", + "handleColor": "#F0F0F0", "horizontalHandleHeight": 4, "verticalHandleWidth": 4 }, @@ -38,84 +38,84 @@ "iconColor": "#606060" }, "emptyContainer": { - "backgroundColor": "#ffffff", - "iconColor": "#cccccc", + "backgroundColor": "#FFFFFF", + "iconColor": "#CCCCCC", "titleTextColor": "#888888" }, "gridAndInfoView": { - "backgroundBlurOverlayColor": "#9e9e9e", - "backgroundColor": "#f6f6f6", - "borderColor": "#dbdbdb", - "buttonColor": "#ffcc00", - "buttonShadowColor": "#aa000000", - "buttonTextColor": "#ffffff", - "cellColor": "#ffffff", - "cellColorWithBackground": "#99ffffff", - "cellSelectedBorderColor": "#ffcc00", - "cellSelectedColor": "#ffffff", - "comicCoverBorderColor": "#30ffffff", - "continueReadingBackgroundColor": "#e8e8e8", + "backgroundBlurOverlayColor": "#9E9E9E", + "backgroundColor": "#F6F6F6", + "borderColor": "#DBDBDB", + "buttonColor": "#FFCC00", + "buttonShadowColor": "#AA000000", + "buttonTextColor": "#FFFFFF", + "cellColor": "#FFFFFF", + "cellColorWithBackground": "#99FFFFFF", + "cellSelectedBorderColor": "#FFCC00", + "cellSelectedColor": "#FFFFFF", + "comicCoverBorderColor": "#30FFFFFF", + "continueReadingBackgroundColor": "#E8E8E8", "continueReadingTextColor": "#000000", - "currentComicBackgroundColor": "#88ffffff", - "currentComicCoverShadowColor": "#ff000000", - "favCheckedColor": "#e84852", - "favUncheckedColor": "#dedede", - "folderCoverBorderColor": "#20ffffff", - "infoBackgroundColor": "#ffffff", + "currentComicBackgroundColor": "#88FFFFFF", + "currentComicCoverShadowColor": "#FF000000", + "favCheckedColor": "#E84852", + "favUncheckedColor": "#DEDEDE", + "folderCoverBorderColor": "#20FFFFFF", + "infoBackgroundColor": "#FFFFFF", "infoBorderColor": "#808080", "infoMetadataTextColor": "#404040", - "infoScrollbarColor": "#ff424246", + "infoScrollbarColor": "#FF424246", "infoShadowColor": "#444444", - "infoTextColor": "#2e2e2e", + "infoTextColor": "#2E2E2E", "itemDetailsColor": "#636363", "itemTitleColor": "#121212", - "linkColor": "#ffcc00", - "newItemColor": "#ffffcc00", - "placeholderFolder1BorderColor": "#20ffffff", + "linkColor": "#FFCC00", + "newItemColor": "#FFFFCC00", + "placeholderFolder1BorderColor": "#20FFFFFF", "placeholderFolder1Color": "#20000000", - "placeholderFolder2BorderColor": "#20ffffff", + "placeholderFolder2BorderColor": "#20FFFFFF", "placeholderFolder2Color": "#88000000", - "ratingSelectedColor": "#2b2b2b", - "ratingUnselectedColor": "#dedede", - "readTickCheckedColor": "#e84852", - "readTickUncheckedColor": "#dedede", - "scrollbarBorderColor": "#aa313131", + "ratingSelectedColor": "#2B2B2B", + "ratingUnselectedColor": "#DEDEDE", + "readTickCheckedColor": "#E84852", + "readTickUncheckedColor": "#DEDEDE", + "scrollbarBorderColor": "#AA313131", "scrollbarColor": "#88424242", "showDropShadow": true }, "helpAboutDialog": { - "headingColor": "#302f2d", - "linkColor": "#c19441" + "headingColor": "#302F2D", + "linkColor": "#C19441" }, "importWidget": { - "backgroundColor": "#fafafa", - "coversDecorationBgColor": "#e6e6e6", - "coversDecorationShadowColor": "#a1a1a1", + "backgroundColor": "#FAFAFA", + "coversDecorationBgColor": "#E6E6E6", + "coversDecorationShadowColor": "#A1A1A1", "coversLabelColor": "#565959", - "coversViewBackgroundColor": "#e6e6e6", + "coversViewBackgroundColor": "#E6E6E6", "currentComicTextColor": "#565959", "descriptionTextColor": "#565959", - "glowLineColor": "#ffe100", + "glowLineColor": "#FFE100", "iconCheckedColor": "#565959", "iconColor": "#495252", - "modeIconColor": "#e6e6e6", + "modeIconColor": "#E6E6E6", "titleTextColor": "#495252" }, "libraryItem": { "libraryIconColor": "#606060", - "libraryIconSelectedColor": "#ffffff", - "libraryIconShadowColor": "#ffffff", - "libraryOptionsIconColor": "#ffffff", + "libraryIconSelectedColor": "#FFFFFF", + "libraryIconShadowColor": "#FFFFFF", + "libraryOptionsIconColor": "#FFFFFF", "selectedBackgroundColor": "#333133", - "selectedTextColor": "#ffffff", + "selectedTextColor": "#FFFFFF", "textColor": "#000000" }, "mainToolbar": { - "backgroundColor": "#f0f0f0", - "dividerColor": "#b8bdc4", + "backgroundColor": "#F0F0F0", + "dividerColor": "#B8BDC4", "folderNameColor": "#333133", "iconColor": "#333133", - "iconDisabledColor": "#b0b0b0" + "iconDisabledColor": "#B0B0B0" }, "menuIcons": { "iconColor": "#606060" @@ -129,136 +129,136 @@ }, "metadataScraperDialog": { "busyIndicatorColor": "#000000", - "buttonBackgroundColor": "#e0e0e0", - "buttonBorderColor": "#cccccc", + "buttonBackgroundColor": "#E0E0E0", + "buttonBorderColor": "#CCCCCC", "buttonTextColor": "#000000", "checkBoxTickColor": "#000000", - "contentAltBackgroundColor": "#e0e0e0", - "contentBackgroundColor": "#ececec", + "contentAltBackgroundColor": "#E0E0E0", + "contentBackgroundColor": "#ECECEC", "contentTextColor": "#000000", - "dialogBackgroundColor": "#fbfbfb", + "dialogBackgroundColor": "#FBFBFB", "downArrowColor": "#222222", - "hyperlinkColor": "#ffcc00", - "labelBackgroundColor": "#ececec", + "hyperlinkColor": "#FFCC00", + "labelBackgroundColor": "#ECECEC", "labelTextColor": "#000000", "navIconColor": "#222222", - "radioCheckedBackgroundColor": "#e0e0e0", + "radioCheckedBackgroundColor": "#E0E0E0", "radioCheckedIndicatorColor": "#222222", - "radioUncheckedColor": "#e0e0e0", + "radioUncheckedColor": "#E0E0E0", "rowIconColor": "#222222", - "tableAltBackgroundColor": "#fafafa", - "tableBackgroundColor": "#f4f4f4", - "tableBorderColor": "#cccccc", - "tableHeaderBackgroundColor": "#e0e0e0", - "tableHeaderBorderColor": "#c0c0c0", - "tableHeaderGradientColor": "#e0e0e0", + "tableAltBackgroundColor": "#FAFAFA", + "tableBackgroundColor": "#F4F4F4", + "tableBorderColor": "#CCCCCC", + "tableHeaderBackgroundColor": "#E0E0E0", + "tableHeaderBorderColor": "#C0C0C0", + "tableHeaderGradientColor": "#E0E0E0", "tableHeaderTextColor": "#333333", - "tableScrollBackgroundColor": "#d0d0d0", + "tableScrollBackgroundColor": "#D0D0D0", "tableScrollHandleColor": "#888888", - "tableSectionBorderDark": "#cccccc", - "tableSectionBorderLight": "#ffffff", - "tableSelectedColor": "#dddddd", - "toolButtonAccentColor": "#a0a0a0", + "tableSectionBorderDark": "#CCCCCC", + "tableSectionBorderLight": "#FFFFFF", + "tableSelectedColor": "#DDDDDD", + "toolButtonAccentColor": "#A0A0A0", "upArrowColor": "#222222" }, "navigationTree": { "branchIndicatorColor": "#606060", - "branchIndicatorSelectedColor": "#ffffff", + "branchIndicatorSelectedColor": "#FFFFFF", "folderIconColor": "#606060", - "folderIconSelectedColor": "#ffffff", + "folderIconSelectedColor": "#FFFFFF", "folderIconSelectedShadowColor": "#161616", - "folderIconShadowColor": "#ffffff", - "folderNotCompletedColor": "#555f7f", - "folderReadOverlayColor": "#ffffff", + "folderIconShadowColor": "#FFFFFF", + "folderNotCompletedColor": "#555F7F", + "folderReadOverlayColor": "#FFFFFF", "folderReadOverlaySelectedColor": "#161616", - "newItemColor": "#555f7f", - "scrollBackgroundColor": "#e0e0e0", + "newItemColor": "#555F7F", + "scrollBackgroundColor": "#E0E0E0", "scrollHandleColor": "#888888", - "selectedTextColor": "#ffffff", + "selectedTextColor": "#FFFFFF", "selectionBackgroundColor": "#333133", "textColor": "#000000" }, "noLibrariesWidget": { - "backgroundColor": "#ffffff", + "backgroundColor": "#FFFFFF", "descriptionTextColor": "#565959", - "iconColor": "#cccccc", - "noLibrariesLineColor": "#a8a8a8", + "iconColor": "#CCCCCC", + "noLibrariesLineColor": "#A8A8A8", "textColor": "#495252" }, "readingListIcons": { - "currentlyReadingMainColor": "#ffcc00", - "currentlyReadingMainSelectedColor": "#ffcc00", + "currentlyReadingMainColor": "#FFCC00", + "currentlyReadingMainSelectedColor": "#FFCC00", "currentlyReadingOuterColor": "#000000", "currentlyReadingOuterSelectedColor": "#000000", - "favoritesMainColor": "#e15055", - "favoritesMainSelectedColor": "#e15055", + "favoritesMainColor": "#E15055", + "favoritesMainSelectedColor": "#E15055", "labelColors": { - "blue": "#82c7ff", - "cyan": "#a0fddb", - "dark": "#b7b7b7", - "green": "#ade738", - "light": "#cbcbcb", - "orange": "#f5c240", - "pink": "#fd9cda", - "purple": "#d692fc", - "red": "#f67a7b", - "violet": "#8f95ff", - "white": "#fcfcfc", - "yellow": "#f2e446" + "blue": "#82C7FF", + "cyan": "#A0FDDB", + "dark": "#B7B7B7", + "green": "#ADE738", + "light": "#CBCBCB", + "orange": "#F5C240", + "pink": "#FD9CDA", + "purple": "#D692FC", + "red": "#F67A7B", + "violet": "#8F95FF", + "white": "#FCFCFC", + "yellow": "#F2E446" }, - "labelShadowColor": "#8f8f8f", + "labelShadowColor": "#8F8F8F", "labelShadowSelectedColor": "#161616", - "listDetailColor": "#ffffff", + "listDetailColor": "#FFFFFF", "listDetailSelectedColor": "#161616", "listMainColor": "#808080", - "listMainSelectedColor": "#ffffff", - "listShadowColor": "#8f8f8f", + "listMainSelectedColor": "#FFFFFF", + "listShadowColor": "#8F8F8F", "listShadowSelectedColor": "#161616", "readingListMainColor": "#808080", "readingListMainSelectedColor": "#808080", - "specialListShadowColor": "#8f8f8f", + "specialListShadowColor": "#8F8F8F", "specialListShadowSelectedColor": "#161616" }, "searchLineEdit": { "backgroundColor": "#333133", - "iconColor": "#efefef", - "textColor": "#ffffff" + "iconColor": "#EFEFEF", + "textColor": "#FFFFFF" }, "serverConfigDialog": { - "backgroundColor": "#ffffff", + "backgroundColor": "#FFFFFF", "checkBoxTextColor": "#262626", "decorationColor": "#606060", "labelTextColor": "#575757", - "propagandaTextColor": "#4d4d4d", - "qrBackgroundColor": "#ffffff", + "propagandaTextColor": "#4D4D4D", + "qrBackgroundColor": "#FFFFFF", "qrForegroundColor": "#606060", - "qrMessageTextColor": "#a3a3a3", + "qrMessageTextColor": "#A3A3A3", "titleTextColor": "#474747" }, "shortcutsIcons": { "iconColor": "#606060" }, "sidebar": { - "backgroundColor": "#fbfbfb", + "backgroundColor": "#FBFBFB", "busyIndicatorColor": "#808080", - "sectionSeparatorColor": "#e0e0e0", + "sectionSeparatorColor": "#E0E0E0", "separatorColor": "#808080", - "titleDropShadowColor": "#ffffff", - "titleTextColor": "#4a494a", + "titleDropShadowColor": "#FFFFFF", + "titleTextColor": "#4A494A", "uppercaseLabels": true }, "sidebarIcons": { - "iconColor": "#4f4e4f", - "shadowColor": "#fbfbfb", + "iconColor": "#4F4E4F", + "shadowColor": "#FBFBFB", "useSystemFolderIcons": false }, "whatsNewDialog": { - "backgroundColor": "#ffffff", + "backgroundColor": "#FFFFFF", "closeButtonColor": "#444444", - "contentTextColor": "#0a0a0a", - "headerDecorationColor": "#e8b800", - "headerTextColor": "#0a0a0a", - "linkColor": "#e8b800", + "contentTextColor": "#0A0A0A", + "headerDecorationColor": "#E8B800", + "headerTextColor": "#0A0A0A", + "linkColor": "#E8B800", "versionTextColor": "#858585" } } diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index ae0c16392..47729aad8 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -120,6 +120,8 @@ add_library(common_gui STATIC themes/shared/whats_new_dialog_theme.h themes/theme_editor_dialog.h themes/theme_editor_dialog.cpp + themes/theme_json_utils.h + themes/theme_json_utils.cpp themes/theme_meta.h themes/theme_repository.h themes/theme_repository.cpp diff --git a/common/themes/theme_editor_dialog.cpp b/common/themes/theme_editor_dialog.cpp index c969aa29b..b8fa6b7d7 100644 --- a/common/themes/theme_editor_dialog.cpp +++ b/common/themes/theme_editor_dialog.cpp @@ -1,4 +1,5 @@ #include "theme_editor_dialog.h" +#include "theme_json_utils.h" #include #include @@ -51,17 +52,8 @@ static QString displayKey(const QString &key) return result; } -static bool isColorString(const QString &s) -{ - // Accepts #RGB, #RRGGBB, #AARRGGBB - if (!s.startsWith('#')) - return false; - const int len = s.length(); - return len == 4 || len == 7 || len == 9; -} - ThemeEditorDialog::ThemeEditorDialog(const QJsonObject ¶ms, QWidget *parent) - : QDialog(parent), params(params) + : QDialog(parent), params(normalizeThemeJson(params)) { setWindowTitle(tr("Theme Editor")); resize(520, 700); @@ -206,7 +198,7 @@ void ThemeEditorDialog::populate(QTreeWidgetItem *parent, const QJsonObject &obj item->setData(0, PathRole, childPath); const QString strVal = val.toString(); - if (val.isString() && isColorString(strVal)) { + if (val.isString() && isThemeHexColorString(strVal)) { const QColor color(strVal); item->setIcon(1, colorIcon(color)); item->setText(1, strVal); @@ -256,11 +248,12 @@ void ThemeEditorDialog::applyColorToItem(QTreeWidgetItem *item, const QColor &co const QString hexStr = color.alpha() < 255 ? color.name(QColor::HexArgb) : color.name(QColor::HexRgb); - item->setText(1, hexStr); + const QString normalizedHexStr = hexStr.toUpper(); + item->setText(1, normalizedHexStr); item->setIcon(1, colorIcon(color)); const QStringList path = item->data(0, PathRole).toStringList(); - setJsonPath(params, path, hexStr); + setJsonPath(params, path, normalizedHexStr); } void ThemeEditorDialog::toggleBoolItem(QTreeWidgetItem *item) @@ -409,7 +402,7 @@ void ThemeEditorDialog::saveToFile() QMessageBox::warning(this, tr("Save failed"), tr("Could not open file for writing:\n%1").arg(path)); return; } - file.write(QJsonDocument(params).toJson(QJsonDocument::Indented)); + file.write(serializeNormalizedThemeJson(params)); } void ThemeEditorDialog::loadFromFile() @@ -436,7 +429,7 @@ void ThemeEditorDialog::loadFromFile() return; } - params = doc.object(); + params = normalizeThemeJson(doc.object()); syncMetaFromParams(); tree->clear(); populate(nullptr, params, { }); diff --git a/common/themes/theme_json_utils.cpp b/common/themes/theme_json_utils.cpp new file mode 100644 index 000000000..0225af643 --- /dev/null +++ b/common/themes/theme_json_utils.cpp @@ -0,0 +1,50 @@ +#include "theme_json_utils.h" + +#include +#include +#include + +namespace { + +QJsonValue normalizeThemeJsonValue(const QJsonValue &value) +{ + if (value.isObject()) + return normalizeThemeJson(value.toObject()); + + if (value.isArray()) { + QJsonArray normalizedArray = value.toArray(); + for (int i = 0; i < normalizedArray.size(); ++i) + normalizedArray[i] = normalizeThemeJsonValue(normalizedArray.at(i)); + return normalizedArray; + } + + if (value.isString()) { + const QString stringValue = value.toString(); + if (isThemeHexColorString(stringValue)) + return stringValue.toUpper(); + } + + return value; +} + +} + +bool isThemeHexColorString(const QString &value) +{ + static const QRegularExpression colorRegex( + "^#(?:[0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$"); + return colorRegex.match(value).hasMatch(); +} + +QJsonObject normalizeThemeJson(const QJsonObject &json) +{ + QJsonObject normalized; + for (auto it = json.constBegin(); it != json.constEnd(); ++it) + normalized.insert(it.key(), normalizeThemeJsonValue(it.value())); + return normalized; +} + +QByteArray serializeNormalizedThemeJson(const QJsonObject &json, QJsonDocument::JsonFormat format) +{ + return QJsonDocument(normalizeThemeJson(json)).toJson(format); +} diff --git a/common/themes/theme_json_utils.h b/common/themes/theme_json_utils.h new file mode 100644 index 000000000..106f4638d --- /dev/null +++ b/common/themes/theme_json_utils.h @@ -0,0 +1,14 @@ +#ifndef THEME_JSON_UTILS_H +#define THEME_JSON_UTILS_H + +#include +#include +#include +#include + +bool isThemeHexColorString(const QString &value); +QJsonObject normalizeThemeJson(const QJsonObject &json); +QByteArray serializeNormalizedThemeJson(const QJsonObject &json, + QJsonDocument::JsonFormat format = QJsonDocument::Indented); + +#endif // THEME_JSON_UTILS_H diff --git a/common/themes/theme_repository.cpp b/common/themes/theme_repository.cpp index 96a3e0d5c..2b324bca5 100644 --- a/common/themes/theme_repository.cpp +++ b/common/themes/theme_repository.cpp @@ -1,4 +1,5 @@ #include "theme_repository.h" +#include "theme_json_utils.h" #include #include @@ -78,7 +79,7 @@ QString ThemeRepository::saveUserTheme(QJsonObject themeJson) QFile file(filePath); if (file.open(QIODevice::WriteOnly)) { - file.write(QJsonDocument(themeJson).toJson(QJsonDocument::Indented)); + file.write(serializeNormalizedThemeJson(themeJson)); file.close(); } From 1fd9fb6cabc06c415e1ea232f8c42905507497c5 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 22 Mar 2026 15:29:08 +0100 Subject: [PATCH 160/187] Fix Italian translation for Restore --- YACReader/yacreader_it.ts | 2 +- YACReaderLibrary/yacreaderlibrary_it.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/YACReader/yacreader_it.ts b/YACReader/yacreader_it.ts index 2812cc445..ab167aec7 100644 --- a/YACReader/yacreader_it.ts +++ b/YACReader/yacreader_it.ts @@ -3994,7 +3994,7 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https &Restore - &Rnegozio + &Ripristina diff --git a/YACReaderLibrary/yacreaderlibrary_it.ts b/YACReaderLibrary/yacreaderlibrary_it.ts index 6316ee61f..e4135f39e 100644 --- a/YACReaderLibrary/yacreaderlibrary_it.ts +++ b/YACReaderLibrary/yacreaderlibrary_it.ts @@ -4014,7 +4014,7 @@ Migliora le prestazioni! &Restore - &Rnegozio + &Ripristina From 64a2f9fdf828518e3b01ad12c3c66ad7255cf6dc Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 22 Mar 2026 18:15:54 +0100 Subject: [PATCH 161/187] Translation fixes --- YACReader/yacreader_de.ts | 2 +- YACReader/yacreader_fr.ts | 2 +- YACReader/yacreader_it.ts | 6 +++--- YACReader/yacreader_nl.ts | 4 ++-- YACReader/yacreader_pt.ts | 2 +- YACReader/yacreader_ru.ts | 2 +- YACReaderLibrary/yacreaderlibrary_de.ts | 2 +- YACReaderLibrary/yacreaderlibrary_fr.ts | 2 +- YACReaderLibrary/yacreaderlibrary_it.ts | 2 +- YACReaderLibrary/yacreaderlibrary_nl.ts | 4 ++-- YACReaderLibrary/yacreaderlibrary_pt.ts | 2 +- YACReaderLibrary/yacreaderlibrary_ru.ts | 2 +- YACReaderLibraryServer/yacreaderlibraryserver_de.ts | 2 +- YACReaderLibraryServer/yacreaderlibraryserver_fr.ts | 2 +- YACReaderLibraryServer/yacreaderlibraryserver_nl.ts | 4 ++-- YACReaderLibraryServer/yacreaderlibraryserver_pt.ts | 2 +- YACReaderLibraryServer/yacreaderlibraryserver_ru.ts | 2 +- 17 files changed, 22 insertions(+), 22 deletions(-) diff --git a/YACReader/yacreader_de.ts b/YACReader/yacreader_de.ts index b5fe18b39..0f4a2ef35 100644 --- a/YACReader/yacreader_de.ts +++ b/YACReader/yacreader_de.ts @@ -3164,7 +3164,7 @@ Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Do Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - Halten Sie gedrückt, um den ausgewählten Wert in der Benutzeroberfläche zu blinken (Magenta / umgeschaltet / 0↔10). Releases stellen das Original wieder her. + Halten Sie gedrückt, um den ausgewählten Wert in der Benutzeroberfläche zu blinken (Magenta / umgeschaltet / 0↔10). Loslassen stellt das Original wieder her. diff --git a/YACReader/yacreader_fr.ts b/YACReader/yacreader_fr.ts index c38b7cda7..45f7bdf05 100644 --- a/YACReader/yacreader_fr.ts +++ b/YACReader/yacreader_fr.ts @@ -4000,7 +4000,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quit</b> dans le menu contextuel de l'icône de la barre d'état système. + YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quitter</b> dans le menu contextuel de l'icône de la barre d'état système. diff --git a/YACReader/yacreader_it.ts b/YACReader/yacreader_it.ts index ab167aec7..5297c8025 100644 --- a/YACReader/yacreader_it.ts +++ b/YACReader/yacreader_it.ts @@ -215,7 +215,7 @@ Click on any image to go to the bookmark - Click su qualsiasi immagine per andare al bookmark + Clicca su qualsiasi immagine per andare al segnalibro @@ -4025,7 +4025,7 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https Click to overwrite - Click per sovrascrivere + Clicca per sovrascrivere @@ -4041,7 +4041,7 @@ Per conoscere le impostazioni disponibili, consultare la documentazione su https Click to overwrite - Click per sovrascrivere + Clicca per sovrascrivere diff --git a/YACReader/yacreader_nl.ts b/YACReader/yacreader_nl.ts index 2855d7889..038540d1e 100644 --- a/YACReader/yacreader_nl.ts +++ b/YACReader/yacreader_nl.ts @@ -2919,7 +2919,7 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - Houd ingedrukt om de geselecteerde waarde in de gebruikersinterface te laten knipperen (magenta / geschakeld / 0↔10). Releases herstellen het origineel. + Houd ingedrukt om de geselecteerde waarde in de gebruikersinterface te laten knipperen (magenta / geschakeld / 0↔10). Loslaten herstelt het origineel. @@ -3828,7 +3828,7 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary blijft actief in het systeemvak. Om het programma te beëindigen, kiest u <b>Quit</b> in het contextmenu van het systeemvakpictogram. + YACReaderLibrary blijft actief in het systeemvak. Om het programma te beëindigen, kiest u <b>Afsluiten</b> in het contextmenu van het systeemvakpictogram. diff --git a/YACReader/yacreader_pt.ts b/YACReader/yacreader_pt.ts index fada5a6ac..c72198e98 100644 --- a/YACReader/yacreader_pt.ts +++ b/YACReader/yacreader_pt.ts @@ -3784,7 +3784,7 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary continuará em execução na bandeja do sistema. Para encerrar o programa, escolha <b>Quit</b> no menu de contexto do ícone da bandeja do sistema. + YACReaderLibrary continuará em execução na bandeja do sistema. Para encerrar o programa, escolha <b>Sair</b> no menu de contexto do ícone da bandeja do sistema. diff --git a/YACReader/yacreader_ru.ts b/YACReader/yacreader_ru.ts index c1b68c389..3cd42b98e 100644 --- a/YACReader/yacreader_ru.ts +++ b/YACReader/yacreader_ru.ts @@ -4004,7 +4004,7 @@ YACReaderLibraryServer — это безголовая (без графичес YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary продолжит работать в системном трее. Чтобы завершить работу программы, выберите <b>Quit</b> в контекстном меню значка на панели задач. + YACReaderLibrary продолжит работать в системном трее. Чтобы завершить работу программы, выберите <b>Выход</b> в контекстном меню значка на панели задач. diff --git a/YACReaderLibrary/yacreaderlibrary_de.ts b/YACReaderLibrary/yacreaderlibrary_de.ts index 643502110..d1a856a11 100644 --- a/YACReaderLibrary/yacreaderlibrary_de.ts +++ b/YACReaderLibrary/yacreaderlibrary_de.ts @@ -3189,7 +3189,7 @@ um die Leistung zu verbessern Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - Halten Sie gedrückt, um den ausgewählten Wert in der Benutzeroberfläche zu blinken (Magenta / umgeschaltet / 0↔10). Releases stellen das Original wieder her. + Halten Sie gedrückt, um den ausgewählten Wert in der Benutzeroberfläche zu blinken (Magenta / umgeschaltet / 0↔10). Loslassen stellt das Original wieder her. diff --git a/YACReaderLibrary/yacreaderlibrary_fr.ts b/YACReaderLibrary/yacreaderlibrary_fr.ts index 76d2fdeb0..8a9ccc5f5 100644 --- a/YACReaderLibrary/yacreaderlibrary_fr.ts +++ b/YACReaderLibrary/yacreaderlibrary_fr.ts @@ -3943,7 +3943,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quit</b> dans le menu contextuel de l'icône de la barre d'état système. + YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quitter</b> dans le menu contextuel de l'icône de la barre d'état système. diff --git a/YACReaderLibrary/yacreaderlibrary_it.ts b/YACReaderLibrary/yacreaderlibrary_it.ts index e4135f39e..57845f0cb 100644 --- a/YACReaderLibrary/yacreaderlibrary_it.ts +++ b/YACReaderLibrary/yacreaderlibrary_it.ts @@ -266,7 +266,7 @@ Click on any image to go to the bookmark - Click su qualsiasi immagine per andare al bookmark + Clicca su qualsiasi immagine per andare al segnalibro diff --git a/YACReaderLibrary/yacreaderlibrary_nl.ts b/YACReaderLibrary/yacreaderlibrary_nl.ts index c4059736c..6c31e09a7 100644 --- a/YACReaderLibrary/yacreaderlibrary_nl.ts +++ b/YACReaderLibrary/yacreaderlibrary_nl.ts @@ -2922,7 +2922,7 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - Houd ingedrukt om de geselecteerde waarde in de gebruikersinterface te laten knipperen (magenta / geschakeld / 0↔10). Releases herstellen het origineel. + Houd ingedrukt om de geselecteerde waarde in de gebruikersinterface te laten knipperen (magenta / geschakeld / 0↔10). Loslaten herstelt het origineel. @@ -3831,7 +3831,7 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary blijft actief in het systeemvak. Om het programma te beëindigen, kiest u <b>Quit</b> in het contextmenu van het systeemvakpictogram. + YACReaderLibrary blijft actief in het systeemvak. Om het programma te beëindigen, kiest u <b>Afsluiten</b> in het contextmenu van het systeemvakpictogram. diff --git a/YACReaderLibrary/yacreaderlibrary_pt.ts b/YACReaderLibrary/yacreaderlibrary_pt.ts index d891094e3..e5e3ee717 100644 --- a/YACReaderLibrary/yacreaderlibrary_pt.ts +++ b/YACReaderLibrary/yacreaderlibrary_pt.ts @@ -3763,7 +3763,7 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary continuará em execução na bandeja do sistema. Para encerrar o programa, escolha <b>Quit</b> no menu de contexto do ícone da bandeja do sistema. + YACReaderLibrary continuará em execução na bandeja do sistema. Para encerrar o programa, escolha <b>Sair</b> no menu de contexto do ícone da bandeja do sistema. diff --git a/YACReaderLibrary/yacreaderlibrary_ru.ts b/YACReaderLibrary/yacreaderlibrary_ru.ts index d24815c9c..80745af3a 100644 --- a/YACReaderLibrary/yacreaderlibrary_ru.ts +++ b/YACReaderLibrary/yacreaderlibrary_ru.ts @@ -4000,7 +4000,7 @@ to improve the performance YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary продолжит работать в системном трее. Чтобы завершить работу программы, выберите <b>Quit</b> в контекстном меню значка на панели задач. + YACReaderLibrary продолжит работать в системном трее. Чтобы завершить работу программы, выберите <b>Выход</b> в контекстном меню значка на панели задач. diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_de.ts b/YACReaderLibraryServer/yacreaderlibraryserver_de.ts index 00b49974a..f322c6123 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_de.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_de.ts @@ -2705,7 +2705,7 @@ Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Do Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - Halten Sie gedrückt, um den ausgewählten Wert in der Benutzeroberfläche zu blinken (Magenta / umgeschaltet / 0↔10). Releases stellen das Original wieder her. + Halten Sie gedrückt, um den ausgewählten Wert in der Benutzeroberfläche zu blinken (Magenta / umgeschaltet / 0↔10). Loslassen stellt das Original wieder her. diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_fr.ts b/YACReaderLibraryServer/yacreaderlibraryserver_fr.ts index 7b9897884..d5aef3804 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_fr.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_fr.ts @@ -3614,7 +3614,7 @@ Pour en savoir plus sur les paramètres disponibles, veuillez consulter la docum YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quit</b> dans le menu contextuel de l'icône de la barre d'état système. + YACReaderLibrary continuera à fonctionner dans la barre d'état système. Pour terminer le programme, choisissez <b>Quitter</b> dans le menu contextuel de l'icône de la barre d'état système. diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_nl.ts b/YACReaderLibraryServer/yacreaderlibraryserver_nl.ts index 1115a03f3..f80557d24 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_nl.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_nl.ts @@ -2705,7 +2705,7 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa Hold to flash the selected value in the UI (magenta / toggled / 0↔10). Releases restore the original. - Houd ingedrukt om de geselecteerde waarde in de gebruikersinterface te laten knipperen (magenta / geschakeld / 0↔10). Releases herstellen het origineel. + Houd ingedrukt om de geselecteerde waarde in de gebruikersinterface te laten knipperen (magenta / geschakeld / 0↔10). Loslaten herstelt het origineel. @@ -3614,7 +3614,7 @@ Voor meer informatie over de beschikbare instellingen kunt u de documentatie raa YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary blijft actief in het systeemvak. Om het programma te beëindigen, kiest u <b>Quit</b> in het contextmenu van het systeemvakpictogram. + YACReaderLibrary blijft actief in het systeemvak. Om het programma te beëindigen, kiest u <b>Afsluiten</b> in het contextmenu van het systeemvakpictogram. diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_pt.ts b/YACReaderLibraryServer/yacreaderlibraryserver_pt.ts index f99923569..cfba41b35 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_pt.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_pt.ts @@ -3614,7 +3614,7 @@ Para saber mais sobre as configurações disponíveis, verifique a documentaçã YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary continuará em execução na bandeja do sistema. Para encerrar o programa, escolha <b>Quit</b> no menu de contexto do ícone da bandeja do sistema. + YACReaderLibrary continuará em execução na bandeja do sistema. Para encerrar o programa, escolha <b>Sair</b> no menu de contexto do ícone da bandeja do sistema. diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_ru.ts b/YACReaderLibraryServer/yacreaderlibraryserver_ru.ts index 3e334affd..bf471a703 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_ru.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_ru.ts @@ -3614,7 +3614,7 @@ YACReaderLibraryServer — это безголовая (без графичес YACReaderLibrary will keep running in the system tray. To terminate the program, choose <b>Quit</b> in the context menu of the system tray icon. - YACReaderLibrary продолжит работать в системном трее. Чтобы завершить работу программы, выберите <b>Quit</b> в контекстном меню значка на панели задач. + YACReaderLibrary продолжит работать в системном трее. Чтобы завершить работу программы, выберите <b>Выход</b> в контекстном меню значка на панели задач. From 6752b0b2a49483774d6f9895cf2cba9749b35d32 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 22 Mar 2026 18:35:24 +0100 Subject: [PATCH 162/187] Add more built in themes. --- CHANGELOG.md | 1 + YACReader/themes/builtin_dark1.json | 67 +++++ YACReader/themes/builtin_dark2.json | 67 +++++ YACReader/themes/builtin_dark3.json | 67 +++++ YACReader/themes/builtin_dark4.json | 67 +++++ YACReader/themes/builtin_light1.json | 67 +++++ YACReader/themes/builtin_light2.json | 67 +++++ YACReader/themes/builtin_light3.json | 67 +++++ YACReader/themes/builtin_light4.json | 67 +++++ YACReader/themes/builtin_light5.json | 67 +++++ YACReader/themes/themes.qrc | 9 + YACReaderLibrary/themes/builtin_dark1.json | 264 ++++++++++++++++++++ YACReaderLibrary/themes/builtin_dark2.json | 264 ++++++++++++++++++++ YACReaderLibrary/themes/builtin_dark3.json | 264 ++++++++++++++++++++ YACReaderLibrary/themes/builtin_dark4.json | 264 ++++++++++++++++++++ YACReaderLibrary/themes/builtin_light1.json | 264 ++++++++++++++++++++ YACReaderLibrary/themes/builtin_light2.json | 264 ++++++++++++++++++++ YACReaderLibrary/themes/builtin_light3.json | 264 ++++++++++++++++++++ YACReaderLibrary/themes/builtin_light4.json | 264 ++++++++++++++++++++ YACReaderLibrary/themes/builtin_light5.json | 264 ++++++++++++++++++++ YACReaderLibrary/themes/themes.qrc | 9 + common/themes/theme_repository.cpp | 61 ++++- 22 files changed, 3053 insertions(+), 6 deletions(-) create mode 100644 YACReader/themes/builtin_dark1.json create mode 100644 YACReader/themes/builtin_dark2.json create mode 100644 YACReader/themes/builtin_dark3.json create mode 100644 YACReader/themes/builtin_dark4.json create mode 100644 YACReader/themes/builtin_light1.json create mode 100644 YACReader/themes/builtin_light2.json create mode 100644 YACReader/themes/builtin_light3.json create mode 100644 YACReader/themes/builtin_light4.json create mode 100644 YACReader/themes/builtin_light5.json create mode 100644 YACReaderLibrary/themes/builtin_dark1.json create mode 100644 YACReaderLibrary/themes/builtin_dark2.json create mode 100644 YACReaderLibrary/themes/builtin_dark3.json create mode 100644 YACReaderLibrary/themes/builtin_dark4.json create mode 100644 YACReaderLibrary/themes/builtin_light1.json create mode 100644 YACReaderLibrary/themes/builtin_light2.json create mode 100644 YACReaderLibrary/themes/builtin_light3.json create mode 100644 YACReaderLibrary/themes/builtin_light4.json create mode 100644 YACReaderLibrary/themes/builtin_light5.json diff --git a/CHANGELOG.md b/CHANGELOG.md index d1cb487f2..b90c75d63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Version counting is based on semantic versioning (Major.Feature.Patch) * Migrate Flow implementation from OpenGL to QRhi. This is a full new implementation with better performance and compatibility with operating systems and hardware. * Add light/dark themes support that follow the system configuration. * Add a theme editor and support for custom themes. +* The apps include 12 built in themes to pick from. * Add an application language setting with a system default option in YACReader and YACReaderLibrary. ### All apps diff --git a/YACReader/themes/builtin_dark1.json b/YACReader/themes/builtin_dark1.json new file mode 100644 index 000000000..23e5d7130 --- /dev/null +++ b/YACReader/themes/builtin_dark1.json @@ -0,0 +1,67 @@ +{ + "dialogIcons": { + "iconColor": "#FCFCFA" + }, + "goToFlowWidget": { + "editBackgroundColor": "#AA403E41", + "editBorderColor": "#885B595C", + "editTextColor": "#C1C0C0", + "flowBackgroundColor": "#221F22", + "flowTextColor": "#939293", + "iconColor": "#FCFCFA", + "labelTextColor": "#FCFCFA", + "sliderBorderColor": "#33FCFCFA", + "sliderGrooveColor": "#771C1A1D", + "sliderHandleColor": "#66FCFCFA", + "toolbarBackgroundColor": "#991C1A1D" + }, + "helpAboutDialog": { + "headingColor": "#FCFCFA", + "linkColor": "#78DCE8" + }, + "meta": { + "displayName": "Monodark", + "id": "builtin/dark1", + "targetApp": "YACReader", + "variant": "dark", + "version": "10.0.2" + }, + "shortcutsIcons": { + "iconColor": "#FCFCFA" + }, + "translator": { + "backgroundColor": "#403E41", + "borderColor": "#221F22", + "iconColor": "#FCFCFA", + "inputBackgroundColor": "#2B282D", + "inputDarkerBackgroundColor": "#353236", + "primaryTextColor": "#FCFCFA", + "scrollbarHandleColor": "#D7D6D7", + "secondaryTextColor": "#939293", + "selectionBackgroundColor": "#5B595C" + }, + "toolbar": { + "backgroundColor": "#1C1A1D", + "checkedButtonColor": "#5B595C", + "iconCheckedColor": "#FCFCFA", + "iconColor": "#FCFCFA", + "iconDisabledColor": "#6E6C70", + "menuIndicatorColor": "#FCFCFA", + "separatorColor": "#5B595C" + }, + "viewer": { + "defaultBackgroundColor": "#221F22", + "defaultTextColor": "#939293", + "infoBackgroundColor": "#BB1C1A1D", + "infoTextColor": "#FCFCFA" + }, + "whatsNewDialog": { + "backgroundColor": "#2B282D", + "closeButtonColor": "#FCFCFA", + "contentTextColor": "#E6E6E3", + "headerDecorationColor": "#78DCE8", + "headerTextColor": "#FCFCFA", + "linkColor": "#78DCE8", + "versionTextColor": "#939293" + } +} diff --git a/YACReader/themes/builtin_dark2.json b/YACReader/themes/builtin_dark2.json new file mode 100644 index 000000000..b3e3a6ace --- /dev/null +++ b/YACReader/themes/builtin_dark2.json @@ -0,0 +1,67 @@ +{ + "dialogIcons": { + "iconColor": "#F8F8F2" + }, + "goToFlowWidget": { + "editBackgroundColor": "#AA424450", + "editBorderColor": "#88424450", + "editTextColor": "#EDEDF0", + "flowBackgroundColor": "#282A36", + "flowTextColor": "#6C789C", + "iconColor": "#F8F8F2", + "labelTextColor": "#F8F8F2", + "sliderBorderColor": "#33F8F8F2", + "sliderGrooveColor": "#7721222C", + "sliderHandleColor": "#66F8F8F2", + "toolbarBackgroundColor": "#9921222C" + }, + "helpAboutDialog": { + "headingColor": "#F8F8F2", + "linkColor": "#8BE9FD" + }, + "meta": { + "displayName": "Late Night", + "id": "builtin/dark2", + "targetApp": "YACReader", + "variant": "dark", + "version": "10.1.0" + }, + "shortcutsIcons": { + "iconColor": "#F8F8F2" + }, + "translator": { + "backgroundColor": "#424450", + "borderColor": "#282A36", + "iconColor": "#F8F8F2", + "inputBackgroundColor": "#343746", + "inputDarkerBackgroundColor": "#424450", + "primaryTextColor": "#F8F8F2", + "scrollbarHandleColor": "#EDEDF0", + "secondaryTextColor": "#6272A4", + "selectionBackgroundColor": "#44475A" + }, + "toolbar": { + "backgroundColor": "#21222C", + "checkedButtonColor": "#44475A", + "iconCheckedColor": "#F8F8F2", + "iconColor": "#F8F8F2", + "iconDisabledColor": "#4F566B", + "menuIndicatorColor": "#F8F8F2", + "separatorColor": "#424450" + }, + "viewer": { + "defaultBackgroundColor": "#282A36", + "defaultTextColor": "#6C789C", + "infoBackgroundColor": "#BB21222C", + "infoTextColor": "#F8F8F2" + }, + "whatsNewDialog": { + "backgroundColor": "#343746", + "closeButtonColor": "#F8F8F2", + "contentTextColor": "#EDEDF0", + "headerDecorationColor": "#8BE9FD", + "headerTextColor": "#F8F8F2", + "linkColor": "#8BE9FD", + "versionTextColor": "#6272A4" + } +} diff --git a/YACReader/themes/builtin_dark3.json b/YACReader/themes/builtin_dark3.json new file mode 100644 index 000000000..1d43cf455 --- /dev/null +++ b/YACReader/themes/builtin_dark3.json @@ -0,0 +1,67 @@ +{ + "dialogIcons": { + "iconColor": "#EBDBB2" + }, + "goToFlowWidget": { + "editBackgroundColor": "#AA3C3836", + "editBorderColor": "#88504945", + "editTextColor": "#D5C4A1", + "flowBackgroundColor": "#282828", + "flowTextColor": "#928374", + "iconColor": "#EBDBB2", + "labelTextColor": "#EBDBB2", + "sliderBorderColor": "#33EBDBB2", + "sliderGrooveColor": "#771D2021", + "sliderHandleColor": "#66EBDBB2", + "toolbarBackgroundColor": "#991D2021" + }, + "helpAboutDialog": { + "headingColor": "#EBDBB2", + "linkColor": "#8EC07C" + }, + "meta": { + "displayName": "Retro Dark", + "id": "builtin/dark3", + "targetApp": "YACReader", + "variant": "dark", + "version": "10.1.0" + }, + "shortcutsIcons": { + "iconColor": "#EBDBB2" + }, + "translator": { + "backgroundColor": "#504945", + "borderColor": "#282828", + "iconColor": "#EBDBB2", + "inputBackgroundColor": "#32302F", + "inputDarkerBackgroundColor": "#3C3836", + "primaryTextColor": "#EBDBB2", + "scrollbarHandleColor": "#D5C4A1", + "secondaryTextColor": "#928374", + "selectionBackgroundColor": "#504945" + }, + "toolbar": { + "backgroundColor": "#1D2021", + "checkedButtonColor": "#504945", + "iconCheckedColor": "#EBDBB2", + "iconColor": "#EBDBB2", + "iconDisabledColor": "#5B5248", + "menuIndicatorColor": "#EBDBB2", + "separatorColor": "#504945" + }, + "viewer": { + "defaultBackgroundColor": "#282828", + "defaultTextColor": "#928374", + "infoBackgroundColor": "#BB1D2021", + "infoTextColor": "#EBDBB2" + }, + "whatsNewDialog": { + "backgroundColor": "#32302F", + "closeButtonColor": "#EBDBB2", + "contentTextColor": "#D5C4A1", + "headerDecorationColor": "#8EC07C", + "headerTextColor": "#EBDBB2", + "linkColor": "#8EC07C", + "versionTextColor": "#928374" + } +} diff --git a/YACReader/themes/builtin_dark4.json b/YACReader/themes/builtin_dark4.json new file mode 100644 index 000000000..5d98ecc23 --- /dev/null +++ b/YACReader/themes/builtin_dark4.json @@ -0,0 +1,67 @@ +{ + "dialogIcons": { + "iconColor": "#ECEFF4" + }, + "goToFlowWidget": { + "editBackgroundColor": "#AA434C5E", + "editBorderColor": "#884C566A", + "editTextColor": "#E5E9F0", + "flowBackgroundColor": "#2E3440", + "flowTextColor": "#787D88", + "iconColor": "#ECEFF4", + "labelTextColor": "#ECEFF4", + "sliderBorderColor": "#33ECEFF4", + "sliderGrooveColor": "#772A303B", + "sliderHandleColor": "#66ECEFF4", + "toolbarBackgroundColor": "#992A303B" + }, + "helpAboutDialog": { + "headingColor": "#ECEFF4", + "linkColor": "#8FBCBB" + }, + "meta": { + "displayName": "Frozen Dark", + "id": "builtin/dark4", + "targetApp": "YACReader", + "variant": "dark", + "version": "10.1.0" + }, + "shortcutsIcons": { + "iconColor": "#ECEFF4" + }, + "translator": { + "backgroundColor": "#4C566A", + "borderColor": "#2E3440", + "iconColor": "#ECEFF4", + "inputBackgroundColor": "#3B4252", + "inputDarkerBackgroundColor": "#434C5E", + "primaryTextColor": "#ECEFF4", + "scrollbarHandleColor": "#E5E9F0", + "secondaryTextColor": "#81A1C1", + "selectionBackgroundColor": "#4C566A" + }, + "toolbar": { + "backgroundColor": "#2A303B", + "checkedButtonColor": "#4C566A", + "iconCheckedColor": "#ECEFF4", + "iconColor": "#ECEFF4", + "iconDisabledColor": "#4A5568", + "menuIndicatorColor": "#ECEFF4", + "separatorColor": "#4C566A" + }, + "viewer": { + "defaultBackgroundColor": "#2E3440", + "defaultTextColor": "#787D88", + "infoBackgroundColor": "#BB2A303B", + "infoTextColor": "#ECEFF4" + }, + "whatsNewDialog": { + "backgroundColor": "#3B4252", + "closeButtonColor": "#ECEFF4", + "contentTextColor": "#E5E9F0", + "headerDecorationColor": "#8FBCBB", + "headerTextColor": "#ECEFF4", + "linkColor": "#8FBCBB", + "versionTextColor": "#81A1C1" + } +} diff --git a/YACReader/themes/builtin_light1.json b/YACReader/themes/builtin_light1.json new file mode 100644 index 000000000..f19822fe3 --- /dev/null +++ b/YACReader/themes/builtin_light1.json @@ -0,0 +1,67 @@ +{ + "dialogIcons": { + "iconColor": "#5C5F77" + }, + "goToFlowWidget": { + "editBackgroundColor": "#CCF2F4F8", + "editBorderColor": "#66CCD0DA", + "editTextColor": "#4C4F69", + "flowBackgroundColor": "#E6E9EF", + "flowTextColor": "#5C5F77", + "iconColor": "#4C4F69", + "labelTextColor": "#4C4F69", + "sliderBorderColor": "#33CCD0DA", + "sliderGrooveColor": "#66CCD0DA", + "sliderHandleColor": "#884C4F69", + "toolbarBackgroundColor": "#CCF2F4F8" + }, + "helpAboutDialog": { + "headingColor": "#303446", + "linkColor": "#8CAAEE" + }, + "meta": { + "displayName": "Pastel", + "id": "builtin/light1", + "targetApp": "YACReader", + "variant": "light", + "version": "10.1.0" + }, + "shortcutsIcons": { + "iconColor": "#5C5F77" + }, + "translator": { + "backgroundColor": "#F4F5F8", + "borderColor": "#CCD0DA", + "iconColor": "#5C5F77", + "inputBackgroundColor": "#EFF1F5", + "inputDarkerBackgroundColor": "#E6E9EF", + "primaryTextColor": "#4C4F69", + "scrollbarHandleColor": "#8C8FA1", + "secondaryTextColor": "#8C8FA1", + "selectionBackgroundColor": "#DCE0E8" + }, + "toolbar": { + "backgroundColor": "#F2F4F8", + "checkedButtonColor": "#CCD0DA", + "iconCheckedColor": "#303446", + "iconColor": "#4C4F69", + "iconDisabledColor": "#9CA0B0", + "menuIndicatorColor": "#4C4F69", + "separatorColor": "#CCD0DA" + }, + "viewer": { + "defaultBackgroundColor": "#E6E9EF", + "defaultTextColor": "#5C5F77", + "infoBackgroundColor": "#CCF2F4F8", + "infoTextColor": "#4C4F69" + }, + "whatsNewDialog": { + "backgroundColor": "#FFFFFF", + "closeButtonColor": "#4C4F69", + "contentTextColor": "#303446", + "headerDecorationColor": "#BABBF1", + "headerTextColor": "#303446", + "linkColor": "#8CAAEE", + "versionTextColor": "#8C8FA1" + } +} diff --git a/YACReader/themes/builtin_light2.json b/YACReader/themes/builtin_light2.json new file mode 100644 index 000000000..bac201e04 --- /dev/null +++ b/YACReader/themes/builtin_light2.json @@ -0,0 +1,67 @@ +{ + "dialogIcons": { + "iconColor": "#4A5685" + }, + "goToFlowWidget": { + "editBackgroundColor": "#CCEEF1F8", + "editBorderColor": "#66C4C8DA", + "editTextColor": "#2F334D", + "flowBackgroundColor": "#D5D6DB", + "flowTextColor": "#4A5685", + "iconColor": "#2F334D", + "labelTextColor": "#2F334D", + "sliderBorderColor": "#33C4C8DA", + "sliderGrooveColor": "#66C4C8DA", + "sliderHandleColor": "#882F334D", + "toolbarBackgroundColor": "#CCEEF1F8" + }, + "helpAboutDialog": { + "headingColor": "#2F334D", + "linkColor": "#2E7DE9" + }, + "meta": { + "displayName": "Late Day", + "id": "builtin/light2", + "targetApp": "YACReader", + "variant": "light", + "version": "10.1.0" + }, + "shortcutsIcons": { + "iconColor": "#4A5685" + }, + "translator": { + "backgroundColor": "#F5F6FA", + "borderColor": "#C4C8DA", + "iconColor": "#4A5685", + "inputBackgroundColor": "#EEF1F8", + "inputDarkerBackgroundColor": "#D7D8DD", + "primaryTextColor": "#2F334D", + "scrollbarHandleColor": "#8990B3", + "secondaryTextColor": "#8990B3", + "selectionBackgroundColor": "#D7D8DD" + }, + "toolbar": { + "backgroundColor": "#EEF1F8", + "checkedButtonColor": "#C4C8DA", + "iconCheckedColor": "#2F334D", + "iconColor": "#2F334D", + "iconDisabledColor": "#A1A6C5", + "menuIndicatorColor": "#2F334D", + "separatorColor": "#C4C8DA" + }, + "viewer": { + "defaultBackgroundColor": "#D5D6DB", + "defaultTextColor": "#4A5685", + "infoBackgroundColor": "#CCEEF1F8", + "infoTextColor": "#2F334D" + }, + "whatsNewDialog": { + "backgroundColor": "#FFFFFF", + "closeButtonColor": "#2F334D", + "contentTextColor": "#1F2335", + "headerDecorationColor": "#2E7DE9", + "headerTextColor": "#1F2335", + "linkColor": "#2E7DE9", + "versionTextColor": "#8990B3" + } +} diff --git a/YACReader/themes/builtin_light3.json b/YACReader/themes/builtin_light3.json new file mode 100644 index 000000000..37c822007 --- /dev/null +++ b/YACReader/themes/builtin_light3.json @@ -0,0 +1,67 @@ +{ + "dialogIcons": { + "iconColor": "#708089" + }, + "goToFlowWidget": { + "editBackgroundColor": "#CCFBF7EA", + "editBorderColor": "#66E6E2CC", + "editTextColor": "#4F5B58", + "flowBackgroundColor": "#EFEBD4", + "flowTextColor": "#5C6A72", + "iconColor": "#4F5B58", + "labelTextColor": "#4F5B58", + "sliderBorderColor": "#33E6E2CC", + "sliderGrooveColor": "#66E6E2CC", + "sliderHandleColor": "#884F5B58", + "toolbarBackgroundColor": "#CCFBF7EA" + }, + "helpAboutDialog": { + "headingColor": "#4F5B58", + "linkColor": "#3A94C5" + }, + "meta": { + "displayName": "Fadegreen", + "id": "builtin/light3", + "targetApp": "YACReader", + "variant": "light", + "version": "10.1.0" + }, + "shortcutsIcons": { + "iconColor": "#708089" + }, + "translator": { + "backgroundColor": "#FDF6E3", + "borderColor": "#E6E2CC", + "iconColor": "#708089", + "inputBackgroundColor": "#FFFBEF", + "inputDarkerBackgroundColor": "#F4F0D9", + "primaryTextColor": "#4F5B58", + "scrollbarHandleColor": "#859289", + "secondaryTextColor": "#859289", + "selectionBackgroundColor": "#EFEBD4" + }, + "toolbar": { + "backgroundColor": "#FBF7EA", + "checkedButtonColor": "#E6E2CC", + "iconCheckedColor": "#4F5B58", + "iconColor": "#4F5B58", + "iconDisabledColor": "#9DA9A0", + "menuIndicatorColor": "#4F5B58", + "separatorColor": "#E6E2CC" + }, + "viewer": { + "defaultBackgroundColor": "#EFEBD4", + "defaultTextColor": "#5C6A72", + "infoBackgroundColor": "#CCFBF7EA", + "infoTextColor": "#4F5B58" + }, + "whatsNewDialog": { + "backgroundColor": "#FFFBEF", + "closeButtonColor": "#4F5B58", + "contentTextColor": "#3F4B47", + "headerDecorationColor": "#8DA101", + "headerTextColor": "#3F4B47", + "linkColor": "#3A94C5", + "versionTextColor": "#859289" + } +} diff --git a/YACReader/themes/builtin_light4.json b/YACReader/themes/builtin_light4.json new file mode 100644 index 000000000..d7f33aa62 --- /dev/null +++ b/YACReader/themes/builtin_light4.json @@ -0,0 +1,67 @@ +{ + "dialogIcons": { + "iconColor": "#6E6A86" + }, + "goToFlowWidget": { + "editBackgroundColor": "#CCFFF8F1", + "editBorderColor": "#66D9CEC7", + "editTextColor": "#575279", + "flowBackgroundColor": "#E8DDD3", + "flowTextColor": "#6E6A86", + "iconColor": "#575279", + "labelTextColor": "#575279", + "sliderBorderColor": "#33D9CEC7", + "sliderGrooveColor": "#66D9CEC7", + "sliderHandleColor": "#88575279", + "toolbarBackgroundColor": "#CCFFF8F1" + }, + "helpAboutDialog": { + "headingColor": "#4F4A72", + "linkColor": "#286983" + }, + "meta": { + "displayName": "Rose", + "id": "builtin/light4", + "targetApp": "YACReader", + "variant": "light", + "version": "10.1.0" + }, + "shortcutsIcons": { + "iconColor": "#6E6A86" + }, + "translator": { + "backgroundColor": "#FFF8F2", + "borderColor": "#D9CEC7", + "iconColor": "#6E6A86", + "inputBackgroundColor": "#FAF4ED", + "inputDarkerBackgroundColor": "#F2E9E1", + "primaryTextColor": "#575279", + "scrollbarHandleColor": "#8E879C", + "secondaryTextColor": "#A59EAF", + "selectionBackgroundColor": "#E8DDD3" + }, + "toolbar": { + "backgroundColor": "#FFF8F1", + "checkedButtonColor": "#E8DDD3", + "iconCheckedColor": "#4F4A72", + "iconColor": "#575279", + "iconDisabledColor": "#B4AAB8", + "menuIndicatorColor": "#575279", + "separatorColor": "#D9CEC7" + }, + "viewer": { + "defaultBackgroundColor": "#E8DDD3", + "defaultTextColor": "#6E6A86", + "infoBackgroundColor": "#CCFFF8F1", + "infoTextColor": "#575279" + }, + "whatsNewDialog": { + "backgroundColor": "#FFF8F2", + "closeButtonColor": "#575279", + "contentTextColor": "#4F4A72", + "headerDecorationColor": "#907AA9", + "headerTextColor": "#4F4A72", + "linkColor": "#286983", + "versionTextColor": "#A59EAF" + } +} diff --git a/YACReader/themes/builtin_light5.json b/YACReader/themes/builtin_light5.json new file mode 100644 index 000000000..3cb78d05f --- /dev/null +++ b/YACReader/themes/builtin_light5.json @@ -0,0 +1,67 @@ +{ + "dialogIcons": { + "iconColor": "#716E61" + }, + "goToFlowWidget": { + "editBackgroundColor": "#CCFCF7ED", + "editBorderColor": "#66D8CDBA", + "editTextColor": "#545464", + "flowBackgroundColor": "#E7DCCB", + "flowTextColor": "#716E61", + "iconColor": "#545464", + "labelTextColor": "#545464", + "sliderBorderColor": "#33D8CDBA", + "sliderGrooveColor": "#66D8CDBA", + "sliderHandleColor": "#88545464", + "toolbarBackgroundColor": "#CCFCF7ED" + }, + "helpAboutDialog": { + "headingColor": "#43436C", + "linkColor": "#4D699B" + }, + "meta": { + "displayName": "Lotus", + "id": "builtin/light5", + "targetApp": "YACReader", + "variant": "light", + "version": "10.1.0" + }, + "shortcutsIcons": { + "iconColor": "#716E61" + }, + "translator": { + "backgroundColor": "#FFF9F0", + "borderColor": "#D8CDBA", + "iconColor": "#716E61", + "inputBackgroundColor": "#F7F2E7", + "inputDarkerBackgroundColor": "#F1E7D7", + "primaryTextColor": "#545464", + "scrollbarHandleColor": "#7D7A73", + "secondaryTextColor": "#A6A294", + "selectionBackgroundColor": "#E7DCCB" + }, + "toolbar": { + "backgroundColor": "#FCF7ED", + "checkedButtonColor": "#E7DCCB", + "iconCheckedColor": "#43436C", + "iconColor": "#545464", + "iconDisabledColor": "#A6A294", + "menuIndicatorColor": "#545464", + "separatorColor": "#D8CDBA" + }, + "viewer": { + "defaultBackgroundColor": "#E7DCCB", + "defaultTextColor": "#716E61", + "infoBackgroundColor": "#CCFCF7ED", + "infoTextColor": "#545464" + }, + "whatsNewDialog": { + "backgroundColor": "#FFF9F0", + "closeButtonColor": "#545464", + "contentTextColor": "#43436C", + "headerDecorationColor": "#5D57A3", + "headerTextColor": "#43436C", + "linkColor": "#4D699B", + "versionTextColor": "#A6A294" + } +} diff --git a/YACReader/themes/themes.qrc b/YACReader/themes/themes.qrc index 62ec21fee..d96de307d 100644 --- a/YACReader/themes/themes.qrc +++ b/YACReader/themes/themes.qrc @@ -2,6 +2,15 @@ builtin_classic.json builtin_light.json + builtin_light1.json + builtin_light2.json + builtin_light3.json + builtin_light4.json + builtin_light5.json builtin_dark.json + builtin_dark1.json + builtin_dark2.json + builtin_dark3.json + builtin_dark4.json diff --git a/YACReaderLibrary/themes/builtin_dark1.json b/YACReaderLibrary/themes/builtin_dark1.json new file mode 100644 index 000000000..59127c345 --- /dev/null +++ b/YACReaderLibrary/themes/builtin_dark1.json @@ -0,0 +1,264 @@ +{ + "comicFlow": { + "backgroundColor": "#221F22", + "readMainColor": "#FF6188", + "readTickColor": "#622534", + "readingColor": "#F3BF12", + "textColor": "#939293" + }, + "comicsViewTable": { + "alternateBackgroundColor": "#2A272B", + "backgroundColor": "#221F22", + "headerBackgroundColor": "#2D2A2E", + "headerBorderColor": "#1C1A1D", + "headerGradientColor": "#353236", + "headerTextColor": "#FCFCFA", + "itemBorderBottomColor": "#1C1A1D", + "itemBorderBottomWidth": 0, + "itemBorderTopColor": "#403E41", + "itemBorderTopWidth": 0, + "itemTextColor": "#F2F2F0", + "selectedColor": "#5B595C", + "selectedTextColor": "#FFFFFF", + "starRatingColor": "#FFD866", + "starRatingSelectedColor": "#FFFFFF" + }, + "comicsViewToolbar": { + "backgroundColor": "#1C1A1D", + "checkedBackgroundColor": "#5B595C", + "iconColor": "#FCFCFA", + "separatorColor": "#403E41" + }, + "contentSplitter": { + "handleColor": "#1C1A1D", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "dialogIcons": { + "iconColor": "#FCFCFA" + }, + "emptyContainer": { + "backgroundColor": "#2B282D", + "iconColor": "#5B595C", + "titleTextColor": "#FCFCFA" + }, + "gridAndInfoView": { + "backgroundBlurOverlayColor": "#2B282D", + "backgroundColor": "#2B282D", + "borderColor": "#151316", + "buttonColor": "#78DCE8", + "buttonShadowColor": "#AA000000", + "buttonTextColor": "#1C1A1D", + "cellColor": "#221F22", + "cellColorWithBackground": "#99221F22", + "cellSelectedBorderColor": "#78DCE8", + "cellSelectedColor": "#151316", + "comicCoverBorderColor": "#30FFFFFF", + "continueReadingBackgroundColor": "#881D191D", + "continueReadingTextColor": "#FCFCFA", + "currentComicBackgroundColor": "#55221F22", + "currentComicCoverShadowColor": "#FF000000", + "favCheckedColor": "#FF6188", + "favUncheckedColor": "#1C1A1D", + "folderCoverBorderColor": "#20FFFFFF", + "infoBackgroundColor": "#272428", + "infoBorderColor": "#403E41", + "infoMetadataTextColor": "#A6A5A6", + "infoScrollbarColor": "#FF5B595C", + "infoShadowColor": "#000000", + "infoTextColor": "#FCFCFA", + "itemDetailsColor": "#C1C0C0", + "itemTitleColor": "#FCFCFA", + "linkColor": "#78DCE8", + "newItemColor": "#FFFFD866", + "placeholderFolder1BorderColor": "#20FFFFFF", + "placeholderFolder1Color": "#20221F22", + "placeholderFolder2BorderColor": "#20FFFFFF", + "placeholderFolder2Color": "#88221F22", + "ratingSelectedColor": "#FFD866", + "ratingUnselectedColor": "#1C1A1D", + "readTickCheckedColor": "#A9DC76", + "readTickUncheckedColor": "#1C1A1D", + "scrollbarBorderColor": "#AA353236", + "scrollbarColor": "#885B595C", + "showDropShadow": true + }, + "helpAboutDialog": { + "headingColor": "#FCFCFA", + "linkColor": "#78DCE8" + }, + "importWidget": { + "backgroundColor": "#2B282D", + "coversDecorationBgColor": "#353236", + "coversDecorationShadowColor": "#1C1A1D", + "coversLabelColor": "#A6A5A6", + "coversViewBackgroundColor": "#353236", + "currentComicTextColor": "#A6A5A6", + "descriptionTextColor": "#A6A5A6", + "glowLineColor": "#FFE100", + "iconCheckedColor": "#A9DC76", + "iconColor": "#FCFCFA", + "modeIconColor": "#5B595C", + "titleTextColor": "#FCFCFA" + }, + "libraryItem": { + "libraryIconColor": "#D7D6D7", + "libraryIconSelectedColor": "#FFFFFF", + "libraryIconShadowColor": "#000000", + "libraryOptionsIconColor": "#FCFCFA", + "selectedBackgroundColor": "#221F24", + "selectedTextColor": "#FFFFFF", + "textColor": "#D7D6D7" + }, + "mainToolbar": { + "backgroundColor": "#1C1A1D", + "dividerColor": "#5B595C", + "folderNameColor": "#FCFCFA", + "iconColor": "#FCFCFA", + "iconDisabledColor": "#6E6C70" + }, + "menuIcons": { + "iconColor": "#FCFCFA" + }, + "meta": { + "displayName": "Monodark", + "id": "builtin/dark1", + "targetApp": "YACReaderLibrary", + "variant": "dark", + "version": "10.0.2" + }, + "metadataScraperDialog": { + "busyIndicatorColor": "#FCFCFA", + "buttonBackgroundColor": "#353236", + "buttonBorderColor": "#221F22", + "buttonTextColor": "#FCFCFA", + "checkBoxTickColor": "#FCFCFA", + "contentAltBackgroundColor": "#353236", + "contentBackgroundColor": "#2B282D", + "contentTextColor": "#FCFCFA", + "dialogBackgroundColor": "#403E41", + "downArrowColor": "#A6A5A6", + "hyperlinkColor": "#78DCE8", + "labelBackgroundColor": "#2B282D", + "labelTextColor": "#FCFCFA", + "navIconColor": "#FCFCFA", + "radioCheckedBackgroundColor": "#D7D6D7", + "radioCheckedIndicatorColor": "#5B595C", + "radioUncheckedColor": "#D7D6D7", + "rowIconColor": "#D7D6D7", + "tableAltBackgroundColor": "#353236", + "tableBackgroundColor": "#2D2A2E", + "tableBorderColor": "#221F22", + "tableHeaderBackgroundColor": "#2A272B", + "tableHeaderBorderColor": "#1C1A1D", + "tableHeaderGradientColor": "#353236", + "tableHeaderTextColor": "#FCFCFA", + "tableScrollBackgroundColor": "#403E41", + "tableScrollHandleColor": "#D7D6D7", + "tableSectionBorderDark": "#D7D6D7", + "tableSectionBorderLight": "#FCFCFA", + "tableSelectedColor": "#5B595C", + "toolButtonAccentColor": "#221F22", + "upArrowColor": "#A6A5A6" + }, + "navigationTree": { + "branchIndicatorColor": "#D7D6D7", + "branchIndicatorSelectedColor": "#FFFFFF", + "folderIconColor": "#D7D6D7", + "folderIconSelectedColor": "#FCFCFA", + "folderIconSelectedShadowColor": "#000000", + "folderIconShadowColor": "#000000", + "folderNotCompletedColor": "#FFD866", + "folderReadOverlayColor": "#221F22", + "folderReadOverlaySelectedColor": "#221F22", + "newItemColor": "#FFD866", + "scrollBackgroundColor": "#403E41", + "scrollHandleColor": "#D7D6D7", + "selectedTextColor": "#FFFFFF", + "selectionBackgroundColor": "#221F24", + "textColor": "#D7D6D7" + }, + "noLibrariesWidget": { + "backgroundColor": "#2B282D", + "descriptionTextColor": "#A6A5A6", + "iconColor": "#5B595C", + "noLibrariesLineColor": "#A8A8A8", + "textColor": "#D7D6D7" + }, + "readingListIcons": { + "currentlyReadingMainColor": "#78DCE8", + "currentlyReadingMainSelectedColor": "#78DCE8", + "currentlyReadingOuterColor": "#000000", + "currentlyReadingOuterSelectedColor": "#000000", + "favoritesMainColor": "#FF6188", + "favoritesMainSelectedColor": "#FF6188", + "labelColors": { + "blue": "#6FB3FF", + "cyan": "#78DCE8", + "dark": "#939293", + "green": "#A9DC76", + "light": "#D7D6D7", + "orange": "#FC9867", + "pink": "#FF90C2", + "purple": "#D39DF2", + "red": "#FF6188", + "violet": "#8B7DFF", + "white": "#FCFCFA", + "yellow": "#FFD866" + }, + "labelShadowColor": "#000000", + "labelShadowSelectedColor": "#000000", + "listDetailColor": "#5B595C", + "listDetailSelectedColor": "#5B595C", + "listMainColor": "#E6E6E3", + "listMainSelectedColor": "#E6E6E3", + "listShadowColor": "#000000", + "listShadowSelectedColor": "#000000", + "readingListMainColor": "#E6E6E3", + "readingListMainSelectedColor": "#E6E6E3", + "specialListShadowColor": "#000000", + "specialListShadowSelectedColor": "#000000" + }, + "searchLineEdit": { + "backgroundColor": "#403E41", + "iconColor": "#FCFCFA", + "textColor": "#C1C0C0" + }, + "serverConfigDialog": { + "backgroundColor": "#2B282D", + "checkBoxTextColor": "#FCFCFA", + "decorationColor": "#FCFCFA", + "labelTextColor": "#D7D6D7", + "propagandaTextColor": "#A6A5A6", + "qrBackgroundColor": "#2D2A2E", + "qrForegroundColor": "#FFFFFF", + "qrMessageTextColor": "#A6A5A6", + "titleTextColor": "#FCFCFA" + }, + "shortcutsIcons": { + "iconColor": "#FCFCFA" + }, + "sidebar": { + "backgroundColor": "#2C292D", + "busyIndicatorColor": "#FFFFFF", + "sectionSeparatorColor": "#403E41", + "separatorColor": "#A6A5A6", + "titleDropShadowColor": "#000000", + "titleTextColor": "#D7D6D7", + "uppercaseLabels": true + }, + "sidebarIcons": { + "iconColor": "#D7D6D7", + "shadowColor": "#000000", + "useSystemFolderIcons": false + }, + "whatsNewDialog": { + "backgroundColor": "#2B282D", + "closeButtonColor": "#FCFCFA", + "contentTextColor": "#E6E6E3", + "headerDecorationColor": "#78DCE8", + "headerTextColor": "#FCFCFA", + "linkColor": "#78DCE8", + "versionTextColor": "#939293" + } +} diff --git a/YACReaderLibrary/themes/builtin_dark2.json b/YACReaderLibrary/themes/builtin_dark2.json new file mode 100644 index 000000000..0585de39b --- /dev/null +++ b/YACReaderLibrary/themes/builtin_dark2.json @@ -0,0 +1,264 @@ +{ + "comicFlow": { + "backgroundColor": "#282A36", + "readMainColor": "#FF5555", + "readTickColor": "#712626", + "readingColor": "#50FA7B", + "textColor": "#6C789C" + }, + "comicsViewTable": { + "alternateBackgroundColor": "#424450", + "backgroundColor": "#282A36", + "headerBackgroundColor": "#343746", + "headerBorderColor": "#21222C", + "headerGradientColor": "#424450", + "headerTextColor": "#F8F8F2", + "itemBorderBottomColor": "#21222C", + "itemBorderBottomWidth": 0, + "itemBorderTopColor": "#424450", + "itemBorderTopWidth": 0, + "itemTextColor": "#F8F8F2", + "selectedColor": "#B1548A", + "selectedTextColor": "#F8F8F2", + "starRatingColor": "#F1FA8C", + "starRatingSelectedColor": "#F8F8F2" + }, + "comicsViewToolbar": { + "backgroundColor": "#21222C", + "checkedBackgroundColor": "#44475A", + "iconColor": "#F8F8F2", + "separatorColor": "#424450" + }, + "contentSplitter": { + "handleColor": "#21222C", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "dialogIcons": { + "iconColor": "#F8F8F2" + }, + "emptyContainer": { + "backgroundColor": "#343746", + "iconColor": "#44475A", + "titleTextColor": "#F8F8F2" + }, + "gridAndInfoView": { + "backgroundBlurOverlayColor": "#282A36", + "backgroundColor": "#282A36", + "borderColor": "#21222C", + "buttonColor": "#50FA7B", + "buttonShadowColor": "#AA000000", + "buttonTextColor": "#21222C", + "cellColor": "#282A36", + "cellColorWithBackground": "#99282A36", + "cellSelectedBorderColor": "#8BE9FD", + "cellSelectedColor": "#44475A", + "comicCoverBorderColor": "#30FFFFFF", + "continueReadingBackgroundColor": "#88393C4D", + "continueReadingTextColor": "#F8F8F2", + "currentComicBackgroundColor": "#55282A36", + "currentComicCoverShadowColor": "#FF000000", + "favCheckedColor": "#FF79C6", + "favUncheckedColor": "#21222C", + "folderCoverBorderColor": "#20FFFFFF", + "infoBackgroundColor": "#343746", + "infoBorderColor": "#424450", + "infoMetadataTextColor": "#6272A4", + "infoScrollbarColor": "#44475A", + "infoShadowColor": "#000000", + "infoTextColor": "#F8F8F2", + "itemDetailsColor": "#EDEDF0", + "itemTitleColor": "#F8F8F2", + "linkColor": "#8BE9FD", + "newItemColor": "#F1FA8C", + "placeholderFolder1BorderColor": "#20FFFFFF", + "placeholderFolder1Color": "#20282A36", + "placeholderFolder2BorderColor": "#20FFFFFF", + "placeholderFolder2Color": "#88282A36", + "ratingSelectedColor": "#F1FA8C", + "ratingUnselectedColor": "#21222C", + "readTickCheckedColor": "#50FA7B", + "readTickUncheckedColor": "#21222C", + "scrollbarBorderColor": "#424450", + "scrollbarColor": "#44475A", + "showDropShadow": true + }, + "helpAboutDialog": { + "headingColor": "#F8F8F2", + "linkColor": "#8BE9FD" + }, + "importWidget": { + "backgroundColor": "#343746", + "coversDecorationBgColor": "#424450", + "coversDecorationShadowColor": "#21222C", + "coversLabelColor": "#6272A4", + "coversViewBackgroundColor": "#424450", + "currentComicTextColor": "#6272A4", + "descriptionTextColor": "#6272A4", + "glowLineColor": "#FFE100", + "iconCheckedColor": "#50FA7B", + "iconColor": "#F8F8F2", + "modeIconColor": "#44475A", + "titleTextColor": "#F8F8F2" + }, + "libraryItem": { + "libraryIconColor": "#EDEDF0", + "libraryIconSelectedColor": "#F8F8F2", + "libraryIconShadowColor": "#000000", + "libraryOptionsIconColor": "#F8F8F2", + "selectedBackgroundColor": "#21222C", + "selectedTextColor": "#F8F8F2", + "textColor": "#EDEDF0" + }, + "mainToolbar": { + "backgroundColor": "#21222C", + "dividerColor": "#424450", + "folderNameColor": "#F8F8F2", + "iconColor": "#F8F8F2", + "iconDisabledColor": "#4F566B" + }, + "menuIcons": { + "iconColor": "#F8F8F2" + }, + "meta": { + "displayName": "Late Night", + "id": "builtin/dark2", + "targetApp": "YACReaderLibrary", + "variant": "dark", + "version": "10.1.0" + }, + "metadataScraperDialog": { + "busyIndicatorColor": "#F8F8F2", + "buttonBackgroundColor": "#424450", + "buttonBorderColor": "#282A36", + "buttonTextColor": "#F8F8F2", + "checkBoxTickColor": "#F8F8F2", + "contentAltBackgroundColor": "#424450", + "contentBackgroundColor": "#343746", + "contentTextColor": "#F8F8F2", + "dialogBackgroundColor": "#424450", + "downArrowColor": "#6272A4", + "hyperlinkColor": "#8BE9FD", + "labelBackgroundColor": "#343746", + "labelTextColor": "#F8F8F2", + "navIconColor": "#F8F8F2", + "radioCheckedBackgroundColor": "#EDEDF0", + "radioCheckedIndicatorColor": "#44475A", + "radioUncheckedColor": "#EDEDF0", + "rowIconColor": "#EDEDF0", + "tableAltBackgroundColor": "#424450", + "tableBackgroundColor": "#343746", + "tableBorderColor": "#282A36", + "tableHeaderBackgroundColor": "#424450", + "tableHeaderBorderColor": "#21222C", + "tableHeaderGradientColor": "#424450", + "tableHeaderTextColor": "#F8F8F2", + "tableScrollBackgroundColor": "#424450", + "tableScrollHandleColor": "#EDEDF0", + "tableSectionBorderDark": "#EDEDF0", + "tableSectionBorderLight": "#F8F8F2", + "tableSelectedColor": "#44475A", + "toolButtonAccentColor": "#282A36", + "upArrowColor": "#6272A4" + }, + "navigationTree": { + "branchIndicatorColor": "#EDEDF0", + "branchIndicatorSelectedColor": "#F8F8F2", + "folderIconColor": "#EDEDF0", + "folderIconSelectedColor": "#F8F8F2", + "folderIconSelectedShadowColor": "#000000", + "folderIconShadowColor": "#000000", + "folderNotCompletedColor": "#F1FA8C", + "folderReadOverlayColor": "#282A36", + "folderReadOverlaySelectedColor": "#282A36", + "newItemColor": "#F1FA8C", + "scrollBackgroundColor": "#424450", + "scrollHandleColor": "#EDEDF0", + "selectedTextColor": "#F8F8F2", + "selectionBackgroundColor": "#21222C", + "textColor": "#EDEDF0" + }, + "noLibrariesWidget": { + "backgroundColor": "#343746", + "descriptionTextColor": "#6272A4", + "iconColor": "#44475A", + "noLibrariesLineColor": "#A8A8A8", + "textColor": "#EDEDF0" + }, + "readingListIcons": { + "currentlyReadingMainColor": "#8BE9FD", + "currentlyReadingMainSelectedColor": "#8BE9FD", + "currentlyReadingOuterColor": "#000000", + "currentlyReadingOuterSelectedColor": "#000000", + "favoritesMainColor": "#FF79C6", + "favoritesMainSelectedColor": "#FF79C6", + "labelColors": { + "blue": "#6A99FF", + "cyan": "#8FF2FD", + "dark": "#636884", + "green": "#8EFAA9", + "light": "#BDBDBF", + "orange": "#FFB86C", + "pink": "#FF79C6", + "purple": "#BD93F9", + "red": "#FF5555", + "violet": "#A5A7FF", + "white": "#F8F8F2", + "yellow": "#F1FA8C" + }, + "labelShadowColor": "#000000", + "labelShadowSelectedColor": "#000000", + "listDetailColor": "#6272A4", + "listDetailSelectedColor": "#6272A4", + "listMainColor": "#EDEDF0", + "listMainSelectedColor": "#EDEDF0", + "listShadowColor": "#000000", + "listShadowSelectedColor": "#000000", + "readingListMainColor": "#EDEDF0", + "readingListMainSelectedColor": "#EDEDF0", + "specialListShadowColor": "#000000", + "specialListShadowSelectedColor": "#000000" + }, + "searchLineEdit": { + "backgroundColor": "#424450", + "iconColor": "#F8F8F2", + "textColor": "#EDEDF0" + }, + "serverConfigDialog": { + "backgroundColor": "#343746", + "checkBoxTextColor": "#F8F8F2", + "decorationColor": "#F8F8F2", + "labelTextColor": "#EDEDF0", + "propagandaTextColor": "#6272A4", + "qrBackgroundColor": "#343746", + "qrForegroundColor": "#F8F8F2", + "qrMessageTextColor": "#6272A4", + "titleTextColor": "#F8F8F2" + }, + "shortcutsIcons": { + "iconColor": "#F8F8F2" + }, + "sidebar": { + "backgroundColor": "#343746", + "busyIndicatorColor": "#F8F8F2", + "sectionSeparatorColor": "#424450", + "separatorColor": "#6272A4", + "titleDropShadowColor": "#000000", + "titleTextColor": "#EDEDF0", + "uppercaseLabels": true + }, + "sidebarIcons": { + "iconColor": "#EDEDF0", + "shadowColor": "#000000", + "useSystemFolderIcons": false + }, + "whatsNewDialog": { + "backgroundColor": "#343746", + "closeButtonColor": "#F8F8F2", + "contentTextColor": "#EDEDF0", + "headerDecorationColor": "#8BE9FD", + "headerTextColor": "#F8F8F2", + "linkColor": "#8BE9FD", + "versionTextColor": "#6272A4" + } +} diff --git a/YACReaderLibrary/themes/builtin_dark3.json b/YACReaderLibrary/themes/builtin_dark3.json new file mode 100644 index 000000000..a6d5335c1 --- /dev/null +++ b/YACReaderLibrary/themes/builtin_dark3.json @@ -0,0 +1,264 @@ +{ + "comicFlow": { + "backgroundColor": "#282828", + "readMainColor": "#F0503E", + "readTickColor": "#B63D2F", + "readingColor": "#FABD2F", + "textColor": "#928374" + }, + "comicsViewTable": { + "alternateBackgroundColor": "#3C3836", + "backgroundColor": "#282828", + "headerBackgroundColor": "#32302F", + "headerBorderColor": "#1D2021", + "headerGradientColor": "#3C3836", + "headerTextColor": "#EBDBB2", + "itemBorderBottomColor": "#1D2021", + "itemBorderBottomWidth": 0, + "itemBorderTopColor": "#504945", + "itemBorderTopWidth": 0, + "itemTextColor": "#EBDBB2", + "selectedColor": "#504945", + "selectedTextColor": "#EBDBB2", + "starRatingColor": "#FABD2F", + "starRatingSelectedColor": "#EBDBB2" + }, + "comicsViewToolbar": { + "backgroundColor": "#1D2021", + "checkedBackgroundColor": "#504945", + "iconColor": "#EBDBB2", + "separatorColor": "#504945" + }, + "contentSplitter": { + "handleColor": "#1D2021", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "dialogIcons": { + "iconColor": "#EBDBB2" + }, + "emptyContainer": { + "backgroundColor": "#32302F", + "iconColor": "#504945", + "titleTextColor": "#EBDBB2" + }, + "gridAndInfoView": { + "backgroundBlurOverlayColor": "#282828", + "backgroundColor": "#282828", + "borderColor": "#1D2021", + "buttonColor": "#B8BB26", + "buttonShadowColor": "#AA000000", + "buttonTextColor": "#1D2021", + "cellColor": "#282828", + "cellColorWithBackground": "#99282828", + "cellSelectedBorderColor": "#8EC07C", + "cellSelectedColor": "#504945", + "comicCoverBorderColor": "#30FFFFFF", + "continueReadingBackgroundColor": "#884A433E", + "continueReadingTextColor": "#EBDBB2", + "currentComicBackgroundColor": "#55282828", + "currentComicCoverShadowColor": "#FF000000", + "favCheckedColor": "#D3869B", + "favUncheckedColor": "#1D2021", + "folderCoverBorderColor": "#20FFFFFF", + "infoBackgroundColor": "#32302F", + "infoBorderColor": "#504945", + "infoMetadataTextColor": "#928374", + "infoScrollbarColor": "#504945", + "infoShadowColor": "#000000", + "infoTextColor": "#EBDBB2", + "itemDetailsColor": "#D5C4A1", + "itemTitleColor": "#EBDBB2", + "linkColor": "#8EC07C", + "newItemColor": "#FABD2F", + "placeholderFolder1BorderColor": "#20FFFFFF", + "placeholderFolder1Color": "#20282828", + "placeholderFolder2BorderColor": "#20FFFFFF", + "placeholderFolder2Color": "#88282828", + "ratingSelectedColor": "#FABD2F", + "ratingUnselectedColor": "#1D2021", + "readTickCheckedColor": "#B8BB26", + "readTickUncheckedColor": "#1D2021", + "scrollbarBorderColor": "#504945", + "scrollbarColor": "#504945", + "showDropShadow": true + }, + "helpAboutDialog": { + "headingColor": "#EBDBB2", + "linkColor": "#8EC07C" + }, + "importWidget": { + "backgroundColor": "#32302F", + "coversDecorationBgColor": "#3C3836", + "coversDecorationShadowColor": "#1D2021", + "coversLabelColor": "#928374", + "coversViewBackgroundColor": "#3C3836", + "currentComicTextColor": "#928374", + "descriptionTextColor": "#928374", + "glowLineColor": "#FFE100", + "iconCheckedColor": "#B8BB26", + "iconColor": "#EBDBB2", + "modeIconColor": "#504945", + "titleTextColor": "#EBDBB2" + }, + "libraryItem": { + "libraryIconColor": "#D5C4A1", + "libraryIconSelectedColor": "#EBDBB2", + "libraryIconShadowColor": "#000000", + "libraryOptionsIconColor": "#EBDBB2", + "selectedBackgroundColor": "#1D2021", + "selectedTextColor": "#EBDBB2", + "textColor": "#D5C4A1" + }, + "mainToolbar": { + "backgroundColor": "#1D2021", + "dividerColor": "#504945", + "folderNameColor": "#EBDBB2", + "iconColor": "#EBDBB2", + "iconDisabledColor": "#5B5248" + }, + "menuIcons": { + "iconColor": "#EBDBB2" + }, + "meta": { + "displayName": "Retro Dark", + "id": "builtin/dark3", + "targetApp": "YACReaderLibrary", + "variant": "dark", + "version": "10.1.0" + }, + "metadataScraperDialog": { + "busyIndicatorColor": "#EBDBB2", + "buttonBackgroundColor": "#3C3836", + "buttonBorderColor": "#282828", + "buttonTextColor": "#EBDBB2", + "checkBoxTickColor": "#EBDBB2", + "contentAltBackgroundColor": "#3C3836", + "contentBackgroundColor": "#32302F", + "contentTextColor": "#EBDBB2", + "dialogBackgroundColor": "#504945", + "downArrowColor": "#928374", + "hyperlinkColor": "#8EC07C", + "labelBackgroundColor": "#32302F", + "labelTextColor": "#EBDBB2", + "navIconColor": "#EBDBB2", + "radioCheckedBackgroundColor": "#D5C4A1", + "radioCheckedIndicatorColor": "#504945", + "radioUncheckedColor": "#D5C4A1", + "rowIconColor": "#D5C4A1", + "tableAltBackgroundColor": "#3C3836", + "tableBackgroundColor": "#32302F", + "tableBorderColor": "#282828", + "tableHeaderBackgroundColor": "#3C3836", + "tableHeaderBorderColor": "#1D2021", + "tableHeaderGradientColor": "#504945", + "tableHeaderTextColor": "#EBDBB2", + "tableScrollBackgroundColor": "#504945", + "tableScrollHandleColor": "#D5C4A1", + "tableSectionBorderDark": "#D5C4A1", + "tableSectionBorderLight": "#EBDBB2", + "tableSelectedColor": "#504945", + "toolButtonAccentColor": "#282828", + "upArrowColor": "#928374" + }, + "navigationTree": { + "branchIndicatorColor": "#D5C4A1", + "branchIndicatorSelectedColor": "#EBDBB2", + "folderIconColor": "#D5C4A1", + "folderIconSelectedColor": "#EBDBB2", + "folderIconSelectedShadowColor": "#000000", + "folderIconShadowColor": "#000000", + "folderNotCompletedColor": "#FABD2F", + "folderReadOverlayColor": "#282828", + "folderReadOverlaySelectedColor": "#282828", + "newItemColor": "#FABD2F", + "scrollBackgroundColor": "#3C3836", + "scrollHandleColor": "#D5C4A1", + "selectedTextColor": "#EBDBB2", + "selectionBackgroundColor": "#1D2021", + "textColor": "#D5C4A1" + }, + "noLibrariesWidget": { + "backgroundColor": "#32302F", + "descriptionTextColor": "#928374", + "iconColor": "#504945", + "noLibrariesLineColor": "#A8A8A8", + "textColor": "#D5C4A1" + }, + "readingListIcons": { + "currentlyReadingMainColor": "#8EC07C", + "currentlyReadingMainSelectedColor": "#8EC07C", + "currentlyReadingOuterColor": "#000000", + "currentlyReadingOuterSelectedColor": "#000000", + "favoritesMainColor": "#D3869B", + "favoritesMainSelectedColor": "#D3869B", + "labelColors": { + "blue": "#83A598", + "cyan": "#8EC07C", + "dark": "#928374", + "green": "#B8BB26", + "light": "#D5C4A1", + "orange": "#FE8019", + "pink": "#D3869B", + "purple": "#B16396", + "red": "#FB4934", + "violet": "#9978BE", + "white": "#EBDBB2", + "yellow": "#FABD2F" + }, + "labelShadowColor": "#000000", + "labelShadowSelectedColor": "#000000", + "listDetailColor": "#928374", + "listDetailSelectedColor": "#928374", + "listMainColor": "#D5C4A1", + "listMainSelectedColor": "#D5C4A1", + "listShadowColor": "#000000", + "listShadowSelectedColor": "#000000", + "readingListMainColor": "#D5C4A1", + "readingListMainSelectedColor": "#D5C4A1", + "specialListShadowColor": "#000000", + "specialListShadowSelectedColor": "#000000" + }, + "searchLineEdit": { + "backgroundColor": "#3C3836", + "iconColor": "#EBDBB2", + "textColor": "#D5C4A1" + }, + "serverConfigDialog": { + "backgroundColor": "#32302F", + "checkBoxTextColor": "#EBDBB2", + "decorationColor": "#EBDBB2", + "labelTextColor": "#D5C4A1", + "propagandaTextColor": "#928374", + "qrBackgroundColor": "#32302F", + "qrForegroundColor": "#EBDBB2", + "qrMessageTextColor": "#928374", + "titleTextColor": "#EBDBB2" + }, + "shortcutsIcons": { + "iconColor": "#EBDBB2" + }, + "sidebar": { + "backgroundColor": "#32302F", + "busyIndicatorColor": "#EBDBB2", + "sectionSeparatorColor": "#504945", + "separatorColor": "#928374", + "titleDropShadowColor": "#000000", + "titleTextColor": "#D5C4A1", + "uppercaseLabels": true + }, + "sidebarIcons": { + "iconColor": "#D5C4A1", + "shadowColor": "#000000", + "useSystemFolderIcons": false + }, + "whatsNewDialog": { + "backgroundColor": "#32302F", + "closeButtonColor": "#EBDBB2", + "contentTextColor": "#D5C4A1", + "headerDecorationColor": "#8EC07C", + "headerTextColor": "#EBDBB2", + "linkColor": "#8EC07C", + "versionTextColor": "#928374" + } +} diff --git a/YACReaderLibrary/themes/builtin_dark4.json b/YACReaderLibrary/themes/builtin_dark4.json new file mode 100644 index 000000000..e1144a9ce --- /dev/null +++ b/YACReaderLibrary/themes/builtin_dark4.json @@ -0,0 +1,264 @@ +{ + "comicFlow": { + "backgroundColor": "#2E3440", + "readMainColor": "#BF616A", + "readTickColor": "#552B2F", + "readingColor": "#EBCB8B", + "textColor": "#787D88" + }, + "comicsViewTable": { + "alternateBackgroundColor": "#353C4A", + "backgroundColor": "#2E3440", + "headerBackgroundColor": "#3B4252", + "headerBorderColor": "#2A303B", + "headerGradientColor": "#434C5E", + "headerTextColor": "#ECEFF4", + "itemBorderBottomColor": "#2A303B", + "itemBorderBottomWidth": 0, + "itemBorderTopColor": "#4C566A", + "itemBorderTopWidth": 0, + "itemTextColor": "#ECEFF4", + "selectedColor": "#22262F", + "selectedTextColor": "#ECEFF4", + "starRatingColor": "#EBCB8B", + "starRatingSelectedColor": "#ECEFF4" + }, + "comicsViewToolbar": { + "backgroundColor": "#2A303B", + "checkedBackgroundColor": "#4C566A", + "iconColor": "#ECEFF4", + "separatorColor": "#4C566A" + }, + "contentSplitter": { + "handleColor": "#2A303B", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "dialogIcons": { + "iconColor": "#ECEFF4" + }, + "emptyContainer": { + "backgroundColor": "#3B4252", + "iconColor": "#4C566A", + "titleTextColor": "#ECEFF4" + }, + "gridAndInfoView": { + "backgroundBlurOverlayColor": "#2E3440", + "backgroundColor": "#2E3440", + "borderColor": "#2A303B", + "buttonColor": "#A3BE8C", + "buttonShadowColor": "#AA000000", + "buttonTextColor": "#2A303B", + "cellColor": "#2E3440", + "cellColorWithBackground": "#992E3440", + "cellSelectedBorderColor": "#8FBCBB", + "cellSelectedColor": "#4C566A", + "comicCoverBorderColor": "#30FFFFFF", + "continueReadingBackgroundColor": "#880C0E11", + "continueReadingTextColor": "#ECEFF4", + "currentComicBackgroundColor": "#552E3440", + "currentComicCoverShadowColor": "#FF000000", + "favCheckedColor": "#D8A6B3", + "favUncheckedColor": "#2A303B", + "folderCoverBorderColor": "#20FFFFFF", + "infoBackgroundColor": "#3B4252", + "infoBorderColor": "#4C566A", + "infoMetadataTextColor": "#81A1C1", + "infoScrollbarColor": "#4C566A", + "infoShadowColor": "#000000", + "infoTextColor": "#ECEFF4", + "itemDetailsColor": "#E5E9F0", + "itemTitleColor": "#ECEFF4", + "linkColor": "#8FBCBB", + "newItemColor": "#EBCB8B", + "placeholderFolder1BorderColor": "#20FFFFFF", + "placeholderFolder1Color": "#202E3440", + "placeholderFolder2BorderColor": "#20FFFFFF", + "placeholderFolder2Color": "#882E3440", + "ratingSelectedColor": "#EBCB8B", + "ratingUnselectedColor": "#2A303B", + "readTickCheckedColor": "#A3BE8C", + "readTickUncheckedColor": "#2A303B", + "scrollbarBorderColor": "#4C566A", + "scrollbarColor": "#4C566A", + "showDropShadow": true + }, + "helpAboutDialog": { + "headingColor": "#ECEFF4", + "linkColor": "#8FBCBB" + }, + "importWidget": { + "backgroundColor": "#3B4252", + "coversDecorationBgColor": "#434C5E", + "coversDecorationShadowColor": "#2A303B", + "coversLabelColor": "#81A1C1", + "coversViewBackgroundColor": "#434C5E", + "currentComicTextColor": "#81A1C1", + "descriptionTextColor": "#81A1C1", + "glowLineColor": "#FFE100", + "iconCheckedColor": "#A3BE8C", + "iconColor": "#ECEFF4", + "modeIconColor": "#4C566A", + "titleTextColor": "#ECEFF4" + }, + "libraryItem": { + "libraryIconColor": "#E5E9F0", + "libraryIconSelectedColor": "#ECEFF4", + "libraryIconShadowColor": "#000000", + "libraryOptionsIconColor": "#ECEFF4", + "selectedBackgroundColor": "#2E3440", + "selectedTextColor": "#ECEFF4", + "textColor": "#E5E9F0" + }, + "mainToolbar": { + "backgroundColor": "#2A303B", + "dividerColor": "#4C566A", + "folderNameColor": "#ECEFF4", + "iconColor": "#ECEFF4", + "iconDisabledColor": "#4A5568" + }, + "menuIcons": { + "iconColor": "#ECEFF4" + }, + "meta": { + "displayName": "Frozen Dark", + "id": "builtin/dark4", + "targetApp": "YACReaderLibrary", + "variant": "dark", + "version": "10.1.0" + }, + "metadataScraperDialog": { + "busyIndicatorColor": "#ECEFF4", + "buttonBackgroundColor": "#434C5E", + "buttonBorderColor": "#2E3440", + "buttonTextColor": "#ECEFF4", + "checkBoxTickColor": "#ECEFF4", + "contentAltBackgroundColor": "#434C5E", + "contentBackgroundColor": "#3B4252", + "contentTextColor": "#ECEFF4", + "dialogBackgroundColor": "#4C566A", + "downArrowColor": "#81A1C1", + "hyperlinkColor": "#8FBCBB", + "labelBackgroundColor": "#3B4252", + "labelTextColor": "#ECEFF4", + "navIconColor": "#ECEFF4", + "radioCheckedBackgroundColor": "#E5E9F0", + "radioCheckedIndicatorColor": "#4C566A", + "radioUncheckedColor": "#E5E9F0", + "rowIconColor": "#E5E9F0", + "tableAltBackgroundColor": "#434C5E", + "tableBackgroundColor": "#3B4252", + "tableBorderColor": "#2E3440", + "tableHeaderBackgroundColor": "#434C5E", + "tableHeaderBorderColor": "#2A303B", + "tableHeaderGradientColor": "#4C566A", + "tableHeaderTextColor": "#ECEFF4", + "tableScrollBackgroundColor": "#4C566A", + "tableScrollHandleColor": "#E5E9F0", + "tableSectionBorderDark": "#E5E9F0", + "tableSectionBorderLight": "#ECEFF4", + "tableSelectedColor": "#4C566A", + "toolButtonAccentColor": "#2E3440", + "upArrowColor": "#81A1C1" + }, + "navigationTree": { + "branchIndicatorColor": "#E5E9F0", + "branchIndicatorSelectedColor": "#ECEFF4", + "folderIconColor": "#E5E9F0", + "folderIconSelectedColor": "#ECEFF4", + "folderIconSelectedShadowColor": "#000000", + "folderIconShadowColor": "#000000", + "folderNotCompletedColor": "#EBCB8B", + "folderReadOverlayColor": "#2E3440", + "folderReadOverlaySelectedColor": "#2E3440", + "newItemColor": "#EBCB8B", + "scrollBackgroundColor": "#434C5E", + "scrollHandleColor": "#E5E9F0", + "selectedTextColor": "#ECEFF4", + "selectionBackgroundColor": "#2E3440", + "textColor": "#E5E9F0" + }, + "noLibrariesWidget": { + "backgroundColor": "#3B4252", + "descriptionTextColor": "#81A1C1", + "iconColor": "#4C566A", + "noLibrariesLineColor": "#A8A8A8", + "textColor": "#E5E9F0" + }, + "readingListIcons": { + "currentlyReadingMainColor": "#8FBCBB", + "currentlyReadingMainSelectedColor": "#8FBCBB", + "currentlyReadingOuterColor": "#000000", + "currentlyReadingOuterSelectedColor": "#000000", + "favoritesMainColor": "#D8A6B3", + "favoritesMainSelectedColor": "#D8A6B3", + "labelColors": { + "blue": "#5E81AC", + "cyan": "#8FBCBB", + "dark": "#64788D", + "green": "#A3BE8C", + "light": "#ADB1B6", + "orange": "#D08770", + "pink": "#D8A6B3", + "purple": "#A484C1", + "red": "#BF616A", + "violet": "#948CB4", + "white": "#ECEFF4", + "yellow": "#EBCB8B" + }, + "labelShadowColor": "#000000", + "labelShadowSelectedColor": "#000000", + "listDetailColor": "#81A1C1", + "listDetailSelectedColor": "#81A1C1", + "listMainColor": "#E5E9F0", + "listMainSelectedColor": "#E5E9F0", + "listShadowColor": "#000000", + "listShadowSelectedColor": "#000000", + "readingListMainColor": "#E5E9F0", + "readingListMainSelectedColor": "#E5E9F0", + "specialListShadowColor": "#000000", + "specialListShadowSelectedColor": "#000000" + }, + "searchLineEdit": { + "backgroundColor": "#434C5E", + "iconColor": "#ECEFF4", + "textColor": "#E5E9F0" + }, + "serverConfigDialog": { + "backgroundColor": "#3B4252", + "checkBoxTextColor": "#ECEFF4", + "decorationColor": "#ECEFF4", + "labelTextColor": "#E5E9F0", + "propagandaTextColor": "#81A1C1", + "qrBackgroundColor": "#3B4252", + "qrForegroundColor": "#ECEFF4", + "qrMessageTextColor": "#81A1C1", + "titleTextColor": "#ECEFF4" + }, + "shortcutsIcons": { + "iconColor": "#ECEFF4" + }, + "sidebar": { + "backgroundColor": "#3B4252", + "busyIndicatorColor": "#ECEFF4", + "sectionSeparatorColor": "#4C566A", + "separatorColor": "#81A1C1", + "titleDropShadowColor": "#000000", + "titleTextColor": "#E5E9F0", + "uppercaseLabels": true + }, + "sidebarIcons": { + "iconColor": "#E5E9F0", + "shadowColor": "#000000", + "useSystemFolderIcons": false + }, + "whatsNewDialog": { + "backgroundColor": "#3B4252", + "closeButtonColor": "#ECEFF4", + "contentTextColor": "#E5E9F0", + "headerDecorationColor": "#8FBCBB", + "headerTextColor": "#ECEFF4", + "linkColor": "#8FBCBB", + "versionTextColor": "#81A1C1" + } +} diff --git a/YACReaderLibrary/themes/builtin_light1.json b/YACReaderLibrary/themes/builtin_light1.json new file mode 100644 index 000000000..662d8ac39 --- /dev/null +++ b/YACReaderLibrary/themes/builtin_light1.json @@ -0,0 +1,264 @@ +{ + "comicFlow": { + "backgroundColor": "#E6E9EF", + "readMainColor": "#EE99A0", + "readTickColor": "#ED8796", + "readingColor": "#EED49F", + "textColor": "#5C5F77" + }, + "comicsViewTable": { + "alternateBackgroundColor": "#E6E9EF", + "backgroundColor": "#EFF1F5", + "headerBackgroundColor": "#ECEFF5", + "headerBorderColor": "#BCC0CC", + "headerGradientColor": "#ECEFF5", + "headerTextColor": "#4C4F69", + "itemBorderBottomColor": "#CCD0DA", + "itemBorderBottomWidth": 0, + "itemBorderTopColor": "#F5F6F8", + "itemBorderTopWidth": 0, + "itemTextColor": "#4C4F69", + "selectedColor": "#4C4F69", + "selectedTextColor": "#FFFFFF", + "starRatingColor": "#EED49F", + "starRatingSelectedColor": "#FFFFFF" + }, + "comicsViewToolbar": { + "backgroundColor": "#F2F4F8", + "checkedBackgroundColor": "#CCD0DA", + "iconColor": "#4C4F69", + "separatorColor": "#CCD0DA" + }, + "contentSplitter": { + "handleColor": "#DCE0E8", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "dialogIcons": { + "iconColor": "#5C5F77" + }, + "emptyContainer": { + "backgroundColor": "#EFF1F5", + "iconColor": "#BCC0CC", + "titleTextColor": "#7C7F93" + }, + "gridAndInfoView": { + "backgroundBlurOverlayColor": "#CCD0DA", + "backgroundColor": "#EFF1F5", + "borderColor": "#DCE0E8", + "buttonColor": "#8CAAEE", + "buttonShadowColor": "#AA000000", + "buttonTextColor": "#303446", + "cellColor": "#FFFFFF", + "cellColorWithBackground": "#99FFFFFF", + "cellSelectedBorderColor": "#B7BDF8", + "cellSelectedColor": "#F4F5F8", + "comicCoverBorderColor": "#30FFFFFF", + "continueReadingBackgroundColor": "#E6E9EF", + "continueReadingTextColor": "#4C4F69", + "currentComicBackgroundColor": "#88EFF1F5", + "currentComicCoverShadowColor": "#FF000000", + "favCheckedColor": "#F5BDE6", + "favUncheckedColor": "#8C8FA1", + "folderCoverBorderColor": "#20FFFFFF", + "infoBackgroundColor": "#FFFFFF", + "infoBorderColor": "#CCD0DA", + "infoMetadataTextColor": "#6C6F85", + "infoScrollbarColor": "#FF7C7F93", + "infoShadowColor": "#8C8FA1", + "infoTextColor": "#4C4F69", + "itemDetailsColor": "#6C6F85", + "itemTitleColor": "#303446", + "linkColor": "#8CAAEE", + "newItemColor": "#FFE5C890", + "placeholderFolder1BorderColor": "#20FFFFFF", + "placeholderFolder1Color": "#10CCD0DA", + "placeholderFolder2BorderColor": "#20FFFFFF", + "placeholderFolder2Color": "#40BCC0CC", + "ratingSelectedColor": "#4C4F69", + "ratingUnselectedColor": "#8C8FA1", + "readTickCheckedColor": "#A6D189", + "readTickUncheckedColor": "#8C8FA1", + "scrollbarBorderColor": "#AACCD0DA", + "scrollbarColor": "#888C8FA1", + "showDropShadow": true + }, + "helpAboutDialog": { + "headingColor": "#303446", + "linkColor": "#8CAAEE" + }, + "importWidget": { + "backgroundColor": "#EFF1F5", + "coversDecorationBgColor": "#E6E9EF", + "coversDecorationShadowColor": "#BCC0CC", + "coversLabelColor": "#6C6F85", + "coversViewBackgroundColor": "#E6E9EF", + "currentComicTextColor": "#6C6F85", + "descriptionTextColor": "#6C6F85", + "glowLineColor": "#E5C890", + "iconCheckedColor": "#A6D189", + "iconColor": "#4C4F69", + "modeIconColor": "#DCE0E8", + "titleTextColor": "#4C4F69" + }, + "libraryItem": { + "libraryIconColor": "#6C6F85", + "libraryIconSelectedColor": "#FFFFFF", + "libraryIconShadowColor": "#EFF1F5", + "libraryOptionsIconColor": "#FFFFFF", + "selectedBackgroundColor": "#4C4F69", + "selectedTextColor": "#FFFFFF", + "textColor": "#4C4F69" + }, + "mainToolbar": { + "backgroundColor": "#F2F4F8", + "dividerColor": "#CCD0DA", + "folderNameColor": "#4C4F69", + "iconColor": "#4C4F69", + "iconDisabledColor": "#9CA0B0" + }, + "menuIcons": { + "iconColor": "#5C5F77" + }, + "meta": { + "displayName": "Pastel", + "id": "builtin/light1", + "targetApp": "YACReaderLibrary", + "variant": "light", + "version": "10.1.0" + }, + "metadataScraperDialog": { + "busyIndicatorColor": "#4C4F69", + "buttonBackgroundColor": "#E6E9EF", + "buttonBorderColor": "#CCD0DA", + "buttonTextColor": "#4C4F69", + "checkBoxTickColor": "#4C4F69", + "contentAltBackgroundColor": "#E6E9EF", + "contentBackgroundColor": "#EFF1F5", + "contentTextColor": "#4C4F69", + "dialogBackgroundColor": "#F4F5F8", + "downArrowColor": "#4C4F69", + "hyperlinkColor": "#8CAAEE", + "labelBackgroundColor": "#EFF1F5", + "labelTextColor": "#4C4F69", + "navIconColor": "#BABBF1", + "radioCheckedBackgroundColor": "#DCE0E8", + "radioCheckedIndicatorColor": "#4C4F69", + "radioUncheckedColor": "#BCC0CC", + "rowIconColor": "#BABBF1", + "tableAltBackgroundColor": "#F4F5F8", + "tableBackgroundColor": "#EFF1F5", + "tableBorderColor": "#CCD0DA", + "tableHeaderBackgroundColor": "#E6E9EF", + "tableHeaderBorderColor": "#BCC0CC", + "tableHeaderGradientColor": "#E6E9EF", + "tableHeaderTextColor": "#4C4F69", + "tableScrollBackgroundColor": "#DCE0E8", + "tableScrollHandleColor": "#8C8FA1", + "tableSectionBorderDark": "#CCD0DA", + "tableSectionBorderLight": "#FFFFFF", + "tableSelectedColor": "#DCE0E8", + "toolButtonAccentColor": "#B5BFE2", + "upArrowColor": "#4C4F69" + }, + "navigationTree": { + "branchIndicatorColor": "#6C6F85", + "branchIndicatorSelectedColor": "#FFFFFF", + "folderIconColor": "#6C6F85", + "folderIconSelectedColor": "#FFFFFF", + "folderIconSelectedShadowColor": "#4C4F69", + "folderIconShadowColor": "#EFF1F5", + "folderNotCompletedColor": "#E5C890", + "folderReadOverlayColor": "#FFFFFF", + "folderReadOverlaySelectedColor": "#4C4F69", + "newItemColor": "#E5C890", + "scrollBackgroundColor": "#DCE0E8", + "scrollHandleColor": "#8C8FA1", + "selectedTextColor": "#FFFFFF", + "selectionBackgroundColor": "#4C4F69", + "textColor": "#4C4F69" + }, + "noLibrariesWidget": { + "backgroundColor": "#EFF1F5", + "descriptionTextColor": "#6C6F85", + "iconColor": "#BCC0CC", + "noLibrariesLineColor": "#CCD0DA", + "textColor": "#4C4F69" + }, + "readingListIcons": { + "currentlyReadingMainColor": "#8CAAEE", + "currentlyReadingMainSelectedColor": "#8CAAEE", + "currentlyReadingOuterColor": "#4C4F69", + "currentlyReadingOuterSelectedColor": "#4C4F69", + "favoritesMainColor": "#F4B8E4", + "favoritesMainSelectedColor": "#F4B8E4", + "labelColors": { + "blue": "#8CAAEE", + "cyan": "#99D1DB", + "dark": "#949CBB", + "green": "#A6D189", + "light": "#B5BFE2", + "orange": "#EF9F76", + "pink": "#F4B8E4", + "purple": "#CA9EE6", + "red": "#E78284", + "violet": "#BABBF1", + "white": "#EFF1F5", + "yellow": "#E5C890" + }, + "labelShadowColor": "#B5BFE2", + "labelShadowSelectedColor": "#4C4F69", + "listDetailColor": "#FFFFFF", + "listDetailSelectedColor": "#4C4F69", + "listMainColor": "#6C6F85", + "listMainSelectedColor": "#FFFFFF", + "listShadowColor": "#9CA0B0", + "listShadowSelectedColor": "#4C4F69", + "readingListMainColor": "#6C6F85", + "readingListMainSelectedColor": "#FFFFFF", + "specialListShadowColor": "#9CA0B0", + "specialListShadowSelectedColor": "#4C4F69" + }, + "searchLineEdit": { + "backgroundColor": "#4C4F69", + "iconColor": "#EFF1F5", + "textColor": "#FFFFFF" + }, + "serverConfigDialog": { + "backgroundColor": "#EFF1F5", + "checkBoxTextColor": "#4C4F69", + "decorationColor": "#6C6F85", + "labelTextColor": "#5C5F77", + "propagandaTextColor": "#6C6F85", + "qrBackgroundColor": "#FFFFFF", + "qrForegroundColor": "#4C4F69", + "qrMessageTextColor": "#8C8FA1", + "titleTextColor": "#303446" + }, + "shortcutsIcons": { + "iconColor": "#5C5F77" + }, + "sidebar": { + "backgroundColor": "#F4F5F8", + "busyIndicatorColor": "#BABBF1", + "sectionSeparatorColor": "#DCE0E8", + "separatorColor": "#9CA0B0", + "titleDropShadowColor": "#FFFFFF", + "titleTextColor": "#4C4F69", + "uppercaseLabels": true + }, + "sidebarIcons": { + "iconColor": "#5C5F77", + "shadowColor": "#F4F5F8", + "useSystemFolderIcons": false + }, + "whatsNewDialog": { + "backgroundColor": "#FFFFFF", + "closeButtonColor": "#4C4F69", + "contentTextColor": "#303446", + "headerDecorationColor": "#BABBF1", + "headerTextColor": "#303446", + "linkColor": "#8CAAEE", + "versionTextColor": "#8C8FA1" + } +} diff --git a/YACReaderLibrary/themes/builtin_light2.json b/YACReaderLibrary/themes/builtin_light2.json new file mode 100644 index 000000000..cdff8ce64 --- /dev/null +++ b/YACReaderLibrary/themes/builtin_light2.json @@ -0,0 +1,264 @@ +{ + "comicFlow": { + "backgroundColor": "#D5D6DB", + "readMainColor": "#F52A65", + "readTickColor": "#C64343", + "readingColor": "#8C6C3E", + "textColor": "#4A5685" + }, + "comicsViewTable": { + "alternateBackgroundColor": "#D7D8DD", + "backgroundColor": "#E1E2E7", + "headerBackgroundColor": "#E6E8EF", + "headerBorderColor": "#C4C8DA", + "headerGradientColor": "#E6E8EF", + "headerTextColor": "#2F334D", + "itemBorderBottomColor": "#C4C8DA", + "itemBorderBottomWidth": 0, + "itemBorderTopColor": "#F5F6F8", + "itemBorderTopWidth": 0, + "itemTextColor": "#2F334D", + "selectedColor": "#3760BF", + "selectedTextColor": "#FFFFFF", + "starRatingColor": "#8C6C3E", + "starRatingSelectedColor": "#FFFFFF" + }, + "comicsViewToolbar": { + "backgroundColor": "#EEF1F8", + "checkedBackgroundColor": "#C4C8DA", + "iconColor": "#2F334D", + "separatorColor": "#C4C8DA" + }, + "contentSplitter": { + "handleColor": "#D7D8DD", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "dialogIcons": { + "iconColor": "#4A5685" + }, + "emptyContainer": { + "backgroundColor": "#E1E2E7", + "iconColor": "#C4C8DA", + "titleTextColor": "#68709A" + }, + "gridAndInfoView": { + "backgroundBlurOverlayColor": "#B4B5B9", + "backgroundColor": "#E1E2E7", + "borderColor": "#D5D6DB", + "buttonColor": "#3760BF", + "buttonShadowColor": "#AA000000", + "buttonTextColor": "#FFFFFF", + "cellColor": "#FFFFFF", + "cellColorWithBackground": "#99FFFFFF", + "cellSelectedBorderColor": "#2E7DE9", + "cellSelectedColor": "#EEF1F8", + "comicCoverBorderColor": "#30FFFFFF", + "continueReadingBackgroundColor": "#D7D8DD", + "continueReadingTextColor": "#2F334D", + "currentComicBackgroundColor": "#88E1E2E7", + "currentComicCoverShadowColor": "#FF000000", + "favCheckedColor": "#D20065", + "favUncheckedColor": "#8990B3", + "folderCoverBorderColor": "#20FFFFFF", + "infoBackgroundColor": "#FFFFFF", + "infoBorderColor": "#C4C8DA", + "infoMetadataTextColor": "#68709A", + "infoScrollbarColor": "#FF6172B0", + "infoShadowColor": "#8990B3", + "infoTextColor": "#2F334D", + "itemDetailsColor": "#4A5685", + "itemTitleColor": "#1F2335", + "linkColor": "#2E7DE9", + "newItemColor": "#FF8C6C3E", + "placeholderFolder1BorderColor": "#20FFFFFF", + "placeholderFolder1Color": "#10C4C8DA", + "placeholderFolder2BorderColor": "#20FFFFFF", + "placeholderFolder2Color": "#40B4B5B9", + "ratingSelectedColor": "#3760BF", + "ratingUnselectedColor": "#8990B3", + "readTickCheckedColor": "#587539", + "readTickUncheckedColor": "#8990B3", + "scrollbarBorderColor": "#AAC4C8DA", + "scrollbarColor": "#888990B3", + "showDropShadow": true + }, + "helpAboutDialog": { + "headingColor": "#2F334D", + "linkColor": "#2E7DE9" + }, + "importWidget": { + "backgroundColor": "#E1E2E7", + "coversDecorationBgColor": "#D5D6DB", + "coversDecorationShadowColor": "#C4C8DA", + "coversLabelColor": "#4A5685", + "coversViewBackgroundColor": "#D5D6DB", + "currentComicTextColor": "#4A5685", + "descriptionTextColor": "#4A5685", + "glowLineColor": "#8C6C3E", + "iconCheckedColor": "#587539", + "iconColor": "#2F334D", + "modeIconColor": "#D5D6DB", + "titleTextColor": "#2F334D" + }, + "libraryItem": { + "libraryIconColor": "#4A5685", + "libraryIconSelectedColor": "#FFFFFF", + "libraryIconShadowColor": "#E1E2E7", + "libraryOptionsIconColor": "#FFFFFF", + "selectedBackgroundColor": "#3760BF", + "selectedTextColor": "#FFFFFF", + "textColor": "#2F334D" + }, + "mainToolbar": { + "backgroundColor": "#EEF1F8", + "dividerColor": "#C4C8DA", + "folderNameColor": "#2F334D", + "iconColor": "#2F334D", + "iconDisabledColor": "#A1A6C5" + }, + "menuIcons": { + "iconColor": "#4A5685" + }, + "meta": { + "displayName": "Late Day", + "id": "builtin/light2", + "targetApp": "YACReaderLibrary", + "variant": "light", + "version": "10.1.0" + }, + "metadataScraperDialog": { + "busyIndicatorColor": "#2F334D", + "buttonBackgroundColor": "#D5D6DB", + "buttonBorderColor": "#C4C8DA", + "buttonTextColor": "#2F334D", + "checkBoxTickColor": "#2F334D", + "contentAltBackgroundColor": "#D7D8DD", + "contentBackgroundColor": "#EEF1F8", + "contentTextColor": "#2F334D", + "dialogBackgroundColor": "#F5F6FA", + "downArrowColor": "#2F334D", + "hyperlinkColor": "#2E7DE9", + "labelBackgroundColor": "#EEF1F8", + "labelTextColor": "#2F334D", + "navIconColor": "#3760BF", + "radioCheckedBackgroundColor": "#C4C8DA", + "radioCheckedIndicatorColor": "#2F334D", + "radioUncheckedColor": "#D5D6DB", + "rowIconColor": "#3760BF", + "tableAltBackgroundColor": "#F5F6FA", + "tableBackgroundColor": "#EEF1F8", + "tableBorderColor": "#C4C8DA", + "tableHeaderBackgroundColor": "#D7D8DD", + "tableHeaderBorderColor": "#C4C8DA", + "tableHeaderGradientColor": "#D5D6DB", + "tableHeaderTextColor": "#2F334D", + "tableScrollBackgroundColor": "#D5D6DB", + "tableScrollHandleColor": "#8990B3", + "tableSectionBorderDark": "#C4C8DA", + "tableSectionBorderLight": "#FFFFFF", + "tableSelectedColor": "#D7D8DD", + "toolButtonAccentColor": "#A1A6C5", + "upArrowColor": "#2F334D" + }, + "navigationTree": { + "branchIndicatorColor": "#4A5685", + "branchIndicatorSelectedColor": "#FFFFFF", + "folderIconColor": "#4A5685", + "folderIconSelectedColor": "#FFFFFF", + "folderIconSelectedShadowColor": "#3760BF", + "folderIconShadowColor": "#E1E2E7", + "folderNotCompletedColor": "#8C6C3E", + "folderReadOverlayColor": "#FFFFFF", + "folderReadOverlaySelectedColor": "#3760BF", + "newItemColor": "#8C6C3E", + "scrollBackgroundColor": "#D5D6DB", + "scrollHandleColor": "#8990B3", + "selectedTextColor": "#FFFFFF", + "selectionBackgroundColor": "#3760BF", + "textColor": "#2F334D" + }, + "noLibrariesWidget": { + "backgroundColor": "#E1E2E7", + "descriptionTextColor": "#4A5685", + "iconColor": "#C4C8DA", + "noLibrariesLineColor": "#C4C8DA", + "textColor": "#2F334D" + }, + "readingListIcons": { + "currentlyReadingMainColor": "#2E7DE9", + "currentlyReadingMainSelectedColor": "#2E7DE9", + "currentlyReadingOuterColor": "#3760BF", + "currentlyReadingOuterSelectedColor": "#3760BF", + "favoritesMainColor": "#D20065", + "favoritesMainSelectedColor": "#D20065", + "labelColors": { + "blue": "#2E7DE9", + "cyan": "#007197", + "dark": "#8990B3", + "green": "#587539", + "light": "#C4C8DA", + "orange": "#B15C00", + "pink": "#D20065", + "purple": "#9854F1", + "red": "#F52A65", + "violet": "#7847BD", + "white": "#E1E2E7", + "yellow": "#8C6C3E" + }, + "labelShadowColor": "#A1A6C5", + "labelShadowSelectedColor": "#3760BF", + "listDetailColor": "#FFFFFF", + "listDetailSelectedColor": "#3760BF", + "listMainColor": "#6172B0", + "listMainSelectedColor": "#FFFFFF", + "listShadowColor": "#A1A6C5", + "listShadowSelectedColor": "#3760BF", + "readingListMainColor": "#6172B0", + "readingListMainSelectedColor": "#FFFFFF", + "specialListShadowColor": "#A1A6C5", + "specialListShadowSelectedColor": "#3760BF" + }, + "searchLineEdit": { + "backgroundColor": "#3760BF", + "iconColor": "#E1E2E7", + "textColor": "#FFFFFF" + }, + "serverConfigDialog": { + "backgroundColor": "#E1E2E7", + "checkBoxTextColor": "#2F334D", + "decorationColor": "#4A5685", + "labelTextColor": "#4A5685", + "propagandaTextColor": "#68709A", + "qrBackgroundColor": "#FFFFFF", + "qrForegroundColor": "#3760BF", + "qrMessageTextColor": "#8990B3", + "titleTextColor": "#1F2335" + }, + "shortcutsIcons": { + "iconColor": "#4A5685" + }, + "sidebar": { + "backgroundColor": "#EEF1F8", + "busyIndicatorColor": "#2E7DE9", + "sectionSeparatorColor": "#D5D6DB", + "separatorColor": "#8990B3", + "titleDropShadowColor": "#FFFFFF", + "titleTextColor": "#2F334D", + "uppercaseLabels": true + }, + "sidebarIcons": { + "iconColor": "#4A5685", + "shadowColor": "#EEF1F8", + "useSystemFolderIcons": false + }, + "whatsNewDialog": { + "backgroundColor": "#FFFFFF", + "closeButtonColor": "#2F334D", + "contentTextColor": "#1F2335", + "headerDecorationColor": "#2E7DE9", + "headerTextColor": "#1F2335", + "linkColor": "#2E7DE9", + "versionTextColor": "#8990B3" + } +} diff --git a/YACReaderLibrary/themes/builtin_light3.json b/YACReaderLibrary/themes/builtin_light3.json new file mode 100644 index 000000000..a6fd68a82 --- /dev/null +++ b/YACReaderLibrary/themes/builtin_light3.json @@ -0,0 +1,264 @@ +{ + "comicFlow": { + "backgroundColor": "#EFEBD4", + "readMainColor": "#F85552", + "readTickColor": "#C74C4A", + "readingColor": "#DFA000", + "textColor": "#5C6A72" + }, + "comicsViewTable": { + "alternateBackgroundColor": "#F4F0D9", + "backgroundColor": "#FDF6E3", + "headerBackgroundColor": "#F8F3E4", + "headerBorderColor": "#E6E2CC", + "headerGradientColor": "#F8F3E4", + "headerTextColor": "#5C6A72", + "itemBorderBottomColor": "#E6E2CC", + "itemBorderBottomWidth": 0, + "itemBorderTopColor": "#FFFBEF", + "itemBorderTopWidth": 0, + "itemTextColor": "#4F5B58", + "selectedColor": "#5C6A72", + "selectedTextColor": "#FFFBEF", + "starRatingColor": "#DFA000", + "starRatingSelectedColor": "#FFFBEF" + }, + "comicsViewToolbar": { + "backgroundColor": "#FBF7EA", + "checkedBackgroundColor": "#E6E2CC", + "iconColor": "#5C6A72", + "separatorColor": "#E6E2CC" + }, + "contentSplitter": { + "handleColor": "#EFEBD4", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "dialogIcons": { + "iconColor": "#708089" + }, + "emptyContainer": { + "backgroundColor": "#FDF6E3", + "iconColor": "#E6E2CC", + "titleTextColor": "#859289" + }, + "gridAndInfoView": { + "backgroundBlurOverlayColor": "#E6E2CC", + "backgroundColor": "#FDF6E3", + "borderColor": "#E6E2CC", + "buttonColor": "#5C6A72", + "buttonShadowColor": "#AA000000", + "buttonTextColor": "#FDF6E3", + "cellColor": "#FFFBEF", + "cellColorWithBackground": "#99FFFBEF", + "cellSelectedBorderColor": "#3A94C5", + "cellSelectedColor": "#F4F0D9", + "comicCoverBorderColor": "#30FFFFFF", + "continueReadingBackgroundColor": "#EFEBD4", + "continueReadingTextColor": "#4F5B58", + "currentComicBackgroundColor": "#88FDF6E3", + "currentComicCoverShadowColor": "#FF000000", + "favCheckedColor": "#DF69BA", + "favUncheckedColor": "#859289", + "folderCoverBorderColor": "#20FFFFFF", + "infoBackgroundColor": "#FFFBEF", + "infoBorderColor": "#E6E2CC", + "infoMetadataTextColor": "#708089", + "infoScrollbarColor": "#FF708089", + "infoShadowColor": "#9DA9A0", + "infoTextColor": "#4F5B58", + "itemDetailsColor": "#708089", + "itemTitleColor": "#3F4B47", + "linkColor": "#3A94C5", + "newItemColor": "#FFDFA000", + "placeholderFolder1BorderColor": "#20FFFFFF", + "placeholderFolder1Color": "#10E6E2CC", + "placeholderFolder2BorderColor": "#20FFFFFF", + "placeholderFolder2Color": "#40D3C6AA", + "ratingSelectedColor": "#5C6A72", + "ratingUnselectedColor": "#859289", + "readTickCheckedColor": "#8DA101", + "readTickUncheckedColor": "#859289", + "scrollbarBorderColor": "#AAE6E2CC", + "scrollbarColor": "#88859289", + "showDropShadow": true + }, + "helpAboutDialog": { + "headingColor": "#4F5B58", + "linkColor": "#3A94C5" + }, + "importWidget": { + "backgroundColor": "#FDF6E3", + "coversDecorationBgColor": "#F4F0D9", + "coversDecorationShadowColor": "#E6E2CC", + "coversLabelColor": "#708089", + "coversViewBackgroundColor": "#F4F0D9", + "currentComicTextColor": "#708089", + "descriptionTextColor": "#708089", + "glowLineColor": "#DFA000", + "iconCheckedColor": "#8DA101", + "iconColor": "#5C6A72", + "modeIconColor": "#E6E2CC", + "titleTextColor": "#4F5B58" + }, + "libraryItem": { + "libraryIconColor": "#708089", + "libraryIconSelectedColor": "#FFFFFF", + "libraryIconShadowColor": "#FDF6E3", + "libraryOptionsIconColor": "#FFFFFF", + "selectedBackgroundColor": "#5C6A72", + "selectedTextColor": "#FFFFFF", + "textColor": "#4F5B58" + }, + "mainToolbar": { + "backgroundColor": "#FBF7EA", + "dividerColor": "#E6E2CC", + "folderNameColor": "#4F5B58", + "iconColor": "#4F5B58", + "iconDisabledColor": "#9DA9A0" + }, + "menuIcons": { + "iconColor": "#708089" + }, + "meta": { + "displayName": "Fadegreen", + "id": "builtin/light3", + "targetApp": "YACReaderLibrary", + "variant": "light", + "version": "10.1.0" + }, + "metadataScraperDialog": { + "busyIndicatorColor": "#4F5B58", + "buttonBackgroundColor": "#F4F0D9", + "buttonBorderColor": "#E6E2CC", + "buttonTextColor": "#4F5B58", + "checkBoxTickColor": "#4F5B58", + "contentAltBackgroundColor": "#F4F0D9", + "contentBackgroundColor": "#FFFBEF", + "contentTextColor": "#4F5B58", + "dialogBackgroundColor": "#FDF6E3", + "downArrowColor": "#4F5B58", + "hyperlinkColor": "#3A94C5", + "labelBackgroundColor": "#FFFBEF", + "labelTextColor": "#4F5B58", + "navIconColor": "#4F5B58", + "radioCheckedBackgroundColor": "#E6E2CC", + "radioCheckedIndicatorColor": "#5C6A72", + "radioUncheckedColor": "#E6E2CC", + "rowIconColor": "#4F5B58", + "tableAltBackgroundColor": "#FDF6E3", + "tableBackgroundColor": "#FFFBEF", + "tableBorderColor": "#E6E2CC", + "tableHeaderBackgroundColor": "#F4F0D9", + "tableHeaderBorderColor": "#E6E2CC", + "tableHeaderGradientColor": "#EFEBD4", + "tableHeaderTextColor": "#5C6A72", + "tableScrollBackgroundColor": "#E6E2CC", + "tableScrollHandleColor": "#859289", + "tableSectionBorderDark": "#E6E2CC", + "tableSectionBorderLight": "#FFFFFF", + "tableSelectedColor": "#EFEBD4", + "toolButtonAccentColor": "#9DA9A0", + "upArrowColor": "#4F5B58" + }, + "navigationTree": { + "branchIndicatorColor": "#708089", + "branchIndicatorSelectedColor": "#FFFFFF", + "folderIconColor": "#708089", + "folderIconSelectedColor": "#FFFFFF", + "folderIconSelectedShadowColor": "#5C6A72", + "folderIconShadowColor": "#FDF6E3", + "folderNotCompletedColor": "#DFA000", + "folderReadOverlayColor": "#FFFFFF", + "folderReadOverlaySelectedColor": "#5C6A72", + "newItemColor": "#DFA000", + "scrollBackgroundColor": "#E6E2CC", + "scrollHandleColor": "#859289", + "selectedTextColor": "#FFFFFF", + "selectionBackgroundColor": "#5C6A72", + "textColor": "#4F5B58" + }, + "noLibrariesWidget": { + "backgroundColor": "#FDF6E3", + "descriptionTextColor": "#708089", + "iconColor": "#E6E2CC", + "noLibrariesLineColor": "#D3C6AA", + "textColor": "#4F5B58" + }, + "readingListIcons": { + "currentlyReadingMainColor": "#3A94C5", + "currentlyReadingMainSelectedColor": "#3A94C5", + "currentlyReadingOuterColor": "#5C6A72", + "currentlyReadingOuterSelectedColor": "#5C6A72", + "favoritesMainColor": "#DF69BA", + "favoritesMainSelectedColor": "#DF69BA", + "labelColors": { + "blue": "#3A94C5", + "cyan": "#35A77C", + "dark": "#859289", + "green": "#8DA101", + "light": "#E6E2CC", + "orange": "#F57D26", + "pink": "#DF69BA", + "purple": "#A676E0", + "red": "#F85552", + "violet": "#7F6CD9", + "white": "#FDF6E3", + "yellow": "#DFA000" + }, + "labelShadowColor": "#9DA9A0", + "labelShadowSelectedColor": "#5C6A72", + "listDetailColor": "#FFFFFF", + "listDetailSelectedColor": "#5C6A72", + "listMainColor": "#708089", + "listMainSelectedColor": "#FFFFFF", + "listShadowColor": "#9DA9A0", + "listShadowSelectedColor": "#5C6A72", + "readingListMainColor": "#708089", + "readingListMainSelectedColor": "#FFFFFF", + "specialListShadowColor": "#9DA9A0", + "specialListShadowSelectedColor": "#5C6A72" + }, + "searchLineEdit": { + "backgroundColor": "#5C6A72", + "iconColor": "#FDF6E3", + "textColor": "#FFFFFF" + }, + "serverConfigDialog": { + "backgroundColor": "#FDF6E3", + "checkBoxTextColor": "#4F5B58", + "decorationColor": "#708089", + "labelTextColor": "#708089", + "propagandaTextColor": "#859289", + "qrBackgroundColor": "#FFFBEF", + "qrForegroundColor": "#5C6A72", + "qrMessageTextColor": "#9DA9A0", + "titleTextColor": "#3F4B47" + }, + "shortcutsIcons": { + "iconColor": "#708089" + }, + "sidebar": { + "backgroundColor": "#FFFBEF", + "busyIndicatorColor": "#3A94C5", + "sectionSeparatorColor": "#E6E2CC", + "separatorColor": "#859289", + "titleDropShadowColor": "#FDF6E3", + "titleTextColor": "#4F5B58", + "uppercaseLabels": true + }, + "sidebarIcons": { + "iconColor": "#708089", + "shadowColor": "#FFFBEF", + "useSystemFolderIcons": false + }, + "whatsNewDialog": { + "backgroundColor": "#FFFBEF", + "closeButtonColor": "#4F5B58", + "contentTextColor": "#3F4B47", + "headerDecorationColor": "#8DA101", + "headerTextColor": "#3F4B47", + "linkColor": "#3A94C5", + "versionTextColor": "#859289" + } +} diff --git a/YACReaderLibrary/themes/builtin_light4.json b/YACReaderLibrary/themes/builtin_light4.json new file mode 100644 index 000000000..d9619ff9c --- /dev/null +++ b/YACReaderLibrary/themes/builtin_light4.json @@ -0,0 +1,264 @@ +{ + "comicFlow": { + "backgroundColor": "#E8DDD3", + "readMainColor": "#B4637A", + "readTickColor": "#9D536B", + "readingColor": "#EA9D34", + "textColor": "#6E6A86" + }, + "comicsViewTable": { + "alternateBackgroundColor": "#F2E9E1", + "backgroundColor": "#FAF4ED", + "headerBackgroundColor": "#FFF8F1", + "headerBorderColor": "#D9CEC7", + "headerGradientColor": "#FFF8F1", + "headerTextColor": "#575279", + "itemBorderBottomColor": "#E8DDD3", + "itemBorderBottomWidth": 0, + "itemBorderTopColor": "#FFFFFF", + "itemBorderTopWidth": 0, + "itemTextColor": "#575279", + "selectedColor": "#907AA9", + "selectedTextColor": "#FFFFFF", + "starRatingColor": "#EA9D34", + "starRatingSelectedColor": "#FFFFFF" + }, + "comicsViewToolbar": { + "backgroundColor": "#FFF8F1", + "checkedBackgroundColor": "#E8DDD3", + "iconColor": "#575279", + "separatorColor": "#D9CEC7" + }, + "contentSplitter": { + "handleColor": "#E8DDD3", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "dialogIcons": { + "iconColor": "#6E6A86" + }, + "emptyContainer": { + "backgroundColor": "#FAF4ED", + "iconColor": "#D9CEC7", + "titleTextColor": "#9893A5" + }, + "gridAndInfoView": { + "backgroundBlurOverlayColor": "#D9CEC7", + "backgroundColor": "#FAF4ED", + "borderColor": "#E8DDD3", + "buttonColor": "#286983", + "buttonShadowColor": "#AA000000", + "buttonTextColor": "#FFFFFF", + "cellColor": "#FFF8F2", + "cellColorWithBackground": "#99FFF8F2", + "cellSelectedBorderColor": "#907AA9", + "cellSelectedColor": "#FDF7F0", + "comicCoverBorderColor": "#30FFFFFF", + "continueReadingBackgroundColor": "#F2E9E1", + "continueReadingTextColor": "#575279", + "currentComicBackgroundColor": "#88FAF4ED", + "currentComicCoverShadowColor": "#FF000000", + "favCheckedColor": "#B4637A", + "favUncheckedColor": "#8E879C", + "folderCoverBorderColor": "#20FFFFFF", + "infoBackgroundColor": "#FFF8F2", + "infoBorderColor": "#D9CEC7", + "infoMetadataTextColor": "#797593", + "infoScrollbarColor": "#FF8E879C", + "infoShadowColor": "#A59EAF", + "infoTextColor": "#575279", + "itemDetailsColor": "#6E6A86", + "itemTitleColor": "#4F4A72", + "linkColor": "#286983", + "newItemColor": "#FFEA9D34", + "placeholderFolder1BorderColor": "#20FFFFFF", + "placeholderFolder1Color": "#10E8DDD3", + "placeholderFolder2BorderColor": "#20FFFFFF", + "placeholderFolder2Color": "#40D9CEC7", + "ratingSelectedColor": "#907AA9", + "ratingUnselectedColor": "#8E879C", + "readTickCheckedColor": "#5E8D73", + "readTickUncheckedColor": "#8E879C", + "scrollbarBorderColor": "#AAD9CEC7", + "scrollbarColor": "#888E879C", + "showDropShadow": true + }, + "helpAboutDialog": { + "headingColor": "#4F4A72", + "linkColor": "#286983" + }, + "importWidget": { + "backgroundColor": "#FAF4ED", + "coversDecorationBgColor": "#E8DDD3", + "coversDecorationShadowColor": "#D9CEC7", + "coversLabelColor": "#6E6A86", + "coversViewBackgroundColor": "#E8DDD3", + "currentComicTextColor": "#6E6A86", + "descriptionTextColor": "#6E6A86", + "glowLineColor": "#EA9D34", + "iconCheckedColor": "#5E8D73", + "iconColor": "#575279", + "modeIconColor": "#F2E9E1", + "titleTextColor": "#575279" + }, + "libraryItem": { + "libraryIconColor": "#6E6A86", + "libraryIconSelectedColor": "#FFFFFF", + "libraryIconShadowColor": "#FAF4ED", + "libraryOptionsIconColor": "#FFFFFF", + "selectedBackgroundColor": "#907AA9", + "selectedTextColor": "#FFFFFF", + "textColor": "#575279" + }, + "mainToolbar": { + "backgroundColor": "#FFF8F1", + "dividerColor": "#D9CEC7", + "folderNameColor": "#575279", + "iconColor": "#575279", + "iconDisabledColor": "#B4AAB8" + }, + "menuIcons": { + "iconColor": "#6E6A86" + }, + "meta": { + "displayName": "Rose", + "id": "builtin/light4", + "targetApp": "YACReaderLibrary", + "variant": "light", + "version": "10.1.0" + }, + "metadataScraperDialog": { + "busyIndicatorColor": "#575279", + "buttonBackgroundColor": "#F2E9E1", + "buttonBorderColor": "#D9CEC7", + "buttonTextColor": "#575279", + "checkBoxTickColor": "#575279", + "contentAltBackgroundColor": "#F2E9E1", + "contentBackgroundColor": "#FAF4ED", + "contentTextColor": "#575279", + "dialogBackgroundColor": "#FFF8F2", + "downArrowColor": "#575279", + "hyperlinkColor": "#286983", + "labelBackgroundColor": "#FAF4ED", + "labelTextColor": "#575279", + "navIconColor": "#907AA9", + "radioCheckedBackgroundColor": "#E8DDD3", + "radioCheckedIndicatorColor": "#575279", + "radioUncheckedColor": "#D9CEC7", + "rowIconColor": "#907AA9", + "tableAltBackgroundColor": "#FFF8F2", + "tableBackgroundColor": "#FAF4ED", + "tableBorderColor": "#D9CEC7", + "tableHeaderBackgroundColor": "#F2E9E1", + "tableHeaderBorderColor": "#D9CEC7", + "tableHeaderGradientColor": "#F2E9E1", + "tableHeaderTextColor": "#575279", + "tableScrollBackgroundColor": "#E8DDD3", + "tableScrollHandleColor": "#8E879C", + "tableSectionBorderDark": "#D9CEC7", + "tableSectionBorderLight": "#FFFFFF", + "tableSelectedColor": "#E8DDD3", + "toolButtonAccentColor": "#B4AAB8", + "upArrowColor": "#575279" + }, + "navigationTree": { + "branchIndicatorColor": "#6E6A86", + "branchIndicatorSelectedColor": "#FFFFFF", + "folderIconColor": "#6E6A86", + "folderIconSelectedColor": "#FFFFFF", + "folderIconSelectedShadowColor": "#907AA9", + "folderIconShadowColor": "#FAF4ED", + "folderNotCompletedColor": "#EA9D34", + "folderReadOverlayColor": "#FFFFFF", + "folderReadOverlaySelectedColor": "#907AA9", + "newItemColor": "#EA9D34", + "scrollBackgroundColor": "#F2E9E1", + "scrollHandleColor": "#8E879C", + "selectedTextColor": "#FFFFFF", + "selectionBackgroundColor": "#907AA9", + "textColor": "#575279" + }, + "noLibrariesWidget": { + "backgroundColor": "#FAF4ED", + "descriptionTextColor": "#6E6A86", + "iconColor": "#D9CEC7", + "noLibrariesLineColor": "#E8DDD3", + "textColor": "#575279" + }, + "readingListIcons": { + "currentlyReadingMainColor": "#286983", + "currentlyReadingMainSelectedColor": "#286983", + "currentlyReadingOuterColor": "#907AA9", + "currentlyReadingOuterSelectedColor": "#907AA9", + "favoritesMainColor": "#B4637A", + "favoritesMainSelectedColor": "#B4637A", + "labelColors": { + "blue": "#286983", + "cyan": "#56949F", + "dark": "#797593", + "green": "#5E8D73", + "light": "#D9CEC7", + "orange": "#C8842F", + "pink": "#D7827E", + "purple": "#907AA9", + "red": "#B4637A", + "violet": "#7C6FA8", + "white": "#FAF4ED", + "yellow": "#EA9D34" + }, + "labelShadowColor": "#B4AAB8", + "labelShadowSelectedColor": "#907AA9", + "listDetailColor": "#FFFFFF", + "listDetailSelectedColor": "#907AA9", + "listMainColor": "#797593", + "listMainSelectedColor": "#FFFFFF", + "listShadowColor": "#B4AAB8", + "listShadowSelectedColor": "#907AA9", + "readingListMainColor": "#797593", + "readingListMainSelectedColor": "#FFFFFF", + "specialListShadowColor": "#B4AAB8", + "specialListShadowSelectedColor": "#907AA9" + }, + "searchLineEdit": { + "backgroundColor": "#575279", + "iconColor": "#FAF4ED", + "textColor": "#FFFFFF" + }, + "serverConfigDialog": { + "backgroundColor": "#FAF4ED", + "checkBoxTextColor": "#575279", + "decorationColor": "#6E6A86", + "labelTextColor": "#6E6A86", + "propagandaTextColor": "#797593", + "qrBackgroundColor": "#FFF8F2", + "qrForegroundColor": "#575279", + "qrMessageTextColor": "#A59EAF", + "titleTextColor": "#4F4A72" + }, + "shortcutsIcons": { + "iconColor": "#6E6A86" + }, + "sidebar": { + "backgroundColor": "#FFF7F1", + "busyIndicatorColor": "#286983", + "sectionSeparatorColor": "#E8DDD3", + "separatorColor": "#A59EAF", + "titleDropShadowColor": "#FFFFFF", + "titleTextColor": "#575279", + "uppercaseLabels": true + }, + "sidebarIcons": { + "iconColor": "#6E6A86", + "shadowColor": "#FFF7F1", + "useSystemFolderIcons": false + }, + "whatsNewDialog": { + "backgroundColor": "#FFF8F2", + "closeButtonColor": "#575279", + "contentTextColor": "#4F4A72", + "headerDecorationColor": "#907AA9", + "headerTextColor": "#4F4A72", + "linkColor": "#286983", + "versionTextColor": "#A59EAF" + } +} diff --git a/YACReaderLibrary/themes/builtin_light5.json b/YACReaderLibrary/themes/builtin_light5.json new file mode 100644 index 000000000..f6fbaa3a8 --- /dev/null +++ b/YACReaderLibrary/themes/builtin_light5.json @@ -0,0 +1,264 @@ +{ + "comicFlow": { + "backgroundColor": "#E7DCCB", + "readMainColor": "#C84053", + "readTickColor": "#A53A49", + "readingColor": "#B98D3B", + "textColor": "#716E61" + }, + "comicsViewTable": { + "alternateBackgroundColor": "#F1E7D7", + "backgroundColor": "#F7F2E7", + "headerBackgroundColor": "#FCF7ED", + "headerBorderColor": "#D8CDBA", + "headerGradientColor": "#FCF7ED", + "headerTextColor": "#545464", + "itemBorderBottomColor": "#E3D8C7", + "itemBorderBottomWidth": 0, + "itemBorderTopColor": "#FFFFFF", + "itemBorderTopWidth": 0, + "itemTextColor": "#545464", + "selectedColor": "#5D57A3", + "selectedTextColor": "#FFFFFF", + "starRatingColor": "#B98D3B", + "starRatingSelectedColor": "#FFFFFF" + }, + "comicsViewToolbar": { + "backgroundColor": "#FCF7ED", + "checkedBackgroundColor": "#E7DCCB", + "iconColor": "#545464", + "separatorColor": "#D8CDBA" + }, + "contentSplitter": { + "handleColor": "#E3D8C7", + "horizontalHandleHeight": 4, + "verticalHandleWidth": 4 + }, + "dialogIcons": { + "iconColor": "#716E61" + }, + "emptyContainer": { + "backgroundColor": "#F7F2E7", + "iconColor": "#D8CDBA", + "titleTextColor": "#8A8980" + }, + "gridAndInfoView": { + "backgroundBlurOverlayColor": "#C9BDAA", + "backgroundColor": "#F7F2E7", + "borderColor": "#E3D8C7", + "buttonColor": "#4D699B", + "buttonShadowColor": "#AA000000", + "buttonTextColor": "#FFFFFF", + "cellColor": "#FFF9F0", + "cellColorWithBackground": "#99FFF9F0", + "cellSelectedBorderColor": "#5D57A3", + "cellSelectedColor": "#FBF6ED", + "comicCoverBorderColor": "#30FFFFFF", + "continueReadingBackgroundColor": "#F1E7D7", + "continueReadingTextColor": "#545464", + "currentComicBackgroundColor": "#88F7F2E7", + "currentComicCoverShadowColor": "#FF000000", + "favCheckedColor": "#B35B79", + "favUncheckedColor": "#7D7A73", + "folderCoverBorderColor": "#20FFFFFF", + "infoBackgroundColor": "#FFF9F0", + "infoBorderColor": "#D8CDBA", + "infoMetadataTextColor": "#716E61", + "infoScrollbarColor": "#FF7D7A73", + "infoShadowColor": "#8A8980", + "infoTextColor": "#545464", + "itemDetailsColor": "#716E61", + "itemTitleColor": "#43436C", + "linkColor": "#4D699B", + "newItemColor": "#FFB98D3B", + "placeholderFolder1BorderColor": "#20FFFFFF", + "placeholderFolder1Color": "#10E3D8C7", + "placeholderFolder2BorderColor": "#20FFFFFF", + "placeholderFolder2Color": "#40C9BDAA", + "ratingSelectedColor": "#5D57A3", + "ratingUnselectedColor": "#7D7A73", + "readTickCheckedColor": "#6F894E", + "readTickUncheckedColor": "#7D7A73", + "scrollbarBorderColor": "#AAD8CDBA", + "scrollbarColor": "#887D7A73", + "showDropShadow": true + }, + "helpAboutDialog": { + "headingColor": "#43436C", + "linkColor": "#4D699B" + }, + "importWidget": { + "backgroundColor": "#F7F2E7", + "coversDecorationBgColor": "#E7DCCB", + "coversDecorationShadowColor": "#D8CDBA", + "coversLabelColor": "#716E61", + "coversViewBackgroundColor": "#E7DCCB", + "currentComicTextColor": "#716E61", + "descriptionTextColor": "#716E61", + "glowLineColor": "#B98D3B", + "iconCheckedColor": "#6F894E", + "iconColor": "#545464", + "modeIconColor": "#E7DCCB", + "titleTextColor": "#545464" + }, + "libraryItem": { + "libraryIconColor": "#716E61", + "libraryIconSelectedColor": "#FFFFFF", + "libraryIconShadowColor": "#F7F2E7", + "libraryOptionsIconColor": "#FFFFFF", + "selectedBackgroundColor": "#5D57A3", + "selectedTextColor": "#FFFFFF", + "textColor": "#545464" + }, + "mainToolbar": { + "backgroundColor": "#FCF7ED", + "dividerColor": "#D8CDBA", + "folderNameColor": "#545464", + "iconColor": "#545464", + "iconDisabledColor": "#A6A294" + }, + "menuIcons": { + "iconColor": "#716E61" + }, + "meta": { + "displayName": "Lotus", + "id": "builtin/light5", + "targetApp": "YACReaderLibrary", + "variant": "light", + "version": "10.1.0" + }, + "metadataScraperDialog": { + "busyIndicatorColor": "#545464", + "buttonBackgroundColor": "#F1E7D7", + "buttonBorderColor": "#D8CDBA", + "buttonTextColor": "#545464", + "checkBoxTickColor": "#545464", + "contentAltBackgroundColor": "#F1E7D7", + "contentBackgroundColor": "#F7F2E7", + "contentTextColor": "#545464", + "dialogBackgroundColor": "#FFF9F0", + "downArrowColor": "#545464", + "hyperlinkColor": "#4D699B", + "labelBackgroundColor": "#F7F2E7", + "labelTextColor": "#545464", + "navIconColor": "#5D57A3", + "radioCheckedBackgroundColor": "#E7DCCB", + "radioCheckedIndicatorColor": "#545464", + "radioUncheckedColor": "#D8CDBA", + "rowIconColor": "#5D57A3", + "tableAltBackgroundColor": "#FFF9F0", + "tableBackgroundColor": "#F7F2E7", + "tableBorderColor": "#D8CDBA", + "tableHeaderBackgroundColor": "#F1E7D7", + "tableHeaderBorderColor": "#D8CDBA", + "tableHeaderGradientColor": "#F1E7D7", + "tableHeaderTextColor": "#545464", + "tableScrollBackgroundColor": "#E7DCCB", + "tableScrollHandleColor": "#7D7A73", + "tableSectionBorderDark": "#D8CDBA", + "tableSectionBorderLight": "#FFFFFF", + "tableSelectedColor": "#E7DCCB", + "toolButtonAccentColor": "#A6A294", + "upArrowColor": "#545464" + }, + "navigationTree": { + "branchIndicatorColor": "#716E61", + "branchIndicatorSelectedColor": "#FFFFFF", + "folderIconColor": "#716E61", + "folderIconSelectedColor": "#FFFFFF", + "folderIconSelectedShadowColor": "#5D57A3", + "folderIconShadowColor": "#F7F2E7", + "folderNotCompletedColor": "#B98D3B", + "folderReadOverlayColor": "#FFFFFF", + "folderReadOverlaySelectedColor": "#5D57A3", + "newItemColor": "#B98D3B", + "scrollBackgroundColor": "#F1E7D7", + "scrollHandleColor": "#7D7A73", + "selectedTextColor": "#FFFFFF", + "selectionBackgroundColor": "#5D57A3", + "textColor": "#545464" + }, + "noLibrariesWidget": { + "backgroundColor": "#F7F2E7", + "descriptionTextColor": "#716E61", + "iconColor": "#D8CDBA", + "noLibrariesLineColor": "#E3D8C7", + "textColor": "#545464" + }, + "readingListIcons": { + "currentlyReadingMainColor": "#4D699B", + "currentlyReadingMainSelectedColor": "#4D699B", + "currentlyReadingOuterColor": "#5D57A3", + "currentlyReadingOuterSelectedColor": "#5D57A3", + "favoritesMainColor": "#B35B79", + "favoritesMainSelectedColor": "#B35B79", + "labelColors": { + "blue": "#4D699B", + "cyan": "#597B75", + "dark": "#716E61", + "green": "#6F894E", + "light": "#D8CDBA", + "orange": "#CC6D00", + "pink": "#B35B79", + "purple": "#7E6C9A", + "red": "#C84053", + "violet": "#5D57A3", + "white": "#F7F2E7", + "yellow": "#B98D3B" + }, + "labelShadowColor": "#A6A294", + "labelShadowSelectedColor": "#5D57A3", + "listDetailColor": "#FFFFFF", + "listDetailSelectedColor": "#5D57A3", + "listMainColor": "#716E61", + "listMainSelectedColor": "#FFFFFF", + "listShadowColor": "#A6A294", + "listShadowSelectedColor": "#5D57A3", + "readingListMainColor": "#716E61", + "readingListMainSelectedColor": "#FFFFFF", + "specialListShadowColor": "#A6A294", + "specialListShadowSelectedColor": "#5D57A3" + }, + "searchLineEdit": { + "backgroundColor": "#545464", + "iconColor": "#F7F2E7", + "textColor": "#FFFFFF" + }, + "serverConfigDialog": { + "backgroundColor": "#F7F2E7", + "checkBoxTextColor": "#545464", + "decorationColor": "#716E61", + "labelTextColor": "#716E61", + "propagandaTextColor": "#8A8980", + "qrBackgroundColor": "#FFF9F0", + "qrForegroundColor": "#545464", + "qrMessageTextColor": "#A6A294", + "titleTextColor": "#43436C" + }, + "shortcutsIcons": { + "iconColor": "#716E61" + }, + "sidebar": { + "backgroundColor": "#FBF6EC", + "busyIndicatorColor": "#4D699B", + "sectionSeparatorColor": "#E3D8C7", + "separatorColor": "#8A8980", + "titleDropShadowColor": "#FFFFFF", + "titleTextColor": "#545464", + "uppercaseLabels": true + }, + "sidebarIcons": { + "iconColor": "#716E61", + "shadowColor": "#FBF6EC", + "useSystemFolderIcons": false + }, + "whatsNewDialog": { + "backgroundColor": "#FFF9F0", + "closeButtonColor": "#545464", + "contentTextColor": "#43436C", + "headerDecorationColor": "#5D57A3", + "headerTextColor": "#43436C", + "linkColor": "#4D699B", + "versionTextColor": "#A6A294" + } +} diff --git a/YACReaderLibrary/themes/themes.qrc b/YACReaderLibrary/themes/themes.qrc index 62ec21fee..d96de307d 100644 --- a/YACReaderLibrary/themes/themes.qrc +++ b/YACReaderLibrary/themes/themes.qrc @@ -2,6 +2,15 @@ builtin_classic.json builtin_light.json + builtin_light1.json + builtin_light2.json + builtin_light3.json + builtin_light4.json + builtin_light5.json builtin_dark.json + builtin_dark1.json + builtin_dark2.json + builtin_dark3.json + builtin_dark4.json diff --git a/common/themes/theme_repository.cpp b/common/themes/theme_repository.cpp index 2b324bca5..2365109b4 100644 --- a/common/themes/theme_repository.cpp +++ b/common/themes/theme_repository.cpp @@ -1,12 +1,37 @@ #include "theme_repository.h" #include "theme_json_utils.h" +#include #include #include #include #include #include +namespace { +QString builtinNameFromFileName(QString fileName) +{ + if (fileName.endsWith(".json")) + fileName.chop(5); + + if (fileName.startsWith("builtin_")) + fileName.remove(0, 8); + + return fileName; +} + +int builtinSortRank(const QString &name) +{ + if (name == QStringLiteral("classic")) + return 0; + if (name == QStringLiteral("light")) + return 1; + if (name == QStringLiteral("dark")) + return 2; + return 3; +} +} + ThemeRepository::ThemeRepository(const QString &qrcPrefix, const QString &userThemesDir, const QString &targetApp) : qrcPrefix(qrcPrefix), userThemesDir(userThemesDir), targetApp(targetApp) { @@ -43,9 +68,19 @@ bool ThemeRepository::contains(const QString &themeId) const QJsonObject ThemeRepository::loadThemeJson(const QString &themeId) const { - for (const auto &b : builtins) - if (b.id == themeId) - return readJsonFile(b.resourcePath); + for (const auto &b : builtins) { + if (b.id != themeId) + continue; + + QJsonObject json = readJsonFile(b.resourcePath); + if (json.isEmpty()) + return { }; + + auto meta = json["meta"].toObject(); + meta["id"] = b.id; + json["meta"] = meta; + return json; + } for (const auto &u : userThemes) if (u.id == themeId) @@ -145,10 +180,24 @@ void ThemeRepository::scanBuiltins() { builtins.clear(); - static const QStringList builtinNames = { "classic", "light", "dark" }; + QDir dir(qrcPrefix); + QStringList builtinFiles = dir.entryList({ QStringLiteral("builtin_*.json") }, QDir::Files, QDir::Name); + std::sort(builtinFiles.begin(), builtinFiles.end(), [](const QString &lhs, const QString &rhs) { + const QString lhsName = builtinNameFromFileName(lhs); + const QString rhsName = builtinNameFromFileName(rhs); + const int lhsRank = builtinSortRank(lhsName); + const int rhsRank = builtinSortRank(rhsName); + if (lhsRank != rhsRank) + return lhsRank < rhsRank; + return lhsName < rhsName; + }); + + for (const auto &fileName : builtinFiles) { + const QString name = builtinNameFromFileName(fileName); + if (name.isEmpty()) + continue; - for (const auto &name : builtinNames) { - const QString resourcePath = qrcPrefix + "/builtin_" + name + ".json"; + const QString resourcePath = dir.absoluteFilePath(fileName); const QJsonObject json = readJsonFile(resourcePath); if (json.isEmpty()) continue; From 9af9e8547aec31c57f600a482a0da35d0cedb761 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 22 Mar 2026 18:52:16 +0100 Subject: [PATCH 163/187] Fix label colors in the default Dark theme --- YACReaderLibrary/themes/builtin_dark.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/YACReaderLibrary/themes/builtin_dark.json b/YACReaderLibrary/themes/builtin_dark.json index c43986486..3964ec748 100644 --- a/YACReaderLibrary/themes/builtin_dark.json +++ b/YACReaderLibrary/themes/builtin_dark.json @@ -195,9 +195,9 @@ "labelColors": { "blue": "#82C7FF", "cyan": "#A0FDDB", - "dark": "#B7B7B7", + "dark": "#7C7C7C", "green": "#ADE738", - "light": "#CBCBCB", + "light": "#AFAFAF", "orange": "#F5C240", "pink": "#FD9CDA", "purple": "#D692FC", From 2367a1919e684dab35da276efb478a57424685d9 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 22 Mar 2026 18:55:27 +0100 Subject: [PATCH 164/187] Format --- common/themes/theme_editor_dialog.cpp | 1 + common/themes/theme_repository.cpp | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/common/themes/theme_editor_dialog.cpp b/common/themes/theme_editor_dialog.cpp index b8fa6b7d7..391b6d54f 100644 --- a/common/themes/theme_editor_dialog.cpp +++ b/common/themes/theme_editor_dialog.cpp @@ -1,4 +1,5 @@ #include "theme_editor_dialog.h" + #include "theme_json_utils.h" #include diff --git a/common/themes/theme_repository.cpp b/common/themes/theme_repository.cpp index 2365109b4..989219f1c 100644 --- a/common/themes/theme_repository.cpp +++ b/common/themes/theme_repository.cpp @@ -1,13 +1,15 @@ #include "theme_repository.h" + #include "theme_json_utils.h" -#include #include #include #include #include #include +#include + namespace { QString builtinNameFromFileName(QString fileName) { From f3efa4ecc82d8ae875175859f44b55aaf93c4d54 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Tue, 24 Mar 2026 19:05:40 +0100 Subject: [PATCH 165/187] Don't live regenerate the theme when writing in the the name field --- common/themes/theme_editor_dialog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/themes/theme_editor_dialog.cpp b/common/themes/theme_editor_dialog.cpp index 391b6d54f..fbaac06d6 100644 --- a/common/themes/theme_editor_dialog.cpp +++ b/common/themes/theme_editor_dialog.cpp @@ -108,6 +108,8 @@ ThemeEditorDialog::ThemeEditorDialog(const QJsonObject ¶ms, QWidget *parent) auto meta = this->params["meta"].toObject(); meta["displayName"] = text; this->params["meta"] = meta; + }); + connect(nameEdit, &QLineEdit::editingFinished, this, [this]() { emit themeJsonChanged(this->params); }); connect(variantCombo, &QComboBox::currentIndexChanged, this, [this](int index) { From 15a780fc9bd36efa71b5a8ee86e40f91418b87dd Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Tue, 24 Mar 2026 22:16:46 +0100 Subject: [PATCH 166/187] Fix German translations --- YACReader/yacreader_de.ts | 2 +- YACReaderLibrary/yacreaderlibrary_de.ts | 2 +- YACReaderLibraryServer/yacreaderlibraryserver_de.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/YACReader/yacreader_de.ts b/YACReader/yacreader_de.ts index 0f4a2ef35..1ef934e1f 100644 --- a/YACReader/yacreader_de.ts +++ b/YACReader/yacreader_de.ts @@ -3214,7 +3214,7 @@ Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Do Save and apply - Speichern und bewerben + Speichern und anwenden diff --git a/YACReaderLibrary/yacreaderlibrary_de.ts b/YACReaderLibrary/yacreaderlibrary_de.ts index d1a856a11..06f833137 100644 --- a/YACReaderLibrary/yacreaderlibrary_de.ts +++ b/YACReaderLibrary/yacreaderlibrary_de.ts @@ -3239,7 +3239,7 @@ um die Leistung zu verbessern Save and apply - Speichern und bewerben + Speichern und anwenden diff --git a/YACReaderLibraryServer/yacreaderlibraryserver_de.ts b/YACReaderLibraryServer/yacreaderlibraryserver_de.ts index f322c6123..cde929dc3 100644 --- a/YACReaderLibraryServer/yacreaderlibraryserver_de.ts +++ b/YACReaderLibraryServer/yacreaderlibraryserver_de.ts @@ -2755,7 +2755,7 @@ Um mehr über die verfügbaren Einstellungen zu erfahren, lesen Sie bitte die Do Save and apply - Speichern und bewerben + Speichern und anwenden From 49eed6ba85f715899d82c64d24513760757154f4 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Tue, 24 Mar 2026 22:17:41 +0100 Subject: [PATCH 167/187] Use continuous scroll mode automatically when a web comic is open --- YACReader/main_window_viewer.cpp | 73 +++++++++++++++++++++++++++++--- YACReader/main_window_viewer.h | 3 ++ YACReader/viewer.cpp | 51 +++++++++++++++------- YACReader/viewer.h | 3 ++ 4 files changed, 107 insertions(+), 23 deletions(-) diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 28b7747c7..80a513c57 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -55,6 +55,68 @@ void MainWindowViewer::afterLaunchTasks() whatsNewController.showWhatsNewIfNeeded(this); } +void MainWindowViewer::applySavedReaderMode() +{ + Configuration &config = Configuration::getConfiguration(); + const bool manga = config.getDoubleMangaPage(); + const bool continuousScroll = config.getContinuousScroll(); + viewer->setMangaWithoutStoringSetting(manga); + viewer->setContinuousScrollWithoutStoringSetting(continuousScroll); + syncModeActions(manga, continuousScroll); +} + +void MainWindowViewer::applyLibraryReaderMode(YACReader::FileType type) +{ + Configuration &config = Configuration::getConfiguration(); + bool manga = false; + bool continuousScroll = config.getContinuousScroll(); + + switch (type) { + case YACReader::FileType::Manga: + manga = true; + break; + case YACReader::FileType::WebComic: + continuousScroll = true; + break; + case YACReader::FileType::Comic: + case YACReader::FileType::WesternManga: + case YACReader::FileType::Yonkoma: + default: + break; + } + + viewer->setMangaWithoutStoringSetting(manga); + viewer->setContinuousScrollWithoutStoringSetting(continuousScroll); + syncModeActions(manga, continuousScroll); +} + +void MainWindowViewer::syncModeActions(bool manga, bool continuousScroll) +{ + doubleMangaPageAction->setChecked(manga); + + if (continuousScroll) { + continuousScrollAction->setChecked(true); + } else { + switch (Configuration::getConfiguration().getFitMode()) { + case YACReader::FitMode::ToWidth: + adjustWidthAction->setChecked(true); + break; + case YACReader::FitMode::ToHeight: + adjustHeightAction->setChecked(true); + break; + case YACReader::FitMode::FullRes: + adjustToFullSizeAction->setChecked(true); + break; + case YACReader::FitMode::FullPage: + default: + fitToPageAction->setChecked(true); + break; + } + } + + doubleMangaPageSwitch(); +} + MainWindowViewer::~MainWindowViewer() { delete settings; @@ -810,12 +872,7 @@ void MainWindowViewer::open(QString path, ComicDB &comic, QList &siblin else setWindowTitle("YACReader - " + fi.fileName()); - auto type = comic.info.type.value(); - // TODO: support comic.info.type by adjusting the scrolling and double page mode behaviour depending on the actual type, for now type is mapped to manga mode - auto isManga = type == YACReader::FileType::Manga; - - viewer->setMangaWithoutStoringSetting(isManga); - doubleMangaPageAction->setChecked(isManga); + applyLibraryReaderMode(comic.info.type.value()); viewer->open(path, comic); enableActions(); @@ -855,7 +912,6 @@ void MainWindowViewer::open(QString path, qint64 comicId, qint64 libraryId, YACR void MainWindowViewer::openComicFromPath(QString pathFile) { - doubleMangaPageAction->setChecked(Configuration::getConfiguration().getDoubleMangaPage()); openComic(pathFile); isClient = false; // this method is used for direct openings updatePrevNextActions(!previousComicPath.isEmpty(), !nextComicPath.isEmpty()); @@ -876,6 +932,7 @@ void MainWindowViewer::openComic(QString pathFile) setWindowTitle("YACReader - " + fi.fileName()); enableActions(); + applySavedReaderMode(); viewer->open(pathFile); Configuration::getConfiguration().updateOpenRecentList(fi.absoluteFilePath()); @@ -901,6 +958,7 @@ void MainWindowViewer::openFolderFromPath(QString pathDir) setWindowTitle("YACReader - " + fi.fileName()); enableActions(); + applySavedReaderMode(); viewer->open(pathDir); Configuration::getConfiguration().updateOpenRecentList(fi.absoluteFilePath()); @@ -916,6 +974,7 @@ void MainWindowViewer::openFolderFromPath(QString pathDir, QString atFileName) setWindowTitle("YACReader - " + fi.fileName()); enableActions(); + applySavedReaderMode(); QDir d(pathDir); d.setFilter(QDir::Files | QDir::NoDotAndDotDot); diff --git a/YACReader/main_window_viewer.h b/YACReader/main_window_viewer.h index 24b6a4f7f..b1c1b5d0a 100644 --- a/YACReader/main_window_viewer.h +++ b/YACReader/main_window_viewer.h @@ -174,6 +174,9 @@ public slots: void setActionsEnabled(bool enabled); void setMglassActionsEnabled(bool enabled); void setLoadedComicActionsEnabled(bool enabled); + void syncModeActions(bool manga, bool continuousScroll); + void applySavedReaderMode(); + void applyLibraryReaderMode(YACReader::FileType type); //! Manejadores de evento: // void resizeEvent(QResizeEvent * event); diff --git a/YACReader/viewer.cpp b/YACReader/viewer.cpp index 5a0334cfa..c2b310cfd 100644 --- a/YACReader/viewer.cpp +++ b/YACReader/viewer.cpp @@ -111,10 +111,10 @@ Viewer::Viewer(QWidget *parent) doublePageSwitch(); if (Configuration::getConfiguration().getDoubleMangaPage()) - doubleMangaPageSwitch(); + setMangaModeImpl(true, false); if (Configuration::getConfiguration().getContinuousScroll()) - setContinuousScroll(true); + setContinuousScrollImpl(true, false); createConnections(); @@ -1188,41 +1188,49 @@ void Viewer::doublePageSwitch() Configuration::getConfiguration().setDoublePage(doublePage); } -void Viewer::setContinuousScroll(bool enabled) +void Viewer::setContinuousScrollImpl(bool enabled, bool persistSettings) { if (continuousScroll == enabled) { return; } + continuousScroll = enabled; - Configuration::getConfiguration().setContinuousScroll(continuousScroll); + if (persistSettings) { + Configuration::getConfiguration().setContinuousScroll(continuousScroll); + } if (continuousScroll) { continuousViewModel->setZoomFactor(zoom); if (render->hasLoadedComic()) { continuousViewModel->setViewportSize(viewport()->width(), viewport()->height()); continuousViewModel->setNumPages(render->numPages()); - // set the current page as model state before any layout/scroll happens lastCenterPage = render->getIndex(); continuousViewModel->setAnchorPage(lastCenterPage); - // pick up sizes of pages already in the buffer probeContinuousBufferedPages(); - // trigger a render cycle so new pages arrive via pageRendered signal render->update(); setActiveWidget(continuousWidget); scrollToCurrentContinuousPage(); continuousWidget->update(); viewport()->update(); } - // if no comic is loaded, messageLabel stays as the active widget } else { lastCenterPage = -1; if (render->hasLoadedComic()) { updatePage(); } - // if no comic is loaded, messageLabel stays as the active widget } } +void Viewer::setContinuousScrollWithoutStoringSetting(bool enabled) +{ + setContinuousScrollImpl(enabled, false); +} + +void Viewer::setContinuousScroll(bool enabled) +{ + setContinuousScrollImpl(enabled, true); +} + void Viewer::onContinuousScroll(int value) { if (!continuousScroll || !render->hasLoadedComic() || applyingContinuousModelState) { @@ -1345,21 +1353,32 @@ void Viewer::onRenderPageChanged(int page) scrollToCurrentContinuousPage(); } -void Viewer::setMangaWithoutStoringSetting(bool manga) +void Viewer::setMangaModeImpl(bool manga, bool persistSettings) { + if (doubleMangaPage == manga) { + return; + } + doubleMangaPage = manga; + + if (persistSettings) { + Configuration &config = Configuration::getConfiguration(); + config.setDoubleMangaPage(doubleMangaPage); + goToFlow->updateConfig(config.getSettings()); + } + render->setManga(manga); goToFlow->setFlowRightToLeft(doubleMangaPage); } +void Viewer::setMangaWithoutStoringSetting(bool manga) +{ + setMangaModeImpl(manga, false); +} + void Viewer::doubleMangaPageSwitch() { - doubleMangaPage = !doubleMangaPage; - render->doubleMangaPageSwitch(); - Configuration &config = Configuration::getConfiguration(); - config.setDoubleMangaPage(doubleMangaPage); - goToFlow->setFlowRightToLeft(doubleMangaPage); - goToFlow->updateConfig(config.getSettings()); + setMangaModeImpl(!doubleMangaPage, true); } void Viewer::resetContent() diff --git a/YACReader/viewer.h b/YACReader/viewer.h index 62071d112..5936ea0b5 100644 --- a/YACReader/viewer.h +++ b/YACReader/viewer.h @@ -86,6 +86,7 @@ public slots: void save(); void doublePageSwitch(); void setMangaWithoutStoringSetting(bool manga); + void setContinuousScrollWithoutStoringSetting(bool enabled); void doubleMangaPageSwitch(); void resetContent(); void setLoadingMessage(); @@ -202,6 +203,8 @@ public slots: void onNumPagesReady(unsigned int numPages); void onRenderPageChanged(int page); void setActiveWidget(QWidget *w); + void setContinuousScrollImpl(bool enabled, bool persistSettings); + void setMangaModeImpl(bool manga, bool persistSettings); //! Mouse handler std::unique_ptr mouseHandler; From f3b94e420ad91b655f3bcdc61d50fbefbcb6fa95 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 29 Mar 2026 22:15:43 +0200 Subject: [PATCH 168/187] find_package GuiPrivate explicitly --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d28ff285..767b5c2b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,6 +94,7 @@ else() Core Core5Compat Gui + GuiPrivate LinguistTools Multimedia Network From 27c94bcb53478c06704cc0b5b957bee0a268fde5 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 29 Mar 2026 22:18:17 +0200 Subject: [PATCH 169/187] Add missing resource: yacreaderlibraryserver_images_rcc --- YACReaderLibraryServer/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/YACReaderLibraryServer/CMakeLists.txt b/YACReaderLibraryServer/CMakeLists.txt index 9accc389f..f4a751692 100644 --- a/YACReaderLibraryServer/CMakeLists.txt +++ b/YACReaderLibraryServer/CMakeLists.txt @@ -19,6 +19,8 @@ target_compile_definitions(YACReaderLibraryServer PRIVATE YACREADER_LIBRARY ) +# Resources +qt_add_resources(yacreaderlibraryserver_images_rcc "${CMAKE_CURRENT_SOURCE_DIR}/images.qrc") target_sources(YACReaderLibraryServer PRIVATE ${yacreaderlibraryserver_images_rcc}) # Translations From 52dd4e4c3cf204e2e2186ec3ac87555f94cea109 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 29 Mar 2026 22:55:16 +0200 Subject: [PATCH 170/187] Improve backends handling and make DECOMPRESSION_BACKEND and PDF_BACKEND settings easier to discover --- .github/workflows/build.yml | 6 +- CMakeLists.txt | 82 ++++++++++++++------- cmake/BackendHelpers.cmake | 44 ++++++++++++ cmake/PdfBackend.cmake | 100 ++++++++++++++++++-------- compileOSX.sh | 1 + compressed_archive/CMakeLists.txt | 116 ++++++++++++++++++------------ docker/Dockerfile | 1 + docker/Dockerfile.aarch64 | 1 + 8 files changed, 248 insertions(+), 103 deletions(-) create mode 100644 cmake/BackendHelpers.cmake diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 165f44aef..e0e532317 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -80,6 +80,7 @@ jobs: run: | cmake -B build \ -DDECOMPRESSION_BACKEND=unarr \ + -DPDF_BACKEND=poppler \ -DBUILD_NUMBER="${{ needs.initialization.outputs.build_number }}" \ -DCMAKE_BUILD_TYPE=Release cmake --build build --parallel 2 @@ -113,6 +114,7 @@ jobs: run: | cmake -B build \ -DDECOMPRESSION_BACKEND=7zip \ + -DPDF_BACKEND=poppler \ -DBUILD_NUMBER="${{ needs.initialization.outputs.build_number }}" \ -DCMAKE_BUILD_TYPE=Release cmake --build build --parallel 2 @@ -201,7 +203,7 @@ jobs: run: | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" set PATH=C:\Qt\6.9.3\msvc2022_64\bin;%PATH% - cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DDECOMPRESSION_BACKEND=7zip -DBUILD_NUMBER="${{ needs.initialization.outputs.build_number }}" -DCMAKE_PREFIX_PATH=C:\Qt\6.9.3\msvc2022_64 + cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DDECOMPRESSION_BACKEND=7zip -DPDF_BACKEND=pdfium -DBUILD_NUMBER="${{ needs.initialization.outputs.build_number }}" -DCMAKE_PREFIX_PATH=C:\Qt\6.9.3\msvc2022_64 cmake --build build --parallel - name: Run tests @@ -346,7 +348,7 @@ jobs: run: | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64 set PATH=C:\Qt\6.9.3\msvc2022_arm64\bin;%PATH% - cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DDECOMPRESSION_BACKEND=7zip -DBUILD_NUMBER="${{ needs.initialization.outputs.build_number }}" -DCMAKE_PREFIX_PATH=C:\Qt\6.9.3\msvc2022_arm64 -DQT_HOST_PATH=C:\Qt\6.9.3\msvc2022_64 -DCMAKE_SYSTEM_PROCESSOR=ARM64 + cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DDECOMPRESSION_BACKEND=7zip -DPDF_BACKEND=pdfium -DBUILD_NUMBER="${{ needs.initialization.outputs.build_number }}" -DCMAKE_PREFIX_PATH=C:\Qt\6.9.3\msvc2022_arm64 -DQT_HOST_PATH=C:\Qt\6.9.3\msvc2022_64 -DCMAKE_SYSTEM_PROCESSOR=ARM64 cmake --build build --parallel - name: Upload executables for signing diff --git a/CMakeLists.txt b/CMakeLists.txt index 767b5c2b7..24048b26e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,21 +30,13 @@ endif() # Install paths include(GNUInstallDirs) -find_package(PkgConfig) +list(PREPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") # Compiler options (MSVC flags, NOMINMAX, etc.) include(cmake/CompilerOptions.cmake) # --- Build options --- -# Archive decompression backend (mutually exclusive) -set(DECOMPRESSION_BACKEND "" CACHE STRING "Archive backend: unarr | 7zip | libarchive") -set_property(CACHE DECOMPRESSION_BACKEND PROPERTY STRINGS "unarr" "7zip" "libarchive") - -# PDF rendering backend (mutually exclusive) -set(PDF_BACKEND "" CACHE STRING "PDF backend: pdfium | poppler | pdfkit | no_pdf") -set_property(CACHE PDF_BACKEND PROPERTY STRINGS "pdfium" "poppler" "pdfkit" "no_pdf") - # Build configuration option(BUILD_TESTS "Build tests" ON) option(BUILD_SERVER_STANDALONE "Server standalone install (Linux only)" OFF) @@ -52,25 +44,63 @@ option(BUILD_SERVER_STANDALONE "Server standalone install (Linux only)" OFF) # Build number (set by CI) set(BUILD_NUMBER "" CACHE STRING "CI build number") +set(YACREADER_DECOMPRESSION_BACKENDS unarr 7zip libarchive) +set(YACREADER_PDF_BACKENDS pdfium poppler pdfkit no_pdf) + # --- Platform defaults (mirrors config.pri) --- -if(NOT DECOMPRESSION_BACKEND OR DECOMPRESSION_BACKEND STREQUAL "") - if(UNIX AND NOT APPLE) - set(DECOMPRESSION_BACKEND "unarr") - else() - set(DECOMPRESSION_BACKEND "7zip") - endif() - message(STATUS "DECOMPRESSION_BACKEND defaulted to: ${DECOMPRESSION_BACKEND}") +if(UNIX AND NOT APPLE) + set(_default_decompression_backend "unarr") + set(_default_pdf_backend "poppler") +elseif(APPLE) + set(_default_decompression_backend "7zip") + set(_default_pdf_backend "pdfkit") +else() + set(_default_decompression_backend "7zip") + set(_default_pdf_backend "pdfium") endif() -if(NOT PDF_BACKEND OR PDF_BACKEND STREQUAL "") - if(UNIX AND NOT APPLE) - set(PDF_BACKEND "poppler") - elseif(APPLE) - set(PDF_BACKEND "pdfkit") - else() - set(PDF_BACKEND "pdfium") - endif() - message(STATUS "PDF_BACKEND defaulted to: ${PDF_BACKEND}") +# Archive decompression backend (mutually exclusive) +set(_decompression_backend_value "") +if(DEFINED CACHE{DECOMPRESSION_BACKEND}) + set(_decompression_backend_value "$CACHE{DECOMPRESSION_BACKEND}") +endif() +if(_decompression_backend_value STREQUAL "") + set(_decompression_backend_value "${_default_decompression_backend}") + string(JOIN ", " _available_decompression_backends ${YACREADER_DECOMPRESSION_BACKENDS}) + message(STATUS + "DECOMPRESSION_BACKEND not set, defaulting to ${_decompression_backend_value}. " + "Available: ${_available_decompression_backends}.") +endif() +set(DECOMPRESSION_BACKEND "${_decompression_backend_value}" CACHE STRING + "Archive backend: unarr | 7zip | libarchive" FORCE) +set_property(CACHE DECOMPRESSION_BACKEND PROPERTY STRINGS ${YACREADER_DECOMPRESSION_BACKENDS}) +if(NOT DECOMPRESSION_BACKEND IN_LIST YACREADER_DECOMPRESSION_BACKENDS) + string(JOIN ", " _valid_decompression_backends ${YACREADER_DECOMPRESSION_BACKENDS}) + message(FATAL_ERROR + "Unknown DECOMPRESSION_BACKEND: '${DECOMPRESSION_BACKEND}'. " + "Use one of: ${_valid_decompression_backends}") +endif() + +# PDF rendering backend (mutually exclusive) +set(_pdf_backend_value "") +if(DEFINED CACHE{PDF_BACKEND}) + set(_pdf_backend_value "$CACHE{PDF_BACKEND}") +endif() +if(_pdf_backend_value STREQUAL "") + set(_pdf_backend_value "${_default_pdf_backend}") + string(JOIN ", " _available_pdf_backends ${YACREADER_PDF_BACKENDS}) + message(STATUS + "PDF_BACKEND not set, defaulting to ${_pdf_backend_value}. " + "Available: ${_available_pdf_backends}.") +endif() +set(PDF_BACKEND "${_pdf_backend_value}" CACHE STRING + "PDF backend: pdfium | poppler | pdfkit | no_pdf" FORCE) +set_property(CACHE PDF_BACKEND PROPERTY STRINGS ${YACREADER_PDF_BACKENDS}) +if(NOT PDF_BACKEND IN_LIST YACREADER_PDF_BACKENDS) + string(JOIN ", " _valid_pdf_backends ${YACREADER_PDF_BACKENDS}) + message(FATAL_ERROR + "Unknown PDF_BACKEND: '${PDF_BACKEND}'. " + "Use one of: ${_valid_pdf_backends}") endif() # macOS universal binary default @@ -114,7 +144,7 @@ endif() qt_standard_project_setup() # PDF backend detection (creates pdf_backend_iface INTERFACE target) -include(cmake/PdfBackend.cmake) +include(PdfBackend) # Output directory set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") diff --git a/cmake/BackendHelpers.cmake b/cmake/BackendHelpers.cmake new file mode 100644 index 000000000..9f15fb1f9 --- /dev/null +++ b/cmake/BackendHelpers.cmake @@ -0,0 +1,44 @@ +include_guard(GLOBAL) + +function(yacreader_get_windows_arch_subdir out_var) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64" OR CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64") + set(_arch "arm64") + elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(_arch "x86") + else() + set(_arch "x64") + endif() + + set(${out_var} "${_arch}" PARENT_SCOPE) +endfunction() + +function(yacreader_add_imported_library target_name) + set(options) + set(oneValueArgs TYPE LOCATION IMPORTED_IMPLIB INCLUDE_DIR) + set(multiValueArgs LINK_LIBRARIES) + cmake_parse_arguments(YR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT YR_TYPE) + set(YR_TYPE UNKNOWN) + endif() + + if(NOT TARGET "${target_name}") + add_library("${target_name}" ${YR_TYPE} IMPORTED GLOBAL) + endif() + + if(YR_LOCATION) + set_property(TARGET "${target_name}" PROPERTY IMPORTED_LOCATION "${YR_LOCATION}") + endif() + + if(YR_IMPORTED_IMPLIB) + set_property(TARGET "${target_name}" PROPERTY IMPORTED_IMPLIB "${YR_IMPORTED_IMPLIB}") + endif() + + if(YR_INCLUDE_DIR) + set_property(TARGET "${target_name}" PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${YR_INCLUDE_DIR}") + endif() + + if(YR_LINK_LIBRARIES) + set_property(TARGET "${target_name}" PROPERTY INTERFACE_LINK_LIBRARIES "${YR_LINK_LIBRARIES}") + endif() +endfunction() diff --git a/cmake/PdfBackend.cmake b/cmake/PdfBackend.cmake index a9f9ce1fd..2a0a3aa32 100644 --- a/cmake/PdfBackend.cmake +++ b/cmake/PdfBackend.cmake @@ -2,6 +2,8 @@ # Creates an INTERFACE target 'pdf_backend_iface' that propagates # compile definitions and link libraries based on PDF_BACKEND. +include(BackendHelpers) + add_library(pdf_backend_iface INTERFACE) if(PDF_BACKEND STREQUAL "no_pdf") @@ -12,35 +14,62 @@ elseif(PDF_BACKEND STREQUAL "pdfium") message(STATUS "PDF backend: pdfium") target_compile_definitions(pdf_backend_iface INTERFACE USE_PDFIUM) - if(MSVC) - target_include_directories(pdf_backend_iface INTERFACE - "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/public") - if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64" OR CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64") - target_link_directories(pdf_backend_iface INTERFACE - "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/arm64") - else() - target_link_directories(pdf_backend_iface INTERFACE - "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/x64") + if(WIN32) + yacreader_get_windows_arch_subdir(_pdfium_arch) + set(_pdfium_include_dir "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/public") + set(_pdfium_implib "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/${_pdfium_arch}/pdfium.lib") + set(_pdfium_dll "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/${_pdfium_arch}/pdfium.dll") + if(NOT EXISTS "${_pdfium_include_dir}/fpdfview.h" + OR NOT EXISTS "${_pdfium_implib}" + OR NOT EXISTS "${_pdfium_dll}") + message(FATAL_ERROR + "Could not find bundled pdfium for ${_pdfium_arch}. " + "Expected files under dependencies/pdfium/win/${_pdfium_arch}.") endif() - target_link_libraries(pdf_backend_iface INTERFACE pdfium) + + message(STATUS " Using bundled pdfium (${_pdfium_arch}, Windows)") + yacreader_add_imported_library(YACReader::pdfium + TYPE SHARED + LOCATION "${_pdfium_dll}" + IMPORTED_IMPLIB "${_pdfium_implib}" + INCLUDE_DIR "${_pdfium_include_dir}") + target_link_libraries(pdf_backend_iface INTERFACE YACReader::pdfium) elseif(APPLE) - target_include_directories(pdf_backend_iface INTERFACE - "${CMAKE_SOURCE_DIR}/dependencies/pdfium/macx/include") - target_link_directories(pdf_backend_iface INTERFACE - "${CMAKE_SOURCE_DIR}/dependencies/pdfium/macx/bin") - target_link_libraries(pdf_backend_iface INTERFACE pdfium) + set(_pdfium_include_dir "${CMAKE_SOURCE_DIR}/dependencies/pdfium/macx/include") + set(_pdfium_library "${CMAKE_SOURCE_DIR}/dependencies/pdfium/macx/bin/libpdfium.a") + if(NOT EXISTS "${_pdfium_include_dir}/fpdfview.h" OR NOT EXISTS "${_pdfium_library}") + message(FATAL_ERROR "Could not find bundled pdfium under dependencies/pdfium/macx.") + endif() + + message(STATUS " Using bundled pdfium (macOS)") + yacreader_add_imported_library(YACReader::pdfium + TYPE STATIC + LOCATION "${_pdfium_library}" + INCLUDE_DIR "${_pdfium_include_dir}") + target_link_libraries(pdf_backend_iface INTERFACE YACReader::pdfium) else() - # Linux: try pkg-config first, then system path - pkg_check_modules(PDFIUM QUIET IMPORTED_TARGET libpdfium) - if(PDFIUM_FOUND) + # Linux: try pkg-config first, then a normal CMake search. + find_package(PkgConfig QUIET) + if(PkgConfig_FOUND) + pkg_check_modules(PDFIUM QUIET IMPORTED_TARGET libpdfium) + endif() + + if(TARGET PkgConfig::PDFIUM) message(STATUS " Found pdfium via pkg-config") target_link_libraries(pdf_backend_iface INTERFACE PkgConfig::PDFIUM) - elseif(EXISTS "/usr/include/pdfium") - message(STATUS " Found pdfium at /usr/include/pdfium") - target_include_directories(pdf_backend_iface INTERFACE /usr/include/pdfium) - target_link_libraries(pdf_backend_iface INTERFACE pdfium) else() - message(FATAL_ERROR "Could not find libpdfium. Install it or use a different PDF_BACKEND.") + find_path(PDFIUM_INCLUDE_DIR NAMES fpdfview.h PATH_SUFFIXES pdfium) + find_library(PDFIUM_LIBRARY NAMES pdfium libpdfium) + if(PDFIUM_INCLUDE_DIR AND PDFIUM_LIBRARY) + message(STATUS " Found pdfium via CMake search") + yacreader_add_imported_library(YACReader::pdfium + TYPE UNKNOWN + LOCATION "${PDFIUM_LIBRARY}" + INCLUDE_DIR "${PDFIUM_INCLUDE_DIR}") + target_link_libraries(pdf_backend_iface INTERFACE YACReader::pdfium) + else() + message(FATAL_ERROR "Could not find libpdfium. Install it or use a different PDF_BACKEND.") + endif() endif() endif() @@ -60,20 +89,31 @@ elseif(PDF_BACKEND STREQUAL "poppler") target_link_libraries(pdf_backend_iface INTERFACE Poppler::Qt6) else() # Fall back to pkg-config (standard on Linux; on Windows requires vcpkg pkgconf) - pkg_check_modules(POPPLER QUIET IMPORTED_TARGET poppler-qt6) - if(POPPLER_FOUND) + find_package(PkgConfig QUIET) + if(PkgConfig_FOUND) + pkg_check_modules(POPPLER QUIET IMPORTED_TARGET poppler-qt6) + endif() + + if(TARGET PkgConfig::POPPLER) message(STATUS " Found poppler-qt6 via pkg-config") target_link_libraries(pdf_backend_iface INTERFACE PkgConfig::POPPLER) - elseif(NOT MSVC AND EXISTS "/usr/include/poppler/qt6") - message(STATUS " Found poppler-qt6 at /usr/include/poppler/qt6") - target_include_directories(pdf_backend_iface INTERFACE /usr/include/poppler/qt6) - target_link_libraries(pdf_backend_iface INTERFACE poppler-qt6) elseif(MSVC) message(FATAL_ERROR "Could not find poppler-qt6. " "Install via vcpkg: vcpkg install poppler[qt6]:x64-windows " "then configure cmake with the vcpkg toolchain file.") else() - message(FATAL_ERROR "Could not find poppler-qt6. Install libpoppler-qt6-dev or use a different PDF_BACKEND.") + find_path(POPPLER_QT6_INCLUDE_DIR NAMES poppler-qt6.h PATH_SUFFIXES poppler/qt6) + find_library(POPPLER_QT6_LIBRARY NAMES poppler-qt6) + if(POPPLER_QT6_INCLUDE_DIR AND POPPLER_QT6_LIBRARY) + message(STATUS " Found poppler-qt6 via CMake search") + yacreader_add_imported_library(YACReader::poppler_qt6 + TYPE UNKNOWN + LOCATION "${POPPLER_QT6_LIBRARY}" + INCLUDE_DIR "${POPPLER_QT6_INCLUDE_DIR}") + target_link_libraries(pdf_backend_iface INTERFACE YACReader::poppler_qt6) + else() + message(FATAL_ERROR "Could not find poppler-qt6. Install libpoppler-qt6-dev or use a different PDF_BACKEND.") + endif() endif() endif() diff --git a/compileOSX.sh b/compileOSX.sh index b75e3f9eb..460c96846 100755 --- a/compileOSX.sh +++ b/compileOSX.sh @@ -33,6 +33,7 @@ echo "Configuring and building with CMake" cmake -B build \ -G Ninja \ -DDECOMPRESSION_BACKEND=7zip \ + -DPDF_BACKEND=pdfkit \ -DBUILD_NUMBER="${BUILD_NUMBER}" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_OSX_ARCHITECTURES="${ARCHS}" \ diff --git a/compressed_archive/CMakeLists.txt b/compressed_archive/CMakeLists.txt index 215f45abd..948b766ca 100644 --- a/compressed_archive/CMakeLists.txt +++ b/compressed_archive/CMakeLists.txt @@ -1,6 +1,8 @@ # Comic archive decompression backend (cbx_backend) # Switched on DECOMPRESSION_BACKEND: unarr | 7zip | libarchive +include(BackendHelpers) + add_library(cbx_backend STATIC) if(DECOMPRESSION_BACKEND STREQUAL "unarr") @@ -14,45 +16,78 @@ if(DECOMPRESSION_BACKEND STREQUAL "unarr") target_include_directories(cbx_backend PUBLIC unarr) target_compile_definitions(cbx_backend PUBLIC use_unarr) - # Try CMake config first, then pkg-config, then system path - find_package(unarr QUIET) - if(unarr_FOUND) + # Try CMake config first, then pkg-config, then bundled/system libraries. + set(_unarr_target "") + + find_package(unarr QUIET CONFIG) + if(TARGET unarr::unarr) message(STATUS " Found unarr via CMake config") - target_link_libraries(cbx_backend PRIVATE unarr::unarr) - else() + set(_unarr_target unarr::unarr) + endif() + + if(NOT _unarr_target AND APPLE) + set(_unarr_include_dir "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx") + set(_unarr_library "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx/libunarr.a") + if(EXISTS "${_unarr_include_dir}/unarr.h" AND EXISTS "${_unarr_library}") + message(STATUS " Using bundled unarr (macOS)") + yacreader_add_imported_library(YACReader::unarr + TYPE STATIC + LOCATION "${_unarr_library}" + INCLUDE_DIR "${_unarr_include_dir}" + LINK_LIBRARIES "z;bz2") + set(_unarr_target YACReader::unarr) + endif() + endif() + + if(NOT _unarr_target AND WIN32) + yacreader_get_windows_arch_subdir(_unarr_arch) + set(_unarr_include_dir "${CMAKE_SOURCE_DIR}/dependencies/unarr/win") + set(_unarr_implib "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/${_unarr_arch}/unarr.lib") + set(_unarr_dll "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/${_unarr_arch}/unarr.dll") + if(EXISTS "${_unarr_include_dir}/unarr.h" AND EXISTS "${_unarr_implib}" AND EXISTS "${_unarr_dll}") + message(STATUS " Using bundled unarr (${_unarr_arch}, Windows)") + yacreader_add_imported_library(YACReader::unarr + TYPE SHARED + LOCATION "${_unarr_dll}" + IMPORTED_IMPLIB "${_unarr_implib}" + INCLUDE_DIR "${_unarr_include_dir}") + set(_unarr_target YACReader::unarr) + target_compile_definitions(cbx_backend PRIVATE UNARR_IS_SHARED_LIBRARY) + endif() + endif() + + if(NOT _unarr_target) + find_package(PkgConfig QUIET) + endif() + + if(NOT _unarr_target AND PkgConfig_FOUND) pkg_check_modules(UNARR QUIET IMPORTED_TARGET libunarr) - if(UNARR_FOUND) + if(TARGET PkgConfig::UNARR) message(STATUS " Found unarr via pkg-config") - target_link_libraries(cbx_backend PRIVATE PkgConfig::UNARR) - elseif(APPLE AND EXISTS "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx/libunarr.a") - message(STATUS " Found prebuilt unarr in dependencies (macOS)") - target_include_directories(cbx_backend PRIVATE - "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx") - target_link_directories(cbx_backend PRIVATE - "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx") - target_link_libraries(cbx_backend PRIVATE unarr z bz2) - elseif(WIN32 AND EXISTS "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/unarr.h") - message(STATUS " Found prebuilt unarr in dependencies (Windows)") - target_include_directories(cbx_backend PRIVATE - "${CMAKE_SOURCE_DIR}/dependencies/unarr/win") - if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64") - target_link_directories(cbx_backend PRIVATE - "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/arm64") - else() - target_link_directories(cbx_backend PRIVATE - "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/x64") - endif() - target_link_libraries(cbx_backend PRIVATE unarr) - target_compile_definitions(cbx_backend PRIVATE UNARR_IS_SHARED_LIBRARY) - elseif(EXISTS "/usr/include/unarr.h") - message(STATUS " Found system unarr at /usr/include") - target_link_libraries(cbx_backend PRIVATE unarr) - else() - message(FATAL_ERROR - "Could not find unarr. Install libunarr or use a different DECOMPRESSION_BACKEND.") + set(_unarr_target PkgConfig::UNARR) + endif() + endif() + + if(NOT _unarr_target) + find_path(UNARR_INCLUDE_DIR NAMES unarr.h) + find_library(UNARR_LIBRARY NAMES unarr libunarr) + if(UNARR_INCLUDE_DIR AND UNARR_LIBRARY) + message(STATUS " Found unarr via CMake search") + yacreader_add_imported_library(YACReader::unarr + TYPE UNKNOWN + LOCATION "${UNARR_LIBRARY}" + INCLUDE_DIR "${UNARR_INCLUDE_DIR}") + set(_unarr_target YACReader::unarr) endif() endif() + if(NOT _unarr_target) + message(FATAL_ERROR + "Could not find unarr. Install libunarr or use a different DECOMPRESSION_BACKEND.") + endif() + + target_link_libraries(cbx_backend PRIVATE ${_unarr_target}) + elseif(DECOMPRESSION_BACKEND STREQUAL "7zip") message(STATUS "Decompression backend: 7zip (in-tree)") @@ -135,18 +170,9 @@ elseif(DECOMPRESSION_BACKEND STREQUAL "libarchive") target_include_directories(cbx_backend PUBLIC libarchive) target_compile_definitions(cbx_backend PUBLIC use_libarchive) - # Try pkg-config first, then system path - pkg_check_modules(LIBARCHIVE QUIET IMPORTED_TARGET libarchive) - if(LIBARCHIVE_FOUND) - message(STATUS " Found libarchive via pkg-config") - target_link_libraries(cbx_backend PRIVATE PkgConfig::LIBARCHIVE) - elseif(EXISTS "/usr/include/archive.h") - message(STATUS " Found system libarchive at /usr/include") - target_link_libraries(cbx_backend PRIVATE archive) - else() - message(FATAL_ERROR - "Could not find libarchive. Install it or use a different DECOMPRESSION_BACKEND.") - endif() + find_package(LibArchive REQUIRED) + message(STATUS " Found libarchive ${LibArchive_VERSION}") + target_link_libraries(cbx_backend PRIVATE LibArchive::LibArchive) else() message(FATAL_ERROR diff --git a/docker/Dockerfile b/docker/Dockerfile index 50629fc77..bf87ed6b4 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -65,6 +65,7 @@ RUN cd /src/git && \ cmake -B build -G Ninja \ -DCMAKE_INSTALL_PREFIX=/app \ -DDECOMPRESSION_BACKEND=7zip \ + -DPDF_BACKEND=poppler \ -DBUILD_SERVER_STANDALONE=ON \ -DCMAKE_BUILD_TYPE=Release && \ cmake --build build --parallel && \ diff --git a/docker/Dockerfile.aarch64 b/docker/Dockerfile.aarch64 index aa75208bc..5bb39b361 100644 --- a/docker/Dockerfile.aarch64 +++ b/docker/Dockerfile.aarch64 @@ -62,6 +62,7 @@ RUN cd /src/git && \ cmake -B build -G Ninja \ -DCMAKE_INSTALL_PREFIX=/app \ -DDECOMPRESSION_BACKEND=7zip \ + -DPDF_BACKEND=poppler \ -DBUILD_SERVER_STANDALONE=ON \ -DCMAKE_BUILD_TYPE=Release && \ cmake --build build --parallel && \ From 268b23376be551fe41c80f0c7cae4d99b8d7f980 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 29 Mar 2026 23:15:24 +0200 Subject: [PATCH 171/187] Use Find*.cmake files for backend discovery --- cmake/BackendHelpers.cmake | 6 +- cmake/FindPopplerQt6.cmake | 43 ++++++++++++++ cmake/Findpdfium.cmake | 72 +++++++++++++++++++++++ cmake/Findunarr.cmake | 74 +++++++++++++++++++++++ cmake/PdfBackend.cmake | 98 ++++++------------------------- compressed_archive/CMakeLists.txt | 72 +++-------------------- 6 files changed, 221 insertions(+), 144 deletions(-) create mode 100644 cmake/FindPopplerQt6.cmake create mode 100644 cmake/Findpdfium.cmake create mode 100644 cmake/Findunarr.cmake diff --git a/cmake/BackendHelpers.cmake b/cmake/BackendHelpers.cmake index 9f15fb1f9..38e8b4d03 100644 --- a/cmake/BackendHelpers.cmake +++ b/cmake/BackendHelpers.cmake @@ -15,7 +15,7 @@ endfunction() function(yacreader_add_imported_library target_name) set(options) set(oneValueArgs TYPE LOCATION IMPORTED_IMPLIB INCLUDE_DIR) - set(multiValueArgs LINK_LIBRARIES) + set(multiValueArgs LINK_LIBRARIES COMPILE_DEFINITIONS) cmake_parse_arguments(YR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(NOT YR_TYPE) @@ -41,4 +41,8 @@ function(yacreader_add_imported_library target_name) if(YR_LINK_LIBRARIES) set_property(TARGET "${target_name}" PROPERTY INTERFACE_LINK_LIBRARIES "${YR_LINK_LIBRARIES}") endif() + + if(YR_COMPILE_DEFINITIONS) + set_property(TARGET "${target_name}" PROPERTY INTERFACE_COMPILE_DEFINITIONS "${YR_COMPILE_DEFINITIONS}") + endif() endfunction() diff --git a/cmake/FindPopplerQt6.cmake b/cmake/FindPopplerQt6.cmake new file mode 100644 index 000000000..1b79501f5 --- /dev/null +++ b/cmake/FindPopplerQt6.cmake @@ -0,0 +1,43 @@ +include(BackendHelpers) +include(FindPackageHandleStandardArgs) + +set(PopplerQt6_PROVIDER "") +set(PopplerQt6_TARGET "") +set(PopplerQt6_INCLUDE_DIRS "") +set(PopplerQt6_LIBRARIES "") + +if(NOT TARGET Poppler::Qt6) + find_package(PkgConfig QUIET) + if(PkgConfig_FOUND) + pkg_check_modules(POPPLERQT6 QUIET IMPORTED_TARGET poppler-qt6) + if(TARGET PkgConfig::POPPLERQT6) + yacreader_add_imported_library(Poppler::Qt6 + TYPE INTERFACE + LINK_LIBRARIES "PkgConfig::POPPLERQT6") + set(PopplerQt6_PROVIDER "pkg-config") + set(PopplerQt6_INCLUDE_DIRS "${POPPLERQT6_INCLUDE_DIRS}") + endif() + endif() +endif() + +if(NOT TARGET Poppler::Qt6) + find_path(POPPLERQT6_INCLUDE_DIR NAMES poppler-qt6.h PATH_SUFFIXES poppler/qt6) + find_library(POPPLERQT6_LIBRARY NAMES poppler-qt6) + if(POPPLERQT6_INCLUDE_DIR AND POPPLERQT6_LIBRARY) + yacreader_add_imported_library(Poppler::Qt6 + TYPE UNKNOWN + LOCATION "${POPPLERQT6_LIBRARY}" + INCLUDE_DIR "${POPPLERQT6_INCLUDE_DIR}") + set(PopplerQt6_PROVIDER "CMake search") + set(PopplerQt6_INCLUDE_DIRS "${POPPLERQT6_INCLUDE_DIR}") + endif() +endif() + +if(TARGET Poppler::Qt6) + set(PopplerQt6_TARGET Poppler::Qt6) + set(PopplerQt6_LIBRARIES Poppler::Qt6) +endif() + +find_package_handle_standard_args(PopplerQt6 REQUIRED_VARS PopplerQt6_TARGET) + +mark_as_advanced(POPPLERQT6_INCLUDE_DIR POPPLERQT6_LIBRARY) diff --git a/cmake/Findpdfium.cmake b/cmake/Findpdfium.cmake new file mode 100644 index 000000000..17689ecf1 --- /dev/null +++ b/cmake/Findpdfium.cmake @@ -0,0 +1,72 @@ +include(BackendHelpers) +include(FindPackageHandleStandardArgs) + +set(pdfium_PROVIDER "") +set(pdfium_TARGET "") +set(pdfium_INCLUDE_DIRS "") +set(pdfium_LIBRARIES "") + +if(NOT TARGET pdfium::pdfium AND WIN32) + yacreader_get_windows_arch_subdir(_pdfium_arch) + set(_pdfium_include_dir "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/public") + set(_pdfium_implib "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/${_pdfium_arch}/pdfium.lib") + set(_pdfium_dll "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/${_pdfium_arch}/pdfium.dll") + if(EXISTS "${_pdfium_include_dir}/fpdfview.h" AND EXISTS "${_pdfium_implib}" AND EXISTS "${_pdfium_dll}") + yacreader_add_imported_library(pdfium::pdfium + TYPE SHARED + LOCATION "${_pdfium_dll}" + IMPORTED_IMPLIB "${_pdfium_implib}" + INCLUDE_DIR "${_pdfium_include_dir}") + set(pdfium_PROVIDER "bundled dependencies (${_pdfium_arch}, Windows)") + set(pdfium_INCLUDE_DIRS "${_pdfium_include_dir}") + endif() +endif() + +if(NOT TARGET pdfium::pdfium AND APPLE) + set(_pdfium_include_dir "${CMAKE_SOURCE_DIR}/dependencies/pdfium/macx/include") + set(_pdfium_library "${CMAKE_SOURCE_DIR}/dependencies/pdfium/macx/bin/libpdfium.a") + if(EXISTS "${_pdfium_include_dir}/fpdfview.h" AND EXISTS "${_pdfium_library}") + yacreader_add_imported_library(pdfium::pdfium + TYPE STATIC + LOCATION "${_pdfium_library}" + INCLUDE_DIR "${_pdfium_include_dir}") + set(pdfium_PROVIDER "bundled dependencies (macOS)") + set(pdfium_INCLUDE_DIRS "${_pdfium_include_dir}") + endif() +endif() + +if(NOT TARGET pdfium::pdfium) + find_package(PkgConfig QUIET) + if(PkgConfig_FOUND) + pkg_check_modules(PDFIUM QUIET IMPORTED_TARGET libpdfium) + if(TARGET PkgConfig::PDFIUM) + yacreader_add_imported_library(pdfium::pdfium + TYPE INTERFACE + LINK_LIBRARIES "PkgConfig::PDFIUM") + set(pdfium_PROVIDER "pkg-config") + set(pdfium_INCLUDE_DIRS "${PDFIUM_INCLUDE_DIRS}") + endif() + endif() +endif() + +if(NOT TARGET pdfium::pdfium) + find_path(PDFIUM_INCLUDE_DIR NAMES fpdfview.h PATH_SUFFIXES pdfium) + find_library(PDFIUM_LIBRARY NAMES pdfium libpdfium) + if(PDFIUM_INCLUDE_DIR AND PDFIUM_LIBRARY) + yacreader_add_imported_library(pdfium::pdfium + TYPE UNKNOWN + LOCATION "${PDFIUM_LIBRARY}" + INCLUDE_DIR "${PDFIUM_INCLUDE_DIR}") + set(pdfium_PROVIDER "CMake search") + set(pdfium_INCLUDE_DIRS "${PDFIUM_INCLUDE_DIR}") + endif() +endif() + +if(TARGET pdfium::pdfium) + set(pdfium_TARGET pdfium::pdfium) + set(pdfium_LIBRARIES pdfium::pdfium) +endif() + +find_package_handle_standard_args(pdfium REQUIRED_VARS pdfium_TARGET) + +mark_as_advanced(PDFIUM_INCLUDE_DIR PDFIUM_LIBRARY) diff --git a/cmake/Findunarr.cmake b/cmake/Findunarr.cmake new file mode 100644 index 000000000..4aa9ef0ab --- /dev/null +++ b/cmake/Findunarr.cmake @@ -0,0 +1,74 @@ +include(BackendHelpers) +include(FindPackageHandleStandardArgs) + +set(unarr_PROVIDER "") +set(unarr_TARGET "") +set(unarr_INCLUDE_DIRS "") +set(unarr_LIBRARIES "") + +if(NOT TARGET unarr::unarr AND APPLE) + set(_unarr_include_dir "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx") + set(_unarr_library "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx/libunarr.a") + if(EXISTS "${_unarr_include_dir}/unarr.h" AND EXISTS "${_unarr_library}") + yacreader_add_imported_library(unarr::unarr + TYPE STATIC + LOCATION "${_unarr_library}" + INCLUDE_DIR "${_unarr_include_dir}" + LINK_LIBRARIES "z;bz2") + set(unarr_PROVIDER "bundled dependencies (macOS)") + set(unarr_INCLUDE_DIRS "${_unarr_include_dir}") + endif() +endif() + +if(NOT TARGET unarr::unarr AND WIN32) + yacreader_get_windows_arch_subdir(_unarr_arch) + set(_unarr_include_dir "${CMAKE_SOURCE_DIR}/dependencies/unarr/win") + set(_unarr_implib "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/${_unarr_arch}/unarr.lib") + set(_unarr_dll "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/${_unarr_arch}/unarr.dll") + if(EXISTS "${_unarr_include_dir}/unarr.h" AND EXISTS "${_unarr_implib}" AND EXISTS "${_unarr_dll}") + yacreader_add_imported_library(unarr::unarr + TYPE SHARED + LOCATION "${_unarr_dll}" + IMPORTED_IMPLIB "${_unarr_implib}" + INCLUDE_DIR "${_unarr_include_dir}" + COMPILE_DEFINITIONS "UNARR_IS_SHARED_LIBRARY") + set(unarr_PROVIDER "bundled dependencies (${_unarr_arch}, Windows)") + set(unarr_INCLUDE_DIRS "${_unarr_include_dir}") + endif() +endif() + +if(NOT TARGET unarr::unarr) + find_package(PkgConfig QUIET) + if(PkgConfig_FOUND) + pkg_check_modules(UNARR QUIET IMPORTED_TARGET libunarr) + if(TARGET PkgConfig::UNARR) + yacreader_add_imported_library(unarr::unarr + TYPE INTERFACE + LINK_LIBRARIES "PkgConfig::UNARR") + set(unarr_PROVIDER "pkg-config") + set(unarr_INCLUDE_DIRS "${UNARR_INCLUDE_DIRS}") + endif() + endif() +endif() + +if(NOT TARGET unarr::unarr) + find_path(UNARR_INCLUDE_DIR NAMES unarr.h) + find_library(UNARR_LIBRARY NAMES unarr libunarr) + if(UNARR_INCLUDE_DIR AND UNARR_LIBRARY) + yacreader_add_imported_library(unarr::unarr + TYPE UNKNOWN + LOCATION "${UNARR_LIBRARY}" + INCLUDE_DIR "${UNARR_INCLUDE_DIR}") + set(unarr_PROVIDER "CMake search") + set(unarr_INCLUDE_DIRS "${UNARR_INCLUDE_DIR}") + endif() +endif() + +if(TARGET unarr::unarr) + set(unarr_TARGET unarr::unarr) + set(unarr_LIBRARIES unarr::unarr) +endif() + +find_package_handle_standard_args(unarr REQUIRED_VARS unarr_TARGET) + +mark_as_advanced(UNARR_INCLUDE_DIR UNARR_LIBRARY) diff --git a/cmake/PdfBackend.cmake b/cmake/PdfBackend.cmake index 2a0a3aa32..dc7f48b54 100644 --- a/cmake/PdfBackend.cmake +++ b/cmake/PdfBackend.cmake @@ -2,8 +2,6 @@ # Creates an INTERFACE target 'pdf_backend_iface' that propagates # compile definitions and link libraries based on PDF_BACKEND. -include(BackendHelpers) - add_library(pdf_backend_iface INTERFACE) if(PDF_BACKEND STREQUAL "no_pdf") @@ -14,65 +12,21 @@ elseif(PDF_BACKEND STREQUAL "pdfium") message(STATUS "PDF backend: pdfium") target_compile_definitions(pdf_backend_iface INTERFACE USE_PDFIUM) - if(WIN32) - yacreader_get_windows_arch_subdir(_pdfium_arch) - set(_pdfium_include_dir "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/public") - set(_pdfium_implib "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/${_pdfium_arch}/pdfium.lib") - set(_pdfium_dll "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/${_pdfium_arch}/pdfium.dll") - if(NOT EXISTS "${_pdfium_include_dir}/fpdfview.h" - OR NOT EXISTS "${_pdfium_implib}" - OR NOT EXISTS "${_pdfium_dll}") - message(FATAL_ERROR - "Could not find bundled pdfium for ${_pdfium_arch}. " - "Expected files under dependencies/pdfium/win/${_pdfium_arch}.") - endif() - - message(STATUS " Using bundled pdfium (${_pdfium_arch}, Windows)") - yacreader_add_imported_library(YACReader::pdfium - TYPE SHARED - LOCATION "${_pdfium_dll}" - IMPORTED_IMPLIB "${_pdfium_implib}" - INCLUDE_DIR "${_pdfium_include_dir}") - target_link_libraries(pdf_backend_iface INTERFACE YACReader::pdfium) - elseif(APPLE) - set(_pdfium_include_dir "${CMAKE_SOURCE_DIR}/dependencies/pdfium/macx/include") - set(_pdfium_library "${CMAKE_SOURCE_DIR}/dependencies/pdfium/macx/bin/libpdfium.a") - if(NOT EXISTS "${_pdfium_include_dir}/fpdfview.h" OR NOT EXISTS "${_pdfium_library}") - message(FATAL_ERROR "Could not find bundled pdfium under dependencies/pdfium/macx.") - endif() - - message(STATUS " Using bundled pdfium (macOS)") - yacreader_add_imported_library(YACReader::pdfium - TYPE STATIC - LOCATION "${_pdfium_library}" - INCLUDE_DIR "${_pdfium_include_dir}") - target_link_libraries(pdf_backend_iface INTERFACE YACReader::pdfium) + find_package(pdfium QUIET CONFIG) + if(TARGET pdfium::pdfium) + message(STATUS " Found pdfium via CMake config") else() - # Linux: try pkg-config first, then a normal CMake search. - find_package(PkgConfig QUIET) - if(PkgConfig_FOUND) - pkg_check_modules(PDFIUM QUIET IMPORTED_TARGET libpdfium) + find_package(pdfium QUIET MODULE) + if(NOT TARGET pdfium::pdfium) + message(FATAL_ERROR "Could not find libpdfium. Install it or use a different PDF_BACKEND.") endif() - - if(TARGET PkgConfig::PDFIUM) - message(STATUS " Found pdfium via pkg-config") - target_link_libraries(pdf_backend_iface INTERFACE PkgConfig::PDFIUM) - else() - find_path(PDFIUM_INCLUDE_DIR NAMES fpdfview.h PATH_SUFFIXES pdfium) - find_library(PDFIUM_LIBRARY NAMES pdfium libpdfium) - if(PDFIUM_INCLUDE_DIR AND PDFIUM_LIBRARY) - message(STATUS " Found pdfium via CMake search") - yacreader_add_imported_library(YACReader::pdfium - TYPE UNKNOWN - LOCATION "${PDFIUM_LIBRARY}" - INCLUDE_DIR "${PDFIUM_INCLUDE_DIR}") - target_link_libraries(pdf_backend_iface INTERFACE YACReader::pdfium) - else() - message(FATAL_ERROR "Could not find libpdfium. Install it or use a different PDF_BACKEND.") - endif() + if(pdfium_PROVIDER) + message(STATUS " Found pdfium via ${pdfium_PROVIDER}") endif() endif() + target_link_libraries(pdf_backend_iface INTERFACE pdfium::pdfium) + elseif(PDF_BACKEND STREQUAL "poppler") message(STATUS "PDF backend: poppler") target_compile_definitions(pdf_backend_iface INTERFACE USE_POPPLER) @@ -85,38 +39,24 @@ elseif(PDF_BACKEND STREQUAL "poppler") # On Windows: vcpkg install poppler[qt6]:x64-windows, then pass the vcpkg toolchain file find_package(Poppler QUIET CONFIG) if(TARGET Poppler::Qt6) - message(STATUS " Found poppler-qt6 via cmake config") - target_link_libraries(pdf_backend_iface INTERFACE Poppler::Qt6) + message(STATUS " Found poppler-qt6 via CMake config") else() - # Fall back to pkg-config (standard on Linux; on Windows requires vcpkg pkgconf) - find_package(PkgConfig QUIET) - if(PkgConfig_FOUND) - pkg_check_modules(POPPLER QUIET IMPORTED_TARGET poppler-qt6) - endif() - - if(TARGET PkgConfig::POPPLER) - message(STATUS " Found poppler-qt6 via pkg-config") - target_link_libraries(pdf_backend_iface INTERFACE PkgConfig::POPPLER) + find_package(PopplerQt6 QUIET MODULE) + if(TARGET Poppler::Qt6) + if(PopplerQt6_PROVIDER) + message(STATUS " Found poppler-qt6 via ${PopplerQt6_PROVIDER}") + endif() elseif(MSVC) message(FATAL_ERROR "Could not find poppler-qt6. " "Install via vcpkg: vcpkg install poppler[qt6]:x64-windows " "then configure cmake with the vcpkg toolchain file.") else() - find_path(POPPLER_QT6_INCLUDE_DIR NAMES poppler-qt6.h PATH_SUFFIXES poppler/qt6) - find_library(POPPLER_QT6_LIBRARY NAMES poppler-qt6) - if(POPPLER_QT6_INCLUDE_DIR AND POPPLER_QT6_LIBRARY) - message(STATUS " Found poppler-qt6 via CMake search") - yacreader_add_imported_library(YACReader::poppler_qt6 - TYPE UNKNOWN - LOCATION "${POPPLER_QT6_LIBRARY}" - INCLUDE_DIR "${POPPLER_QT6_INCLUDE_DIR}") - target_link_libraries(pdf_backend_iface INTERFACE YACReader::poppler_qt6) - else() - message(FATAL_ERROR "Could not find poppler-qt6. Install libpoppler-qt6-dev or use a different PDF_BACKEND.") - endif() + message(FATAL_ERROR "Could not find poppler-qt6. Install libpoppler-qt6-dev or use a different PDF_BACKEND.") endif() endif() + target_link_libraries(pdf_backend_iface INTERFACE Poppler::Qt6) + elseif(PDF_BACKEND STREQUAL "pdfkit") message(STATUS "PDF backend: pdfkit (macOS)") if(NOT APPLE) diff --git a/compressed_archive/CMakeLists.txt b/compressed_archive/CMakeLists.txt index 948b766ca..928fb622f 100644 --- a/compressed_archive/CMakeLists.txt +++ b/compressed_archive/CMakeLists.txt @@ -1,8 +1,6 @@ # Comic archive decompression backend (cbx_backend) # Switched on DECOMPRESSION_BACKEND: unarr | 7zip | libarchive -include(BackendHelpers) - add_library(cbx_backend STATIC) if(DECOMPRESSION_BACKEND STREQUAL "unarr") @@ -16,77 +14,23 @@ if(DECOMPRESSION_BACKEND STREQUAL "unarr") target_include_directories(cbx_backend PUBLIC unarr) target_compile_definitions(cbx_backend PUBLIC use_unarr) - # Try CMake config first, then pkg-config, then bundled/system libraries. - set(_unarr_target "") - find_package(unarr QUIET CONFIG) if(TARGET unarr::unarr) message(STATUS " Found unarr via CMake config") - set(_unarr_target unarr::unarr) - endif() - - if(NOT _unarr_target AND APPLE) - set(_unarr_include_dir "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx") - set(_unarr_library "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx/libunarr.a") - if(EXISTS "${_unarr_include_dir}/unarr.h" AND EXISTS "${_unarr_library}") - message(STATUS " Using bundled unarr (macOS)") - yacreader_add_imported_library(YACReader::unarr - TYPE STATIC - LOCATION "${_unarr_library}" - INCLUDE_DIR "${_unarr_include_dir}" - LINK_LIBRARIES "z;bz2") - set(_unarr_target YACReader::unarr) - endif() - endif() - - if(NOT _unarr_target AND WIN32) - yacreader_get_windows_arch_subdir(_unarr_arch) - set(_unarr_include_dir "${CMAKE_SOURCE_DIR}/dependencies/unarr/win") - set(_unarr_implib "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/${_unarr_arch}/unarr.lib") - set(_unarr_dll "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/${_unarr_arch}/unarr.dll") - if(EXISTS "${_unarr_include_dir}/unarr.h" AND EXISTS "${_unarr_implib}" AND EXISTS "${_unarr_dll}") - message(STATUS " Using bundled unarr (${_unarr_arch}, Windows)") - yacreader_add_imported_library(YACReader::unarr - TYPE SHARED - LOCATION "${_unarr_dll}" - IMPORTED_IMPLIB "${_unarr_implib}" - INCLUDE_DIR "${_unarr_include_dir}") - set(_unarr_target YACReader::unarr) - target_compile_definitions(cbx_backend PRIVATE UNARR_IS_SHARED_LIBRARY) - endif() - endif() - - if(NOT _unarr_target) - find_package(PkgConfig QUIET) - endif() - - if(NOT _unarr_target AND PkgConfig_FOUND) - pkg_check_modules(UNARR QUIET IMPORTED_TARGET libunarr) - if(TARGET PkgConfig::UNARR) - message(STATUS " Found unarr via pkg-config") - set(_unarr_target PkgConfig::UNARR) - endif() + else() + find_package(unarr QUIET MODULE) endif() - if(NOT _unarr_target) - find_path(UNARR_INCLUDE_DIR NAMES unarr.h) - find_library(UNARR_LIBRARY NAMES unarr libunarr) - if(UNARR_INCLUDE_DIR AND UNARR_LIBRARY) - message(STATUS " Found unarr via CMake search") - yacreader_add_imported_library(YACReader::unarr - TYPE UNKNOWN - LOCATION "${UNARR_LIBRARY}" - INCLUDE_DIR "${UNARR_INCLUDE_DIR}") - set(_unarr_target YACReader::unarr) - endif() - endif() - - if(NOT _unarr_target) + if(NOT TARGET unarr::unarr) message(FATAL_ERROR "Could not find unarr. Install libunarr or use a different DECOMPRESSION_BACKEND.") endif() - target_link_libraries(cbx_backend PRIVATE ${_unarr_target}) + if(unarr_PROVIDER) + message(STATUS " Found unarr via ${unarr_PROVIDER}") + endif() + + target_link_libraries(cbx_backend PRIVATE unarr::unarr) elseif(DECOMPRESSION_BACKEND STREQUAL "7zip") message(STATUS "Decompression backend: 7zip (in-tree)") From 4376a898764000f7785e57a9d4c904f27fc903c9 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Sun, 29 Mar 2026 23:28:47 +0200 Subject: [PATCH 172/187] Better linux install handling --- CMakeLists.txt | 23 ----------------------- YACReader/CMakeLists.txt | 10 ++++++++++ YACReaderLibrary/CMakeLists.txt | 12 +++++++++++- YACReaderLibraryServer/CMakeLists.txt | 4 ++-- 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24048b26e..4be52589c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,29 +187,6 @@ if(BUILD_TESTS AND NOT BUILD_SERVER_STANDALONE) add_subdirectory(tests) endif() -# --- Linux top-level install rules --- -if(UNIX AND NOT APPLE) - # Man pages - if(EXISTS "${CMAKE_SOURCE_DIR}/YACReader.1") - install(FILES YACReader.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) - endif() - if(EXISTS "${CMAKE_SOURCE_DIR}/YACReaderLibrary.1") - install(FILES YACReaderLibrary.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) - endif() - - # Desktop files - if(EXISTS "${CMAKE_SOURCE_DIR}/YACReader.desktop") - install(FILES YACReader.desktop YACReaderLibrary.desktop - DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) - endif() - - # Icons - if(EXISTS "${CMAKE_SOURCE_DIR}/YACReader.svg") - install(FILES YACReader.svg YACReaderLibrary.svg - DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps) - endif() -endif() - # Summary message(STATUS "") message(STATUS "YACReader ${PROJECT_VERSION} build configuration:") diff --git a/YACReader/CMakeLists.txt b/YACReader/CMakeLists.txt index 02f3cca52..dd20fed22 100644 --- a/YACReader/CMakeLists.txt +++ b/YACReader/CMakeLists.txt @@ -129,5 +129,15 @@ endif() if(UNIX AND NOT APPLE) target_compile_definitions(YACReader PRIVATE "DATADIR=\"${CMAKE_INSTALL_FULL_DATADIR}\"") + install(TARGETS YACReader RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(FILES + "${PROJECT_SOURCE_DIR}/YACReader.1" + DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + install(FILES + "${PROJECT_SOURCE_DIR}/YACReader.desktop" + DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) + install(FILES + "${PROJECT_SOURCE_DIR}/YACReader.svg" + DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps) endif() diff --git a/YACReaderLibrary/CMakeLists.txt b/YACReaderLibrary/CMakeLists.txt index 5fff54c74..97c87db38 100644 --- a/YACReaderLibrary/CMakeLists.txt +++ b/YACReaderLibrary/CMakeLists.txt @@ -303,11 +303,21 @@ if(UNIX AND NOT APPLE) "LIBDIR=\"${CMAKE_INSTALL_FULL_LIBDIR}\"" "DATADIR=\"${CMAKE_INSTALL_FULL_DATADIR}\"" "BINDIR=\"${CMAKE_INSTALL_FULL_BINDIR}\"") + install(TARGETS YACReaderLibrary RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(FILES + "${PROJECT_SOURCE_DIR}/YACReaderLibrary.1" + DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + install(FILES + "${PROJECT_SOURCE_DIR}/YACReaderLibrary.desktop" + DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) + install(FILES + "${PROJECT_SOURCE_DIR}/YACReaderLibrary.svg" + DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps) # Server web files (for bundled server mode) if(NOT BUILD_SERVER_STANDALONE) - install(DIRECTORY ${CMAKE_SOURCE_DIR}/release/server + install(DIRECTORY "${PROJECT_SOURCE_DIR}/release/server" DESTINATION ${CMAKE_INSTALL_DATADIR}/yacreader) endif() endif() diff --git a/YACReaderLibraryServer/CMakeLists.txt b/YACReaderLibraryServer/CMakeLists.txt index f4a751692..16df0ac9e 100644 --- a/YACReaderLibraryServer/CMakeLists.txt +++ b/YACReaderLibraryServer/CMakeLists.txt @@ -85,11 +85,11 @@ if(UNIX AND NOT APPLE) # Standalone server: install server web files alongside the binary if(BUILD_SERVER_STANDALONE) - install(DIRECTORY ${CMAKE_SOURCE_DIR}/release/server + install(DIRECTORY "${PROJECT_SOURCE_DIR}/release/server" DESTINATION ${CMAKE_INSTALL_DATADIR}/yacreader) endif() # systemd service - install(FILES yacreaderlibraryserver.service + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/yacreaderlibraryserver.service" DESTINATION ${CMAKE_INSTALL_LIBDIR}/systemd/user) endif() From e40dd9b22a59ebf2b40dd3a2e8d3593150a91df8 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 08:32:20 +0200 Subject: [PATCH 173/187] Clean up CompilerOptions.cmake --- CMakeLists.txt | 2 +- cmake/CompilerOptions.cmake | 17 ++++------------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4be52589c..e000cfe6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ endif() include(GNUInstallDirs) list(PREPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") -# Compiler options (MSVC flags, NOMINMAX, etc.) +# Compiler options (MSVC flags) include(cmake/CompilerOptions.cmake) # --- Build options --- diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake index 2b1378dc7..2ef38eb32 100644 --- a/cmake/CompilerOptions.cmake +++ b/cmake/CompilerOptions.cmake @@ -1,20 +1,11 @@ # Compiler options for YACReader -# Mirrors config.pri: C++20, NOMINMAX, MSVC conformance flags - -add_compile_definitions(NOMINMAX) if(MSVC) + # Prevent windows.h from defining min/max macros that conflict with + # std::min, std::max, std::numeric_limits::max(), etc. + add_compile_definitions(NOMINMAX) + # /Zc:__cplusplus: report correct __cplusplus value # /permissive-: strict standard conformance add_compile_options(/Zc:__cplusplus /permissive-) - - # Release optimizations (mirrors qmake QMAKE_CXXFLAGS_RELEASE) - string(APPEND CMAKE_CXX_FLAGS_RELEASE " /DNDEBUG") -elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") - string(APPEND CMAKE_CXX_FLAGS_RELEASE " -DNDEBUG") endif() - -# Qt deprecation warnings -add_compile_definitions( - QT_DEPRECATED_WARNINGS -) From be3f140aeadd0b499cec4f9f0778d40888c7cd50 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 08:44:58 +0200 Subject: [PATCH 174/187] Remove QT_DISABLE_DEPRECATED_BEFORE from PdfBackend.cmake --- cmake/PdfBackend.cmake | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cmake/PdfBackend.cmake b/cmake/PdfBackend.cmake index dc7f48b54..e27775945 100644 --- a/cmake/PdfBackend.cmake +++ b/cmake/PdfBackend.cmake @@ -67,11 +67,3 @@ elseif(PDF_BACKEND STREQUAL "pdfkit") else() message(FATAL_ERROR "Unknown PDF_BACKEND: '${PDF_BACKEND}'. Use: pdfium, poppler, pdfkit, or no_pdf") endif() - -# Set QT_DISABLE_DEPRECATED_BEFORE based on backend -# poppler requires older deprecated API -if(PDF_BACKEND STREQUAL "poppler") - target_compile_definitions(pdf_backend_iface INTERFACE QT_DISABLE_DEPRECATED_BEFORE=0x050900) -else() - target_compile_definitions(pdf_backend_iface INTERFACE QT_DISABLE_DEPRECATED_BEFORE=0x050F00) -endif() From 12a5949b16b6e3c4bc342f8ecaac2b9765c2ff9c Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 08:51:00 +0200 Subject: [PATCH 175/187] Use QT_DISABLE_DEPRECATED_UP_TO globally Set to 6.4 until we can bump up the minimum qt version in the server project. --- cmake/CompilerOptions.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake index 2ef38eb32..c90fa6f8d 100644 --- a/cmake/CompilerOptions.cmake +++ b/cmake/CompilerOptions.cmake @@ -9,3 +9,5 @@ if(MSVC) # /permissive-: strict standard conformance add_compile_options(/Zc:__cplusplus /permissive-) endif() + +add_compile_definitions(QT_DISABLE_DEPRECATED_UP_TO=0x060400) From e6cbfa634bfd6194c772964754882537d995f2ab Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 15:48:02 +0200 Subject: [PATCH 176/187] Fix all compilation issues after enabling QT_DISABLE_DEPRECATED_UP_TO --- YACReader/bookmarks_dialog.cpp | 4 +- YACReader/main.cpp | 6 -- YACReader/main_window_viewer.cpp | 4 +- YACReaderLibrary/comic_files_manager.cpp | 9 ++- ...comic_vine_all_volume_comics_retriever.cpp | 6 +- .../comic_vine/comic_vine_dialog.cpp | 12 +-- .../comic_vine/comic_vine_json_parser.cpp | 4 +- .../comic_vine/model/volume_comics_model.cpp | 2 +- .../comic_vine/sort_volume_comics.cpp | 4 +- YACReaderLibrary/comics_view.cpp | 6 +- .../current_comic_view_helper.cpp | 4 +- YACReaderLibrary/db/comic_model.cpp | 78 +++++++++++-------- YACReaderLibrary/db/data_base_management.cpp | 9 +-- YACReaderLibrary/db/folder_model.cpp | 10 +-- YACReaderLibrary/db/reading_list_model.cpp | 2 +- YACReaderLibrary/db_helper.cpp | 45 ++++++----- YACReaderLibrary/folder_content_view.cpp | 2 +- YACReaderLibrary/grid_comics_view.cpp | 2 +- YACReaderLibrary/import_widget.cpp | 4 +- YACReaderLibrary/info_comics_view.cpp | 2 +- YACReaderLibrary/library_creator.cpp | 6 +- YACReaderLibrary/library_window.cpp | 20 +++-- YACReaderLibrary/main.cpp | 6 -- .../controllers/v2/librariescontroller_v2.cpp | 2 +- .../controllers/v2/synccontroller_v2.cpp | 14 ++-- YACReaderLibrary/server/static.cpp | 4 +- YACReaderLibrary/yacreader_folders_view.cpp | 8 +- YACReaderLibrary/yacreader_libraries.cpp | 29 +++---- YACReaderLibrary/yacreader_libraries.h | 24 +++--- .../yacreader_reading_lists_view.cpp | 2 +- YACReaderLibraryServer/CMakeLists.txt | 4 - YACReaderLibraryServer/images.qrc | 6 -- YACReaderLibraryServer/libraries_updater.cpp | 4 +- common/bookmarks.cpp | 4 +- common/comic.cpp | 21 ++--- common/rhi/yacreader_comic_flow_rhi.cpp | 4 +- compressed_archive/compressed_archive.cpp | 4 +- custom_widgets/yacreader_macosx_toolbar.mm | 2 +- custom_widgets/yacreader_table_view.cpp | 2 +- custom_widgets/yacreader_treeview.cpp | 5 +- shortcuts_management/shortcuts_manager.cpp | 4 +- tests/compressed_archive_test/main.cpp | 5 +- .../unittest/QtTestUtil/TestRegistry.cpp | 7 +- third_party/QsLog/unittest/TestLog.h | 2 +- .../httpserver/httpconnectionhandlerpool.cpp | 7 +- .../QtWebApp/httpserver/httpcookie.cpp | 3 +- .../QtWebApp/httpserver/httprequest.cpp | 9 ++- .../QtWebApp/httpserver/httpresponse.cpp | 5 +- .../templateengine/templateloader.cpp | 5 +- 49 files changed, 228 insertions(+), 205 deletions(-) delete mode 100644 YACReaderLibraryServer/images.qrc diff --git a/YACReader/bookmarks_dialog.cpp b/YACReader/bookmarks_dialog.cpp index 1d3153945..6348d7016 100644 --- a/YACReader/bookmarks_dialog.cpp +++ b/YACReader/bookmarks_dialog.cpp @@ -9,6 +9,8 @@ #include #include +#include + BookmarksDialog::BookmarksDialog(QWidget *parent) : QDialog(parent) { @@ -28,7 +30,7 @@ BookmarksDialog::BookmarksDialog(QWidget *parent) QString labelsStyle = "QLabel {color:white;}"; - foreach (QLabel *label, pages) { + for (QLabel *const label : std::as_const(pages)) { label->setStyleSheet(labelsStyle); } diff --git a/YACReader/main.cpp b/YACReader/main.cpp index c4485b6c6..85437d982 100644 --- a/YACReader/main.cpp +++ b/YACReader/main.cpp @@ -92,12 +92,6 @@ int main(int argc, char *argv[]) { qInstallMessageHandler(messageHandler); - static const char ENV_VAR_QT_DEVICE_PIXEL_RATIO[] = "QT_DEVICE_PIXEL_RATIO"; - if (!qEnvironmentVariableIsSet(ENV_VAR_QT_DEVICE_PIXEL_RATIO) && !qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR") && !qEnvironmentVariableIsSet("QT_SCALE_FACTOR") && !qEnvironmentVariableIsSet("QT_SCREEN_SCALE_FACTORS")) { - QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - } - - QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); QImageReader::setAllocationLimit(0); diff --git a/YACReader/main_window_viewer.cpp b/YACReader/main_window_viewer.cpp index 80a513c57..6070cd3c2 100644 --- a/YACReader/main_window_viewer.cpp +++ b/YACReader/main_window_viewer.cpp @@ -984,7 +984,7 @@ void MainWindowViewer::openFolderFromPath(QString pathDir, QString atFileName) std::sort(list.begin(), list.end(), naturalSortLessThanCI); int i = 0; - foreach (QString path, list) { + for (const QString &path : std::as_const(list)) { if (path.endsWith(atFileName)) break; i++; @@ -1554,7 +1554,7 @@ void MainWindowViewer::getSiblingComics(QString path, QString currentComic) txtS << path << '\n'; txtS << currentComic << '\n'; txtS << "Comic list count : " + list.count() << '\n'; - foreach(QString s, list){ + for (const QString &s : std::as_const(list)) { txtS << s << '\n'; } f.close(); diff --git a/YACReaderLibrary/comic_files_manager.cpp b/YACReaderLibrary/comic_files_manager.cpp index 517c4f121..9512def19 100644 --- a/YACReaderLibrary/comic_files_manager.cpp +++ b/YACReaderLibrary/comic_files_manager.cpp @@ -33,7 +33,7 @@ QList> ComicFilesManager::getDroppedFiles(const QList> dropedFiles; QString currentPath; - foreach (QUrl url, urls) { + for (const auto &url : urls) { currentPath = url.toLocalFile(); if (currentPath.endsWith('/')) currentPath = currentPath.remove(currentPath.length() - 1, 1); // QTBUG-35896 QUrl.toLocalFile inconsistency. @@ -44,7 +44,8 @@ QList> ComicFilesManager::getDroppedFiles(const QList source; - foreach (source, comics) { + const auto &comicSources = comics; + for (const auto &source : comicSources) { if (canceled) { if (successProcesingFiles) diff --git a/YACReaderLibrary/comic_vine/comic_vine_all_volume_comics_retriever.cpp b/YACReaderLibrary/comic_vine/comic_vine_all_volume_comics_retriever.cpp index 58afc5a47..6e5092d38 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_all_volume_comics_retriever.cpp +++ b/YACReaderLibrary/comic_vine/comic_vine_all_volume_comics_retriever.cpp @@ -54,7 +54,7 @@ QString ComicVineAllVolumeComicsRetriever::consolidateJSON() QJsonObject consolidatedJSON; QJsonArray comicsInfo; - foreach (QByteArray json, jsonResponses) { + for (const auto &json : jsonResponses) { QJsonDocument doc = QJsonDocument::fromJson(json); if (doc.isNull() || !doc.isObject() || doc.isEmpty()) { @@ -72,8 +72,8 @@ QString ComicVineAllVolumeComicsRetriever::consolidateJSON() continue; } - QJsonArray resultsArray = results.toArray(); - foreach (const QJsonValue &v, resultsArray) + const auto resultsArray = results.toArray(); + for (const auto &v : resultsArray) comicsInfo.append(v); } } diff --git a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp index 15effb3a2..ff4910e32 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp +++ b/YACReaderLibrary/comic_vine/comic_vine_dialog.cpp @@ -442,23 +442,23 @@ void ComicVineDialog::queryTimeOut() void ComicVineDialog::getComicsInfo(QList> matchingInfo, const SelectedVolumeInfo &volumeInfo) { - QPair p; QList comics; - foreach (p, matchingInfo) { + const auto &matches = matchingInfo; + for (auto match : matches) { auto comicVineClient = new ComicVineClient; // connect(comicVineClient,SIGNAL(searchResult(QString)),this,SLOT(debugClientResults(QString))); // connect(comicVineClient,SIGNAL(timeOut()),this,SLOT(queryTimeOut())); // connect(comicVineClient,SIGNAL(finished()),comicVineClient,SLOT(deleteLater())); bool error; bool timeout; - QByteArray result = comicVineClient->getComicDetail(p.second, error, timeout); // TODO check timeOut or Connection error + QByteArray result = comicVineClient->getComicDetail(match.second, error, timeout); // TODO check timeOut or Connection error if (error || timeout) continue; // TODO - ComicDB comic = YACReader::parseCVJSONComicInfo(p.first, result, volumeInfo); // TODO check result error - comic.info.comicVineID = p.second; + ComicDB comic = YACReader::parseCVJSONComicInfo(match.first, result, volumeInfo); // TODO check result error + comic.info.comicVineID = match.second; comics.push_back(comic); - setLoadingMessage(tr("Retrieving tags for : %1").arg(p.first.getFileName())); + setLoadingMessage(tr("Retrieving tags for : %1").arg(match.first.getFileName())); } DBHelper::updateComicsInfo(comics, databasePath); diff --git a/YACReaderLibrary/comic_vine/comic_vine_json_parser.cpp b/YACReaderLibrary/comic_vine/comic_vine_json_parser.cpp index 90ac8244a..1b0c93462 100644 --- a/YACReaderLibrary/comic_vine/comic_vine_json_parser.cpp +++ b/YACReaderLibrary/comic_vine/comic_vine_json_parser.cpp @@ -142,8 +142,8 @@ QMultiMap getAuthors(const QVariant &json_authors) QString authorName = resultsValue.value("name").toString(); - QStringList roles = resultsValue.value("role").toString().split(","); - foreach (QString role, roles) { + const QStringList roles = resultsValue.value("role").toString().split(","); + for (const auto &role : roles) { if (role.trimmed() == "writer") authors.insert("writer", authorName); else if (role.trimmed() == "inker") diff --git a/YACReaderLibrary/comic_vine/model/volume_comics_model.cpp b/YACReaderLibrary/comic_vine/model/volume_comics_model.cpp index d88700a92..579b6a642 100644 --- a/YACReaderLibrary/comic_vine/model/volume_comics_model.cpp +++ b/YACReaderLibrary/comic_vine/model/volume_comics_model.cpp @@ -47,7 +47,7 @@ void VolumeComicsModel::load(const QString &json) /*void VolumeComicsModel::load(const QStringList &jsonList) { - foreach (QString json, jsonList) { + for (const auto &json : jsonList) { load(json); } }*/ diff --git a/YACReaderLibrary/comic_vine/sort_volume_comics.cpp b/YACReaderLibrary/comic_vine/sort_volume_comics.cpp index 16cf75c65..c6823bd75 100644 --- a/YACReaderLibrary/comic_vine/sort_volume_comics.cpp +++ b/YACReaderLibrary/comic_vine/sort_volume_comics.cpp @@ -247,13 +247,13 @@ void SortVolumeComics::showRemovedComicsSelector() QList> SortVolumeComics::getMatchingInfo() { - QList comicList = localComicsModel->getData(); + const auto comicList = localComicsModel->getData(); QList> l; int index = 0; QString id; - foreach (ComicDB c, comicList) { + for (const auto &c : comicList) { id = volumeComicsModel->getComicId(index); if (!c.getFileName().isEmpty() && !id.isEmpty()) // there is a valid comic, and valid comic ID { diff --git a/YACReaderLibrary/comics_view.cpp b/YACReaderLibrary/comics_view.cpp index c00d0aa4f..149b2057f 100644 --- a/YACReaderLibrary/comics_view.cpp +++ b/YACReaderLibrary/comics_view.cpp @@ -81,12 +81,10 @@ void ComicsView::dragEnterEvent(QDragEnterEvent *event) event->acceptProposedAction(); else { QLOG_TRACE() << "dragEnterEvent"; - QList urlList; - if (event->mimeData()->hasUrls() && event->dropAction() == Qt::CopyAction) { - urlList = event->mimeData()->urls(); + const auto urlList = event->mimeData()->urls(); QString currentPath; - foreach (QUrl url, urlList) { + for (const auto &url : urlList) { // comics or folders are accepted, folders' content is validate in dropEvent (avoid any lag before droping) currentPath = url.toLocalFile(); if (Comic::fileIsComic(currentPath) || QFileInfo(currentPath).isDir()) { diff --git a/YACReaderLibrary/current_comic_view_helper.cpp b/YACReaderLibrary/current_comic_view_helper.cpp index 988190787..025502945 100644 --- a/YACReaderLibrary/current_comic_view_helper.cpp +++ b/YACReaderLibrary/current_comic_view_helper.cpp @@ -4,9 +4,9 @@ ComicDB currentComicFromModel(ComicModel *model, bool &found) { - auto comics = model->getAllComics(); + const auto comics = model->getAllComics(); - foreach (auto comic, comics) { + for (const auto &comic : comics) { if (comic.info.read == false) { found = true; return comic; diff --git a/YACReaderLibrary/db/comic_model.cpp b/YACReaderLibrary/db/comic_model.cpp index 01cf7039f..501d09520 100644 --- a/YACReaderLibrary/db/comic_model.cpp +++ b/YACReaderLibrary/db/comic_model.cpp @@ -74,17 +74,20 @@ bool ComicModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int if (!data->formats().contains(YACReader::YACReaderLibrarComiscSelectionMimeDataFormat)) return false; - QList comicIds = YACReader::mimeDataToComicsIds(data); + const QList comicIds = YACReader::mimeDataToComicsIds(data); QList currentIndexes; int i; - foreach (qulonglong id, comicIds) { - i = 0; - foreach (ComicItem *item, _data) { - if (item->data(Id) == id) { - currentIndexes << i; - break; + { + const auto ¤tData = _data; + for (const auto id : comicIds) { + i = 0; + for (auto *item : currentData) { + if (item->data(Id) == id) { + currentIndexes << i; + break; + } + i++; } - i++; } } @@ -102,26 +105,30 @@ bool ComicModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int QList newSorting; - i = 0; - foreach (ComicItem *item, _data) { - if (!currentIndexes.contains(i)) { - - if (item == destinationItem) { - foreach (int index, currentIndexes) { - resortedData << _data.at(index); - newSorting << index; + const auto ¤tIndexList = currentIndexes; + { + const auto ¤tData = _data; + i = 0; + for (auto *item : currentData) { + if (!currentIndexes.contains(i)) { + + if (item == destinationItem) { + for (const auto index : currentIndexList) { + resortedData << _data.at(index); + newSorting << index; + } } + + resortedData << item; + newSorting << i; } - resortedData << item; - newSorting << i; + i++; } - - i++; } if (destinationItem == 0) { - foreach (int index, currentIndexes) { + for (const auto index : currentIndexList) { resortedData << _data.at(index); newSorting << index; } @@ -134,9 +141,10 @@ bool ComicModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int if (tempRow < 0) tempRow = _data.count(); - foreach (qulonglong id, comicIds) { + for (const auto id : comicIds) { int i = 0; - foreach (ComicItem *item, _data) { + const auto dataSnapshot = _data; + for (auto *item : dataSnapshot) { if (item->data(Id) == id) { beginMoveRows(parent, i, i, parent, tempRow); @@ -162,7 +170,8 @@ bool ComicModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int // TODO fix selection QList allComicIds; - foreach (ComicItem *item, _data) { + const auto &allData = _data; + for (auto *item : allData) { allComicIds << item->data(Id).toULongLong(); } QString connectionName = ""; @@ -211,7 +220,7 @@ QMimeData *ComicModel::mimeData(const QModelIndexList &indexes) const // custom model data // application/yacreader-comics-ids + list of ids in a QByteArray QList ids; - foreach (QModelIndex index, indexes) { + for (const auto &index : indexes) { QLOG_DEBUG() << "dragging : " << index.data(IdRole).toULongLong(); ids << index.data(IdRole).toULongLong(); } @@ -605,7 +614,8 @@ QList ComicModel::createReadingListData(unsigned long long parentRe enableResorting = ids.length() == 1; // only resorting if no sublists exist - foreach (qulonglong id, ids) { + const auto &readingListIds = ids; + for (const auto id : readingListIds) { QSqlQuery selectQuery(db); selectQuery.prepare("SELECT " COMIC_MODEL_QUERY_FIELDS " " "FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) " @@ -996,10 +1006,11 @@ QList ComicModel::getComics(QList list) QVector ComicModel::setComicsRead(QList list, YACReaderComicReadStatus read) { QString connectionName = ""; + const auto &comicIndexes = list; { QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); db.transaction(); - foreach (QModelIndex mi, list) { + for (const auto &mi : comicIndexes) { if (read == YACReader::Read) { _data.value(mi.row())->setData(ComicModel::ReadColumn, QVariant(true)); bool found; @@ -1033,10 +1044,11 @@ QVector ComicModel::setComicsRead(QList l void ComicModel::setComicsType(QList list, FileType type) { QString connectionName = ""; + const auto &comicIndexes = list; { QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); db.transaction(); - foreach (QModelIndex mi, list) { + for (const auto &mi : comicIndexes) { bool found; ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db, found); c.info.type = QVariant::fromValue(type); @@ -1047,7 +1059,7 @@ void ComicModel::setComicsType(QList list, FileType type) } QSqlDatabase::removeDatabase(connectionName); - foreach (QModelIndex mi, list) { + for (const auto &mi : comicIndexes) { _data.value(mi.row())->setData(ComicModel::Type, QVariant::fromValue(type)); } @@ -1058,12 +1070,13 @@ qint64 ComicModel::asignNumbers(QList list, int startingNumber) { qint64 idFirst; QString connectionName = ""; + const auto &comicIndexes = list; { QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); db.transaction(); idFirst = _data.value(list[0].row())->data(ComicModel::Id).toULongLong(); int i = 0; - foreach (QModelIndex mi, list) { + for (const auto &mi : comicIndexes) { bool found; ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db, found); c.info.number = startingNumber + i; @@ -1097,7 +1110,7 @@ QList ComicModel::getIndexesFromIds(const QList &comicI { QList comicsIndexes; - foreach (qulonglong id, comicIds) + for (const auto id : comicIds) comicsIndexes << getIndexFromId(id); return comicsIndexes; @@ -1180,7 +1193,8 @@ void ComicModel::reload(const ComicDB &comic) { int row = 0; bool found = false; - foreach (ComicItem *item, _data) { + const auto ¤tData = _data; + for (auto *item : currentData) { if (item->data(ComicModel::Id).toULongLong() == comic.id) { found = true; item->setData(ComicModel::ReadColumn, comic.info.read); diff --git a/YACReaderLibrary/db/data_base_management.cpp b/YACReaderLibrary/db/data_base_management.cpp index 05d1cceb1..767da97b4 100644 --- a/YACReaderLibrary/db/data_base_management.cpp +++ b/YACReaderLibrary/db/data_base_management.cpp @@ -753,8 +753,7 @@ bool DataBaseManagement::importComicsInfo(QString source, QString dest) } destDB.commit(); - QString hash; - foreach (hash, hashes) { + for (const auto &hash : hashes) { QSqlQuery getComic(destDB); getComic.prepare("SELECT c.path,ci.coverPage FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) where ci.hash = :hash"); getComic.bindValue(":hash", hash); @@ -860,7 +859,7 @@ bool DataBaseManagement::addColumns(const QString &tableName, const QStringList QString sql = "ALTER TABLE %1 ADD COLUMN %2"; bool returnValue = true; - foreach (QString columnDef, columnDefs) { + for (const auto &columnDef : columnDefs) { QSqlQuery alterTable(db); alterTable.prepare(sql.arg(tableName).arg(columnDef)); // alterTableComicInfo.bindValue(":column_def",columnDef); @@ -925,10 +924,10 @@ int DataBaseManagement::compareVersions(const QString &v1, const QString v2) QList v1il; QList v2il; - foreach (QString s, v1l) + for (const auto &s : v1l) v1il.append(s.toInt()); - foreach (QString s, v2l) + for (const auto &s : v2l) v2il.append(s.toInt()); for (int i = 0; i < qMin(v1il.length(), v2il.length()); i++) { diff --git a/YACReaderLibrary/db/folder_model.cpp b/YACReaderLibrary/db/folder_model.cpp index de9b6b7a8..3048f60fd 100644 --- a/YACReaderLibrary/db/folder_model.cpp +++ b/YACReaderLibrary/db/folder_model.cpp @@ -196,7 +196,7 @@ void FolderModel::reload() takeUpdatedChildrenInfo(rootItem, QModelIndex(), newModelData.rootItem); // copy items from newModelData to this model that are not in this model - foreach (auto key, newModelData.items.keys()) { + for (const auto key : newModelData.items.keys()) { if (!items.contains(key)) { items[key] = (newModelData.items[key]); } @@ -221,7 +221,7 @@ void FolderModel::reload() items = newModelData.items; // copy items from newModelData to this model that are not in this model - foreach (auto key, newModelData.items.keys()) { + for (const auto key : newModelData.items.keys()) { if (!items.contains(key)) { items[key] = (newModelData.items[key]); } @@ -605,7 +605,7 @@ void FolderModel::updateFolderCompletedStatus(const QModelIndexList &list, bool { QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); db.transaction(); - foreach (QModelIndex mi, list) { + for (const auto &mi : list) { auto item = static_cast(mi.internalPointer()); item->setData(FolderModel::Completed, status); @@ -629,7 +629,7 @@ void FolderModel::updateFolderFinishedStatus(const QModelIndexList &list, bool s { QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); db.transaction(); - foreach (QModelIndex mi, list) { + for (const auto &mi : list) { auto item = static_cast(mi.internalPointer()); item->setData(FolderModel::Finished, status); @@ -653,7 +653,7 @@ void FolderModel::updateFolderType(const QModelIndexList &list, YACReader::FileT { QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); db.transaction(); - foreach (QModelIndex mi, list) { + for (const auto &mi : list) { auto item = static_cast(mi.internalPointer()); std::function setType; diff --git a/YACReaderLibrary/db/reading_list_model.cpp b/YACReaderLibrary/db/reading_list_model.cpp index d503042ab..b3391658c 100644 --- a/YACReaderLibrary/db/reading_list_model.cpp +++ b/YACReaderLibrary/db/reading_list_model.cpp @@ -711,7 +711,7 @@ void ReadingListModel::reorderingChildren(QList children) { QList childrenIds; int i = 0; - foreach (ReadingListItem *item, children) { + for (auto *item : children) { item->setOrdering(i++); childrenIds << item->getId(); } diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index a0c4d4735..9e8afe145 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -436,7 +436,8 @@ QList DBHelper::getReadingListFullContent(qulonglong libraryId, qulongl while (subfolders.next()) ids << subfolders.value(0).toULongLong(); - foreach (qulonglong id, ids) { + const auto &subfolderIds = ids; + for (const auto id : subfolderIds) { QSqlQuery selectQuery(db); QString params; @@ -546,7 +547,7 @@ void DBHelper::deleteComicsFromFavorites(const QList &comicsList, QSqlD QSqlQuery query(db); query.prepare("DELETE FROM comic_default_reading_list WHERE comic_id = :comic_id AND default_reading_list_id = 1"); - foreach (ComicDB comic, comicsList) { + for (const auto &comic : comicsList) { query.bindValue(":comic_id", comic.id); query.exec(); } @@ -578,7 +579,7 @@ void DBHelper::deleteComicsFromLabel(const QList &comicsList, qulonglon QSqlQuery query(db); query.prepare("DELETE FROM comic_label WHERE comic_id = :comic_id AND label_id = :label_id"); - foreach (ComicDB comic, comicsList) { + for (const auto &comic : comicsList) { query.bindValue(":comic_id", comic.id); query.bindValue(":label_id", labelId); query.exec(); @@ -598,7 +599,7 @@ void DBHelper::deleteComicsFromReadingList(const QList &comicsList, qul QSqlQuery query(db); query.prepare("DELETE FROM comic_reading_list WHERE comic_id = :comic_id AND reading_list_id = :reading_list_id"); - foreach (ComicDB comic, comicsList) { + for (const auto &comic : comicsList) { query.bindValue(":comic_id", comic.id); query.bindValue(":reading_list_id", readingListId); query.exec(); @@ -1086,7 +1087,8 @@ QMap> DBHelper::updateFromRemoteClient(const QMap> moreRecentComics; - foreach (qulonglong libraryId, comics.keys()) { + const auto libraryIds = comics.keys(); + for (const auto libraryId : libraryIds) { QList libraryMoreRecentComics; QString libraryPath = DBHelper::getLibraries().getPath(libraryId); @@ -1108,7 +1110,8 @@ QMap> DBHelper::updateFromRemoteClient(const QMap comicInfo.id contains comic id ComicDB comic = DBHelper::loadComic(comicInfo.id, db, found); @@ -1193,11 +1196,10 @@ QMap> DBHelper::updateFromRemoteClient(const QMap &comics) { - YACReaderLibraries libraries = DBHelper::getLibraries(); + const YACReaderLibraries libraries = DBHelper::getLibraries(); + const QStringList names = libraries.getNames(); - QStringList names = libraries.getNames(); - - foreach (QString name, names) { + for (const auto &name : names) { QString libraryPath = DBHelper::getLibraries().getPath(libraries.getId(name)); QString connectionName = ""; { @@ -1214,7 +1216,7 @@ void DBHelper::updateFromRemoteClientWithHash(const QList &comics) "rating = :rating" " WHERE id = :id "); - foreach (ComicInfo comicInfo, comics) { + for (const auto &comicInfo : comics) { ComicInfo info = loadComicInfo(comicInfo.hash, db); if (!info.existOnDb) { @@ -1285,7 +1287,8 @@ void DBHelper::reasignOrderToSublists(QList ids, QSqlDatabase &db) "WHERE id = :id"); db.transaction(); int order = 0; - foreach (qulonglong id, ids) { + const auto &readingListIds = ids; + for (const auto id : readingListIds) { updateOrdering.bindValue(":ordering", order++); updateOrdering.bindValue(":id", id); updateOrdering.exec(); @@ -1302,7 +1305,8 @@ void DBHelper::reasignOrderToComicsInFavorites(QList comicIds, QSqlD "WHERE comic_id = :comic_id AND default_reading_list_id = 1"); db.transaction(); int order = 0; - foreach (qulonglong id, comicIds) { + const auto &favoriteComicIds = comicIds; + for (const auto id : favoriteComicIds) { updateOrdering.bindValue(":ordering", order++); updateOrdering.bindValue(":comic_id", id); updateOrdering.exec(); @@ -1319,7 +1323,8 @@ void DBHelper::reasignOrderToComicsInLabel(qulonglong labelId, QList "WHERE comic_id = :comic_id AND label_id = :label_id"); db.transaction(); int order = 0; - foreach (qulonglong id, comicIds) { + const auto &labelComicIds = comicIds; + for (const auto id : labelComicIds) { updateOrdering.bindValue(":ordering", order++); updateOrdering.bindValue(":comic_id", id); updateOrdering.bindValue(":label_id", labelId); @@ -1337,7 +1342,8 @@ void DBHelper::reasignOrderToComicsInReadingList(qulonglong readingListId, QList "WHERE comic_id = :comic_id AND reading_list_id = :reading_list_id"); db.transaction(); int order = 0; - foreach (qulonglong id, comicIds) { + const auto &readingListComicIds = comicIds; + for (const auto id : readingListComicIds) { updateOrdering.bindValue(":ordering", order++); updateOrdering.bindValue(":comic_id", id); updateOrdering.bindValue(":reading_list_id", readingListId); @@ -1355,7 +1361,8 @@ void DBHelper::updateComicsInfo(QList &comics, const QString &databaseP QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath); db.open(); db.transaction(); - foreach (ComicDB comic, comics) { + const auto &comicsRef = comics; + for (auto comic : comicsRef) { DBHelper::update(&(comic.info), db); } db.commit(); @@ -1487,7 +1494,7 @@ void DBHelper::insertComicsInFavorites(const QList &comicsList, QSqlDat query.prepare("INSERT INTO comic_default_reading_list (default_reading_list_id, comic_id, ordering) " "VALUES (1, :comic_id, :ordering)"); - foreach (ComicDB comic, comicsList) { + for (const auto &comic : comicsList) { query.bindValue(":comic_id", comic.id); query.bindValue(":ordering", numComics++); query.exec(); @@ -1511,7 +1518,7 @@ void DBHelper::insertComicsInLabel(const QList &comicsList, qulonglong query.prepare("INSERT INTO comic_label (label_id, comic_id, ordering) " "VALUES (:label_id, :comic_id, :ordering)"); - foreach (ComicDB comic, comicsList) { + for (const auto &comic : comicsList) { query.bindValue(":label_id", labelId); query.bindValue(":comic_id", comic.id); query.bindValue(":ordering", numComics++); @@ -1536,7 +1543,7 @@ void DBHelper::insertComicsInReadingList(const QList &comicsList, qulon query.prepare("INSERT INTO comic_reading_list (reading_list_id, comic_id, ordering) " "VALUES (:reading_list_id, :comic_id, :ordering)"); - foreach (ComicDB comic, comicsList) { + for (const auto &comic : comicsList) { query.bindValue(":reading_list_id", readingListId); query.bindValue(":comic_id", comic.id); query.bindValue(":ordering", numComics++); diff --git a/YACReaderLibrary/folder_content_view.cpp b/YACReaderLibrary/folder_content_view.cpp index ec6a5d27b..b14e51871 100644 --- a/YACReaderLibrary/folder_content_view.cpp +++ b/YACReaderLibrary/folder_content_view.cpp @@ -236,7 +236,7 @@ bool FolderContentView::canDropUrls(const QList &urls, Qt::DropAction acti { if (action == Qt::CopyAction) { QString currentPath; - foreach (QUrl url, urls) { + for (const auto &url : urls) { // comics or folders are accepted, folders' content is validate in dropEvent (avoid any lag before droping) currentPath = url.toLocalFile(); if (Comic::fileIsComic(currentPath) || QFileInfo(currentPath).isDir()) diff --git a/YACReaderLibrary/grid_comics_view.cpp b/YACReaderLibrary/grid_comics_view.cpp index 804891e93..26fd4aaf4 100644 --- a/YACReaderLibrary/grid_comics_view.cpp +++ b/YACReaderLibrary/grid_comics_view.cpp @@ -452,7 +452,7 @@ bool GridComicsView::canDropUrls(const QList &urls, Qt::DropAction action) { if (action == Qt::CopyAction) { QString currentPath; - foreach (QUrl url, urls) { + for (const auto &url : urls) { // comics or folders are accepted, folders' content is validate in dropEvent (avoid any lag before droping) currentPath = url.toLocalFile(); if (Comic::fileIsComic(currentPath) || QFileInfo(currentPath).isDir()) diff --git a/YACReaderLibrary/import_widget.cpp b/YACReaderLibrary/import_widget.cpp index 9dafa3958..522e46568 100644 --- a/YACReaderLibrary/import_widget.cpp +++ b/YACReaderLibrary/import_widget.cpp @@ -215,7 +215,7 @@ void ImportWidget::newComic(const QString &path, const QString &coverPath) previousWidth += 10 + p.width(); - foreach (QGraphicsItem *itemToRemove, coversScene->items()) { + for (auto *itemToRemove : coversScene->items()) { auto last = dynamic_cast(itemToRemove); if ((last->pos().x() + last->pixmap().width()) < coversView->horizontalScrollBar()->value()) // TODO check this @@ -263,7 +263,7 @@ void ImportWidget::addCoverTest() } else j++; - foreach (QGraphicsItem *itemToMove, coversScene->items()) { + for (auto *itemToMove : coversScene->items()) { auto timer = new QTimeLine(/*350*/ 1000); timer->setFrameRange(0, 60); diff --git a/YACReaderLibrary/info_comics_view.cpp b/YACReaderLibrary/info_comics_view.cpp index 47d118cba..f86327d52 100644 --- a/YACReaderLibrary/info_comics_view.cpp +++ b/YACReaderLibrary/info_comics_view.cpp @@ -189,7 +189,7 @@ bool InfoComicsView::canDropUrls(const QList &urls, Qt::DropAction action) { if (action == Qt::CopyAction) { QString currentPath; - foreach (QUrl url, urls) { + for (const auto &url : urls) { // comics or folders are accepted, folders' content is validate in dropEvent (avoid any lag before droping) currentPath = url.toLocalFile(); if (Comic::fileIsComic(currentPath) || QFileInfo(currentPath).isDir()) diff --git a/YACReaderLibrary/library_creator.cpp b/YACReaderLibrary/library_creator.cpp index 4bfdfffb9..3b55c3af3 100644 --- a/YACReaderLibrary/library_creator.cpp +++ b/YACReaderLibrary/library_creator.cpp @@ -100,7 +100,7 @@ void LibraryCreator::updateFolder(const QString &source, const QString &target, _currentPathFolders.append(rootFolder(db)); - foreach (QString folderName, folders) { + for (const auto &folderName : folders) { if (folderName.isEmpty()) { break; } @@ -472,7 +472,7 @@ void LibraryCreator::update(QDir dirS) listS.append(listSFolders); listS.append(listSFiles); // QLOG_DEBUG() << "---------------------------------------------------------"; - // foreach(QFileInfo info,listS) + // for (const QFileInfo &info : listS) // QLOG_DEBUG() << info.fileName(); // QLOG_TRACE() << "END Getting info from dir" << dirS.absolutePath(); @@ -488,7 +488,7 @@ void LibraryCreator::update(QDir dirS) listD.append(folders); listD.append(comics); // QLOG_DEBUG() << "---------------------------------------------------------"; - // foreach(LibraryItem * info,listD) + // for (auto *info : listD) // QLOG_DEBUG() << info->name; // QLOG_DEBUG() << "---------------------------------------------------------"; int lenghtS = listS.size(); diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 8e455b950..f7ceb3743 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -1582,7 +1582,7 @@ void LibraryWindow::setupAddToSubmenu(QMenu &menu) const QList labels = listsModel->getLabels(); if (labels.count() > 0) menu.addSeparator(); - foreach (LabelItem *label, labels) { + for (auto *label : labels) { auto action = new QAction(this); action->setIcon(label->getIcon()); action->setText(label->name()); @@ -1621,8 +1621,8 @@ void LibraryWindow::saveSelectedCoversTo() QFileDialog saveDialog; QString folderPath = saveDialog.getExistingDirectory(this, tr("Save covers"), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)); if (!folderPath.isEmpty()) { - QModelIndexList comics = getSelectedComics(); - foreach (QModelIndex comic, comics) { + const auto comics = getSelectedComics(); + for (const auto &comic : comics) { QString origin = comic.data(ComicModel::CoverPathRole).toString().remove("file:///").remove("file:"); QString destination = QDir(folderPath).filePath(comic.data(ComicModel::FileNameRole).toString() + ".jpg"); @@ -1803,7 +1803,8 @@ void LibraryWindow::openLibrary(QString path, QString name) void LibraryWindow::loadLibraries() { libraries.load(); - foreach (QString name, libraries.getNames()) + const auto libraryNames = libraries.getNames(); + for (const auto &name : libraryNames) selectedLibrary->addItem(name, libraries.getPath(name)); } @@ -1848,9 +1849,12 @@ void LibraryWindow::deleteCurrentLibrary() void LibraryWindow::removeLibrary() { QString currentLibrary = selectedLibrary->currentText(); - QMessageBox *messageBox = new QMessageBox(tr("Are you sure?"), tr("Do you want remove ") + currentLibrary + tr(" library?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::YesToAll, QMessageBox::No); + QMessageBox *messageBox = new QMessageBox(QMessageBox::Question, + tr("Are you sure?"), + tr("Do you want remove ") + currentLibrary + tr(" library?"), + QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No, + this); messageBox->button(QMessageBox::YesToAll)->setText(tr("Remove and delete metadata")); - messageBox->setParent(this); messageBox->setWindowModality(Qt::WindowModal); int ret = messageBox->exec(); if (ret == QMessageBox::Yes) { @@ -2141,7 +2145,7 @@ void LibraryWindow::showComicVineScraper() if (s.contains(COMIC_VINE_API_KEY)) { QModelIndexList indexList = getSelectedComics(); - QList comics = comicsModel->getComics(indexList); + const auto comics = comicsModel->getComics(indexList); ComicDB c = comics[0]; _comicIdEdited = c.id; // static_cast(indexList[0].internalPointer())->data(4).toULongLong(); @@ -2507,7 +2511,7 @@ void LibraryWindow::deleteComicsFromDisk() QList paths; QString libraryPath = currentPath(); - foreach (ComicDB comic, comics) { + for (const auto &comic : comics) { paths.append(libraryPath + comic.path); QLOG_TRACE() << comic.path; QLOG_TRACE() << comic.id; diff --git a/YACReaderLibrary/main.cpp b/YACReaderLibrary/main.cpp index 2494fc6d9..a77c4925d 100644 --- a/YACReaderLibrary/main.cpp +++ b/YACReaderLibrary/main.cpp @@ -125,12 +125,6 @@ int main(int argc, char **argv) { qInstallMessageHandler(messageHandler); - static const char ENV_VAR_QT_DEVICE_PIXEL_RATIO[] = "QT_DEVICE_PIXEL_RATIO"; - if (!qEnvironmentVariableIsSet(ENV_VAR_QT_DEVICE_PIXEL_RATIO) && !qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR") && !qEnvironmentVariableIsSet("QT_SCALE_FACTOR") && !qEnvironmentVariableIsSet("QT_SCREEN_SCALE_FACTORS")) { - QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - } - - QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); QImageReader::setAllocationLimit(0); diff --git a/YACReaderLibrary/server/controllers/v2/librariescontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/librariescontroller_v2.cpp index 9eb737398..4039ef2c8 100644 --- a/YACReaderLibrary/server/controllers/v2/librariescontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/librariescontroller_v2.cpp @@ -16,7 +16,7 @@ void LibrariesControllerV2::service(HttpRequest & /* request */, HttpResponse &r QJsonArray librariesJson; - foreach (YACReaderLibrary library, libraries) { + for (const auto &library : libraries) { QJsonObject libraryJson; libraryJson["name"] = library.getName(); diff --git a/YACReaderLibrary/server/controllers/v2/synccontroller_v2.cpp b/YACReaderLibrary/server/controllers/v2/synccontroller_v2.cpp index edba69f9a..23f6d92bb 100644 --- a/YACReaderLibrary/server/controllers/v2/synccontroller_v2.cpp +++ b/YACReaderLibrary/server/controllers/v2/synccontroller_v2.cpp @@ -24,7 +24,7 @@ void SyncControllerV2::service(HttpRequest &request, HttpResponse &response) QLOG_TRACE() << "POST DATA: " << postData; if (postData.length() > 0) { - QList data = postData.split("\n"); + const auto data = postData.split("\n"); qulonglong libraryId; qulonglong comicId; @@ -35,17 +35,17 @@ void SyncControllerV2::service(HttpRequest &request, HttpResponse &response) QMap> comics; QList comicsWithNoLibrary; - auto libraries = DBHelper::getLibraries(); + const auto libraries = DBHelper::getLibraries(); bool clientSendsHasBeenOpened = false; bool clientSendsImageFilters = false; - foreach (QString comicInfo, data) { + for (const auto &comicInfo : data) { if (comicInfo.isEmpty()) { continue; } - QList comicInfoProgress = comicInfo.split("\t"); + const auto comicInfoProgress = comicInfo.split("\t"); if (comicInfoProgress.isEmpty()) { continue; @@ -166,11 +166,13 @@ void SyncControllerV2::service(HttpRequest &request, HttpResponse &response) if (!comics.isEmpty()) { auto moreRecentComicsFound = DBHelper::updateFromRemoteClient(comics, clientSendsHasBeenOpened, clientSendsImageFilters); + const auto libraryIds = moreRecentComicsFound.keys(); - foreach (qulonglong libraryId, moreRecentComicsFound.keys()) { + for (const auto libraryId : libraryIds) { auto libraryUuid = DBHelper::getLibraries().getLibraryIdFromLegacyId(libraryId); + const auto &libraryComics = moreRecentComicsFound[libraryId]; - foreach (ComicDB comic, moreRecentComicsFound[libraryId]) { + for (const auto &comic : libraryComics) { items.append(YACReaderServerDataHelper::fullComicToJSON(libraryId, libraryUuid, comic)); } } diff --git a/YACReaderLibrary/server/static.cpp b/YACReaderLibrary/server/static.cpp index fd8a563af..9610df738 100644 --- a/YACReaderLibrary/server/static.cpp +++ b/YACReaderLibrary/server/static.cpp @@ -45,7 +45,7 @@ QString Static::getConfigDir() searchList.append(QDir::rootPath() + "etc/opt"); searchList.append(QDir::rootPath() + "etc"); - foreach (QString dir, searchList) { + for (const auto &dir : searchList) { QFile file(dir + "/" + configFileName); if (file.exists()) { // found @@ -56,7 +56,7 @@ QString Static::getConfigDir() } // not found - foreach (QString dir, searchList) { + for (const auto &dir : searchList) { qWarning("%s/%s not found", qPrintable(dir), qPrintable(configFileName)); } qWarning("Cannot find config file %s", qPrintable(configFileName)); // TODO establecer los valores por defecto diff --git a/YACReaderLibrary/yacreader_folders_view.cpp b/YACReaderLibrary/yacreader_folders_view.cpp index 54d413be9..18a63e9d5 100644 --- a/YACReaderLibrary/yacreader_folders_view.cpp +++ b/YACReaderLibrary/yacreader_folders_view.cpp @@ -16,12 +16,10 @@ void YACReaderFoldersView::dragEnterEvent(QDragEnterEvent *event) { YACReaderTreeView::dragEnterEvent(event); - QList urlList; - if (event->mimeData()->hasUrls() && event->dropAction() == Qt::CopyAction) { - urlList = event->mimeData()->urls(); + const auto urlList = event->mimeData()->urls(); QString currentPath; - foreach (QUrl url, urlList) { + for (const auto &url : urlList) { // comics or folders are accepted, folders' content is validate in dropEvent (avoid any lag before droping) currentPath = url.toLocalFile(); if (Comic::fileIsComic(currentPath) || QFileInfo(currentPath).isDir()) { @@ -53,7 +51,7 @@ void YACReaderFoldersView::dropEvent(QDropEvent *event) if (validAction) { QList> droppedFiles = ComicFilesManager::getDroppedFiles(event->mimeData()->urls()); - QModelIndex destinationIndex = indexAt(event->pos()); + QModelIndex destinationIndex = indexAt(event->position().toPoint()); if (event->dropAction() == Qt::CopyAction) { QLOG_DEBUG() << "copy - tree :" << droppedFiles; diff --git a/YACReaderLibrary/yacreader_libraries.cpp b/YACReaderLibrary/yacreader_libraries.cpp index 54fea2fe7..6e16d97d2 100644 --- a/YACReaderLibrary/yacreader_libraries.cpp +++ b/YACReaderLibrary/yacreader_libraries.cpp @@ -38,54 +38,54 @@ YACReaderLibraries::YACReaderLibraries(const YACReaderLibraries &source) { } -QList YACReaderLibraries::getNames() +QList YACReaderLibraries::getNames() const { QList names; std::transform(libraries.cbegin(), libraries.cend(), std::back_inserter(names), [](const YACReaderLibrary &library) { return library.getName(); }); return names; } -QString YACReaderLibraries::getPath(const QString &name) +QString YACReaderLibraries::getPath(const QString &name) const { auto library = std::find_if(libraries.cbegin(), libraries.cend(), [name](const YACReaderLibrary &library) { return library.getName() == name; }); return library != libraries.cend() ? library->getPath() : ""; } -QString YACReaderLibraries::getPath(int id) +QString YACReaderLibraries::getPath(int id) const { auto library = std::find_if(libraries.cbegin(), libraries.cend(), [id](const YACReaderLibrary &library) { return library.getLegacyId() == id; }); return library != libraries.cend() ? library->getPath() : ""; } -QString YACReaderLibraries::getPath(const QUuid &id) +QString YACReaderLibraries::getPath(const QUuid &id) const { auto library = std::find_if(libraries.cbegin(), libraries.cend(), [id](const YACReaderLibrary &library) { return library.getId() == id; }); return library != libraries.cend() ? library->getPath() : ""; } -QString YACReaderLibraries::getDBPath(int id) +QString YACReaderLibraries::getDBPath(int id) const { return LibraryPaths::libraryDataPath(getPath(id)); } -QString YACReaderLibraries::getName(int id) +QString YACReaderLibraries::getName(int id) const { auto library = std::find_if(libraries.cbegin(), libraries.cend(), [id](const YACReaderLibrary &library) { return library.getLegacyId() == id; }); return library != libraries.cend() ? library->getName() : ""; } -bool YACReaderLibraries::isEmpty() +bool YACReaderLibraries::isEmpty() const { return libraries.isEmpty(); } -bool YACReaderLibraries::contains(const QString &name) +bool YACReaderLibraries::contains(const QString &name) const { auto library = std::find_if(libraries.cbegin(), libraries.cend(), [name](const YACReaderLibrary &library) { return library.getName() == name; }); return library != libraries.cend(); } -bool YACReaderLibraries::contains(int id) +bool YACReaderLibraries::contains(int id) const { auto library = std::find_if(libraries.cbegin(), libraries.cend(), [id](const YACReaderLibrary &library) { return library.getLegacyId() == id; }); return library != libraries.cend(); @@ -104,19 +104,19 @@ void YACReaderLibraries::rename(const QString &oldName, const QString &newName) libraries.append(YACReaderLibrary(newName, library->getPath(), library->getLegacyId(), library->getId())); } -int YACReaderLibraries::getId(const QString &name) +int YACReaderLibraries::getId(const QString &name) const { auto library = std::find_if(libraries.cbegin(), libraries.cend(), [name](const YACReaderLibrary &library) { return library.getName() == name; }); return library != libraries.cend() ? library->getLegacyId() : -1; } -QUuid YACReaderLibraries::getUuid(const QString &name) +QUuid YACReaderLibraries::getUuid(const QString &name) const { auto library = std::find_if(libraries.cbegin(), libraries.cend(), [name](const YACReaderLibrary &library) { return library.getName() == name; }); return library != libraries.cend() ? library->getId() : QUuid(); } -int YACReaderLibraries::getIdFromUuid(const QUuid &uuid) +int YACReaderLibraries::getIdFromUuid(const QUuid &uuid) const { auto library = std::find_if(libraries.cbegin(), libraries.cend(), [uuid](const YACReaderLibrary &library) { return library.getId() == uuid; }); return library != libraries.cend() ? library->getLegacyId() : -1; @@ -149,8 +149,9 @@ QUuid YACReaderLibraries::getLibraryIdFromLegacyId(int legacyId) const void YACReaderLibraries::addLibrary(const QString &name, const QString &path) { int legacyId = 0; - foreach (YACReaderLibrary l, libraries) - legacyId = qMax(legacyId, l.getLegacyId()); + const auto &existingLibraries = libraries; + for (const auto &library : existingLibraries) + legacyId = qMax(legacyId, library.getLegacyId()); legacyId++; auto id = readFromLibraryFolder(path); diff --git a/YACReaderLibrary/yacreader_libraries.h b/YACReaderLibrary/yacreader_libraries.h index e7e8c86d2..c370eb4f2 100644 --- a/YACReaderLibrary/yacreader_libraries.h +++ b/YACReaderLibrary/yacreader_libraries.h @@ -12,20 +12,20 @@ class YACReaderLibraries : public QObject public: YACReaderLibraries(); YACReaderLibraries(const YACReaderLibraries &source); - QList getNames(); - QString getPath(const QString &name); - QString getPath(int id); - QString getPath(const QUuid &id); - QString getDBPath(int id); - QString getName(int id); - bool isEmpty(); - bool contains(const QString &name); - bool contains(int id); + QList getNames() const; + QString getPath(const QString &name) const; + QString getPath(int id) const; + QString getPath(const QUuid &id) const; + QString getDBPath(int id) const; + QString getName(int id) const; + bool isEmpty() const; + bool contains(const QString &name) const; + bool contains(int id) const; void remove(const QString &name); void rename(const QString &oldName, const QString &newName); - int getId(const QString &name); - QUuid getUuid(const QString &name); - int getIdFromUuid(const QUuid &uuid); + int getId(const QString &name) const; + QUuid getUuid(const QString &name) const; + int getIdFromUuid(const QUuid &uuid) const; YACReaderLibraries &operator=(const YACReaderLibraries &source); QList getLibraries() const; QList sortedLibraries() const; diff --git a/YACReaderLibrary/yacreader_reading_lists_view.cpp b/YACReaderLibrary/yacreader_reading_lists_view.cpp index 080845569..7f4c37225 100644 --- a/YACReaderLibrary/yacreader_reading_lists_view.cpp +++ b/YACReaderLibrary/yacreader_reading_lists_view.cpp @@ -24,7 +24,7 @@ void YACReaderReadingListsView::dragEnterEvent(QDragEnterEvent *event) void YACReaderReadingListsView::dragMoveEvent(QDragMoveEvent *event) { YACReaderTreeView::dragMoveEvent(event); - QModelIndex destinationIndex = indexAt(event->pos()); + QModelIndex destinationIndex = indexAt(event->position().toPoint()); if (model()->canDropMimeData(event->mimeData(), event->proposedAction(), destinationIndex.row(), destinationIndex.column(), destinationIndex.parent())) event->acceptProposedAction(); } diff --git a/YACReaderLibraryServer/CMakeLists.txt b/YACReaderLibraryServer/CMakeLists.txt index 16df0ac9e..94081193c 100644 --- a/YACReaderLibraryServer/CMakeLists.txt +++ b/YACReaderLibraryServer/CMakeLists.txt @@ -19,10 +19,6 @@ target_compile_definitions(YACReaderLibraryServer PRIVATE YACREADER_LIBRARY ) -# Resources -qt_add_resources(yacreaderlibraryserver_images_rcc "${CMAKE_CURRENT_SOURCE_DIR}/images.qrc") -target_sources(YACReaderLibraryServer PRIVATE ${yacreaderlibraryserver_images_rcc}) - # Translations qt_add_translations(YACReaderLibraryServer TS_FILES diff --git a/YACReaderLibraryServer/images.qrc b/YACReaderLibraryServer/images.qrc deleted file mode 100644 index 1ea3a08e0..000000000 --- a/YACReaderLibraryServer/images.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - ../images/f_overlayed.png - ../images/f_overlayed_retina.png - - diff --git a/YACReaderLibraryServer/libraries_updater.cpp b/YACReaderLibraryServer/libraries_updater.cpp index a2c1d625c..1b2631eb8 100644 --- a/YACReaderLibraryServer/libraries_updater.cpp +++ b/YACReaderLibraryServer/libraries_updater.cpp @@ -4,6 +4,8 @@ #include "yacreader_global.h" #include "yacreader_libraries.h" +#include + LibrariesUpdater::LibrariesUpdater() { } @@ -14,7 +16,7 @@ void LibrariesUpdater::updateIfNeeded() libraries.load(); - foreach (QString name, libraries.getNames()) { + for (const QString &name : libraries.getNames()) { QString libraryPath = libraries.getPath(name); QString libraryDataPath = YACReader::LibraryPaths::libraryDataPath(libraryPath); QString databasePath = YACReader::LibraryPaths::libraryDatabasePath(libraryPath); diff --git a/common/bookmarks.cpp b/common/bookmarks.cpp index 83bad65e1..e357411ba 100644 --- a/common/bookmarks.cpp +++ b/common/bookmarks.cpp @@ -8,6 +8,8 @@ #include #include +#include + Bookmarks::Bookmarks() : lastPageIndex(0) { @@ -93,7 +95,7 @@ void Bookmarks::clear() bool Bookmarks::load(const QList &bookmarkIndexes, int lastPage) { lastPageIndex = lastPage; - foreach (int b, bookmarkIndexes) + for (const int b : std::as_const(bookmarkIndexes)) if (b != -1) { latestBookmarks.push_back(b); bookmarks.insert(b, QImage()); diff --git a/common/comic.cpp b/common/comic.cpp index 7351bd14b..6d9bbfeff 100644 --- a/common/comic.cpp +++ b/common/comic.cpp @@ -15,6 +15,7 @@ #include #include +#include enum YACReaderPageSortingMode { YACReaderNumericalSorting, @@ -304,7 +305,7 @@ QList Comic::findValidComicFiles(const QList &list) QLOG_DEBUG() << "-findValidComicFiles-"; QList validComicFiles; QString currentPath; - foreach (QUrl url, list) { + for (const QUrl &url : std::as_const(list)) { currentPath = url.toLocalFile(); if (Comic::fileIsComic(currentPath)) { validComicFiles << currentPath; @@ -330,7 +331,7 @@ QList Comic::findValidComicFilesInFolder(const QString &path) QFileInfoList folderContent = folder.entryInfoList(); QString currentPath; - foreach (QFileInfo info, folderContent) { + for (const QFileInfo &info : std::as_const(folderContent)) { currentPath = info.absoluteFilePath(); if (info.isDir()) { validComicFiles << findValidComicFilesInFolder(currentPath); // find comics recursively @@ -415,10 +416,10 @@ QList FileComic::filter(const QList &src) QList filtered; bool fileAccepted = false; - foreach (QString fileName, src) { + for (const QString &fileName : std::as_const(src)) { fileAccepted = false; if (!fileName.contains("__MACOSX")) { - foreach (QString extension, extensions) { + for (const QString &extension : std::as_const(extensions)) { if (fileName.endsWith(extension, Qt::CaseInsensitive)) { fileAccepted = true; break; @@ -473,7 +474,7 @@ bool FileComic::isCancelled() QList> FileComic::getSections(int §ionIndex) { QVector sortedIndexes; - foreach (QString name, _fileNames) { + for (const QString &name : std::as_const(_fileNames)) { sortedIndexes.append(_order.indexOf(name)); } QList> sections; @@ -483,7 +484,7 @@ QList> FileComic::getSections(int §ionIndex) QVector section; int idx = 0; unsigned int realIdx; - foreach (quint32 i, sortedIndexes) { + for (const quint32 i : std::as_const(sortedIndexes)) { if (_firstPage == idx) { sectionIndex = sectionCount; @@ -499,7 +500,7 @@ QList> FileComic::getSections(int §ionIndex) if (section.indexOf(realIdx) != 0) { QVector section1; QVector section2; - foreach (quint32 si, section) { + for (const quint32 si : std::as_const(section)) { if (si < realIdx) { section1.append(si); } else { @@ -532,7 +533,7 @@ QList> FileComic::getSections(int §ionIndex) if (section.indexOf(realIdx) != 0) { QVector section1; QVector section2; - foreach (quint32 si, section) { + for (const quint32 si : std::as_const(section)) { if (si < realIdx) { section1.append(si); } else { @@ -626,7 +627,7 @@ void FileComic::process() } // archive.getAllData(QVector(),this); /* - foreach(QString name,_fileNames) + for (const auto &name : _fileNames) { index = _order.indexOf(name); sortedIndex = _fileNames.indexOf(name); @@ -1017,7 +1018,7 @@ void get_double_pages(const QList &pageNames, QList &singlePag QString mostCommonPrefix = get_most_common_prefix(pageNames); - foreach (const QString &pageName, pageNames) { + for (const QString &pageName : std::as_const(pageNames)) { if (is_double_page(pageName.split('/').last(), mostCommonPrefix, maxExpectedDoublePagesNumberLenght)) { doublePageNames.append(pageName); } else { diff --git a/common/rhi/yacreader_comic_flow_rhi.cpp b/common/rhi/yacreader_comic_flow_rhi.cpp index abf3ab587..bba348df3 100644 --- a/common/rhi/yacreader_comic_flow_rhi.cpp +++ b/common/rhi/yacreader_comic_flow_rhi.cpp @@ -2,6 +2,8 @@ #include +#include + // YACReaderComicFlow3D implementation YACReaderComicFlow3D::YACReaderComicFlow3D(QWidget *parent, struct Preset p) : YACReaderFlow3D(parent, p) @@ -126,7 +128,7 @@ void YACReaderComicFlow3D::resortCovers(QList newOrder) QVector imagesNew; int index = 0; - foreach (int i, newOrder) { + for (const int i : std::as_const(newOrder)) { if (i < 0 || i >= images.size()) { continue; } diff --git a/compressed_archive/compressed_archive.cpp b/compressed_archive/compressed_archive.cpp index 65aff55fa..dd878007b 100644 --- a/compressed_archive/compressed_archive.cpp +++ b/compressed_archive/compressed_archive.cpp @@ -12,6 +12,8 @@ #include #include +#include + #define _MY_WINAPI WINAPI typedef quint32(_MY_WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *interfaceID, void **outObject); @@ -235,7 +237,7 @@ QVector CompressedArchive::translateIndexes(const QVector &ind { QVector translatedIndexes; - foreach (quint32 i, indexes) { + for (const quint32 i : std::as_const(indexes)) { if (i < (quint32)offsets.length()) translatedIndexes.append(offsets.at(i)); } diff --git a/custom_widgets/yacreader_macosx_toolbar.mm b/custom_widgets/yacreader_macosx_toolbar.mm index 2338eb30b..483177ac5 100644 --- a/custom_widgets/yacreader_macosx_toolbar.mm +++ b/custom_widgets/yacreader_macosx_toolbar.mm @@ -198,7 +198,7 @@ - (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar NSMutableArray *array = [[NSMutableArray alloc] init]; QList items = mytoolbar->items(); - foreach (const QMacToolBarItem * item, items) { + for (const auto *item : items) { [array addObject : item->nativeToolBarItem().itemIdentifier]; } return array; diff --git a/custom_widgets/yacreader_table_view.cpp b/custom_widgets/yacreader_table_view.cpp index d434fb47d..9d3b1bffd 100644 --- a/custom_widgets/yacreader_table_view.cpp +++ b/custom_widgets/yacreader_table_view.cpp @@ -407,7 +407,7 @@ void StarEditor::leaveEvent(QEvent *event) void StarEditor::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { - int star = starAtPosition(event->x()); + int star = starAtPosition(event->position().x()); if (star != myStarRating.starCount() && star != -1) { myStarRating.setStarCount(star); diff --git a/custom_widgets/yacreader_treeview.cpp b/custom_widgets/yacreader_treeview.cpp index 5ddaadcfd..63c3e33da 100644 --- a/custom_widgets/yacreader_treeview.cpp +++ b/custom_widgets/yacreader_treeview.cpp @@ -66,9 +66,10 @@ void YACReaderTreeView::dragMoveEvent(QDragMoveEvent *event) QTreeView::dragMoveEvent(event); // fix for drop auto expand - QModelIndex underMouse = indexAt(event->pos()); + auto point = event->position().toPoint(); + QModelIndex underMouse = indexAt(point); if (underMouse.isValid()) { - expandPos = event->pos(); + expandPos = point; connect(&expandTimer, &QTimer::timeout, this, &YACReaderTreeView::expandCurrent); expandTimer.setSingleShot(true); expandTimer.start(500); diff --git a/shortcuts_management/shortcuts_manager.cpp b/shortcuts_management/shortcuts_manager.cpp index 6ca75c216..87eca2b8f 100644 --- a/shortcuts_management/shortcuts_manager.cpp +++ b/shortcuts_management/shortcuts_manager.cpp @@ -5,6 +5,8 @@ #include #include +#include + ShortcutsManager::ShortcutsManager() { initDefaultShorcuts(); @@ -127,7 +129,7 @@ bool ShortcutsManager::checkConflicts(const QKeySequence &shortcut, const QActio if (shortcut.isEmpty()) return false; - foreach (QAction *action, actions) { + for (QAction *action : std::as_const(actions)) { if (action != dest) // if the same shortcut is setted there is no conflict if (action->shortcut() == shortcut) return true; diff --git a/tests/compressed_archive_test/main.cpp b/tests/compressed_archive_test/main.cpp index 4f681c9fa..44177efd4 100644 --- a/tests/compressed_archive_test/main.cpp +++ b/tests/compressed_archive_test/main.cpp @@ -6,6 +6,7 @@ #include #include +#include using namespace std; @@ -36,7 +37,7 @@ int main(int argc, char *argv[]) timer.start(); quint32 totalFiles = 0; - foreach (QString format, supportedFormats) { + for (const QString &format : std::as_const(supportedFormats)) { QDir rootDir(s); if (!rootDir.cd(format)) { cout << "Folder for format '" << format.toStdString() << "' not found" << endl; @@ -49,7 +50,7 @@ int main(int argc, char *argv[]) quint32 errors = 0; quint64 init = timer.elapsed(); - foreach (QFileInfo fileInfo, files) { + for (const QFileInfo &fileInfo : std::as_const(files)) { totalFiles++; totalFormat++; CompressedArchive archive(fileInfo.filePath()); diff --git a/third_party/QsLog/unittest/QtTestUtil/TestRegistry.cpp b/third_party/QsLog/unittest/QtTestUtil/TestRegistry.cpp index 5460f4052..d4de9ee19 100644 --- a/third_party/QsLog/unittest/QtTestUtil/TestRegistry.cpp +++ b/third_party/QsLog/unittest/QtTestUtil/TestRegistry.cpp @@ -21,9 +21,10 @@ void TestRegistry::registerTest(QObject* test) { int TestRegistry::runTests(int argc, char* argv[]) { int result = 0; - foreach(QObject* test, tests_) { - result |= QTest::qExec(test, argc, argv); - } + const auto &tests = tests_; + for (auto *test : tests) { + result |= QTest::qExec(test, argc, argv); + } return result; } diff --git a/third_party/QsLog/unittest/TestLog.h b/third_party/QsLog/unittest/TestLog.h index ba3df1922..edc665834 100644 --- a/third_party/QsLog/unittest/TestLog.h +++ b/third_party/QsLog/unittest/TestLog.h @@ -63,7 +63,7 @@ class MockDestination : public QsLogging::Destination bool hasMessage(const QString &messageContent, QsLogging::Level level) const { - Q_FOREACH (const Message &m, mMessages) { + for (const auto &m : mMessages) { if (m.level == level && m.text.contains(messageContent)) return true; } diff --git a/third_party/QtWebApp/httpserver/httpconnectionhandlerpool.cpp b/third_party/QtWebApp/httpserver/httpconnectionhandlerpool.cpp index 5a03d0ce5..240d0f92d 100644 --- a/third_party/QtWebApp/httpserver/httpconnectionhandlerpool.cpp +++ b/third_party/QtWebApp/httpserver/httpconnectionhandlerpool.cpp @@ -5,6 +5,7 @@ #include #endif #include +#include #include "httpconnectionhandlerpool.h" using namespace stefanfrings; @@ -25,7 +26,7 @@ HttpConnectionHandlerPool::HttpConnectionHandlerPool(const QSettings *settings, HttpConnectionHandlerPool::~HttpConnectionHandlerPool() { // delete all connection handlers and wait until their threads are closed - foreach(HttpConnectionHandler* handler, pool) + for (HttpConnectionHandler *handler : std::as_const(pool)) { delete handler; } @@ -39,7 +40,7 @@ HttpConnectionHandler* HttpConnectionHandlerPool::getConnectionHandler() HttpConnectionHandler* freeHandler=0; mutex.lock(); // find a free handler in pool - foreach(HttpConnectionHandler* handler, pool) + for (HttpConnectionHandler *handler : std::as_const(pool)) { if (!handler->isBusy()) { @@ -69,7 +70,7 @@ void HttpConnectionHandlerPool::cleanup() int maxIdleHandlers=settings->value("minThreads",1).toInt(); int idleCounter=0; mutex.lock(); - foreach(HttpConnectionHandler* handler, pool) + for (HttpConnectionHandler *handler : std::as_const(pool)) { if (!handler->isBusy()) { diff --git a/third_party/QtWebApp/httpserver/httpcookie.cpp b/third_party/QtWebApp/httpserver/httpcookie.cpp index d85232e83..bde70caac 100644 --- a/third_party/QtWebApp/httpserver/httpcookie.cpp +++ b/third_party/QtWebApp/httpserver/httpcookie.cpp @@ -4,6 +4,7 @@ */ #include "httpcookie.h" +#include using namespace stefanfrings; @@ -37,7 +38,7 @@ HttpCookie::HttpCookie(const QByteArray source) secure=false; httpOnly=false; QList list=splitCSV(source); - foreach(QByteArray part, list) + for (const QByteArray &part : std::as_const(list)) { // Split the part into name and value diff --git a/third_party/QtWebApp/httpserver/httprequest.cpp b/third_party/QtWebApp/httpserver/httprequest.cpp index c9294b7a4..c076c5d9b 100644 --- a/third_party/QtWebApp/httpserver/httprequest.cpp +++ b/third_party/QtWebApp/httpserver/httprequest.cpp @@ -6,6 +6,7 @@ #include "httprequest.h" #include #include +#include #include "httpcookie.h" using namespace stefanfrings; @@ -239,7 +240,7 @@ void HttpRequest::decodeRequestParams() } // Split the parameters into pairs of value and name QList list=rawParameters.split('&'); - foreach (QByteArray part, list) + for (const QByteArray &part : std::as_const(list)) { int equalsChar=part.indexOf('='); if (equalsChar>=0) @@ -261,10 +262,10 @@ void HttpRequest::extractCookies() #ifdef SUPERVERBOSE qDebug("HttpRequest: extract cookies"); #endif - foreach(QByteArray cookieStr, headers.values("cookie")) + for (const QByteArray &cookieStr : headers.values("cookie")) { QList list=HttpCookie::splitCSV(cookieStr); - foreach(QByteArray part, list) + for (const QByteArray &part : std::as_const(list)) { #ifdef SUPERVERBOSE qDebug("HttpRequest: found cookie %s",part.data()); @@ -532,7 +533,7 @@ void HttpRequest::parseMultiPartFile() HttpRequest::~HttpRequest() { - foreach(QByteArray key, uploadedFiles.keys()) + for (const QByteArray &key : uploadedFiles.keys()) { QTemporaryFile* file=uploadedFiles.value(key); if (file->isOpen()) diff --git a/third_party/QtWebApp/httpserver/httpresponse.cpp b/third_party/QtWebApp/httpserver/httpresponse.cpp index a2afba89c..597be0f4f 100644 --- a/third_party/QtWebApp/httpserver/httpresponse.cpp +++ b/third_party/QtWebApp/httpserver/httpresponse.cpp @@ -4,6 +4,7 @@ */ #include "httpresponse.h" +#include using namespace stefanfrings; @@ -54,14 +55,14 @@ void HttpResponse::writeHeaders() buffer.append(' '); buffer.append(statusText); buffer.append("\r\n"); - foreach(QByteArray name, headers.keys()) + for (const QByteArray &name : headers.keys()) { buffer.append(name); buffer.append(": "); buffer.append(headers.value(name)); buffer.append("\r\n"); } - foreach(HttpCookie cookie,cookies.values()) + for (const HttpCookie &cookie : cookies.values()) { buffer.append("Set-Cookie: "); buffer.append(cookie.toByteArray()); diff --git a/third_party/QtWebApp/templateengine/templateloader.cpp b/third_party/QtWebApp/templateengine/templateloader.cpp index 0db3115b2..1dda0d7c8 100644 --- a/third_party/QtWebApp/templateengine/templateloader.cpp +++ b/third_party/QtWebApp/templateengine/templateloader.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #include #else @@ -81,7 +82,7 @@ Template TemplateLoader::getTemplate(QString templateName, QString locales) #endif // Search for exact match - foreach (QString loc,locs) + for (QString loc : std::as_const(locs)) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) loc.replace(QRegularExpression(";.*"),""); @@ -102,7 +103,7 @@ Template TemplateLoader::getTemplate(QString templateName, QString locales) } // Search for correct language but any country - foreach (QString loc,locs) + for (QString loc : std::as_const(locs)) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) loc.replace(QRegularExpression("[;_-].*"),""); From 8cc9ffc35582c20a8f680daae905618395b5a837 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 15:56:27 +0200 Subject: [PATCH 177/187] Sanitize CMake source directory references --- CMakeLists.txt | 2 +- YACReader/CMakeLists.txt | 6 +++--- YACReaderLibrary/CMakeLists.txt | 6 +++--- YACReaderLibrary/comic_vine/CMakeLists.txt | 4 ++-- YACReaderLibraryServer/CMakeLists.txt | 4 ++-- cmake/Findpdfium.cmake | 12 +++++++----- cmake/Findunarr.cmake | 12 +++++++----- custom_widgets/CMakeLists.txt | 8 ++++---- shortcuts_management/CMakeLists.txt | 4 ++-- 9 files changed, 31 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e000cfe6e..095fd242a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ endif() # Install paths include(GNUInstallDirs) -list(PREPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # Compiler options (MSVC flags) include(cmake/CompilerOptions.cmake) diff --git a/YACReader/CMakeLists.txt b/YACReader/CMakeLists.txt index dd20fed22..070fb9dd5 100644 --- a/YACReader/CMakeLists.txt +++ b/YACReader/CMakeLists.txt @@ -42,8 +42,8 @@ qt_add_executable(YACReader WIN32 themes/theme.h themes/theme_factory.h themes/theme_factory.cpp - ${CMAKE_SOURCE_DIR}/common/themes/theme_manager.h - ${CMAKE_SOURCE_DIR}/common/themes/theme_manager.cpp + ${PROJECT_SOURCE_DIR}/common/themes/theme_manager.h + ${PROJECT_SOURCE_DIR}/common/themes/theme_manager.cpp ) target_include_directories(YACReader PRIVATE @@ -57,7 +57,7 @@ target_compile_definitions(YACReader PRIVATE YACREADER) qt_add_resources(yacreader_images_rcc "${CMAKE_CURRENT_SOURCE_DIR}/yacreader_images.qrc") qt_add_resources(yacreader_files_rcc "${CMAKE_CURRENT_SOURCE_DIR}/yacreader_files.qrc") qt_add_resources(yacreader_themes_rcc "${CMAKE_CURRENT_SOURCE_DIR}/themes/themes.qrc") -qt_add_resources(yacreader_common_images_rcc "${CMAKE_SOURCE_DIR}/common/themes/appearance_config_images.qrc") +qt_add_resources(yacreader_common_images_rcc "${PROJECT_SOURCE_DIR}/common/themes/appearance_config_images.qrc") target_sources(YACReader PRIVATE ${yacreader_images_rcc} ${yacreader_files_rcc} diff --git a/YACReaderLibrary/CMakeLists.txt b/YACReaderLibrary/CMakeLists.txt index 97c87db38..a86629faf 100644 --- a/YACReaderLibrary/CMakeLists.txt +++ b/YACReaderLibrary/CMakeLists.txt @@ -176,8 +176,8 @@ qt_add_executable(YACReaderLibrary WIN32 themes/theme.h themes/theme_factory.h themes/theme_factory.cpp - ${CMAKE_SOURCE_DIR}/common/themes/theme_manager.h - ${CMAKE_SOURCE_DIR}/common/themes/theme_manager.cpp + ${PROJECT_SOURCE_DIR}/common/themes/theme_manager.h + ${PROJECT_SOURCE_DIR}/common/themes/theme_manager.cpp ) # macOS-specific sources @@ -204,7 +204,7 @@ qt_add_resources(yacreaderlibrary_images_rcc "${CMAKE_CURRENT_SOURCE_DIR}/images qt_add_resources(yacreaderlibrary_files_rcc "${CMAKE_CURRENT_SOURCE_DIR}/files.qrc") qt_add_resources(yacreaderlibrary_qml_rcc "${CMAKE_CURRENT_SOURCE_DIR}/qml.qrc") qt_add_resources(yacreaderlibrary_themes_rcc "${CMAKE_CURRENT_SOURCE_DIR}/themes/themes.qrc") -qt_add_resources(yacreaderlibrary_common_images_rcc "${CMAKE_SOURCE_DIR}/common/themes/appearance_config_images.qrc") +qt_add_resources(yacreaderlibrary_common_images_rcc "${PROJECT_SOURCE_DIR}/common/themes/appearance_config_images.qrc") target_sources(YACReaderLibrary PRIVATE ${yacreaderlibrary_images_rcc} ${yacreaderlibrary_files_rcc} diff --git a/YACReaderLibrary/comic_vine/CMakeLists.txt b/YACReaderLibrary/comic_vine/CMakeLists.txt index e6ea50d69..cc0ca1a10 100644 --- a/YACReaderLibrary/comic_vine/CMakeLists.txt +++ b/YACReaderLibrary/comic_vine/CMakeLists.txt @@ -56,8 +56,8 @@ target_include_directories(comic_vine PUBLIC ) # App-specific theme.h needed for themable.h → theme_manager.h → theme.h chain target_include_directories(comic_vine PRIVATE - ${CMAKE_SOURCE_DIR}/YACReaderLibrary/themes - ${CMAKE_SOURCE_DIR}/YACReaderLibrary/db + ${PROJECT_SOURCE_DIR}/YACReaderLibrary/themes + ${PROJECT_SOURCE_DIR}/YACReaderLibrary/db ) target_link_libraries(comic_vine PUBLIC Qt::Core diff --git a/YACReaderLibraryServer/CMakeLists.txt b/YACReaderLibraryServer/CMakeLists.txt index 94081193c..42b5a27b4 100644 --- a/YACReaderLibraryServer/CMakeLists.txt +++ b/YACReaderLibraryServer/CMakeLists.txt @@ -10,8 +10,8 @@ qt_add_executable(YACReaderLibraryServer target_include_directories(YACReaderLibraryServer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/YACReaderLibrary - ${CMAKE_SOURCE_DIR}/YACReaderLibrary/db + ${PROJECT_SOURCE_DIR}/YACReaderLibrary + ${PROJECT_SOURCE_DIR}/YACReaderLibrary/db ) target_compile_definitions(YACReaderLibraryServer PRIVATE diff --git a/cmake/Findpdfium.cmake b/cmake/Findpdfium.cmake index 17689ecf1..526991066 100644 --- a/cmake/Findpdfium.cmake +++ b/cmake/Findpdfium.cmake @@ -6,11 +6,13 @@ set(pdfium_TARGET "") set(pdfium_INCLUDE_DIRS "") set(pdfium_LIBRARIES "") +get_filename_component(_pdfium_bundled_root "${CMAKE_CURRENT_LIST_DIR}/../dependencies/pdfium" ABSOLUTE) + if(NOT TARGET pdfium::pdfium AND WIN32) yacreader_get_windows_arch_subdir(_pdfium_arch) - set(_pdfium_include_dir "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/public") - set(_pdfium_implib "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/${_pdfium_arch}/pdfium.lib") - set(_pdfium_dll "${CMAKE_SOURCE_DIR}/dependencies/pdfium/win/${_pdfium_arch}/pdfium.dll") + set(_pdfium_include_dir "${_pdfium_bundled_root}/win/public") + set(_pdfium_implib "${_pdfium_bundled_root}/win/${_pdfium_arch}/pdfium.lib") + set(_pdfium_dll "${_pdfium_bundled_root}/win/${_pdfium_arch}/pdfium.dll") if(EXISTS "${_pdfium_include_dir}/fpdfview.h" AND EXISTS "${_pdfium_implib}" AND EXISTS "${_pdfium_dll}") yacreader_add_imported_library(pdfium::pdfium TYPE SHARED @@ -23,8 +25,8 @@ if(NOT TARGET pdfium::pdfium AND WIN32) endif() if(NOT TARGET pdfium::pdfium AND APPLE) - set(_pdfium_include_dir "${CMAKE_SOURCE_DIR}/dependencies/pdfium/macx/include") - set(_pdfium_library "${CMAKE_SOURCE_DIR}/dependencies/pdfium/macx/bin/libpdfium.a") + set(_pdfium_include_dir "${_pdfium_bundled_root}/macx/include") + set(_pdfium_library "${_pdfium_bundled_root}/macx/bin/libpdfium.a") if(EXISTS "${_pdfium_include_dir}/fpdfview.h" AND EXISTS "${_pdfium_library}") yacreader_add_imported_library(pdfium::pdfium TYPE STATIC diff --git a/cmake/Findunarr.cmake b/cmake/Findunarr.cmake index 4aa9ef0ab..aa0cb1702 100644 --- a/cmake/Findunarr.cmake +++ b/cmake/Findunarr.cmake @@ -6,9 +6,11 @@ set(unarr_TARGET "") set(unarr_INCLUDE_DIRS "") set(unarr_LIBRARIES "") +get_filename_component(_unarr_bundled_root "${CMAKE_CURRENT_LIST_DIR}/../dependencies/unarr" ABSOLUTE) + if(NOT TARGET unarr::unarr AND APPLE) - set(_unarr_include_dir "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx") - set(_unarr_library "${CMAKE_SOURCE_DIR}/dependencies/unarr/macx/libunarr.a") + set(_unarr_include_dir "${_unarr_bundled_root}/macx") + set(_unarr_library "${_unarr_bundled_root}/macx/libunarr.a") if(EXISTS "${_unarr_include_dir}/unarr.h" AND EXISTS "${_unarr_library}") yacreader_add_imported_library(unarr::unarr TYPE STATIC @@ -22,9 +24,9 @@ endif() if(NOT TARGET unarr::unarr AND WIN32) yacreader_get_windows_arch_subdir(_unarr_arch) - set(_unarr_include_dir "${CMAKE_SOURCE_DIR}/dependencies/unarr/win") - set(_unarr_implib "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/${_unarr_arch}/unarr.lib") - set(_unarr_dll "${CMAKE_SOURCE_DIR}/dependencies/unarr/win/${_unarr_arch}/unarr.dll") + set(_unarr_include_dir "${_unarr_bundled_root}/win") + set(_unarr_implib "${_unarr_bundled_root}/win/${_unarr_arch}/unarr.lib") + set(_unarr_dll "${_unarr_bundled_root}/win/${_unarr_arch}/unarr.dll") if(EXISTS "${_unarr_include_dir}/unarr.h" AND EXISTS "${_unarr_implib}" AND EXISTS "${_unarr_dll}") yacreader_add_imported_library(unarr::unarr TYPE SHARED diff --git a/custom_widgets/CMakeLists.txt b/custom_widgets/CMakeLists.txt index 4e5b6f1d6..aaa7ec25a 100644 --- a/custom_widgets/CMakeLists.txt +++ b/custom_widgets/CMakeLists.txt @@ -40,7 +40,7 @@ add_library(custom_widgets_reader STATIC ${WIDGETS_COMMON_SOURCES}) target_include_directories(custom_widgets_reader PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) # App-specific theme.h needed because themable.h → theme_manager.h → theme.h target_include_directories(custom_widgets_reader PRIVATE - ${CMAKE_SOURCE_DIR}/YACReader/themes + ${PROJECT_SOURCE_DIR}/YACReader/themes ) target_compile_definitions(custom_widgets_reader PRIVATE YACREADER) target_link_libraries(custom_widgets_reader PUBLIC @@ -85,9 +85,9 @@ add_library(custom_widgets_library STATIC target_include_directories(custom_widgets_library PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) # App-specific theme.h + YACReaderLibrary headers needed by macosx_toolbar target_include_directories(custom_widgets_library PRIVATE - ${CMAKE_SOURCE_DIR}/YACReaderLibrary/themes - ${CMAKE_SOURCE_DIR}/YACReaderLibrary - ${CMAKE_SOURCE_DIR}/YACReaderLibrary/db + ${PROJECT_SOURCE_DIR}/YACReaderLibrary/themes + ${PROJECT_SOURCE_DIR}/YACReaderLibrary + ${PROJECT_SOURCE_DIR}/YACReaderLibrary/db ) target_compile_definitions(custom_widgets_library PRIVATE YACREADER_LIBRARY) target_link_libraries(custom_widgets_library PUBLIC diff --git a/shortcuts_management/CMakeLists.txt b/shortcuts_management/CMakeLists.txt index a658e4128..4cbbd7217 100644 --- a/shortcuts_management/CMakeLists.txt +++ b/shortcuts_management/CMakeLists.txt @@ -19,7 +19,7 @@ add_library(shortcuts_reader STATIC ${SHORTCUTS_SOURCES}) target_include_directories(shortcuts_reader PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) # App-specific theme.h needed because themable.h → theme_manager.h → theme.h target_include_directories(shortcuts_reader PRIVATE - ${CMAKE_SOURCE_DIR}/YACReader/themes + ${PROJECT_SOURCE_DIR}/YACReader/themes ) target_compile_definitions(shortcuts_reader PRIVATE YACREADER) target_link_libraries(shortcuts_reader PUBLIC Qt::Core Qt::Widgets yr_global common_gui) @@ -28,7 +28,7 @@ target_link_libraries(shortcuts_reader PUBLIC Qt::Core Qt::Widgets yr_global com add_library(shortcuts_library STATIC ${SHORTCUTS_SOURCES}) target_include_directories(shortcuts_library PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(shortcuts_library PRIVATE - ${CMAKE_SOURCE_DIR}/YACReaderLibrary/themes + ${PROJECT_SOURCE_DIR}/YACReaderLibrary/themes ) target_compile_definitions(shortcuts_library PRIVATE YACREADER_LIBRARY) target_link_libraries(shortcuts_library PUBLIC Qt::Core Qt::Widgets yr_global common_gui) From 586c748b42852a1c9c6624eb740f71825d74df27 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 16:14:15 +0200 Subject: [PATCH 178/187] Set the maximum upper cmake version tested --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 095fd242a..82d1f7574 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.25) +cmake_minimum_required(VERSION 3.25...4.3.1) project(YACReader VERSION 10.0.0 From 1a28111dae93e7750630827fe39e54427c9c9c21 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 16:34:02 +0200 Subject: [PATCH 179/187] Migrate qt_add_resources to the Qt6 target-based approach --- YACReader/CMakeLists.txt | 166 ++++++++++++- YACReader/themes/themes.qrc | 16 -- YACReader/yacreader_files.qrc | 12 - YACReader/yacreader_images.qrc | 92 ------- YACReaderLibrary/CMakeLists.txt | 264 +++++++++++++++++++-- YACReaderLibrary/files.qrc | 12 - YACReaderLibrary/images.qrc | 122 ---------- YACReaderLibrary/images_osx.qrc | 5 - YACReaderLibrary/images_win.qrc | 6 - YACReaderLibrary/qml.qrc | 24 -- YACReaderLibrary/themes/themes.qrc | 16 -- common/themes/appearance_config_images.qrc | 8 - 12 files changed, 404 insertions(+), 339 deletions(-) delete mode 100644 YACReader/themes/themes.qrc delete mode 100644 YACReader/yacreader_files.qrc delete mode 100644 YACReader/yacreader_images.qrc delete mode 100644 YACReaderLibrary/files.qrc delete mode 100644 YACReaderLibrary/images.qrc delete mode 100644 YACReaderLibrary/images_osx.qrc delete mode 100644 YACReaderLibrary/images_win.qrc delete mode 100644 YACReaderLibrary/qml.qrc delete mode 100644 YACReaderLibrary/themes/themes.qrc delete mode 100644 common/themes/appearance_config_images.qrc diff --git a/YACReader/CMakeLists.txt b/YACReader/CMakeLists.txt index 070fb9dd5..e6f74b0ae 100644 --- a/YACReader/CMakeLists.txt +++ b/YACReader/CMakeLists.txt @@ -54,15 +54,163 @@ target_include_directories(YACReader PRIVATE target_compile_definitions(YACReader PRIVATE YACREADER) # Resources -qt_add_resources(yacreader_images_rcc "${CMAKE_CURRENT_SOURCE_DIR}/yacreader_images.qrc") -qt_add_resources(yacreader_files_rcc "${CMAKE_CURRENT_SOURCE_DIR}/yacreader_files.qrc") -qt_add_resources(yacreader_themes_rcc "${CMAKE_CURRENT_SOURCE_DIR}/themes/themes.qrc") -qt_add_resources(yacreader_common_images_rcc "${PROJECT_SOURCE_DIR}/common/themes/appearance_config_images.qrc") -target_sources(YACReader PRIVATE - ${yacreader_images_rcc} - ${yacreader_files_rcc} - ${yacreader_themes_rcc} - ${yacreader_common_images_rcc} +set(yacreader_image_files + ${PROJECT_SOURCE_DIR}/images/icon-new.svg + ${PROJECT_SOURCE_DIR}/images/goto.svg + ${PROJECT_SOURCE_DIR}/images/find_folder.svg + ${PROJECT_SOURCE_DIR}/images/flow1.png + ${PROJECT_SOURCE_DIR}/images/flow2.png + ${PROJECT_SOURCE_DIR}/images/flow3.png + ${PROJECT_SOURCE_DIR}/images/flow4.png + ${PROJECT_SOURCE_DIR}/images/flow5.png + ${PROJECT_SOURCE_DIR}/images/notCover.png + ${PROJECT_SOURCE_DIR}/images/close.svg + ${PROJECT_SOURCE_DIR}/images/centerFlow.svg + ${PROJECT_SOURCE_DIR}/images/gotoFlow.svg + ${PROJECT_SOURCE_DIR}/images/defaultCover.png + ${PROJECT_SOURCE_DIR}/images/translator/close.svg + ${PROJECT_SOURCE_DIR}/images/translator/dropDownArrow.svg + ${PROJECT_SOURCE_DIR}/images/translator/fromTo.svg + ${PROJECT_SOURCE_DIR}/images/translator/speaker.svg + ${PROJECT_SOURCE_DIR}/images/translator/translatorSearch.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/clear_shortcut.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/accept_shortcut.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_comics.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_folders.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_general.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_libraries.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_mglass.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_page.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_reading.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_visualization.svg + ${PROJECT_SOURCE_DIR}/images/custom_dialog/custom_close_button.svg + ${PROJECT_SOURCE_DIR}/images/whats_new/whatsnew_header.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/bookmark.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/close.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/doublePage.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/doubleMangaPage.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/fitToPage.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/flow.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/full.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/goto.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/help.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/info.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/magnifyingGlass.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/next.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/open.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/openFolder.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/openNext.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/openPrevious.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/options.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/previous.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/rotateL.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/rotateR.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/save.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/shortcuts.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/showBookmarks.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/toHeight.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/toContinuousScroll.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/toWidth.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/translator.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/zoom.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/bookmark_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/close_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/doublePage_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/doubleMangaPage_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/fitToPage_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/flow_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/full_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/goto_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/help_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/info_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/magnifyingGlass_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/next_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/open_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/openFolder_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/openNext_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/openPrevious_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/options_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/previous_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/rotateL_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/rotateR_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/save_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/shortcuts_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/showBookmarks_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/toHeight_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/toContinuousScroll_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/toWidth_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/translator_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/zoom_18x18.svg + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/menuArrow.svg +) +set(yacreader_file_files + ${PROJECT_SOURCE_DIR}/files/about.html + ${PROJECT_SOURCE_DIR}/files/helpYACReader.html + ${PROJECT_SOURCE_DIR}/files/shortcuts.html +) +set(yacreader_file_files_es + ${PROJECT_SOURCE_DIR}/files/about_es_ES.html + ${PROJECT_SOURCE_DIR}/files/helpYACReader_es_ES.html +) +set_source_files_properties( + ${PROJECT_SOURCE_DIR}/files/about_es_ES.html + PROPERTIES QT_RESOURCE_ALIAS "about.html" +) +set_source_files_properties( + ${PROJECT_SOURCE_DIR}/files/helpYACReader_es_ES.html + PROPERTIES QT_RESOURCE_ALIAS "helpYACReader.html" +) +set(yacreader_theme_files + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_classic.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_light.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_light1.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_light2.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_light3.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_light4.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_light5.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_dark.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_dark1.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_dark2.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_dark3.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_dark4.json +) +set(yacreader_common_theme_image_files + ${PROJECT_SOURCE_DIR}/images/appearance_config/theme-mode-system.svg + ${PROJECT_SOURCE_DIR}/images/appearance_config/theme-mode-light.svg + ${PROJECT_SOURCE_DIR}/images/appearance_config/theme-mode-dark.svg + ${PROJECT_SOURCE_DIR}/images/appearance_config/theme-mode-custom.svg +) + +qt_add_resources(YACReader "yacreader_images" + PREFIX "/" + BASE "${PROJECT_SOURCE_DIR}" + FILES + ${yacreader_image_files} +) +qt_add_resources(YACReader "yacreader_files" + PREFIX "/files" + BASE "${PROJECT_SOURCE_DIR}/files" + FILES + ${yacreader_file_files} +) +qt_add_resources(YACReader "yacreader_files_es" + PREFIX "/files" + LANG "es_ES" + BASE "${PROJECT_SOURCE_DIR}/files" + FILES + ${yacreader_file_files_es} +) +qt_add_resources(YACReader "yacreader_themes" + PREFIX "/themes" + BASE "${CMAKE_CURRENT_SOURCE_DIR}/themes" + FILES + ${yacreader_theme_files} +) +qt_add_resources(YACReader "yacreader_common_theme_images" + PREFIX "/" + BASE "${PROJECT_SOURCE_DIR}" + FILES + ${yacreader_common_theme_image_files} ) # Translations diff --git a/YACReader/themes/themes.qrc b/YACReader/themes/themes.qrc deleted file mode 100644 index d96de307d..000000000 --- a/YACReader/themes/themes.qrc +++ /dev/null @@ -1,16 +0,0 @@ - - - builtin_classic.json - builtin_light.json - builtin_light1.json - builtin_light2.json - builtin_light3.json - builtin_light4.json - builtin_light5.json - builtin_dark.json - builtin_dark1.json - builtin_dark2.json - builtin_dark3.json - builtin_dark4.json - - diff --git a/YACReader/yacreader_files.qrc b/YACReader/yacreader_files.qrc deleted file mode 100644 index b75403122..000000000 --- a/YACReader/yacreader_files.qrc +++ /dev/null @@ -1,12 +0,0 @@ - - - ../files/about.html - ../files/helpYACReader.html - ../files/shortcuts.html - - - - ../files/about_es_ES.html - ../files/helpYACReader_es_ES.html - - diff --git a/YACReader/yacreader_images.qrc b/YACReader/yacreader_images.qrc deleted file mode 100644 index a573b9fb3..000000000 --- a/YACReader/yacreader_images.qrc +++ /dev/null @@ -1,92 +0,0 @@ - - - ../images/icon-new.svg - ../images/goto.svg - ../images/find_folder.svg - ../images/flow1.png - ../images/flow2.png - ../images/flow3.png - ../images/flow4.png - ../images/flow5.png - ../images/notCover.png - ../images/close.svg - ../images/centerFlow.svg - ../images/gotoFlow.svg - ../images/defaultCover.png - - ../images/translator/close.svg - ../images/translator/dropDownArrow.svg - ../images/translator/fromTo.svg - ../images/translator/speaker.svg - ../images/translator/translatorSearch.svg - ../images/shortcuts/clear_shortcut.svg - ../images/shortcuts/accept_shortcut.svg - ../images/shortcuts/shortcuts_group_comics.svg - ../images/shortcuts/shortcuts_group_folders.svg - ../images/shortcuts/shortcuts_group_general.svg - ../images/shortcuts/shortcuts_group_libraries.svg - ../images/shortcuts/shortcuts_group_mglass.svg - ../images/shortcuts/shortcuts_group_page.svg - ../images/shortcuts/shortcuts_group_reading.svg - ../images/shortcuts/shortcuts_group_visualization.svg - ../images/custom_dialog/custom_close_button.svg - ../images/whats_new/whatsnew_header.svg - ../images/viewer_toolbar/bookmark.svg - ../images/viewer_toolbar/close.svg - ../images/viewer_toolbar/doublePage.svg - ../images/viewer_toolbar/doubleMangaPage.svg - ../images/viewer_toolbar/fitToPage.svg - ../images/viewer_toolbar/flow.svg - ../images/viewer_toolbar/full.svg - ../images/viewer_toolbar/goto.svg - ../images/viewer_toolbar/help.svg - ../images/viewer_toolbar/info.svg - ../images/viewer_toolbar/magnifyingGlass.svg - ../images/viewer_toolbar/next.svg - ../images/viewer_toolbar/open.svg - ../images/viewer_toolbar/openFolder.svg - ../images/viewer_toolbar/openNext.svg - ../images/viewer_toolbar/openPrevious.svg - ../images/viewer_toolbar/options.svg - ../images/viewer_toolbar/previous.svg - ../images/viewer_toolbar/rotateL.svg - ../images/viewer_toolbar/rotateR.svg - ../images/viewer_toolbar/save.svg - ../images/viewer_toolbar/shortcuts.svg - ../images/viewer_toolbar/showBookmarks.svg - ../images/viewer_toolbar/toHeight.svg - ../images/viewer_toolbar/toContinuousScroll.svg - ../images/viewer_toolbar/toWidth.svg - ../images/viewer_toolbar/translator.svg - ../images/viewer_toolbar/zoom.svg - ../images/viewer_toolbar/bookmark_18x18.svg - ../images/viewer_toolbar/close_18x18.svg - ../images/viewer_toolbar/doublePage_18x18.svg - ../images/viewer_toolbar/doubleMangaPage_18x18.svg - ../images/viewer_toolbar/fitToPage_18x18.svg - ../images/viewer_toolbar/flow_18x18.svg - ../images/viewer_toolbar/full_18x18.svg - ../images/viewer_toolbar/goto_18x18.svg - ../images/viewer_toolbar/help_18x18.svg - ../images/viewer_toolbar/info_18x18.svg - ../images/viewer_toolbar/magnifyingGlass_18x18.svg - ../images/viewer_toolbar/next_18x18.svg - ../images/viewer_toolbar/open_18x18.svg - ../images/viewer_toolbar/openFolder_18x18.svg - ../images/viewer_toolbar/openNext_18x18.svg - ../images/viewer_toolbar/openPrevious_18x18.svg - ../images/viewer_toolbar/options_18x18.svg - ../images/viewer_toolbar/previous_18x18.svg - ../images/viewer_toolbar/rotateL_18x18.svg - ../images/viewer_toolbar/rotateR_18x18.svg - ../images/viewer_toolbar/save_18x18.svg - ../images/viewer_toolbar/shortcuts_18x18.svg - ../images/viewer_toolbar/showBookmarks_18x18.svg - ../images/viewer_toolbar/toHeight_18x18.svg - ../images/viewer_toolbar/toContinuousScroll_18x18.svg - ../images/viewer_toolbar/toWidth_18x18.svg - ../images/viewer_toolbar/translator_18x18.svg - ../images/viewer_toolbar/zoom_18x18.svg - ../images/viewer_toolbar/menuArrow.svg - - diff --git a/YACReaderLibrary/CMakeLists.txt b/YACReaderLibrary/CMakeLists.txt index a86629faf..ef562b5e3 100644 --- a/YACReaderLibrary/CMakeLists.txt +++ b/YACReaderLibrary/CMakeLists.txt @@ -200,32 +200,262 @@ target_compile_definitions(YACReaderLibrary PRIVATE ) # Resources -qt_add_resources(yacreaderlibrary_images_rcc "${CMAKE_CURRENT_SOURCE_DIR}/images.qrc") -qt_add_resources(yacreaderlibrary_files_rcc "${CMAKE_CURRENT_SOURCE_DIR}/files.qrc") -qt_add_resources(yacreaderlibrary_qml_rcc "${CMAKE_CURRENT_SOURCE_DIR}/qml.qrc") -qt_add_resources(yacreaderlibrary_themes_rcc "${CMAKE_CURRENT_SOURCE_DIR}/themes/themes.qrc") -qt_add_resources(yacreaderlibrary_common_images_rcc "${PROJECT_SOURCE_DIR}/common/themes/appearance_config_images.qrc") -target_sources(YACReaderLibrary PRIVATE - ${yacreaderlibrary_images_rcc} - ${yacreaderlibrary_files_rcc} - ${yacreaderlibrary_qml_rcc} - ${yacreaderlibrary_themes_rcc} - ${yacreaderlibrary_common_images_rcc} +set(yacreaderlibrary_image_files + ${PROJECT_SOURCE_DIR}/images/shortcuts/accept_shortcut.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/clear_shortcut.svg + ${PROJECT_SOURCE_DIR}/images/comic_vine/downArrow.svg + ${PROJECT_SOURCE_DIR}/images/comic_vine/nextPage.svg + ${PROJECT_SOURCE_DIR}/images/comic_vine/previousPage.svg + ${PROJECT_SOURCE_DIR}/images/comic_vine/radioChecked.svg + ${PROJECT_SOURCE_DIR}/images/comic_vine/radioUnchecked.svg + ${PROJECT_SOURCE_DIR}/images/comic_vine/rowDown.svg + ${PROJECT_SOURCE_DIR}/images/comic_vine/rowUp.svg + ${PROJECT_SOURCE_DIR}/images/comic_vine/upArrow.svg + ${PROJECT_SOURCE_DIR}/images/comic_vine/checkBoxTick.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/asignNumber.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/big_size_grid_zoom.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/editComic.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/getInfo.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/hideComicFlow.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/openInYACReader.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/selectAll.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/setReadButton.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/setUnread.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/showMarks.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/small_size_grid_zoom.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/trash.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/show_comic_info.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/setManga.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/setNormal.svg + ${PROJECT_SOURCE_DIR}/images/comics_view_toolbar/showRecentIndicator.svg + ${PROJECT_SOURCE_DIR}/images/defaultCover.png + ${PROJECT_SOURCE_DIR}/images/library_dialogs/edit.svg + ${PROJECT_SOURCE_DIR}/images/empty_container/empty_current_readings.svg + ${PROJECT_SOURCE_DIR}/images/empty_container/empty_favorites.svg + ${PROJECT_SOURCE_DIR}/images/empty_container/empty_folder.svg + ${PROJECT_SOURCE_DIR}/images/empty_container/empty_label.svg + ${PROJECT_SOURCE_DIR}/images/empty_container/empty_reading_list.svg + ${PROJECT_SOURCE_DIR}/images/library_dialogs/exportComicsInfo.svg + ${PROJECT_SOURCE_DIR}/images/library_dialogs/exportLibrary.svg + ${PROJECT_SOURCE_DIR}/images/find_folder.svg + ${PROJECT_SOURCE_DIR}/images/flow1.png + ${PROJECT_SOURCE_DIR}/images/flow2.png + ${PROJECT_SOURCE_DIR}/images/flow3.png + ${PROJECT_SOURCE_DIR}/images/flow4.png + ${PROJECT_SOURCE_DIR}/images/flow5.png + ${PROJECT_SOURCE_DIR}/images/glowLine.svg + ${PROJECT_SOURCE_DIR}/images/metadata_dialog/loadCustomCover.svg + ${PROJECT_SOURCE_DIR}/images/import/coversToggle.svg + ${PROJECT_SOURCE_DIR}/images/icon-new.svg + ${PROJECT_SOURCE_DIR}/images/iconLibrary.png + ${PROJECT_SOURCE_DIR}/images/import/importBottomCoversDecoration.svg + ${PROJECT_SOURCE_DIR}/images/library_dialogs/importComicsInfo.svg + ${PROJECT_SOURCE_DIR}/images/import/importingIcon.svg + ${PROJECT_SOURCE_DIR}/images/library_dialogs/importLibrary.svg + ${PROJECT_SOURCE_DIR}/images/import/importTopCoversDecoration.svg + ${PROJECT_SOURCE_DIR}/images/main_toolbar/back.svg + ${PROJECT_SOURCE_DIR}/images/main_toolbar/forward.svg + ${PROJECT_SOURCE_DIR}/images/main_toolbar/settings.svg + ${PROJECT_SOURCE_DIR}/images/main_toolbar/server.svg + ${PROJECT_SOURCE_DIR}/images/main_toolbar/help.svg + ${PROJECT_SOURCE_DIR}/images/main_toolbar/fullscreen.svg + ${PROJECT_SOURCE_DIR}/images/main_toolbar/flow.svg + ${PROJECT_SOURCE_DIR}/images/main_toolbar/grid.svg + ${PROJECT_SOURCE_DIR}/images/main_toolbar/info.svg + ${PROJECT_SOURCE_DIR}/images/main_toolbar/divider.svg + ${PROJECT_SOURCE_DIR}/images/menus_icons/editIcon.svg + ${PROJECT_SOURCE_DIR}/images/menus_icons/exportComicsInfoIcon.svg + ${PROJECT_SOURCE_DIR}/images/menus_icons/exportLibraryIcon.svg + ${PROJECT_SOURCE_DIR}/images/menus_icons/importComicsInfoIcon.svg + ${PROJECT_SOURCE_DIR}/images/menus_icons/importLibraryIcon.svg + ${PROJECT_SOURCE_DIR}/images/menus_icons/removeLibraryIcon.svg + ${PROJECT_SOURCE_DIR}/images/menus_icons/updateLibraryIcon.svg + ${PROJECT_SOURCE_DIR}/images/menus_icons/open_containing_folder.svg + ${PROJECT_SOURCE_DIR}/images/menus_icons/update_current_folder.svg + ${PROJECT_SOURCE_DIR}/images/library_dialogs/new.svg + ${PROJECT_SOURCE_DIR}/images/metadata_dialog/nextCoverPage.svg + ${PROJECT_SOURCE_DIR}/images/noLibrariesIcon.svg + ${PROJECT_SOURCE_DIR}/images/noLibrariesLine.svg + ${PROJECT_SOURCE_DIR}/images/notCover.png + ${PROJECT_SOURCE_DIR}/images/library_dialogs/openLibrary.svg + ${PROJECT_SOURCE_DIR}/images/metadata_dialog/previousCoverPage.svg + ${PROJECT_SOURCE_DIR}/images/readingRibbon.svg + ${PROJECT_SOURCE_DIR}/images/readRibbon.svg + ${PROJECT_SOURCE_DIR}/images/metadata_dialog/resetCover.svg + ${PROJECT_SOURCE_DIR}/images/search_result.svg + ${PROJECT_SOURCE_DIR}/images/serverConfigBackground.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_comics.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_folders.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_general.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_libraries.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_mglass.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_page.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_reading.svg + ${PROJECT_SOURCE_DIR}/images/shortcuts/shortcuts_group_visualization.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/libraryIcon.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/setRoot.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/expand.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/colapse.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/newLibraryIcon.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/openLibraryIcon.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/addNew_sidebar.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/delete_sidebar.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/addLabelIcon.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/renameListIcon.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/branch-closed.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/branch-open.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/folder.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/folder_finished.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/folder_read_overlay.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/libraryIconSelected.svg + ${PROJECT_SOURCE_DIR}/images/sidebar/libraryOptions.svg + ${PROJECT_SOURCE_DIR}/images/import/updatingIcon.svg + ${PROJECT_SOURCE_DIR}/images/custom_dialog/custom_close_button.svg + ${PROJECT_SOURCE_DIR}/images/whats_new/whatsnew_header.svg + ${PROJECT_SOURCE_DIR}/images/lists/default_0.svg + ${PROJECT_SOURCE_DIR}/images/lists/default_1.svg + ${PROJECT_SOURCE_DIR}/images/lists/default_2.svg + ${PROJECT_SOURCE_DIR}/images/lists/label_template.svg + ${PROJECT_SOURCE_DIR}/images/lists/list.svg + ${PROJECT_SOURCE_DIR}/images/clearSearchNew.svg + ${PROJECT_SOURCE_DIR}/images/iconSearchNew.svg +) +set(yacreaderlibrary_file_files + ${PROJECT_SOURCE_DIR}/files/about.html + ${PROJECT_SOURCE_DIR}/files/helpYACReaderLibrary.html +) +set(yacreaderlibrary_file_files_es + ${PROJECT_SOURCE_DIR}/files/about_es_ES.html + ${PROJECT_SOURCE_DIR}/files/helpYACReaderLibrary_es_ES.html +) +set_source_files_properties( + ${PROJECT_SOURCE_DIR}/files/about_es_ES.html + PROPERTIES QT_RESOURCE_ALIAS "about.html" +) +set_source_files_properties( + ${PROJECT_SOURCE_DIR}/files/helpYACReaderLibrary_es_ES.html + PROPERTIES QT_RESOURCE_ALIAS "helpYACReaderLibrary.html" +) +set(yacreaderlibrary_qml_files + ${CMAKE_CURRENT_SOURCE_DIR}/qml/GridComicsView.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/FolderContentView.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/FlowView.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/InfoTick.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/InfoFavorites.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/InfoRating.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/InfoComicsView.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/tick.svg + ${CMAKE_CURRENT_SOURCE_DIR}/qml/reading.svg + ${CMAKE_CURRENT_SOURCE_DIR}/qml/star.svg + ${CMAKE_CURRENT_SOURCE_DIR}/qml/page.svg + ${CMAKE_CURRENT_SOURCE_DIR}/qml/info-indicator.svg + ${CMAKE_CURRENT_SOURCE_DIR}/qml/info-shadow.svg + ${CMAKE_CURRENT_SOURCE_DIR}/qml/info-top-shadow.svg + ${CMAKE_CURRENT_SOURCE_DIR}/qml/ComicInfoView.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/info-favorites.svg + ${CMAKE_CURRENT_SOURCE_DIR}/qml/info-rating.svg + ${CMAKE_CURRENT_SOURCE_DIR}/qml/info-tag.svg + ${CMAKE_CURRENT_SOURCE_DIR}/qml/info-tick.svg + ${CMAKE_CURRENT_SOURCE_DIR}/qml/prerendered_cover_shadow.png +) +set(yacreaderlibrary_qml_translation_files + ${CMAKE_CURRENT_SOURCE_DIR}/qml/GridComicsView.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/FolderContentView.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/FlowView.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/InfoTick.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/InfoFavorites.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/InfoRating.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/InfoComicsView.qml + ${CMAKE_CURRENT_SOURCE_DIR}/qml/ComicInfoView.qml +) +set(yacreaderlibrary_theme_files + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_classic.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_light.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_light1.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_light2.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_light3.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_light4.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_light5.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_dark.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_dark1.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_dark2.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_dark3.json + ${CMAKE_CURRENT_SOURCE_DIR}/themes/builtin_dark4.json +) +set(yacreaderlibrary_common_theme_image_files + ${PROJECT_SOURCE_DIR}/images/appearance_config/theme-mode-system.svg + ${PROJECT_SOURCE_DIR}/images/appearance_config/theme-mode-light.svg + ${PROJECT_SOURCE_DIR}/images/appearance_config/theme-mode-dark.svg + ${PROJECT_SOURCE_DIR}/images/appearance_config/theme-mode-custom.svg +) + +qt_add_resources(YACReaderLibrary "yacreaderlibrary_images" + PREFIX "/" + BASE "${PROJECT_SOURCE_DIR}" + FILES + ${yacreaderlibrary_image_files} +) +qt_add_resources(YACReaderLibrary "yacreaderlibrary_files" + PREFIX "/files" + BASE "${PROJECT_SOURCE_DIR}/files" + FILES + ${yacreaderlibrary_file_files} +) +qt_add_resources(YACReaderLibrary "yacreaderlibrary_files_es" + PREFIX "/files" + LANG "es_ES" + BASE "${PROJECT_SOURCE_DIR}/files" + FILES + ${yacreaderlibrary_file_files_es} +) +qt_add_resources(YACReaderLibrary "yacreaderlibrary_qml" + PREFIX "/" + BASE "${CMAKE_CURRENT_SOURCE_DIR}" + FILES + ${yacreaderlibrary_qml_files} +) +qt_add_resources(YACReaderLibrary "yacreaderlibrary_themes" + PREFIX "/themes" + BASE "${CMAKE_CURRENT_SOURCE_DIR}/themes" + FILES + ${yacreaderlibrary_theme_files} +) +qt_add_resources(YACReaderLibrary "yacreaderlibrary_common_theme_images" + PREFIX "/" + BASE "${PROJECT_SOURCE_DIR}" + FILES + ${yacreaderlibrary_common_theme_image_files} ) if(WIN32 OR (UNIX AND NOT APPLE)) - qt_add_resources(yacreaderlibrary_images_win_rcc "${CMAKE_CURRENT_SOURCE_DIR}/images_win.qrc") - target_sources(YACReaderLibrary PRIVATE ${yacreaderlibrary_images_win_rcc}) + set(yacreaderlibrary_windows_resource_files + ${PROJECT_SOURCE_DIR}/images/viewer_toolbar/close.svg + ${CMAKE_CURRENT_SOURCE_DIR}/icon.ico + ) + set_source_files_properties( + ${CMAKE_CURRENT_SOURCE_DIR}/icon.ico + PROPERTIES QT_RESOURCE_ALIAS "icon.ico" + ) + qt_add_resources(YACReaderLibrary "yacreaderlibrary_windows_resources" + PREFIX "/" + BASE "${PROJECT_SOURCE_DIR}" + FILES + ${yacreaderlibrary_windows_resource_files} + ) endif() if(APPLE) - qt_add_resources(yacreaderlibrary_images_osx_rcc "${CMAKE_CURRENT_SOURCE_DIR}/images_osx.qrc") - target_sources(YACReaderLibrary PRIVATE ${yacreaderlibrary_images_osx_rcc}) + qt_add_resources(YACReaderLibrary "yacreaderlibrary_macos_resources" + PREFIX "/" + BASE "${CMAKE_CURRENT_SOURCE_DIR}" + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/macostrayicon.svg + ) endif() # Translations qt_add_translations(YACReaderLibrary SOURCE_TARGETS YACReaderLibrary - # Keep full C++ extraction via SOURCE_TARGETS and add qml.qrc as extra input + # Keep full C++ extraction via SOURCE_TARGETS and add the QML files directly # so qsTr() strings in QML are collected too. TS_FILES yacreaderlibrary_es.ts @@ -242,7 +472,7 @@ qt_add_translations(YACReaderLibrary yacreaderlibrary_source.ts yacreaderlibrary_en.ts SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/qml.qrc + ${yacreaderlibrary_qml_translation_files} ) target_link_libraries(YACReaderLibrary PRIVATE diff --git a/YACReaderLibrary/files.qrc b/YACReaderLibrary/files.qrc deleted file mode 100644 index 7a37b2ec1..000000000 --- a/YACReaderLibrary/files.qrc +++ /dev/null @@ -1,12 +0,0 @@ - - - ../files/about.html - ../files/helpYACReaderLibrary.html - - - - ../files/about_es_ES.html - ../files/helpYACReaderLibrary_es_ES.html - - - diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc deleted file mode 100644 index 86783e830..000000000 --- a/YACReaderLibrary/images.qrc +++ /dev/null @@ -1,122 +0,0 @@ - - - ../images/shortcuts/accept_shortcut.svg - ../images/shortcuts/clear_shortcut.svg - ../images/comic_vine/downArrow.svg - ../images/comic_vine/nextPage.svg - ../images/comic_vine/previousPage.svg - ../images/comic_vine/radioChecked.svg - ../images/comic_vine/radioUnchecked.svg - ../images/comic_vine/rowDown.svg - ../images/comic_vine/rowUp.svg - ../images/comic_vine/upArrow.svg - ../images/comic_vine/checkBoxTick.svg - ../images/comics_view_toolbar/asignNumber.svg - ../images/comics_view_toolbar/big_size_grid_zoom.svg - ../images/comics_view_toolbar/editComic.svg - ../images/comics_view_toolbar/getInfo.svg - ../images/comics_view_toolbar/hideComicFlow.svg - ../images/comics_view_toolbar/openInYACReader.svg - ../images/comics_view_toolbar/selectAll.svg - ../images/comics_view_toolbar/setReadButton.svg - ../images/comics_view_toolbar/setUnread.svg - ../images/comics_view_toolbar/showMarks.svg - ../images/comics_view_toolbar/small_size_grid_zoom.svg - ../images/comics_view_toolbar/trash.svg - ../images/comics_view_toolbar/show_comic_info.svg - ../images/comics_view_toolbar/setManga.svg - ../images/comics_view_toolbar/setNormal.svg - ../images/comics_view_toolbar/showRecentIndicator.svg - ../images/defaultCover.png - ../images/library_dialogs/edit.svg - ../images/empty_container/empty_current_readings.svg - ../images/empty_container/empty_favorites.svg - ../images/empty_container/empty_folder.svg - ../images/empty_container/empty_label.svg - ../images/empty_container/empty_reading_list.svg - ../images/library_dialogs/exportComicsInfo.svg - ../images/library_dialogs/exportLibrary.svg - ../images/find_folder.svg - ../images/flow1.png - ../images/flow2.png - ../images/flow3.png - ../images/flow4.png - ../images/flow5.png - ../images/glowLine.svg - ../images/metadata_dialog/loadCustomCover.svg - ../images/import/coversToggle.svg - ../images/icon-new.svg - ../images/iconLibrary.png - ../images/import/importBottomCoversDecoration.svg - ../images/library_dialogs/importComicsInfo.svg - ../images/import/importingIcon.svg - ../images/library_dialogs/importLibrary.svg - ../images/import/importTopCoversDecoration.svg - ../images/main_toolbar/back.svg - ../images/main_toolbar/forward.svg - ../images/main_toolbar/settings.svg - ../images/main_toolbar/server.svg - ../images/main_toolbar/help.svg - ../images/main_toolbar/fullscreen.svg - ../images/main_toolbar/flow.svg - ../images/main_toolbar/grid.svg - ../images/main_toolbar/info.svg - ../images/main_toolbar/divider.svg - ../images/menus_icons/editIcon.svg - ../images/menus_icons/exportComicsInfoIcon.svg - ../images/menus_icons/exportLibraryIcon.svg - ../images/menus_icons/importComicsInfoIcon.svg - ../images/menus_icons/importLibraryIcon.svg - ../images/menus_icons/removeLibraryIcon.svg - ../images/menus_icons/updateLibraryIcon.svg - ../images/menus_icons/open_containing_folder.svg - ../images/menus_icons/update_current_folder.svg - ../images/library_dialogs/new.svg - ../images/metadata_dialog/nextCoverPage.svg - ../images/noLibrariesIcon.svg - ../images/noLibrariesLine.svg - ../images/notCover.png - ../images/library_dialogs/openLibrary.svg - ../images/metadata_dialog/previousCoverPage.svg - ../images/readingRibbon.svg - ../images/readRibbon.svg - ../images/metadata_dialog/resetCover.svg - ../images/search_result.svg - ../images/serverConfigBackground.svg - ../images/shortcuts/shortcuts_group_comics.svg - ../images/shortcuts/shortcuts_group_folders.svg - ../images/shortcuts/shortcuts_group_general.svg - ../images/shortcuts/shortcuts_group_libraries.svg - ../images/shortcuts/shortcuts_group_mglass.svg - ../images/shortcuts/shortcuts_group_page.svg - ../images/shortcuts/shortcuts_group_reading.svg - ../images/shortcuts/shortcuts_group_visualization.svg - ../images/sidebar/libraryIcon.svg - ../images/sidebar/setRoot.svg - ../images/sidebar/expand.svg - ../images/sidebar/colapse.svg - ../images/sidebar/newLibraryIcon.svg - ../images/sidebar/openLibraryIcon.svg - ../images/sidebar/addNew_sidebar.svg - ../images/sidebar/delete_sidebar.svg - ../images/sidebar/addLabelIcon.svg - ../images/sidebar/renameListIcon.svg - ../images/sidebar/branch-closed.svg - ../images/sidebar/branch-open.svg - ../images/sidebar/folder.svg - ../images/sidebar/folder_finished.svg - ../images/sidebar/folder_read_overlay.svg - ../images/sidebar/libraryIconSelected.svg - ../images/sidebar/libraryOptions.svg - ../images/import/updatingIcon.svg - ../images/custom_dialog/custom_close_button.svg - ../images/whats_new/whatsnew_header.svg - ../images/lists/default_0.svg - ../images/lists/default_1.svg - ../images/lists/default_2.svg - ../images/lists/label_template.svg - ../images/lists/list.svg - ../images/clearSearchNew.svg - ../images/iconSearchNew.svg - - diff --git a/YACReaderLibrary/images_osx.qrc b/YACReaderLibrary/images_osx.qrc deleted file mode 100644 index a26df5b0f..000000000 --- a/YACReaderLibrary/images_osx.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - macostrayicon.svg - - diff --git a/YACReaderLibrary/images_win.qrc b/YACReaderLibrary/images_win.qrc deleted file mode 100644 index 9eb496efc..000000000 --- a/YACReaderLibrary/images_win.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - ../images/viewer_toolbar/close.svg - icon.ico - - diff --git a/YACReaderLibrary/qml.qrc b/YACReaderLibrary/qml.qrc deleted file mode 100644 index 2d767d062..000000000 --- a/YACReaderLibrary/qml.qrc +++ /dev/null @@ -1,24 +0,0 @@ - - - qml/GridComicsView.qml - qml/FolderContentView.qml - qml/FlowView.qml - qml/InfoTick.qml - qml/InfoFavorites.qml - qml/InfoRating.qml - qml/InfoComicsView.qml - qml/tick.svg - qml/reading.svg - qml/star.svg - qml/page.svg - qml/info-indicator.svg - qml/info-shadow.svg - qml/info-top-shadow.svg - qml/ComicInfoView.qml - qml/info-favorites.svg - qml/info-rating.svg - qml/info-tag.svg - qml/info-tick.svg - qml/prerendered_cover_shadow.png - - diff --git a/YACReaderLibrary/themes/themes.qrc b/YACReaderLibrary/themes/themes.qrc deleted file mode 100644 index d96de307d..000000000 --- a/YACReaderLibrary/themes/themes.qrc +++ /dev/null @@ -1,16 +0,0 @@ - - - builtin_classic.json - builtin_light.json - builtin_light1.json - builtin_light2.json - builtin_light3.json - builtin_light4.json - builtin_light5.json - builtin_dark.json - builtin_dark1.json - builtin_dark2.json - builtin_dark3.json - builtin_dark4.json - - diff --git a/common/themes/appearance_config_images.qrc b/common/themes/appearance_config_images.qrc deleted file mode 100644 index b67edae76..000000000 --- a/common/themes/appearance_config_images.qrc +++ /dev/null @@ -1,8 +0,0 @@ - - - ../../images/appearance_config/theme-mode-system.svg - ../../images/appearance_config/theme-mode-light.svg - ../../images/appearance_config/theme-mode-dark.svg - ../../images/appearance_config/theme-mode-custom.svg - - From 74aebffd9baf9eb6af8ca4b7bd796892712d9af0 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 16:41:54 +0200 Subject: [PATCH 180/187] Don't use CMAKE_RUNTIME_OUTPUT_DIRECTORY for Linux Windows and macos installer scripts are still used and they rely on that folder --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 82d1f7574..aa4e6da73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,7 +147,9 @@ qt_standard_project_setup() include(PdfBackend) # Output directory -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") +if(WIN32 OR APPLE) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") +endif() # Build number define if(BUILD_NUMBER) From 79a8acbd4291fba8a0647454f2ead41993aca7e6 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 17:19:40 +0200 Subject: [PATCH 181/187] Extract VERSION to avoid duplication --- .github/workflows/build.yml | 8 ++++---- CMakeLists.txt | 8 +++++++- VERSION | 1 + ci/win/create_installer.cmd | 6 +----- common/CMakeLists.txt | 15 +++++++++++++- common/check_new_version.cpp | 39 ++++++++---------------------------- common/version.h.in | 6 ++++++ common/yacreader_global.h | 5 ++++- compileOSX.sh | 2 +- 9 files changed, 46 insertions(+), 44 deletions(-) create mode 100644 VERSION create mode 100644 common/version.h.in diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e0e532317..b846abfd4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -153,7 +153,7 @@ jobs: env: MACOSX_DEPLOYMENT_TARGET: "11" run: | - VERSION="$(cat common/yacreader_global.h | grep '#define VERSION "' | tr -d '#define VERSION' | tr -d '"' )" + VERSION="$(tr -d '\r\n' < VERSION)" SKIP_CODESIGN="${{ env.IS_FORK }}" SKIP_CODESIGN=$(echo "$SKIP_CODESIGN" | tr '[:upper:]' '[:lower:]') ./compileOSX.sh $VERSION ${{ needs.initialization.outputs.build_number }} $SKIP_CODESIGN Qt6 universal @@ -510,7 +510,7 @@ jobs: - name: Get version id: version run: | - VERSION="$(cat common/yacreader_global.h | grep '#define VERSION "' | tr -d '#define VERSION' | tr -d '"' ).${{ needs.initialization.outputs.build_number }}" + VERSION="$(tr -d '\r\n' < VERSION).${{ needs.initialization.outputs.build_number }}" echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" @@ -577,7 +577,7 @@ jobs: - name: Get version id: version run: | - VERSION="$(cat common/yacreader_global.h | grep '#define VERSION "' | tr -d '#define VERSION' | tr -d '"' )" + VERSION="$(tr -d '\r\n' < VERSION)" echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" @@ -648,7 +648,7 @@ jobs: - name: Get version id: version run: | - VERSION="$(cat common/yacreader_global.h | grep '#define VERSION "' | tr -d '#define VERSION' | tr -d '"' ).${{ needs.initialization.outputs.build_number }}" + VERSION="$(tr -d '\r\n' < VERSION).${{ needs.initialization.outputs.build_number }}" echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" diff --git a/CMakeLists.txt b/CMakeLists.txt index aa4e6da73..84c86400e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,13 @@ cmake_minimum_required(VERSION 3.25...4.3.1) +file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" YACREADER_VERSION) +string(STRIP "${YACREADER_VERSION}" YACREADER_VERSION) +if(NOT YACREADER_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+$") + message(FATAL_ERROR "VERSION must contain a semantic version like x.y.z") +endif() + project(YACReader - VERSION 10.0.0 + VERSION ${YACREADER_VERSION} LANGUAGES C CXX ) diff --git a/VERSION b/VERSION new file mode 100644 index 000000000..95c4e8d27 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +10.0.0 \ No newline at end of file diff --git a/ci/win/create_installer.cmd b/ci/win/create_installer.cmd index 2a6580737..2c710359a 100644 --- a/ci/win/create_installer.cmd +++ b/ci/win/create_installer.cmd @@ -52,12 +52,8 @@ for /r %src_path%\build %%f in (*.qm) do ( copy %src_path%\vc_redist.%ARCH%.exe . -type %src_path%\common\yacreader_global.h | findstr /R /C:"#define VERSION " > tmp -set /p VERSION= < tmp -set VERSION=%VERSION:#define VERSION "=% -set VERSION=%VERSION:"=% +set /p VERSION=<%src_path%\VERSION echo %VERSION% -del tmp echo "iscc start" iscc /DVERSION=%VERSION% /DPLATFORM=%ARCH% /DCOMPRESSED_ARCHIVE_BACKEND=%COMPRESSION% /DBUILD_NUMBER=%BUILD_NUMBER% build_installer_qt6.iss || exit /b diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 47729aad8..96125dd69 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,12 +1,23 @@ # Common libraries for YACReader # Fine-grained STATIC targets per concern +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/version.h.in + ${CMAKE_CURRENT_BINARY_DIR}/version.h + @ONLY +) + # --- yr_global (no GUI, used by all 3 apps) --- add_library(yr_global STATIC + ${CMAKE_CURRENT_BINARY_DIR}/version.h + version.h.in yacreader_global.h yacreader_global.cpp ) -target_include_directories(yr_global PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(yr_global PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} +) target_link_libraries(yr_global PUBLIC Qt::Core) if(UNIX AND NOT APPLE) target_compile_definitions(yr_global PRIVATE @@ -171,6 +182,7 @@ target_link_libraries(rhi_flow_reader PUBLIC Qt::Gui Qt::GuiPrivate Qt::Widgets + yr_global ) qt_add_shaders(rhi_flow_reader "flow_shaders_reader" BASE rhi/shaders @@ -194,6 +206,7 @@ target_link_libraries(rhi_flow_library PUBLIC Qt::Gui Qt::GuiPrivate Qt::Widgets + yr_global ) qt_add_shaders(rhi_flow_library "flow_shaders_library" BASE rhi/shaders diff --git a/common/check_new_version.cpp b/common/check_new_version.cpp index 18646a5cc..d8a8bf9e5 100644 --- a/common/check_new_version.cpp +++ b/common/check_new_version.cpp @@ -6,16 +6,15 @@ #include #include #include -#include -#include #include #include +#include #include #define PREVIOUS_VERSION_TESTING "6.0.0" HttpVersionChecker::HttpVersionChecker() - : HttpWorker("https://raw.githubusercontent.com/YACReader/yacreader/master/common/yacreader_global.h", DEFAULT_USER_AGENT) + : HttpWorker("https://raw.githubusercontent.com/YACReader/yacreader/master/VERSION", DEFAULT_USER_AGENT) { connect(this, &HttpVersionChecker::dataReady, this, QOverload::of(&HttpVersionChecker::checkNewVersion)); } @@ -27,39 +26,17 @@ void HttpVersionChecker::checkNewVersion(const QByteArray &data) bool HttpVersionChecker::checkNewVersion(QString sourceContent) { - QRegExp rx("#define VERSION \"([0-9]+).([0-9]+).([0-9]+)\""); - - bool newVersion = false; - bool sameVersion = true; - // bool currentVersionIsNewer = false; #ifdef QT_DEBUG - QString version(PREVIOUS_VERSION_TESTING); + const auto currentVersion = QVersionNumber::fromString(PREVIOUS_VERSION_TESTING); #else - QString version(VERSION); + const auto currentVersion = QVersionNumber::fromString(QString::fromLatin1(VERSION)); #endif - QStringList sl = version.split("."); - if (rx.indexIn(sourceContent) != -1) { - int length = qMin(sl.size(), (rx.cap(4) != "") ? 4 : 3); - for (int i = 0; i < length; i++) { - if (rx.cap(i + 1).toInt() < sl.at(i).toInt()) { - return false; - } - if (rx.cap(i + 1).toInt() > sl.at(i).toInt()) { - newVersion = true; - break; - } else - sameVersion = sameVersion && rx.cap(i + 1).toInt() == sl.at(i).toInt(); - } - if (!newVersion && sameVersion) { - if ((sl.size() == 3) && (rx.cap(4) != "")) - newVersion = true; - } - } + const auto latestVersion = QVersionNumber::fromString(sourceContent.trimmed()); - if (newVersion == true) { + if (!currentVersion.isNull() && !latestVersion.isNull() && QVersionNumber::compare(latestVersion, currentVersion) > 0) { emit newVersionDetected(); return true; - } else { - return false; } + + return false; } diff --git a/common/version.h.in b/common/version.h.in new file mode 100644 index 000000000..07b9f88d0 --- /dev/null +++ b/common/version.h.in @@ -0,0 +1,6 @@ +#ifndef YACREADER_VERSION_H +#define YACREADER_VERSION_H + +#define VERSION "@PROJECT_VERSION@" + +#endif diff --git a/common/yacreader_global.h b/common/yacreader_global.h index 750e6c9a2..810878628 100644 --- a/common/yacreader_global.h +++ b/common/yacreader_global.h @@ -9,7 +9,10 @@ class QLibrary; -#define VERSION "10.0.0" +// Compatibility for already released apps that still parse this file for update checks. +// TODO: remove after old releases have migrated away from scraping this header. +// #define VERSION "10.0.0" +#include "version.h" // Used to check if the database needs to be updated, the version is stored in the database. // This value is only incremented when the database structure changes. diff --git a/compileOSX.sh b/compileOSX.sh index 460c96846..519624dfb 100755 --- a/compileOSX.sh +++ b/compileOSX.sh @@ -1,7 +1,7 @@ #! /bin/bash set -e -VERSION=${1:-"9.9.1"} +VERSION=${1:-$(tr -d '\r\n' < VERSION)} BUILD_NUMBER=${2:-"0"} From e2ddb7eaafb2423486f2ab6fe6a56babcb8222b6 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 17:48:33 +0200 Subject: [PATCH 182/187] Use Qt6:: syntax for Qt modules --- YACReader/CMakeLists.txt | 18 ++++---- YACReaderLibrary/CMakeLists.txt | 38 ++++++++-------- YACReaderLibrary/comic_vine/CMakeLists.txt | 6 +-- YACReaderLibrary/server/CMakeLists.txt | 6 +-- YACReaderLibraryServer/CMakeLists.txt | 8 ++-- common/CMakeLists.txt | 46 ++++++++++---------- compressed_archive/CMakeLists.txt | 2 +- custom_widgets/CMakeLists.txt | 12 ++--- shortcuts_management/CMakeLists.txt | 4 +- tests/compressed_archive_test/CMakeLists.txt | 2 +- tests/concurrent_queue_test/CMakeLists.txt | 4 +- third_party/CMakeLists.txt | 8 ++-- 12 files changed, 77 insertions(+), 77 deletions(-) diff --git a/YACReader/CMakeLists.txt b/YACReader/CMakeLists.txt index e6f74b0ae..a6fcded6f 100644 --- a/YACReader/CMakeLists.txt +++ b/YACReader/CMakeLists.txt @@ -232,15 +232,15 @@ qt_add_translations(YACReader ) target_link_libraries(YACReader PRIVATE - Qt::Core - Qt::Gui - Qt::GuiPrivate - Qt::Network - Qt::Widgets - Qt::Multimedia - Qt::TextToSpeech - Qt::Svg - Qt::Core5Compat + Qt6::Core + Qt6::Gui + Qt6::GuiPrivate + Qt6::Network + Qt6::Widgets + Qt6::Multimedia + Qt6::TextToSpeech + Qt6::Svg + Qt6::Core5Compat comic_backend common_gui rhi_flow_reader diff --git a/YACReaderLibrary/CMakeLists.txt b/YACReaderLibrary/CMakeLists.txt index ef562b5e3..d8586d480 100644 --- a/YACReaderLibrary/CMakeLists.txt +++ b/YACReaderLibrary/CMakeLists.txt @@ -32,10 +32,10 @@ target_include_directories(library_common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/db ) target_link_libraries(library_common PUBLIC - Qt::Core - Qt::Core5Compat - Qt::Network - Qt::Sql + Qt6::Core + Qt6::Core5Compat + Qt6::Network + Qt6::Sql common_all comic_backend cbx_backend @@ -63,14 +63,14 @@ target_include_directories(db_helper PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/db ) target_link_libraries(db_helper PUBLIC - Qt::Core - Qt::Sql + Qt6::Core + Qt6::Sql common_all QsLog ) # When BUILD_SERVER_STANDALONE=ON, only library_common and db_helper are built. -# The full YACReaderLibrary GUI app requires Qt::Widgets and other full-build components. +# The full YACReaderLibrary GUI app requires Qt6::Widgets and other full-build components. if(NOT BUILD_SERVER_STANDALONE) # --- YACReaderLibrary executable --- @@ -476,18 +476,18 @@ qt_add_translations(YACReaderLibrary ) target_link_libraries(YACReaderLibrary PRIVATE - Qt::Core - Qt::Gui - Qt::GuiPrivate - Qt::Network - Qt::Widgets - Qt::Sql - Qt::Svg - Qt::Quick - Qt::Qml - Qt::QuickWidgets - Qt::QuickControls2 - Qt::Core5Compat + Qt6::Core + Qt6::Gui + Qt6::GuiPrivate + Qt6::Network + Qt6::Widgets + Qt6::Sql + Qt6::Svg + Qt6::Quick + Qt6::Qml + Qt6::QuickWidgets + Qt6::QuickControls2 + Qt6::Core5Compat library_common db_helper comic_backend diff --git a/YACReaderLibrary/comic_vine/CMakeLists.txt b/YACReaderLibrary/comic_vine/CMakeLists.txt index cc0ca1a10..947d01b6b 100644 --- a/YACReaderLibrary/comic_vine/CMakeLists.txt +++ b/YACReaderLibrary/comic_vine/CMakeLists.txt @@ -60,9 +60,9 @@ target_include_directories(comic_vine PRIVATE ${PROJECT_SOURCE_DIR}/YACReaderLibrary/db ) target_link_libraries(comic_vine PUBLIC - Qt::Core - Qt::Widgets - Qt::Network + Qt6::Core + Qt6::Widgets + Qt6::Network common_all common_gui custom_widgets_library diff --git a/YACReaderLibrary/server/CMakeLists.txt b/YACReaderLibrary/server/CMakeLists.txt index 5a78620cb..af7b337e1 100644 --- a/YACReaderLibrary/server/CMakeLists.txt +++ b/YACReaderLibrary/server/CMakeLists.txt @@ -73,9 +73,9 @@ if(UNIX AND NOT APPLE) "DATADIR=\"${CMAKE_INSTALL_FULL_DATADIR}\"") endif() target_link_libraries(server PUBLIC - Qt::Core - Qt::Network - Qt::Sql + Qt6::Core + Qt6::Network + Qt6::Sql QtWebApp_httpserver QtWebApp_templateengine QsLog diff --git a/YACReaderLibraryServer/CMakeLists.txt b/YACReaderLibraryServer/CMakeLists.txt index 42b5a27b4..efaf364a5 100644 --- a/YACReaderLibraryServer/CMakeLists.txt +++ b/YACReaderLibraryServer/CMakeLists.txt @@ -36,10 +36,10 @@ qt_add_translations(YACReaderLibraryServer ) target_link_libraries(YACReaderLibraryServer PRIVATE - Qt::Core - Qt::Network - Qt::Sql - Qt::Core5Compat + Qt6::Core + Qt6::Network + Qt6::Sql + Qt6::Core5Compat library_common db_helper comic_backend diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 96125dd69..d8017a655 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -18,7 +18,7 @@ target_include_directories(yr_global PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) -target_link_libraries(yr_global PUBLIC Qt::Core) +target_link_libraries(yr_global PUBLIC Qt6::Core) if(UNIX AND NOT APPLE) target_compile_definitions(yr_global PRIVATE "LIBDIR=\"${CMAKE_INSTALL_FULL_LIBDIR}\"") @@ -30,7 +30,7 @@ add_library(naturalsort STATIC qnaturalsorting.cpp ) target_include_directories(naturalsort PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(naturalsort PUBLIC Qt::Core) +target_link_libraries(naturalsort PUBLIC Qt6::Core) # --- concurrent_queue --- add_library(concurrent_queue STATIC @@ -38,7 +38,7 @@ add_library(concurrent_queue STATIC concurrent_queue.cpp ) target_include_directories(concurrent_queue PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(concurrent_queue PUBLIC Qt::Core) +target_link_libraries(concurrent_queue PUBLIC Qt6::Core) # --- worker (header-only thread helpers) --- add_library(worker INTERFACE) @@ -67,10 +67,10 @@ add_library(common_all STATIC ) target_include_directories(common_all PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(common_all PUBLIC - Qt::Core - Qt::Gui - Qt::Sql - Qt::Network + Qt6::Core + Qt6::Gui + Qt6::Sql + Qt6::Network yr_global naturalsort pdf_backend_iface @@ -92,8 +92,8 @@ endif() target_include_directories(comic_backend PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(comic_backend PUBLIC - Qt::Core - Qt::Gui + Qt6::Core + Qt6::Gui common_all pdf_backend_iface cbx_backend @@ -101,7 +101,7 @@ target_link_libraries(comic_backend PUBLIC ) # GUI-only targets: not needed for server-standalone builds (Qt 6.4+) which -# lack Qt::Widgets, Qt::ShaderTools, Qt::GuiPrivate, etc. +# lack Qt6::Widgets, Qt6::ShaderTools, Qt6::GuiPrivate, etc. if(NOT BUILD_SERVER_STANDALONE) # --- common_gui (GUI-only code: widgets, version check, themes infrastructure) --- @@ -146,11 +146,11 @@ target_include_directories(common_gui PUBLIC ) target_link_libraries(common_gui PUBLIC - Qt::Core - Qt::Core5Compat - Qt::Widgets - Qt::Network - Qt::Svg + Qt6::Core + Qt6::Core5Compat + Qt6::Widgets + Qt6::Network + Qt6::Svg common_all yr_global QsLog @@ -178,10 +178,10 @@ target_include_directories(rhi_flow_reader PUBLIC ) target_compile_definitions(rhi_flow_reader PRIVATE YACREADER) target_link_libraries(rhi_flow_reader PUBLIC - Qt::Core - Qt::Gui - Qt::GuiPrivate - Qt::Widgets + Qt6::Core + Qt6::Gui + Qt6::GuiPrivate + Qt6::Widgets yr_global ) qt_add_shaders(rhi_flow_reader "flow_shaders_reader" @@ -202,10 +202,10 @@ target_include_directories(rhi_flow_library PUBLIC ) target_compile_definitions(rhi_flow_library PRIVATE YACREADER_LIBRARY) target_link_libraries(rhi_flow_library PUBLIC - Qt::Core - Qt::Gui - Qt::GuiPrivate - Qt::Widgets + Qt6::Core + Qt6::Gui + Qt6::GuiPrivate + Qt6::Widgets yr_global ) qt_add_shaders(rhi_flow_library "flow_shaders_library" diff --git a/compressed_archive/CMakeLists.txt b/compressed_archive/CMakeLists.txt index 928fb622f..a5f5ba5c3 100644 --- a/compressed_archive/CMakeLists.txt +++ b/compressed_archive/CMakeLists.txt @@ -125,4 +125,4 @@ else() endif() # Qt, yr_global, and QsLog are needed by all backends -target_link_libraries(cbx_backend PRIVATE Qt::Core yr_global QsLog) +target_link_libraries(cbx_backend PRIVATE Qt6::Core yr_global QsLog) diff --git a/custom_widgets/CMakeLists.txt b/custom_widgets/CMakeLists.txt index aaa7ec25a..84590dad2 100644 --- a/custom_widgets/CMakeLists.txt +++ b/custom_widgets/CMakeLists.txt @@ -44,9 +44,9 @@ target_include_directories(custom_widgets_reader PRIVATE ) target_compile_definitions(custom_widgets_reader PRIVATE YACREADER) target_link_libraries(custom_widgets_reader PUBLIC - Qt::Core - Qt::Widgets - Qt::Network + Qt6::Core + Qt6::Widgets + Qt6::Network common_gui rhi_flow_reader QsLog @@ -91,9 +91,9 @@ target_include_directories(custom_widgets_library PRIVATE ) target_compile_definitions(custom_widgets_library PRIVATE YACREADER_LIBRARY) target_link_libraries(custom_widgets_library PUBLIC - Qt::Core - Qt::Widgets - Qt::Network + Qt6::Core + Qt6::Widgets + Qt6::Network common_gui rhi_flow_library QsLog diff --git a/shortcuts_management/CMakeLists.txt b/shortcuts_management/CMakeLists.txt index 4cbbd7217..3c893d060 100644 --- a/shortcuts_management/CMakeLists.txt +++ b/shortcuts_management/CMakeLists.txt @@ -22,7 +22,7 @@ target_include_directories(shortcuts_reader PRIVATE ${PROJECT_SOURCE_DIR}/YACReader/themes ) target_compile_definitions(shortcuts_reader PRIVATE YACREADER) -target_link_libraries(shortcuts_reader PUBLIC Qt::Core Qt::Widgets yr_global common_gui) +target_link_libraries(shortcuts_reader PUBLIC Qt6::Core Qt6::Widgets yr_global common_gui) # --- shortcuts_library (YACREADER_LIBRARY define) --- add_library(shortcuts_library STATIC ${SHORTCUTS_SOURCES}) @@ -31,4 +31,4 @@ target_include_directories(shortcuts_library PRIVATE ${PROJECT_SOURCE_DIR}/YACReaderLibrary/themes ) target_compile_definitions(shortcuts_library PRIVATE YACREADER_LIBRARY) -target_link_libraries(shortcuts_library PUBLIC Qt::Core Qt::Widgets yr_global common_gui) +target_link_libraries(shortcuts_library PUBLIC Qt6::Core Qt6::Widgets yr_global common_gui) diff --git a/tests/compressed_archive_test/CMakeLists.txt b/tests/compressed_archive_test/CMakeLists.txt index 7b3e40b03..4f0e1c476 100644 --- a/tests/compressed_archive_test/CMakeLists.txt +++ b/tests/compressed_archive_test/CMakeLists.txt @@ -4,7 +4,7 @@ qt_add_executable(compressed_archive_test main.cpp ) target_link_libraries(compressed_archive_test PRIVATE - Qt::Core + Qt6::Core cbx_backend ) if(WIN32) diff --git a/tests/concurrent_queue_test/CMakeLists.txt b/tests/concurrent_queue_test/CMakeLists.txt index b6c490937..380e52b5e 100644 --- a/tests/concurrent_queue_test/CMakeLists.txt +++ b/tests/concurrent_queue_test/CMakeLists.txt @@ -4,8 +4,8 @@ qt_add_executable(concurrent_queue_test concurrent_queue_test.cpp ) target_link_libraries(concurrent_queue_test PRIVATE - Qt::Core - Qt::Test + Qt6::Core + Qt6::Test concurrent_queue ) add_test(NAME concurrent_queue_test diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index d4804f55b..512e57457 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -21,7 +21,7 @@ add_library(QsLog STATIC ) target_include_directories(QsLog PUBLIC QsLog) target_compile_definitions(QsLog PUBLIC QS_LOG_SEPARATE_THREAD) -target_link_libraries(QsLog PUBLIC Qt::Core) +target_link_libraries(QsLog PUBLIC Qt6::Core) # --- QrCode (QR code generation, no Qt dependency) --- add_library(QrCode STATIC @@ -56,7 +56,7 @@ add_library(QtWebApp_httpserver STATIC QtWebApp/httpserver/staticfilecontroller.h ) target_include_directories(QtWebApp_httpserver PUBLIC QtWebApp/httpserver) -target_link_libraries(QtWebApp_httpserver PUBLIC Qt::Network) +target_link_libraries(QtWebApp_httpserver PUBLIC Qt6::Network) # --- QtWebApp template engine --- add_library(QtWebApp_templateengine STATIC @@ -69,7 +69,7 @@ add_library(QtWebApp_templateengine STATIC QtWebApp/templateengine/templatecache.h ) target_include_directories(QtWebApp_templateengine PUBLIC QtWebApp/templateengine) -target_link_libraries(QtWebApp_templateengine PUBLIC Qt::Core5Compat) +target_link_libraries(QtWebApp_templateengine PUBLIC Qt6::Core5Compat) # --- KDSignalThrottler (from KDToolBox) --- add_library(KDSignalThrottler STATIC @@ -77,4 +77,4 @@ add_library(KDSignalThrottler STATIC KDToolBox/KDSignalThrottler.h ) target_include_directories(KDSignalThrottler PUBLIC KDToolBox) -target_link_libraries(KDSignalThrottler PUBLIC Qt::Core) +target_link_libraries(KDSignalThrottler PUBLIC Qt6::Core) From 042e4299965a108a666141e4a5f684ac9e9f0fa8 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 18:24:58 +0200 Subject: [PATCH 183/187] Scope compiler defines and remove forced 7zip NDEBUG --- CMakeLists.txt | 5 --- YACReader/CMakeLists.txt | 1 + YACReaderLibrary/CMakeLists.txt | 3 ++ YACReaderLibrary/comic_vine/CMakeLists.txt | 1 + YACReaderLibrary/server/CMakeLists.txt | 1 + YACReaderLibraryServer/CMakeLists.txt | 4 +++ cmake/CompilerOptions.cmake | 34 +++++++++++++++----- common/CMakeLists.txt | 8 +++++ compressed_archive/CMakeLists.txt | 5 +-- custom_widgets/CMakeLists.txt | 8 +++++ image_processing/CMakeLists.txt | 3 +- shortcuts_management/CMakeLists.txt | 2 ++ tests/compressed_archive_test/CMakeLists.txt | 1 + tests/concurrent_queue_test/CMakeLists.txt | 1 + 14 files changed, 61 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84c86400e..16d12f22a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -157,11 +157,6 @@ if(WIN32 OR APPLE) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") endif() -# Build number define -if(BUILD_NUMBER) - add_compile_definitions("BUILD_NUMBER=\"${BUILD_NUMBER}\"") -endif() - # --- Subdirectories (dependency order) --- add_subdirectory(third_party) add_subdirectory(compressed_archive) diff --git a/YACReader/CMakeLists.txt b/YACReader/CMakeLists.txt index a6fcded6f..ea9322df8 100644 --- a/YACReader/CMakeLists.txt +++ b/YACReader/CMakeLists.txt @@ -45,6 +45,7 @@ qt_add_executable(YACReader WIN32 ${PROJECT_SOURCE_DIR}/common/themes/theme_manager.h ${PROJECT_SOURCE_DIR}/common/themes/theme_manager.cpp ) +yacreader_apply_build_options(YACReader) target_include_directories(YACReader PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/YACReaderLibrary/CMakeLists.txt b/YACReaderLibrary/CMakeLists.txt index d8586d480..38faf04c8 100644 --- a/YACReaderLibrary/CMakeLists.txt +++ b/YACReaderLibrary/CMakeLists.txt @@ -31,6 +31,7 @@ target_include_directories(library_common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/db ) +yacreader_apply_build_options(library_common) target_link_libraries(library_common PUBLIC Qt6::Core Qt6::Core5Compat @@ -62,6 +63,7 @@ target_include_directories(db_helper PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/db ) +yacreader_apply_build_options(db_helper) target_link_libraries(db_helper PUBLIC Qt6::Core Qt6::Sql @@ -179,6 +181,7 @@ qt_add_executable(YACReaderLibrary WIN32 ${PROJECT_SOURCE_DIR}/common/themes/theme_manager.h ${PROJECT_SOURCE_DIR}/common/themes/theme_manager.cpp ) +yacreader_apply_build_options(YACReaderLibrary) # macOS-specific sources if(APPLE) diff --git a/YACReaderLibrary/comic_vine/CMakeLists.txt b/YACReaderLibrary/comic_vine/CMakeLists.txt index 947d01b6b..382e3f0f9 100644 --- a/YACReaderLibrary/comic_vine/CMakeLists.txt +++ b/YACReaderLibrary/comic_vine/CMakeLists.txt @@ -54,6 +54,7 @@ target_include_directories(comic_vine PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/model ) +yacreader_apply_build_options(comic_vine) # App-specific theme.h needed for themable.h → theme_manager.h → theme.h chain target_include_directories(comic_vine PRIVATE ${PROJECT_SOURCE_DIR}/YACReaderLibrary/themes diff --git a/YACReaderLibrary/server/CMakeLists.txt b/YACReaderLibrary/server/CMakeLists.txt index af7b337e1..839072efe 100644 --- a/YACReaderLibrary/server/CMakeLists.txt +++ b/YACReaderLibrary/server/CMakeLists.txt @@ -67,6 +67,7 @@ target_include_directories(server PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/controllers ${CMAKE_CURRENT_SOURCE_DIR}/controllers/v2 ) +yacreader_apply_build_options(server) target_compile_definitions(server PUBLIC SERVER_VERSION_NUMBER="2.1") if(UNIX AND NOT APPLE) target_compile_definitions(server PRIVATE diff --git a/YACReaderLibraryServer/CMakeLists.txt b/YACReaderLibraryServer/CMakeLists.txt index efaf364a5..ed45d4535 100644 --- a/YACReaderLibraryServer/CMakeLists.txt +++ b/YACReaderLibraryServer/CMakeLists.txt @@ -7,6 +7,7 @@ qt_add_executable(YACReaderLibraryServer libraries_updater.h libraries_updater.cpp ) +yacreader_apply_build_options(YACReaderLibraryServer) target_include_directories(YACReaderLibraryServer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} @@ -18,6 +19,9 @@ target_compile_definitions(YACReaderLibraryServer PRIVATE SERVER_RELEASE YACREADER_LIBRARY ) +if(BUILD_NUMBER) + target_compile_definitions(YACReaderLibraryServer PRIVATE "BUILD_NUMBER=\"${BUILD_NUMBER}\"") +endif() # Translations qt_add_translations(YACReaderLibraryServer diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake index c90fa6f8d..429cf9954 100644 --- a/cmake/CompilerOptions.cmake +++ b/cmake/CompilerOptions.cmake @@ -1,13 +1,31 @@ -# Compiler options for YACReader +# Compiler policy for YACReader-owned targets. +# Keep this target internal so third-party code does not inherit our rules. +add_library(yacreader_build_options INTERFACE) + +target_compile_definitions(yacreader_build_options INTERFACE + QT_DISABLE_DEPRECATED_UP_TO=0x060400 +) if(MSVC) - # Prevent windows.h from defining min/max macros that conflict with - # std::min, std::max, std::numeric_limits::max(), etc. - add_compile_definitions(NOMINMAX) + target_compile_definitions(yacreader_build_options INTERFACE + # Prevent windows.h from defining min/max macros that conflict with + # std::min, std::max, std::numeric_limits::max(), etc. + NOMINMAX + ) - # /Zc:__cplusplus: report correct __cplusplus value - # /permissive-: strict standard conformance - add_compile_options(/Zc:__cplusplus /permissive-) + target_compile_options(yacreader_build_options INTERFACE + # /Zc:__cplusplus: report correct __cplusplus value + # /permissive-: strict standard conformance + $<$:/Zc:__cplusplus> + $<$:/permissive-> + ) endif() -add_compile_definitions(QT_DISABLE_DEPRECATED_UP_TO=0x060400) +function(yacreader_apply_build_options) + foreach(target_name IN LISTS ARGN) + if(NOT TARGET "${target_name}") + message(FATAL_ERROR "yacreader_apply_build_options(): unknown target '${target_name}'") + endif() + target_link_libraries("${target_name}" PRIVATE yacreader_build_options) + endforeach() +endfunction() diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index d8017a655..ba76f7cf3 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -18,6 +18,7 @@ target_include_directories(yr_global PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) +yacreader_apply_build_options(yr_global) target_link_libraries(yr_global PUBLIC Qt6::Core) if(UNIX AND NOT APPLE) target_compile_definitions(yr_global PRIVATE @@ -30,6 +31,7 @@ add_library(naturalsort STATIC qnaturalsorting.cpp ) target_include_directories(naturalsort PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +yacreader_apply_build_options(naturalsort) target_link_libraries(naturalsort PUBLIC Qt6::Core) # --- concurrent_queue --- @@ -38,6 +40,7 @@ add_library(concurrent_queue STATIC concurrent_queue.cpp ) target_include_directories(concurrent_queue PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +yacreader_apply_build_options(concurrent_queue) target_link_libraries(concurrent_queue PUBLIC Qt6::Core) # --- worker (header-only thread helpers) --- @@ -66,6 +69,7 @@ add_library(common_all STATIC global_info_provider.cpp ) target_include_directories(common_all PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +yacreader_apply_build_options(common_all) target_link_libraries(common_all PUBLIC Qt6::Core Qt6::Gui @@ -82,6 +86,7 @@ add_library(comic_backend STATIC comic.cpp pdf_comic.h ) +yacreader_apply_build_options(comic_backend) # PDF source depends on backend if(PDF_BACKEND STREQUAL "pdfkit") @@ -144,6 +149,7 @@ target_include_directories(common_gui PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/themes ${CMAKE_CURRENT_SOURCE_DIR}/themes/shared ) +yacreader_apply_build_options(common_gui) target_link_libraries(common_gui PUBLIC Qt6::Core @@ -176,6 +182,7 @@ target_include_directories(rhi_flow_reader PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/rhi ) +yacreader_apply_build_options(rhi_flow_reader) target_compile_definitions(rhi_flow_reader PRIVATE YACREADER) target_link_libraries(rhi_flow_reader PUBLIC Qt6::Core @@ -200,6 +207,7 @@ target_include_directories(rhi_flow_library PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/rhi ) +yacreader_apply_build_options(rhi_flow_library) target_compile_definitions(rhi_flow_library PRIVATE YACREADER_LIBRARY) target_link_libraries(rhi_flow_library PUBLIC Qt6::Core diff --git a/compressed_archive/CMakeLists.txt b/compressed_archive/CMakeLists.txt index a5f5ba5c3..6fd5adcf9 100644 --- a/compressed_archive/CMakeLists.txt +++ b/compressed_archive/CMakeLists.txt @@ -2,6 +2,7 @@ # Switched on DECOMPRESSION_BACKEND: unarr | 7zip | libarchive add_library(cbx_backend STATIC) +yacreader_apply_build_options(cbx_backend) if(DECOMPRESSION_BACKEND STREQUAL "unarr") message(STATUS "Decompression backend: unarr") @@ -88,14 +89,14 @@ elseif(DECOMPRESSION_BACKEND STREQUAL "7zip") if(APPLE) target_compile_definitions(cbx_backend PRIVATE - _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE NDEBUG _REENTRANT + _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE _REENTRANT ENV_UNIX _7ZIP_LARGE_PAGES ENV_MACOSX _TCHAR_DEFINED UNICODE _UNICODE UNIX_USE_WIN_FILE) target_link_libraries(cbx_backend PRIVATE "-framework IOKit" "-framework CoreFoundation") elseif(UNIX) target_compile_definitions(cbx_backend PRIVATE - _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE NDEBUG _REENTRANT + _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE _REENTRANT ENV_UNIX _7ZIP_LARGE_PAGES UNICODE _UNICODE UNIX_USE_WIN_FILE) endif() diff --git a/custom_widgets/CMakeLists.txt b/custom_widgets/CMakeLists.txt index 84590dad2..4e35aa059 100644 --- a/custom_widgets/CMakeLists.txt +++ b/custom_widgets/CMakeLists.txt @@ -38,11 +38,15 @@ endif() # --- custom_widgets_reader (YACReader-specific) --- add_library(custom_widgets_reader STATIC ${WIDGETS_COMMON_SOURCES}) target_include_directories(custom_widgets_reader PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +yacreader_apply_build_options(custom_widgets_reader) # App-specific theme.h needed because themable.h → theme_manager.h → theme.h target_include_directories(custom_widgets_reader PRIVATE ${PROJECT_SOURCE_DIR}/YACReader/themes ) target_compile_definitions(custom_widgets_reader PRIVATE YACREADER) +if(BUILD_NUMBER) + target_compile_definitions(custom_widgets_reader PRIVATE "BUILD_NUMBER=\"${BUILD_NUMBER}\"") +endif() target_link_libraries(custom_widgets_reader PUBLIC Qt6::Core Qt6::Widgets @@ -83,6 +87,7 @@ add_library(custom_widgets_library STATIC ${LIBRARY_EXTRA_WIDGETS} ) target_include_directories(custom_widgets_library PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +yacreader_apply_build_options(custom_widgets_library) # App-specific theme.h + YACReaderLibrary headers needed by macosx_toolbar target_include_directories(custom_widgets_library PRIVATE ${PROJECT_SOURCE_DIR}/YACReaderLibrary/themes @@ -90,6 +95,9 @@ target_include_directories(custom_widgets_library PRIVATE ${PROJECT_SOURCE_DIR}/YACReaderLibrary/db ) target_compile_definitions(custom_widgets_library PRIVATE YACREADER_LIBRARY) +if(BUILD_NUMBER) + target_compile_definitions(custom_widgets_library PRIVATE "BUILD_NUMBER=\"${BUILD_NUMBER}\"") +endif() target_link_libraries(custom_widgets_library PUBLIC Qt6::Core Qt6::Widgets diff --git a/image_processing/CMakeLists.txt b/image_processing/CMakeLists.txt index 7421e7e1d..86079aa44 100644 --- a/image_processing/CMakeLists.txt +++ b/image_processing/CMakeLists.txt @@ -5,5 +5,6 @@ add_library(image_processing STATIC ) target_include_directories(image_processing PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +yacreader_apply_build_options(image_processing) -target_link_libraries(image_processing PRIVATE Qt::Gui) +target_link_libraries(image_processing PRIVATE Qt6::Gui) diff --git a/shortcuts_management/CMakeLists.txt b/shortcuts_management/CMakeLists.txt index 3c893d060..88fab140c 100644 --- a/shortcuts_management/CMakeLists.txt +++ b/shortcuts_management/CMakeLists.txt @@ -17,6 +17,7 @@ set(SHORTCUTS_SOURCES # --- shortcuts_reader (YACREADER define) --- add_library(shortcuts_reader STATIC ${SHORTCUTS_SOURCES}) target_include_directories(shortcuts_reader PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +yacreader_apply_build_options(shortcuts_reader) # App-specific theme.h needed because themable.h → theme_manager.h → theme.h target_include_directories(shortcuts_reader PRIVATE ${PROJECT_SOURCE_DIR}/YACReader/themes @@ -27,6 +28,7 @@ target_link_libraries(shortcuts_reader PUBLIC Qt6::Core Qt6::Widgets yr_global c # --- shortcuts_library (YACREADER_LIBRARY define) --- add_library(shortcuts_library STATIC ${SHORTCUTS_SOURCES}) target_include_directories(shortcuts_library PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +yacreader_apply_build_options(shortcuts_library) target_include_directories(shortcuts_library PRIVATE ${PROJECT_SOURCE_DIR}/YACReaderLibrary/themes ) diff --git a/tests/compressed_archive_test/CMakeLists.txt b/tests/compressed_archive_test/CMakeLists.txt index 4f0e1c476..ad7f4ac89 100644 --- a/tests/compressed_archive_test/CMakeLists.txt +++ b/tests/compressed_archive_test/CMakeLists.txt @@ -3,6 +3,7 @@ qt_add_executable(compressed_archive_test main.cpp ) +yacreader_apply_build_options(compressed_archive_test) target_link_libraries(compressed_archive_test PRIVATE Qt6::Core cbx_backend diff --git a/tests/concurrent_queue_test/CMakeLists.txt b/tests/concurrent_queue_test/CMakeLists.txt index 380e52b5e..4df4df025 100644 --- a/tests/concurrent_queue_test/CMakeLists.txt +++ b/tests/concurrent_queue_test/CMakeLists.txt @@ -3,6 +3,7 @@ qt_add_executable(concurrent_queue_test concurrent_queue_test.cpp ) +yacreader_apply_build_options(concurrent_queue_test) target_link_libraries(concurrent_queue_test PRIVATE Qt6::Core Qt6::Test From 8ddf1a8f907c13082774dcbeea55545b240b9141 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 18:30:57 +0200 Subject: [PATCH 184/187] Improve Summary --- CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 16d12f22a..ed3108de4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -191,13 +191,20 @@ if(BUILD_TESTS AND NOT BUILD_SERVER_STANDALONE) endif() # Summary +if(CMAKE_CONFIGURATION_TYPES) + string(JOIN ", " _configured_build_types ${CMAKE_CONFIGURATION_TYPES}) + set(_build_type_summary "multi-config (${_configured_build_types})") +else() + set(_build_type_summary "${CMAKE_BUILD_TYPE}") +endif() + message(STATUS "") message(STATUS "YACReader ${PROJECT_VERSION} build configuration:") message(STATUS " Decompression backend: ${DECOMPRESSION_BACKEND}") message(STATUS " PDF backend: ${PDF_BACKEND}") message(STATUS " Build tests: ${BUILD_TESTS}") message(STATUS " Server standalone: ${BUILD_SERVER_STANDALONE}") -message(STATUS " Build type: ${CMAKE_BUILD_TYPE}") +message(STATUS " Build type: ${_build_type_summary}") if(BUILD_NUMBER) message(STATUS " Build number: ${BUILD_NUMBER}") endif() From a8c936ee6fb5cd0f2df362e54f2f3b3ee1597755 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 18:32:27 +0200 Subject: [PATCH 185/187] Update AGENTS.md --- AGENTS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 847f487d3..6debdc6dc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -46,8 +46,8 @@ cmake --build build --config Release --target release_translations ``` Important: -- Do not run `lupdate` only on `qml.qrc` (or only on a subset of files), because that can mark unrelated translations as obsolete. -- In `YACReaderLibrary`, `qt_add_translations(...)` is configured to scan full target sources and include QML from `qml.qrc`. +- Do not run `lupdate` only on a hand-picked subset of QML files, because that can mark unrelated translations as obsolete. +- In `YACReaderLibrary`, `qt_add_translations(...)` is configured to scan full target sources and include the QML files directly. - `update_translations` updates both locale TS files and `*_source.ts` template files for all apps. - `*_source.ts` files are translator base templates and must not be treated as shipped locales. From 9dfc35527b20ef44846578259452f7cd6fe58d7b Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 20:17:05 +0200 Subject: [PATCH 186/187] Fix version checking --- common/check_new_version.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/common/check_new_version.cpp b/common/check_new_version.cpp index d8a8bf9e5..00e3c0fcf 100644 --- a/common/check_new_version.cpp +++ b/common/check_new_version.cpp @@ -11,8 +11,6 @@ #include #include -#define PREVIOUS_VERSION_TESTING "6.0.0" - HttpVersionChecker::HttpVersionChecker() : HttpWorker("https://raw.githubusercontent.com/YACReader/yacreader/master/VERSION", DEFAULT_USER_AGENT) { @@ -26,12 +24,17 @@ void HttpVersionChecker::checkNewVersion(const QByteArray &data) bool HttpVersionChecker::checkNewVersion(QString sourceContent) { -#ifdef QT_DEBUG - const auto currentVersion = QVersionNumber::fromString(PREVIOUS_VERSION_TESTING); -#else + const auto currentVersion = QVersionNumber::fromString(QString::fromLatin1(VERSION)); -#endif - const auto latestVersion = QVersionNumber::fromString(sourceContent.trimmed()); + const auto trimmedSourceContent = sourceContent.trimmed(); + qsizetype suffixIndex = 0; + const auto latestVersion = QVersionNumber::fromString(trimmedSourceContent, &suffixIndex); + + if (trimmedSourceContent.isEmpty() || + suffixIndex != trimmedSourceContent.size() || + latestVersion.segments().size() != 3) { + return false; + } if (!currentVersion.isNull() && !latestVersion.isNull() && QVersionNumber::compare(latestVersion, currentVersion) > 0) { emit newVersionDetected(); From 4bcdb3c7da95981326ad0edef294b73deb62eae2 Mon Sep 17 00:00:00 2001 From: luisangelsm Date: Mon, 30 Mar 2026 21:55:37 +0200 Subject: [PATCH 187/187] Fix default background color being stuck when changing themes The color is only persisted if the user sets a color explicitly. --- YACReader/options_dialog.cpp | 17 +++++++++++++++-- YACReader/options_dialog.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/YACReader/options_dialog.cpp b/YACReader/options_dialog.cpp index 0c4a96dc3..f54af77c8 100644 --- a/YACReader/options_dialog.cpp +++ b/YACReader/options_dialog.cpp @@ -279,6 +279,10 @@ OptionsDialog::OptionsDialog(QWidget *parent) void OptionsDialog::applyTheme(const Theme &theme) { pathFindButton->setIcon(theme.dialogIcons.findFolderIcon); + + if (backgroundColorFollowsTheme) { + updateColor(theme.viewer.defaultBackgroundColor); + } } void OptionsDialog::findFolder() @@ -292,6 +296,11 @@ void OptionsDialog::findFolder() void OptionsDialog::showColorDialog() { auto color = QColorDialog::getColor(currentColor, this); + if (!color.isValid()) { + return; + } + + backgroundColorFollowsTheme = false; updateColor(color); } @@ -303,7 +312,7 @@ void OptionsDialog::saveOptions() Configuration::getConfiguration().setShowTimeInInformation(showTimeInInformationLabel->isChecked()); - if (currentColor != theme.viewer.defaultBackgroundColor) { + if (!backgroundColorFollowsTheme) { settings->setValue(BACKGROUND_COLOR, currentColor); } else { settings->remove(BACKGROUND_COLOR); @@ -356,7 +365,10 @@ void OptionsDialog::restoreOptions(QSettings *settings) showTimeInInformationLabel->setChecked(Configuration::getConfiguration().getShowTimeInInformation()); - updateColor(settings->value(BACKGROUND_COLOR, theme.viewer.defaultBackgroundColor).value()); + backgroundColorFollowsTheme = !settings->contains(BACKGROUND_COLOR); + updateColor(backgroundColorFollowsTheme + ? theme.viewer.defaultBackgroundColor + : settings->value(BACKGROUND_COLOR).value()); // fitToWidthRatioS->setSliderPosition(settings->value(FIT_TO_WIDTH_RATIO).toFloat()*100); quickNavi->setChecked(settings->value(QUICK_NAVI_MODE).toBool()); @@ -476,6 +488,7 @@ void OptionsDialog::setFilters(int brightness, int contrast, int gamma) void OptionsDialog::clearBackgroundColor() { + backgroundColorFollowsTheme = true; settings->remove(BACKGROUND_COLOR); updateColor(theme.viewer.defaultBackgroundColor); diff --git a/YACReader/options_dialog.h b/YACReader/options_dialog.h index e89f0d0be..eb65fe1dd 100644 --- a/YACReader/options_dialog.h +++ b/YACReader/options_dialog.h @@ -63,6 +63,7 @@ class OptionsDialog : public YACReaderOptionsDialog, protected Themable YACReaderSpinSliderWidget *gammaS; QColor currentColor; + bool backgroundColorFollowsTheme = true; QComboBox *scalingMethodCombo;