Merge pull request #366 from YACReader/develop

9.11
This commit is contained in:
Luis Ángel San Martín 2023-01-07 10:36:38 +01:00 committed by GitHub
commit fa3e5eac14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 1376 additions and 1332 deletions

View File

@ -2,6 +2,22 @@
Version counting is based on semantic versioning (Major.Feature.Patch)
## WIP
### YACReader
* Fix segfault (or worse) when exiting YACReader while processing a comic.
* Fix last read page calculation in double page mode.
### YACReaderLibrary
* Fix drag&drop in the comics grid view.
* Detect back/forward mouse buttons to move back and forward through the browsing history.
* Fix crash when disabling the server.
### All apps
* Run logger in a dedicated thread to avoid segfaults at application shutdown
* Add support for poppler-qt6 pdf backend
* Remove image allocation limit.
## 9.10
### YACReader

View File

@ -214,28 +214,16 @@ win32 {
$(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 {
# 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 += "LIBDIR=\\\"$$LIBDIR\\\"" "DATADIR=\\\"$$DATADIR\\\""
#MAKE INSTALL
INSTALLS += bin docs icon desktop translation manpage
INSTALLS += bin docs icon desktop manpage
bin.path = $$BINDIR
isEmpty(DESTDIR) {
@ -256,9 +244,6 @@ icon.files = ../YACReader.svg
desktop.path = $$DATADIR/applications
desktop.files = ../YACReader.desktop
translation.path = $$DATADIR/yacreader/languages
translation.files = ../release/languages/yacreader_*
manpage.path = $$DATADIR/man/man1
manpage.files = ../YACReader.1

View File

@ -2,6 +2,7 @@
#include <QDir>
#include <QTranslator>
#include <QCommandLineParser>
#include <QImageReader>
#include "main_window_viewer.h"
#include "configuration.h"
@ -97,6 +98,10 @@ 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);
#endif

View File

@ -382,20 +382,23 @@ Render::Render()
Render::~Render()
{
if (comic != nullptr) {
comic->moveToThread(QApplication::instance()->thread());
comic->deleteLater();
for (auto *pr : pageRenders) {
if (pr != nullptr && pr->wait()) {
delete pr;
}
}
foreach (PageRender *pr, pageRenders)
if (pr != nullptr) {
if (pr->wait())
delete pr;
}
// TODO move to share_ptr
foreach (ImageFilter *filter, filters)
for (auto *filter : filters) {
delete filter;
}
if (comic != nullptr) {
comic->invalidate();
comic->deleteLater();
comic->thread()->quit();
comic->thread()->wait();
}
}
// Este método se encarga de forzar el renderizado de las páginas.
// Actualiza el buffer según es necesario.

View File

@ -1128,7 +1128,9 @@ void Viewer::updateComic(ComicDB &comic)
if (!doublePage || (doublePage && render->currentPageIsDoublePage() == false)) {
comic.info.currentPage = render->getIndex() + 1;
} else {
if (!(render->getIndex() + 1 == comic.info.currentPage || render->getIndex() + 2 == comic.info.currentPage)) {
if (doublePage && render->currentPageIsDoublePage() && (render->getIndex() + 2 >= render->numPages())) {
comic.info.currentPage = std::min(render->numPages(), render->getIndex() + 2);
} else {
comic.info.currentPage = std::min(render->numPages(), render->getIndex() + 1);
}
}

View File

@ -307,6 +307,7 @@ win32 {
$(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
@ -328,24 +329,11 @@ unix:!macx:RESOURCES += qml_win.qrc
macx:RESOURCES += qml_osx.qrc
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 += "LIBDIR=\\\"$$LIBDIR\\\"" "DATADIR=\\\"$$DATADIR\\\"" "BINDIR=\\\"$$BINDIR\\\""
#MAKE INSTALL
INSTALLS += bin icon desktop server translation manpage
INSTALLS += bin icon desktop server manpage
bin.path = $$BINDIR
isEmpty(DESTDIR) {
@ -363,9 +351,6 @@ icon.files = ../YACReaderLibrary.svg
desktop.path = $$DATADIR/applications
desktop.files = ../YACReaderLibrary.desktop
translation.path = $$DATADIR/yacreader/languages
translation.files = ../release/languages/yacreaderlibrary_*
manpage.path = $$DATADIR/man/man1
manpage.files = ../YACReaderLibrary.1
}

View File

@ -33,6 +33,7 @@ ComicVineDialog::ComicVineDialog(QWidget *parent)
: QDialog(parent)
{
setWindowFlags(Qt::Window);
setModal(true);
doLayout();
doStackedWidgets();

View File

@ -11,7 +11,7 @@
#include <QGraphicsItemAnimation>
#include <QTimeLine>
// TODO: is QGLWidget needed here???
//#include <QGLWidget>
// #include <QGLWidget>
#include <QTimer>
#include <QElapsedTimer>
#include <QToolButton>

View File

@ -27,38 +27,31 @@ void InitialComicInfoExtractor::extract()
#ifndef NO_PDF
if (fi.suffix().compare("pdf", Qt::CaseInsensitive) == 0) {
#if defined Q_OS_MAC && defined USE_PDFKIT
MacOSXPDFComic *pdfComic = new MacOSXPDFComic();
auto pdfComic = std::make_unique<MacOSXPDFComic>();
if (!pdfComic->openComic(_fileSource)) {
delete pdfComic;
// QImage p;
// p.load(":/images/notCover.png");
// p.save(_target);
return;
}
#elif defined USE_PDFIUM
auto pdfComic = new PdfiumComic();
auto pdfComic = std::make_unique<PdfiumComic>();
if (!pdfComic->openComic(_fileSource)) {
delete pdfComic;
return;
}
#else
Poppler::Document *pdfComic = Poppler::Document::load(_fileSource);
#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<Poppler::Document>(_pdfComic);
#endif
#endif
if (!pdfComic) {
QLOG_WARN() << "Extracting cover: unable to open PDF file " << _fileSource;
// delete pdfComic; //TODO check if the delete is needed
pdfComic = 0;
// QImage p;
// p.load(":/images/notCover.png");
// p.save(_target);
return;
}
#if !defined USE_PDFKIT && !defined USE_PDFIUM
// poppler only, not mac
if (pdfComic->isLocked()) {
QLOG_WARN() << "Extracting cover: unable to open PDF file " << _fileSource;
delete pdfComic;
return;
}
#endif
@ -75,11 +68,7 @@ void InitialComicInfoExtractor::extract()
saveCover(_target, p);
} else if (_target != "") {
QLOG_WARN() << "Extracting cover: requested cover index greater than numPages " << _fileSource;
// QImage p;
// p.load(":/images/notCover.png");
// p.save(_target);
}
delete pdfComic;
}
return;
}

View File

@ -59,7 +59,7 @@
#include "comic_vine_dialog.h"
#include "api_key_dialog.h"
//#include "yacreader_social_dialog.h"
// #include "yacreader_social_dialog.h"
#include "comics_view.h"
@ -139,6 +139,29 @@ void LibraryWindow::afterLaunchTasks()
}
}
bool LibraryWindow::eventFilter(QObject *object, QEvent *event)
{
if (this->isActiveWindow()) {
if (event->type() == QEvent::MouseButtonRelease) {
auto mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::ForwardButton) {
forwardAction->trigger();
event->accept();
return true;
}
if (mouseEvent->button() == Qt::BackButton) {
backAction->trigger();
event->accept();
return true;
}
}
}
return QMainWindow::eventFilter(object, event);
}
void LibraryWindow::createSettings()
{
settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); // TODO unificar la creación del fichero de config con el servidor

View File

@ -434,6 +434,8 @@ public slots:
void afterLaunchTasks();
bool eventFilter(QObject *object, QEvent *event) override;
private:
//! @brief Exits search mode if it is active.
//! @return true If the search mode was active when this function was called.

View File

@ -11,6 +11,7 @@
#include <QLibrary>
#endif
#include <QCommandLineParser>
#include <QImageReader>
#include "yacreader_global.h"
#include "yacreader_http_server.h"
@ -130,6 +131,10 @@ 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);
#ifdef FORCE_ANGLE
@ -269,6 +274,8 @@ int main(int argc, char **argv)
}
#endif
app.installEventFilter(mw);
int ret = app.exec();
QLOG_INFO() << "YACReaderLibrary closed with exit code :" << ret;

File diff suppressed because it is too large Load Diff

View File

@ -20,73 +20,73 @@ SplitView {
color: info_container.color
}
Rectangle {
id: main
clip: true
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
opacity: 0
visible: false
}
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
opacity: 0
visible: false
}
FastBlur {
anchors.fill: backgroundImg
source: backgroundImg
radius: backgroundBlurRadius
opacity: backgroundBlurOpacity
visible: backgroundBlurVisible
}
FastBlur {
anchors.fill: backgroundImg
source: backgroundImg
radius: backgroundBlurRadius
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
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"
Component {
id: appDelegate
Rectangle
{
id: cell
width: grid.cellWidth
height: grid.cellHeight
color: "#00000000"
scale: mouseArea.containsMouse ? 1.025 : 1
scale: mouseArea.containsMouse ? 1.025 : 1
Behavior on scale {
NumberAnimation { duration: 90 }
}
Behavior on scale {
NumberAnimation { duration: 90 }
}
DropShadow {
anchors.fill: realCell
transparentBorder: true
horizontalOffset: 0
verticalOffset: 0
radius: 10.0
//samples: 17
color: "#FF000000"
source: realCell
visible: (Qt.platform.os === "osx") ? false : true;
}
DropShadow {
anchors.fill: realCell
transparentBorder: true
horizontalOffset: 0
verticalOffset: 0
radius: 10.0
//samples: 17
color: "#FF000000"
source: realCell
visible: (Qt.platform.os === "osx") ? false : true;
}
Rectangle {
id: realCell
Rectangle {
id: realCell
property int position : 0
property bool dragging: false;
Drag.active: mouseArea.drag.active
Drag.hotSpot.x: 32
Drag.hotSpot.y: 32
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
@ -397,267 +397,227 @@ Rectangle {
id: comicRating
anchors {bottom: realCell.bottom; right: ratingImage.left; margins: 4}
text: rating>0?rating:"-"
color: textColor
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
}
DropArea {
Rectangle {
id: scrollView
objectName: "topScrollView"
anchors.fill: parent
anchors.margins: 0
children: grid
onEntered: {
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;
color: "transparent"
function scrollToOrigin() {
grid.contentY = grid.originY
grid.contentX = grid.originX
}
onDropped: {
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(drop.getDataAsString(), destIndex);
}
}
}
}
property Component currentComicView: Component {
id: currentComicView
Rectangle {
id: currentComicViewTopView
color: "#00000000"
height: showCurrentComic ? 270 : 20
property Component currentComicView: Component {
id: currentComicView
Rectangle {
color: (Qt.platform.os === "osx") ? "#88FFFFFF" : "#88000000"
id: currentComicViewTopView
color: "#00000000"
id: currentComicVisualView
height: showCurrentComic ? 270 : 20
width: main.width
height: 250
Rectangle {
color: (Qt.platform.os === "osx") ? "#88FFFFFF" : "#88000000"
visible: showCurrentComic
id: currentComicVisualView
//cover
Image {
id: currentCoverElement
anchors.fill: parent
width: main.width
height: 250
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
}
visible: showCurrentComic
DropShadow {
anchors.fill: currentCoverElement
horizontalOffset: 0
verticalOffset: 0
radius: 8.0
transparentBorder: true
//samples: 17
color: "#FF000000"
source: currentCoverElement
visible: (Qt.platform.os === "osx") ? false : true;
}
//cover
Image {
id: currentCoverElement
anchors.fill: parent
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()
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
}
Flow {
spacing: 0
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
Layout.fillWidth: true
Layout.fillHeight: false
DropShadow {
anchors.fill: currentCoverElement
horizontalOffset: 0
verticalOffset: 0
radius: 8.0
transparentBorder: true
//samples: 17
color: "#FF000000"
source: currentCoverElement
visible: (Qt.platform.os === "osx") ? false : true;
}
id: currentComicDetailsFlowView
property font infoFont: Qt.font({
family: "Arial",
pixelSize: 14
});
property string infoFlowTextColor: infoTextColor
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 {
id: currentComicInfoVolume
color: currentComicDetailsFlowView.infoFlowTextColor
font: currentComicDetailsFlowView.infoFont
text: currentComicInfo.volume ? currentComicInfo.volume : ""
rightPadding: 20
visible: currentComicInfo.volume ? true : false
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()
}
Text {
id: currentComicInfoNumbering
color: currentComicDetailsFlowView.infoFlowTextColor
font: currentComicDetailsFlowView.infoFont
text: currentComicInfo.number + "/" + currentComicInfo.count
rightPadding: 20
visible : currentComicInfo.number ? true : false
}
Flow {
spacing: 0
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
Layout.fillWidth: true
Layout.fillHeight: false
Text {
id: currentComicInfoGenre
color: currentComicDetailsFlowView.infoFlowTextColor
font: currentComicDetailsFlowView.infoFont
text: currentComicInfo.genere ? currentComicInfo.genere : ""
rightPadding: 20
visible: currentComicInfo.genere ? true : false
}
id: currentComicDetailsFlowView
property font infoFont: Qt.font({
family: "Arial",
pixelSize: 14
});
property string infoFlowTextColor: infoTextColor
Text {
id: currentComicInfoDate
color: currentComicDetailsFlowView.infoFlowTextColor
font: currentComicDetailsFlowView.infoFont
text: currentComicInfo.date ? currentComicInfo.date : ""
rightPadding: 20
visible: currentComicInfo.date ? true : false
}
Text {
id: currentComicInfoVolume
color: currentComicDetailsFlowView.infoFlowTextColor
font: currentComicDetailsFlowView.infoFont
text: currentComicInfo.volume ? currentComicInfo.volume : ""
rightPadding: 20
visible: currentComicInfo.volume ? 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: currentComicInfoNumbering
color: currentComicDetailsFlowView.infoFlowTextColor
font: currentComicDetailsFlowView.infoFont
text: currentComicInfo.number + "/" + currentComicInfo.count
rightPadding: 20
visible : currentComicInfo.number ? 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));
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 {
ScrollView {
Layout.topMargin: 6
Layout.rightMargin: 30
Layout.bottomMargin: 5
Layout.fillWidth: true
Layout.maximumHeight: (currentComicVisualView.height * 0.32)
Layout.maximumWidth: 960
width: synopsisScroller.width
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
id: currentComicInfoSinopsis
color: infoTitleColor
font.family: "Arial"
font.pixelSize: 14
wrapMode: Text.WordWrap
contentWidth: -1
contentItem: currentComicInfoSinopsis
text: '<html><head><style>
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: '<html><head><style>
a {
color: #FFCB00;
text-decoration:none;
}
</style></head><body>' + currentComicInfo.synopsis ?? "" + '</body></html>'
visible: currentComicInfo.synopsis ?? false
textFormat: Text.RichText
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
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()
onClicked: comicOpener.triggerOpenCurrentComic()
background: Rectangle {
implicitWidth: 100
implicitHeight: 30
@ -677,203 +637,243 @@ Rectangle {
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: ((Qt.platform.os === "osx") ? false : true) && !readButton.pressed
DropShadow {
anchors.fill: readButton
transparentBorder: true
horizontalOffset: 0
verticalOffset: 0
radius: 8.0
//samples: 17
color: "#AA000000"
source: readButton
visible: ((Qt.platform.os === "osx") ? false : true) && !readButton.pressed
}
}
}
}
}
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
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
currentIndex: 0
cacheBuffer: 0
interactive: true
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 - (showCurrentComic ? 270 : 20)), (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;
}
}
}
}
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;
move: Transition {
NumberAnimation { properties: "x,y"; duration: 250 }
}
var newValue = Math.min((infoFlickable.contentHeight - infoFlickable.height), (Math.max(infoFlickable.originY , infoFlickable.contentY - event.angleDelta.y)));
infoFlickable.contentY = newValue;
}
}
moveDisplaced: Transition {
NumberAnimation { properties: "x,y"; duration: 250 }
}
ScrollBar.vertical: ScrollBar {
visible: infoFlickable.contentHeight > infoFlickable.height
remove: Transition {
ParallelAnimation {
NumberAnimation { property: "opacity"; to: 0; duration: 250 }
contentItem: Item {
implicitWidth: 12
implicitHeight: 26
Rectangle {
color: "#424246"
}
}
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 - (showCurrentComic ? 270 : 20)), (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
anchors.topMargin: 6
anchors.leftMargin: 5
anchors.rightMargin: 4
anchors.bottomMargin: 6
radius: 2
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
}
}
}
}
}
}

View File

@ -5,7 +5,7 @@
#include "static.h"
#include "yacreader_http_server.h"
//#include "dualfilelogger.h"
// #include "dualfilelogger.h"
#include "httplistener.h"
#include "requestmapper.h"
#include "staticfilecontroller.h"

View File

@ -167,8 +167,13 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent)
if (settings->value(SERVER_ON, true).toBool()) {
check->setChecked(true);
generateQR();
} else
} else {
ip->setDisabled(true);
port->setDisabled(true);
accept->setDisabled(true);
check->setChecked(false);
}
performanceWorkaroundCheck->setChecked(settings->value(REMOTE_BROWSE_PERFORMANCE_WORKAROUND, false).toBool());
@ -184,14 +189,18 @@ void ServerConfigDialog::enableServer(int status)
settings->beginGroup("libraryConfig");
if (status == Qt::Checked) {
ip->setDisabled(false);
port->setDisabled(false);
accept->setDisabled(false);
httpServer->start();
this->generateQR();
settings->setValue(SERVER_ON, true);
} else {
httpServer->stop();
qrCode->setPixmap(QPixmap());
ip->clear();
port->setText("");
ip->setDisabled(true);
port->setDisabled(true);
accept->setDisabled(true);
settings->setValue(SERVER_ON, false);
}
settings->endGroup();

