diff --git a/bibletime-3.0.3.tar.xz b/bibletime-3.0.3.tar.xz deleted file mode 100644 index b8fa6a9..0000000 --- a/bibletime-3.0.3.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:80e5e4ccb69a95201036442dd3f13dffcfcb0f001be1222ce7eefcb30fcc2692 -size 1620012 diff --git a/bibletime-3.1.0.tar.xz b/bibletime-3.1.0.tar.xz new file mode 100644 index 0000000..e1b8f33 --- /dev/null +++ b/bibletime-3.1.0.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cfd85a416cfbae467ad2687df98cd553af952aa02869954d33250bdcb4840280 +size 1570636 diff --git a/bibletime.changes b/bibletime.changes index 8b76591..af1896a 100644 --- a/bibletime.changes +++ b/bibletime.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Sat Mar 8 19:21:08 UTC 2025 - Jaime Marquínez Ferrándiz + +- Update to 3.1.0 + * Use Qt 6 +- Add fix_compilation_against_sword_1_8_1.patch and + fixed_grouping_serialization_qt5_compatibility.patch + ------------------------------------------------------------------- Fri Feb 23 11:05:12 UTC 2024 - Dominique Leuenberger diff --git a/bibletime.spec b/bibletime.spec index 0cdcd2b..70c222f 100644 --- a/bibletime.spec +++ b/bibletime.spec @@ -1,7 +1,7 @@ # # spec file for package bibletime # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # Copyright (c) 2012-2014 Lars Vogdt # # All modifications and additions to the file contributed by third parties @@ -21,7 +21,7 @@ %global __requires_exclude qmlimport\\(BibleTime.* Name: bibletime -Version: 3.0.3 +Version: 3.1.0 Release: 0 Summary: A Bible study tool License: GPL-2.0-or-later @@ -29,22 +29,28 @@ Group: Productivity/Scientific/Other URL: http://www.bibletime.info/ Source0: https://github.com/bibletime/bibletime/releases/download/v%{version}/bibletime-%{version}.tar.xz Source1: bibletime-rpmlintrc -BuildRequires: cmake +# PATCH-FIX-UPSTREAM https://github.com/bibletime/bibletime/issues/498 +Patch0: fix_compilation_against_sword_1_8_1.patch +# PATCH-FIX-UPSTREAM https://github.com/bibletime/bibletime/issues/497 +Patch1: fixed_grouping_serialization_qt5_compatibility.patch +BuildRequires: cmake >= 3.12 BuildRequires: curl-devel BuildRequires: fdupes BuildRequires: pkgconfig BuildRequires: update-desktop-files -BuildRequires: cmake(Qt5Core) -BuildRequires: cmake(Qt5Gui) -BuildRequires: cmake(Qt5LinguistTools) -BuildRequires: cmake(Qt5PrintSupport) -BuildRequires: cmake(Qt5Qml) -BuildRequires: cmake(Qt5Svg) -BuildRequires: cmake(Qt5Test) -BuildRequires: cmake(Qt5Widgets) -BuildRequires: cmake(Qt5Xml) -BuildRequires: pkgconfig(libclucene-core) -BuildRequires: pkgconfig(sword) >= 1.7 +BuildRequires: cmake(Qt6Core) +BuildRequires: cmake(Qt6Gui) +BuildRequires: cmake(Qt6LinguistTools) +BuildRequires: cmake(Qt6PrintSupport) +BuildRequires: cmake(Qt6Qml) +BuildRequires: cmake(Qt6Quick) +BuildRequires: cmake(Qt6QuickWidgets) +BuildRequires: cmake(Qt6Svg) +BuildRequires: cmake(Qt6Test) +BuildRequires: cmake(Qt6Widgets) +BuildRequires: cmake(Qt6Xml) +BuildRequires: pkgconfig(libclucene-core) >= 2.0 +BuildRequires: pkgconfig(sword) >= 1.8.1 # Dependencies for building documentation BuildRequires: docbook-xsl-stylesheets BuildRequires: fop @@ -70,27 +76,24 @@ lexicons) and powerful features to work with these texts (search in texts, write own notes, save, print etc.). %prep -%setup -q +%autosetup -p1 %build -%cmake \ -%if 0%{?suse_version} < 1600 +%cmake_qt6 \ -DCMAKE_INSTALL_DOCDIR:PATH=%{_docdir}/%{name} \ -%endif - -DCMAKE_BUILD_TYPE=Release \ -DBT_DOCBOOK_XSL_HTML_CHUNK_XSL=%{_datadir}/xml/docbook/stylesheet/nwalsh/current/html/chunk.xsl \ -DBT_DOCBOOK_XSL_PDF_DOCBOOK_XSL=%{_datadir}/xml/docbook/stylesheet/nwalsh/current/fo/docbook.xsl -%cmake_build +%qt6_build %install -%cmake_install +%qt6_install %fdupes -s %{buildroot} %suse_update_desktop_file -r %{buildroot}%{_datadir}/applications/info.%{name}.BibleTime.desktop Education Humanities %files -%doc ChangeLog README.md +%doc README.md %license LICENSE %{_bindir}/bibletime %{_datadir}/icons/* diff --git a/fix_compilation_against_sword_1_8_1.patch b/fix_compilation_against_sword_1_8_1.patch new file mode 100644 index 0000000..458d018 --- /dev/null +++ b/fix_compilation_against_sword_1_8_1.patch @@ -0,0 +1,48 @@ +From 0be2c8854eba81b94dbf81289d57ec50ab2b6ca4 Mon Sep 17 00:00:00 2001 +From: Jaak Ristioja +Date: Sat, 8 Mar 2025 19:11:41 +0200 +Subject: [PATCH] backend, BtInstallMgr: Fix compilation against Sword 1.8.1 + +The if constexpr body is type-checked regardless of whether the condition holds. +--- + src/backend/btinstallmgr.cpp | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/src/backend/btinstallmgr.cpp b/src/backend/btinstallmgr.cpp +index 063ea2ff4..f6473ec04 100644 +--- a/src/backend/btinstallmgr.cpp ++++ b/src/backend/btinstallmgr.cpp +@@ -51,13 +51,19 @@ inline int calculateIntPercentage(T done, T total) { + } + + template +-struct HasSetTimeoutMillis : std::false_type {}; ++struct TrySetTimeoutMillis { ++ template ++ static void setTimeoutMillis(Args && ...) noexcept {} ++}; + + template +-struct HasSetTimeoutMillis().setTimeoutMillis(0))>> +- : std::true_type +-{}; ++{ ++ template ++ static void setTimeoutMillis(T & c, Args && ... args) ++ { c.setTimeoutMillis(std::forward(args)...); } ++}; + + } // anonymous namespace + +@@ -71,8 +77,7 @@ BtInstallMgr::BtInstallMgr(QObject * parent) + , m_firstCallOfPreStatus(true) + { + setFTPPassive(true); +- if constexpr (HasSetTimeoutMillis::value) +- setTimeoutMillis(0); ++ TrySetTimeoutMillis::setTimeoutMillis(*this, 0); + } + + BtInstallMgr::~BtInstallMgr() { diff --git a/fixed_grouping_serialization_qt5_compatibility.patch b/fixed_grouping_serialization_qt5_compatibility.patch new file mode 100644 index 0000000..c9a94cb --- /dev/null +++ b/fixed_grouping_serialization_qt5_compatibility.patch @@ -0,0 +1,175 @@ +From 52fca59a99bf1bfec88945a1654b9760a5ea8eda Mon Sep 17 00:00:00 2001 +From: Jaak Ristioja +Date: Sat, 8 Mar 2025 00:05:20 +0200 +Subject: [PATCH] backend, BtBookshelfTreeModel: Fixed Grouping serialization + Qt5 compatibility + +The Qt6 API change the of the QList::size() return type from int to qsizetype +broke our the serialization and deserialization logic. This was an oversight +during porting to Qt6, and a rather unpleasantly difficult one to fix, but +thanks God for His mercy! :) +--- + .../bookshelfmodel/btbookshelftreemodel.cpp | 142 +++++++++++++++++- + 1 file changed, 134 insertions(+), 8 deletions(-) + +diff --git a/src/backend/bookshelfmodel/btbookshelftreemodel.cpp b/src/backend/bookshelfmodel/btbookshelftreemodel.cpp +index 6a62e646a..d310d1458 100644 +--- a/src/backend/bookshelfmodel/btbookshelftreemodel.cpp ++++ b/src/backend/bookshelfmodel/btbookshelftreemodel.cpp +@@ -12,7 +12,9 @@ + + #include "btbookshelftreemodel.h" + ++#include + #include ++#include + #include + #include + #include +@@ -627,14 +629,138 @@ QDataStream & operator <<(QDataStream & os, + QDataStream & operator >>(QDataStream & is, + BtBookshelfTreeModel::Grouping & o) + { +- decltype(o.list().size()) s; +- is >> s; +- decltype(o.m_list) newList; +- for (decltype(s) i = 0; i < s; i++) { +- std::underlying_type_t g; +- is >> g; +- newList.append(static_cast(g)); ++ using Size = decltype(o.list().size()); ++ Size size = -1; // -1 stands for invalid ++ ++ // Due to a serialization bug in BibleTime the grouping size may have been ++ // serialized as an int on Qt5 or as qsizetype on Qt6. The complex logic ++ // which follows works around this issue by attempting to parse both cases. ++ // This is not entirely future proof, but good enough for the foreseeable ++ // future, assuming that Qt does not change too much and users upgrade ++ // relatively often enough. ++ using U = std::underlying_type_t; ++ if constexpr (std::is_same_v) { ++ is >> size; ++ } else { ++ // If other strange platforms need to be supported, please let us know: ++ static_assert(sizeof(int) == 4, "Platform not supported"); ++ static_assert(sizeof(Size) == 8, "Platform not supported"); ++ ++ // The following relies on Qt providing us a datastream which only ++ // contains the serialized value and an optional ')' at the end. See ++ // QSettingsPrivate::stringToVariant() in Qt 6.8.2 for details. Assuming ++ // this, and the facts that the size can only be 0, 1 or 2, and that the ++ // values can only be 0 or 1, makes it possible for us to deduce the ++ // width of the serialized size field. ++ static constexpr Size const maxReadSize = ++ sizeof(Size) + sizeof(U) * 2 + 2; ++ char buf[maxReadSize]; ++ auto readSize = is.device()->peek(buf, maxReadSize); ++ if (readSize < maxReadSize) { // Assumptions about Qt must hold ++ if (buf[readSize - 1] == ')') ++ --readSize; ++ if (readSize == 4) { // 4 bytes can only fit an (int) size: ++ int s; ++ is >> s; // Consume (int) ++ if (s == 0) // The (int) size can only be 0. ++ size = 0; ++ } else if (readSize == 8) { ++ // 8 bytes can be either hold a (Size) size of value 0, or a ++ // (int) size of value 1 followed by an (int) value. ++ int s; ++ is >> s; // Consume (int) ++ if (s == 1) { // (int) size of value 1 ++ size = s; ++ } else if (s == 0) { // (Size) size ++ is >> s; // Consume other (int) half of (Size) size ++ if (s == 0) // Both (int) halves must be 0 for (Size) 0 ++ size = 0; ++ } ++ } else if (readSize == 12) { ++ // 12 bytes either holds a (Size) size of value 1 and a value, ++ // or an (int) size of value 2, and two values: ++ int s; ++ is >> s; // Consume (int) ++ if (s == 2) { // (int) size of value 2 ++ size = 2; ++ } else if (s >= 0 && s <= 1) { // First half is either 0 or 1 ++ int s2; ++ is >> s2; // Consume other (int) half of (Size) size ++ if ((s2 ^ 0x1) == s) // Other half is the other way around ++ size = 1; ++ } ++ } else if (readSize == 16) { // must be (Size) 2 + (int) values ++ is >> size; // Consume (Size) size ++ if (size != 2) // The (Size) size can only by 2 ++ size = -1; ++ } // else keep size as -1 (invalid) ++ } + } +- o.m_list = std::move(newList); ++ ++ if (size >= 0 && size <= 2) { ++ decltype(o.m_list) newList; ++ for (; size; --size) { ++ U v; ++ is >> v; ++ if (v < 0 || v > 1) ++ break; ++ newList.append(static_cast(v)); ++ } ++ if (!size) { ++ o.m_list = std::move(newList); ++ return is; ++ } ++ } ++ ++ qWarning() << "Failed to deserialize BtBookshelfTreeModel::Grouping"; ++ is.setStatus(QDataStream::ReadCorruptData); ++ o.m_list.clear(); + return is; + } ++ ++#if 0 ++namespace { ++ ++template ++void testGroupingSerialization_(BtBookshelfTreeModel::Grouping const & expected) ++{ ++ using U = std::underlying_type_t; ++ auto const & list = expected.list(); ++ QByteArray byteArray; ++ { ++ QBuffer buffer(&byteArray); ++ buffer.open(QIODevice::WriteOnly); ++ QDataStream os(&buffer); ++ SizeType s = list.size(); ++ os << s; ++ for (auto const g : list) ++ os << static_cast(g); ++ } ++ QBuffer buffer(&byteArray); ++ buffer.open(QIODevice::ReadOnly); ++ QDataStream is(&buffer); ++ BtBookshelfTreeModel::Grouping value; ++ is >> value; ++ if (value == expected) { ++ qInfo() << "SUCCESS" << Q_FUNC_INFO << byteArray << list; ++ } else { ++ qFatal() << "FAILURE" << Q_FUNC_INFO << byteArray << list; ++ } ++} ++ ++void testGroupingSerialization(BtBookshelfTreeModel::Grouping const & expected){ ++ testGroupingSerialization_(expected); ++ testGroupingSerialization_(expected); ++} ++ ++} // anonymous namespace ++ ++void testGroupingSerializations() { ++ using G = BtBookshelfTreeModel::Grouping; ++ testGroupingSerialization(G::NONE); ++ testGroupingSerialization(G::CAT); ++ testGroupingSerialization(G::CAT_LANG); ++ testGroupingSerialization(G::LANG); ++ testGroupingSerialization(G::LANG_CAT); ++} ++#endif