View File

@ -130,13 +130,6 @@ contains(QMAKE_TARGET.arch, x86_64) {
unix:!macx {
#set install prefix if it's empty
isEmpty(PREFIX) {
PREFIX = /usr
}
BINDIR = $$PREFIX/bin
LIBDIR = $$PREFIX/lib
DATADIR = $$PREFIX/share
DEFINES += "LIBDIR=\\\"$$LIBDIR\\\"" "DATADIR=\\\"$$DATADIR\\\"" "BINDIR=\\\"$$BINDIR\\\""
@ -150,7 +143,7 @@ DEFINES += "LIBDIR=\\\"$$LIBDIR\\\"" "DATADIR=\\\"$$DATADIR\\\"" "BINDIR=\\\"$$
}
CONFIG(server_standalone) {
INSTALLS += bin server translation systemd
INSTALLS += bin server systemd
}
else:CONFIG(server_bundled) {
INSTALLS += bin systemd
@ -169,9 +162,6 @@ server.files = ../release/server
systemd.path = $$LIBDIR/systemd/user
systemd.files = yacreaderlibraryserver.service
translation.path = $$DATADIR/yacreader/languages
translation.files = ../release/languages/yacreaderlibrary_*
# TODO: We need a manpage for yaclibserver
#manpage.path = $$DATADIR/man/man1
#manpage.files = ../YACReaderLibrary.1

View File

@ -1,8 +1,9 @@
//#include <QtCore>
// #include <QtCore>
#include <QCoreApplication>
#include <QSysInfo>
#include <QDir>
#include <QCommandLineParser>
#include <QImageReader>
#include "comic_db.h"
#include "db_helper.h"
@ -81,6 +82,10 @@ 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");

View File

@ -4,7 +4,7 @@ parameters:
qt_version: '6.2.2'
qt_spec: 'msvc2019_64'
qt_aqt_spec: 'win64_msvc2019_64'
vc_redist_url: 'https://aka.ms/vs/16/release/vc_redist.x64.exe'
vc_redist_url: 'https://aka.ms/vs/17/release/vc_redist.x64.exe'
vc_redist_file_name: 'vc_redist.x64.exe'
vc_vars: 'vcvars64.bat'

View File

@ -4,7 +4,7 @@ parameters:
qt_version: '5.15.2'
qt_spec: 'msvc2019_64'
qt_aqt_spec: 'win64_msvc2019_64'
vc_redist_url: 'https://aka.ms/vs/16/release/vc_redist.x64.exe'
vc_redist_url: 'https://aka.ms/vs/17/release/vc_redist.x64.exe'
vc_redist_file_name: 'vc_redist.x64.exe'
vc_vars: 'vcvars64.bat'

View File

@ -234,7 +234,7 @@ jobs:
qt_version: '5.15.2'
qt_spec: 'msvc2019_64'
qt_aqt_spec: 'win64_msvc2019_64'
vc_redist_url: 'https://aka.ms/vs/16/release/vc_redist.x64.exe'
vc_redist_url: 'https://aka.ms/vs/17/release/vc_redist.x64.exe'
vc_redist_file_name: 'vc_redist.x64.exe'
vc_vars: 'vcvars64.bat'
@ -249,7 +249,7 @@ jobs:
qt_version: '6.3.1'
qt_spec: 'msvc2019_64'
qt_aqt_spec: 'win64_msvc2019_64'
vc_redist_url: 'https://aka.ms/vs/16/release/vc_redist.x64.exe'
vc_redist_url: 'https://aka.ms/vs/17/release/vc_redist.x64.exe'
vc_redist_file_name: 'vc_redist.x64.exe'
vc_vars: 'vcvars64.bat'
@ -264,7 +264,7 @@ jobs:
qt_version: '5.15.2'
qt_spec: 'msvc2019'
qt_aqt_spec: 'win32_msvc2019'
vc_redist_url: 'https://aka.ms/vs/16/release/vc_redist.x86.exe'
vc_redist_url: 'https://aka.ms/vs/17/release/vc_redist.x86.exe'
vc_redist_file_name: 'vc_redist.x86.exe'
vc_vars: 'vcvars32.bat'

View File

@ -115,10 +115,6 @@ LaunchYACReaderLibrary=Start YACreaderLibrary after finishing installation
LaunchYACReader=Start YACreader after finishing installation
[Run]
Filename: {tmp}\vc_redist.{#PLATFORM}.exe; \
Parameters: "/uninstall /quiet /norestart"; \
StatusMsg: "Uninstalling VC++ Redistributables..."
Filename: {tmp}\vc_redist.{#PLATFORM}.exe; \
Parameters: "/install /quiet /norestart"; \
StatusMsg: "Installing VC++ Redistributables..."

View File

@ -124,10 +124,6 @@ LaunchYACReaderLibrary=Start YACreaderLibrary after finishing installation
LaunchYACReader=Start YACreader after finishing installation
[Run]
Filename: {tmp}\vc_redist.{#PLATFORM}.exe; \
Parameters: "/uninstall /quiet /norestart"; \
StatusMsg: "Uninstalling VC++ Redistributables..."
Filename: {tmp}\vc_redist.{#PLATFORM}.exe; \
Parameters: "/install /quiet /norestart"; \
StatusMsg: "Installing VC++ Redistributables..."

View File

@ -796,24 +796,27 @@ bool PDFComic::load(const QString &path, const ComicDB &comic)
void PDFComic::process()
{
#if defined Q_OS_MAC && defined USE_PDFKIT
pdfComic = new MacOSXPDFComic();
pdfComic = std::make_unique<MacOSXPDFComic>();
if (!pdfComic->openComic(_path)) {
delete pdfComic;
emit errorOpening();
return;
}
#elif defined USE_PDFIUM
pdfComic = new PdfiumComic();
pdfComic = std::make_unique<PdfiumComic>();
if (!pdfComic->openComic(_path)) {
delete pdfComic;
emit errorOpening();
return;
}
#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<Poppler::Document>(_pdfComic);
#endif
if (!pdfComic) {
// delete pdfComic;
// pdfComic = 0;
moveToThread(QCoreApplication::instance()->thread());
emit errorOpening();
return;
@ -824,7 +827,6 @@ void PDFComic::process()
return;
}
// pdfComic->setRenderHint(Poppler::Document::Antialiasing, true);
pdfComic->setRenderHint(Poppler::Document::TextAntialiasing, true);
#endif
@ -853,7 +855,6 @@ void PDFComic::process()
int buffered_index = _index;
for (int i = buffered_index; i < nPages; i++) {
if (_invalidated) {
delete pdfComic;
moveToThread(QCoreApplication::instance()->thread());
return;
}
@ -862,14 +863,12 @@ void PDFComic::process()
}
for (int i = 0; i < buffered_index; i++) {
if (_invalidated) {
delete pdfComic;
moveToThread(QCoreApplication::instance()->thread());
return;
}
renderPage(i);
}
delete pdfComic;
moveToThread(QCoreApplication::instance()->thread());
emit imagesLoaded();
}
@ -883,15 +882,16 @@ void PDFComic::renderPage(int page)
QImage img = pdfComic->getPage(page);
if (!img.isNull()) {
#else
Poppler::Page *pdfpage = pdfComic->page(page);
std::unique_ptr<Poppler::Page> pdfpage(pdfComic->page(page));
if (pdfpage) {
QImage img = pdfpage->renderToImage(150, 150);
delete pdfpage;
#endif
QByteArray ba;
QBuffer buf(&ba);
buf.open(QIODevice::WriteOnly);
img.save(&buf, "jpg", 96);
_pages[page] = ba;
buf.close();
emit imageLoaded(page);
emit imageLoaded(page, _pages[page]);
}

View File

@ -12,8 +12,8 @@
#include "pdf_comic.h"
#endif // NO_PDF
class ComicDB;
//#define EXTENSIONS << "*.jpg" << "*.jpeg" << "*.png" << "*.gif" << "*.tiff" << "*.tif" << "*.bmp" Comic::getSupportedImageFormats()
//#define EXTENSIONS_LITERAL << ".jpg" << ".jpeg" << ".png" << ".gif" << ".tiff" << ".tif" << ".bmp" //Comic::getSupportedImageLiteralFormats()
// #define EXTENSIONS_LITERAL << ".jpg" << ".jpeg" << ".png" << ".gif" << ".tiff" << ".tif" << ".bmp" //Comic::getSupportedImageLiteralFormats()
class Comic : public QObject
{
Q_OBJECT
@ -165,13 +165,14 @@ class PDFComic : public Comic
private:
// pdf
#if defined Q_OS_MAC && defined USE_PDFKIT
MacOSXPDFComic *pdfComic;
std::unique_ptr<MacOSXPDFComic> pdfComic;
#elif defined USE_PDFIUM
PdfiumComic *pdfComic;
std::unique_ptr<PdfiumComic> pdfComic;
#else
Poppler::Document *pdfComic;
std::unique_ptr<Poppler::Document> pdfComic;
#endif
void renderPage(int page);
// void run();
public:

View File

@ -5,6 +5,7 @@
#include <QImage>
#include <QFile>
#include <QMutex>
#include <QtGlobal>
#if defined Q_OS_MAC && defined USE_PDFKIT
class MacOSXPDFComic
@ -45,6 +46,10 @@ private:
QFile pdfFile;
};
#else
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <poppler-qt6.h>
#else
#include "poppler-qt5.h"
#endif // QT_VERSION
#endif // Q_OS_MAC
#endif // PDF_COMIC_H

View File

@ -6,7 +6,7 @@
#include <QMetaType>
#include <QAbstractItemModel>
#define VERSION "9.10.0"
#define VERSION "9.11.0"
#define REMOTE_BROWSE_PERFORMANCE_WORKAROUND "REMOTE_BROWSE_PERFORMANCE_WORKAROUND"
#define IMPORT_COMIC_INFO_XML_METADATA "IMPORT_COMIC_INFO_XML_METADATA"

View File

@ -93,4 +93,20 @@ macx:!CONFIG(pdfkit):!CONFIG(pdfium):!CONFIG(no_pdf) {
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

View File

@ -46,25 +46,20 @@ YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent)
"color:#858585;");
auto text = new QLabel();
text->setText("New release with the following updates:<br/>"
text->setText("A small update with a bunch of fixes:<br/>"
"<br/>"
"<span style=\"font-weight:600\">YACReader</span><br/>"
" &#8226; Fixed color selection dialog appearing as a subwindow in macos.<br/>"
" &#8226; Better support for HDPI screens (SVG icons).<br/>"
" &#8226; Fix crash when exiting YACReader while it is processing a comic.<br/>"
" &#8226; Fix last read page calculation in double page mode.<br/>"
"<br/>"
"<span style=\"font-weight:600\">YACReaderLibrary</span><br/>"
" &#8226; New folder content view that replaces the old `subfolders in this folder` view shown when folders don't have direct comics. You may need to update your libraries to make folders display properly.<br/>"
" &#8226; Continue Reading view that it is shown for the root folder.<br/>"
" &#8226; UI gets updated when YACReaderLibrary gets updates from YACReader or YACReader for iOS.<br/>"
" &#8226; Fixed going forward history navigation.<br/>"
" &#8226; Fixed selected folder restoration after folder updates.<br/>"
" &#8226; Add option to delete metadata from comics.<br/>"
" &#8226; Better support for HDPI screens (SVG icons).<br/>"
" &#8226; Importing ComicInfo.XML is now optional, you can change the behavior in Settings -> General.<br/>"
" &#8226; Add option to scan XML metadata from all the comics in a folder.<br/>"
" &#8226; Fix drag&drop in the comics grid view.<br/>"
" &#8226; Detect back/forward mouse buttons to move back and forward through the browsing history.<br/>"
" &#8226; Fix crash when disabling the server.<br/>"
"<br/>"
"<span style=\"font-weight:600\">Server</span><br/>"
" &#8226; New webui status page (reachable by navigating to server::port/webui).<br/>"
"<span style=\"font-weight:600\">All apps</span><br/>"
" &#8226; Add support for poppler-qt6 pdf backend (only relevat if you are building YACReader yourself).<br/>"
" &#8226; Remove image allocation limit in Qt6.<br/>"
"<br/>"
"NOTE: Importing metadata from ComicInfo.XML in now disabled by default, if you want you can enable it Settings -> General.<br/>"
"<br/>"

View File

@ -55,18 +55,31 @@ CONFIG(poppler) {
LIBS += -L$$PWD/poppler/dependencies/bin
}
if(unix|mingw):!macx {
!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
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")
}
} else {
error("Could not find poppler-qt5")
!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")
}
}
}
unix:macx {
error (Poppler backend is currently not supported on macOS)

View File

@ -1,7 +1,7 @@
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_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