diff --git a/3rd-party/cove/CMakeLists.txt b/3rd-party/cove/CMakeLists.txt index 329ca9137..efb03c025 100644 --- a/3rd-party/cove/CMakeLists.txt +++ b/3rd-party/cove/CMakeLists.txt @@ -1,8 +1,6 @@ project(Cove) -find_package(Qt5Core ${Qt5Core_VERSION} REQUIRED) -find_package(Qt5Widgets ${Qt5Core_VERSION} REQUIRED) -find_package(Qt5Concurrent ${Qt5Core_VERSION} REQUIRED) +find_package(${Mapper_QT} ${Mapper_QT_VERSION} COMPONENTS Core Widgets Concurrent REQUIRED) set(CMAKE_CXX_STANDARD 14) diff --git a/3rd-party/cove/tests/CMakeLists.txt b/3rd-party/cove/tests/CMakeLists.txt index f946678fc..5d1163c3f 100644 --- a/3rd-party/cove/tests/CMakeLists.txt +++ b/3rd-party/cove/tests/CMakeLists.txt @@ -1,6 +1,4 @@ -find_package(Qt5Core ${Qt5Core_VERSION} REQUIRED) -find_package(Qt5Gui ${Qt5Core_VERSION} REQUIRED) -find_package(Qt5Test ${Qt5Core_VERSION} REQUIRED) +find_package(${Mapper_QT} ${Mapper_QT_VERSION} COMPONENTS Core Gui Test REQUIRED) set(CMAKE_CXX_STANDARD 14) set(CMAKE_AUTOMOC ON) diff --git a/3rd-party/qtsingleapplication/CMakeLists.txt b/3rd-party/qtsingleapplication/CMakeLists.txt index 01d078773..154d7860a 100644 --- a/3rd-party/qtsingleapplication/CMakeLists.txt +++ b/3rd-party/qtsingleapplication/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2012-2015 Kai Pastor +# Copyright 2012-2015, 2017, 2019, 2026 Kai Pastor # # This file is part of OpenOrienteering. # @@ -16,8 +16,7 @@ # You should have received a copy of the GNU General Public License # along with OpenOrienteering. If not, see . -find_package(Qt5Widgets REQUIRED) -find_package(Qt5Network REQUIRED) +find_package(${Mapper_QT} ${Mapper_QT_VERSION} COMPONENTS Widgets Network REQUIRED) set(CMAKE_AUTOMOC ON) set(CMAKE_CXX_CLANG_TIDY "") diff --git a/CMakeLists.txt b/CMakeLists.txt index 900941f3b..3f11a3230 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,12 +227,14 @@ if(Mapper_USE_GDAL) find_package(GDAL MODULE REQUIRED) endif() -find_package(Qt5Core 5.5 REQUIRED) -add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050500) -if (ANDROID AND "${Qt5Core_VERSION}" VERSION_LESS 5.12.1) - message(FATAL_ERROR "At least Qt 5.12.1 is required to build for Android") -elseif ("${Qt5Core_VERSION}" VERSION_LESS 5.8.0) - add_definitions("-D'Q_FALLTHROUGH()=(void)0'") +set(Mapper_QT "Qt5" CACHE STRING "Qt version and prefix") +mark_as_advanced(Mapper_QT) +find_package("${Mapper_QT}" REQUIRED COMPONENTS Core Widgets) +add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050c00) + +set(Mapper_QT_VERSION "${${Mapper_QT}_VERSION}") +if (Mapper_QT_VERSION VERSION_LESS "5.12.1") + message(FATAL_ERROR "At least Qt 5.12.1 is required to build") endif() include("TestBigEndian") diff --git a/doc/manual/CMakeLists.txt b/doc/manual/CMakeLists.txt index 56470b02f..942cf7c7a 100644 --- a/doc/manual/CMakeLists.txt +++ b/doc/manual/CMakeLists.txt @@ -1,6 +1,6 @@ # # Copyright 2012, 2013, 2014 Thomas Schöps -# Copyright 2012-2019 Kai Pastor +# Copyright 2012-2020, 2026 Kai Pastor # # This file is part of OpenOrienteering. # @@ -143,26 +143,19 @@ if(Mapper_MANUAL_QTHELP) # Qt Help generation # - find_package(Qt5Core REQUIRED) - if (Qt5Core_VERSION VERSION_LESS 5.12) - set(qcollectiongenerator_name qcollectiongenerator) - else() - set(qcollectiongenerator_name qhelpgenerator) - endif() - # Qt provides a broken Qt5::qcollectiongenerator when crosscompiling. if (CMAKE_CROSSCOMPILING AND NOT TARGET Qt5::qcollectiongenerator) find_program(Qt5Help_QCOLLECTIONGENERATOR_EXECUTABLE - NAMES ${qcollectiongenerator_name}-qt5 ${qcollectiongenerator_name} + NAMES qhelpgenerator-qt5 qhelpgenerator DOC "The path of the Qt Help collection generator executable" ) - add_executable(Qt5::${qcollectiongenerator_name} IMPORTED) - set_target_properties(Qt5::${qcollectiongenerator_name} PROPERTIES + add_executable(Qt5::qhelpgenerator IMPORTED) + set_target_properties(Qt5::qhelpgenerator PROPERTIES IMPORTED_LOCATION ${Qt5Help_QCOLLECTIONGENERATOR_EXECUTABLE} ) elseif(NOT Qt5Help_QCOLLECTIONGENERATOR_EXECUTABLE) find_package(Qt5Help REQUIRED) - set(Qt5Help_QCOLLECTIONGENERATOR_EXECUTABLE Qt5::${qcollectiongenerator_name}) + set(Qt5Help_QCOLLECTIONGENERATOR_EXECUTABLE Qt5::qhelpgenerator) endif() # Reproducible builds need a modification to the help collection file. @@ -171,16 +164,9 @@ if(Mapper_MANUAL_QTHELP) DOC "The path of the sqlite3 executable" ) if (DEFINED ENV{SOURCE_DATE_EPOCH} AND SQLITE3_EXECUTABLE) - if(Qt5Core_VERSION VERSION_LESS 5.12.0) - file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/timestamp.sql" - "UPDATE 'SettingsTable' SET Value='$ENV{SOURCE_DATE_EPOCH}' where Key='CreationTime';\n" - "DELETE FROM 'SettingsTable' WHERE Key='LastRegisterTime';\n" - ) - else() - file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/timestamp.sql" - "UPDATE TimeStampTable SET TimeStamp=strftime('%Y-%m-%dT%H:%M:%S',datetime($ENV{SOURCE_DATE_EPOCH},'unixepoch'));\n" - ) - endif() + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/timestamp.sql" + "UPDATE TimeStampTable SET TimeStamp=strftime('%Y-%m-%dT%H:%M:%S',datetime($ENV{SOURCE_DATE_EPOCH},'unixepoch'));\n" + ) set(source_date_commands COMMAND ${SQLITE3_EXECUTABLE} "${Mapper_HELP_COLLECTION}" < "timestamp.sql" ) diff --git a/src/core/app_permissions_android.cpp b/src/core/app_permissions_android.cpp index 775af68bf..607dbf924 100644 --- a/src/core/app_permissions_android.cpp +++ b/src/core/app_permissions_android.cpp @@ -22,6 +22,7 @@ #include #include +#include namespace AppPermissions diff --git a/src/core/image_transparency_fixup.h b/src/core/image_transparency_fixup.h index d32a4dcbd..e214aec54 100644 --- a/src/core/image_transparency_fixup.h +++ b/src/core/image_transparency_fixup.h @@ -70,11 +70,7 @@ class ImageTransparencyFixup if (image) { dest = (QRgb*)image->bits(); -#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) dest_end = dest + image->sizeInBytes() / sizeof(QRgb); -#else - dest_end = dest + image->byteCount() / sizeof(QRgb); -#endif } } diff --git a/src/core/objects/text_object.cpp b/src/core/objects/text_object.cpp index cb9cc4198..cc296e697 100644 --- a/src/core/objects/text_object.cpp +++ b/src/core/objects/text_object.cpp @@ -1,6 +1,6 @@ /* * Copyright 2012, 2013 Thomas Schöps - * Copyright 2012-2019, 2025 Kai Pastor + * Copyright 2012-2019, 2025, 2026 Kai Pastor * * This file is part of OpenOrienteering. * @@ -43,12 +43,12 @@ int TextObjectPartInfo::getIndex(double pos_x) const while (right != left) { int middle = (left + right) / 2; - double x = part_x + metrics.width(part_text.left(middle)); + double x = part_x + metrics.horizontalAdvance(part_text.left(middle)); if (pos_x >= x) { if (middle >= right) return right; - double next = part_x + metrics.width(part_text.left(middle + 1)); + double next = part_x + metrics.horizontalAdvance(part_text.left(middle + 1)); if (pos_x < next) if (pos_x < (x + next) / 2) return middle; @@ -61,7 +61,7 @@ int TextObjectPartInfo::getIndex(double pos_x) const { if (middle <= 0) return 0; - double prev = part_x + metrics.width(part_text.left(middle - 1)); + double prev = part_x + metrics.horizontalAdvance(part_text.left(middle - 1)); if (pos_x > prev) if (pos_x > (x + prev) / 2) return middle; @@ -470,7 +470,7 @@ void TextObject::prepareLineInfos() const // Shrink the part and the line part_end = new_part_end; part = text.mid(part_start, part_end - part_start); - part_width = metrics.width(part); + part_width = metrics.horizontalAdvance(part); line_end = part_end; } } @@ -478,7 +478,7 @@ void TextObject::prepareLineInfos() const break; // Add the current part - part_infos.push_back( { part, part_start, part_end, part_x, metrics.width(part), metrics } ); + part_infos.push_back( { part, part_start, part_end, part_x, metrics.horizontalAdvance(part), metrics } ); // Advance to next part position part_start = part_end + 1; diff --git a/src/core/objects/text_object.h b/src/core/objects/text_object.h index cdb244089..e31fbda74 100644 --- a/src/core/objects/text_object.h +++ b/src/core/objects/text_object.h @@ -1,6 +1,6 @@ /* * Copyright 2012, 2013 Thomas Schöps - * Copyright 2012-2019, 2025 Kai Pastor + * Copyright 2012-2019, 2025, 2026 Kai Pastor * * This file is part of OpenOrienteering. * @@ -327,7 +327,7 @@ class TextObject : public Object // clazy:exclude=copyable-polymorphic inline double TextObjectPartInfo::getX(int index) const { - return part_x + metrics.width(part_text.left(index - start_index)); + return part_x + metrics.horizontalAdvance(part_text.left(index - start_index)); } diff --git a/src/core/renderables/renderable.cpp b/src/core/renderables/renderable.cpp index 489cdcc97..bd0f59812 100644 --- a/src/core/renderables/renderable.cpp +++ b/src/core/renderables/renderable.cpp @@ -355,11 +355,7 @@ void MapRenderables::drawOverprintingSimulation(QPainter* painter, const RenderC // if efficiently possible. QImage copy = separation.convertToFormat(QImage::Format_ARGB32); QRgb* dest = (QRgb*)copy.bits(); -#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) const QRgb* dest_end = dest + copy.sizeInBytes() / sizeof(QRgb); -#else - const QRgb* dest_end = dest + copy.byteCount() / sizeof(QRgb); -#endif for (QRgb* px = dest; px < dest_end; ++px) { const unsigned int alpha = qAlpha(*px) * ((255-qGray(*px)) << 16) & 0xff000000; @@ -384,11 +380,7 @@ void MapRenderables::drawOverprintingSimulation(QPainter* painter, const RenderC draw(&p, config_copy); p.end(); QRgb* dest = reinterpret_cast(separation.bits()); -#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) const QRgb* dest_end = dest + separation.sizeInBytes() / sizeof(QRgb); -#else - const QRgb* dest_end = dest + separation.byteCount() / sizeof(QRgb); -#endif for (QRgb* px = dest; px < dest_end; ++px) { /* Each pixel is a premultipled RGBA, so the alpha value is adjusted diff --git a/src/core/symbols/text_symbol.cpp b/src/core/symbols/text_symbol.cpp index 6580c9a9b..215425453 100644 --- a/src/core/symbols/text_symbol.cpp +++ b/src/core/symbols/text_symbol.cpp @@ -1,6 +1,6 @@ /* * Copyright 2012, 2013 Thomas Schöps - * Copyright 2012-2022 Kai Pastor + * Copyright 2012-2022, 2026 Kai Pastor * * This file is part of OpenOrienteering. * @@ -324,7 +324,7 @@ void TextSymbol::updateQFont() qfont.setHintingPreference(QFont::PreferNoHinting); qfont.setKerning(kerning); metrics = QFontMetricsF(qfont); - qfont.setLetterSpacing(QFont::AbsoluteSpacing, metrics.width(QString(QLatin1String{" "})) * character_spacing); + qfont.setLetterSpacing(QFont::AbsoluteSpacing, metrics.horizontalAdvance(QString(QLatin1String{" "})) * character_spacing); qfont.setStyleStrategy(QFont::ForceOutline); diff --git a/src/gui/main_window.cpp b/src/gui/main_window.cpp index a430d3ae2..de0a190fc 100644 --- a/src/gui/main_window.cpp +++ b/src/gui/main_window.cpp @@ -41,7 +41,7 @@ #if defined(Q_OS_ANDROID) # include -# include +# include # include # include #endif @@ -765,7 +765,9 @@ void MainWindow::loadWindowSettings() { #if defined(Q_OS_ANDROID) // Always show the window on the whole available area on Android - resize(QApplication::desktop()->availableGeometry().size()); + // Qt 5.14 adds QWidget::screen(). + if (auto* screen = qApp->screenAt(geometry().center())) + resize(screen->availableGeometry().size()); #else QSettings settings; diff --git a/src/gui/widgets/pie_menu.cpp b/src/gui/widgets/pie_menu.cpp index 0905ae82a..74a5d2136 100644 --- a/src/gui/widgets/pie_menu.cpp +++ b/src/gui/widgets/pie_menu.cpp @@ -1,6 +1,6 @@ /* - * Copyright 2012, 2013 Thomas Schöps - * Copyright 2014 Thomas Schöps, Kai Pastor + * Copyright 2012-2014 Thomas Schöps + * Copyright 2013, 2014, 2016-2019, 2026 Kai Pastor * * This file is part of OpenOrienteering. * @@ -24,9 +24,9 @@ #include #include #include -#include #include #include +#include #include #include "settings.h" @@ -162,18 +162,22 @@ void PieMenu::popup(const QPoint& pos) { updateCachedState(); // We need the current total_radius. - QPoint cursor_pos = QCursor::pos(); - QRect screen_rect = qApp->desktop()->availableGeometry(cursor_pos); - - if (cursor_pos.x() > screen_rect.right() - total_radius) - cursor_pos.setX(screen_rect.right() - total_radius); - else if (cursor_pos.x() < total_radius) - cursor_pos.setX(total_radius); - - if (cursor_pos.y() > screen_rect.bottom() - total_radius) - cursor_pos.setY(screen_rect.bottom() - total_radius); - else if (cursor_pos.y() < total_radius) - cursor_pos.setY(total_radius); + auto* screen = qApp->screenAt(pos); + if (screen) + { + QPoint cursor_pos = QCursor::pos(); + QRect screen_rect = screen->availableGeometry(); + + if (cursor_pos.x() > screen_rect.right() - total_radius) + cursor_pos.setX(screen_rect.right() - total_radius); + else if (cursor_pos.x() < total_radius) + cursor_pos.setX(total_radius); + + if (cursor_pos.y() > screen_rect.bottom() - total_radius) + cursor_pos.setY(screen_rect.bottom() - total_radius); + else if (cursor_pos.y() < total_radius) + cursor_pos.setY(total_radius); + } setGeometry(pos.x() - total_radius, pos.y() - total_radius, 2 * total_radius, 2 * total_radius); diff --git a/src/gui/widgets/symbol_tooltip.cpp b/src/gui/widgets/symbol_tooltip.cpp index 3d8782126..74243a8de 100644 --- a/src/gui/widgets/symbol_tooltip.cpp +++ b/src/gui/widgets/symbol_tooltip.cpp @@ -1,6 +1,6 @@ /* * Copyright 2012, 2013 Thomas Schöps - * Copyright 2017 Kai Pastor + * Copyright 2014, 2016-2019, 2026 Kai Pastor * * This file is part of OpenOrienteering. * @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -33,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -139,8 +139,12 @@ void SymbolToolTip::paintEvent(QPaintEvent* event) void SymbolToolTip::adjustPosition(bool mobile_mode) { + auto* screen = qApp->screenAt(QCursor::pos()); + if (!screen) + return; + auto size = this->size(); - auto desktop = QApplication::desktop()->screenGeometry(QCursor::pos()); + auto desktop = screen->availableGeometry(); const int margin = 3; bool has_room_to_left = (icon_rect.left() - size.width() - margin >= desktop.left()); diff --git a/src/printsupport/CMakeLists.txt b/src/printsupport/CMakeLists.txt index df26a9219..bbb577f1b 100644 --- a/src/printsupport/CMakeLists.txt +++ b/src/printsupport/CMakeLists.txt @@ -23,12 +23,7 @@ find_package(ZLIB REQUIRED) set(CMAKE_CXX_CLANG_TIDY "") set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "") -if (${Qt5PrintSupport_VERSION} VERSION_LESS 5.12.0) - message(FATAL_ERROR "Need at least Qt5PrintSupport 5.12.0, found: ${Qt5PrintSupport_VERSION}") -else() - set(FORK_VERSION qt-5.12.4) -endif() - +set(FORK_VERSION qt-5.12.4) set(PRINTSUPPORT_SRCS advanced_pdf_printer.cpp printer_properties.h diff --git a/src/sensors/gps_display.cpp b/src/sensors/gps_display.cpp index 369bf5076..c4509deab 100644 --- a/src/sensors/gps_display.cpp +++ b/src/sensors/gps_display.cpp @@ -28,10 +28,6 @@ # include # include # include // IWYU pragma: keep -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) -# include -Q_DECLARE_METATYPE(QGeoPositionInfo) // QTBUG-65937 -#endif #endif #include @@ -113,10 +109,6 @@ GPSDisplay::GPSDisplay(MapWidget* widget, const Georeferencing& georeferencing, , georeferencing(georeferencing) { #if defined(QT_POSITIONING_LIB) -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) - static const int register_metatype = qRegisterMetaType(); // QTBUG-65937 - Q_UNUSED(register_metatype) -#endif #if defined(MAPPER_USE_FAKE_POSITION_PLUGIN) { diff --git a/src/templates/template_image.cpp b/src/templates/template_image.cpp index 50d4c59fc..59c03c33d 100644 --- a/src/templates/template_image.cpp +++ b/src/templates/template_image.cpp @@ -349,12 +349,7 @@ void TemplateImage::drawTemplate(QPainter* painter, const QRectF& /*clip_rect*/, // images. This can be worked around by setting a real brush. // Fixed in Qt 5.12.0. /// \todo Fix image opacity in AdvancedPdfEngine -#if QT_VERSION < 0x051200 - if (painter->paintEngine()->type() == QPaintEngine::Pdf - || painter->paintEngine()->type() == AdvancedPdfPrinter::paintEngineType()) -#else if (painter->paintEngine()->type() == AdvancedPdfPrinter::paintEngineType()) -#endif { if (opacity < 1) painter->setBrush(Qt::white); diff --git a/src/util/backports.h b/src/util/backports.h index 4e508159a..67f6b1fe5 100644 --- a/src/util/backports.h +++ b/src/util/backports.h @@ -23,11 +23,6 @@ #include -#if QT_VERSION < 0x050700 -# include "qasconst.h" // IWYU pragma: export -# include "qoverload.h" // IWYU pragma: export -#endif - #if defined(Q_OS_ANDROID) && defined(_GLIBCXX_CMATH) namespace std { diff --git a/src/util/mapper_service_proxy.cpp b/src/util/mapper_service_proxy.cpp index b006db2c6..a4970f597 100644 --- a/src/util/mapper_service_proxy.cpp +++ b/src/util/mapper_service_proxy.cpp @@ -25,6 +25,8 @@ #ifdef Q_OS_ANDROID #include #include +#include +#include #endif #include "gui/main_window.h" diff --git a/test/locale_t.cpp b/test/locale_t.cpp index 94457f6a4..4f9281698 100644 --- a/test/locale_t.cpp +++ b/test/locale_t.cpp @@ -53,19 +53,10 @@ void LocaleTest::testEsperantoQLocale() { QCOMPARE(QLocale::languageToString(QLocale::Esperanto), QString::fromLatin1("Esperanto")); -#if QT_VERSION < 0x050c00 - QEXPECT_FAIL("", "Cannot construct Esperanto QLocale from \"eo\" (issue #792).", Continue); -#endif QCOMPARE(QLocale(QString::fromLatin1("eo")).language(), QLocale::Esperanto); -#if QT_VERSION < 0x050c00 - QEXPECT_FAIL("", "Cannot construct Esperanto QLocale from \"eo_C\".", Continue); -#endif QCOMPARE(QLocale(QString::fromLatin1("eo_C")).language(), QLocale::Esperanto); -#if QT_VERSION < 0x050c00 - QEXPECT_FAIL("", "Cannot construct Esperanto QLocale for AnyScript, AnyCountry.", Continue); -#endif QCOMPARE(QLocale(QLocale::Esperanto, QLocale::AnyScript, QLocale::AnyCountry).language(), QLocale::Esperanto); } diff --git a/test/template_t.cpp b/test/template_t.cpp index c0f84fecc..f61efae83 100644 --- a/test/template_t.cpp +++ b/test/template_t.cpp @@ -325,7 +325,6 @@ private slots: QVERIFY(temp->canBeDrawnOnto()); QVERIFY(!temp->hasUnsavedChanges()); -#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) // for QTemporaryDir::filePath() QTemporaryDir tmp_dir; QVERIFY(tmp_dir.isValid()); temp->setTemplatePath(tmp_dir.filePath(temp->getTemplateFilename())); @@ -347,7 +346,6 @@ private slots: QVERIFY(exporter->doExport()); QVERIFY(!temp->hasUnsavedChanges()); #endif // !defined(MAPPER_BIG_ENDIAN) -#endif // Qt 5.9 } void geoTiffTemplateTest() diff --git a/test/transform_t.cpp b/test/transform_t.cpp index b57cca242..cd7e5c312 100644 --- a/test/transform_t.cpp +++ b/test/transform_t.cpp @@ -29,16 +29,6 @@ using namespace OpenOrienteering; -#if QT_VERSION == 0x050B01 -// Qt 5.11.1 has a regression in QPointF::operator==. -// References: -// https://bugreports.qt.io/browse/QTBUG-69368 -// https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=903237 -// https://github.com/OpenOrienteering/mapper/issues/1116 -# define QTBUG_69368_QUIRK -#endif - - TransformTest::TransformTest(QObject* parent) : QObject(parent) { @@ -435,14 +425,10 @@ void TransformTest::testEstimateSimilarityTransformation() QCOMPARE(t2.template_scale_y, 1.0); QVERIFY(qAbs(t2.template_shear) < 0.000001); -#ifndef QTBUG_69368_QUIRK QCOMPARE(QPointF(passpoints[0].calculated_coords), QPointF(passpoints[0].dest_coords)); QVERIFY(passpoints[0].error < min_distance); QCOMPARE(QPointF(passpoints[1].calculated_coords), QPointF(passpoints[1].dest_coords)); QVERIFY(passpoints[1].error < min_distance); -#else - QWARN("Parts of test skipped to avoid hitting QTBUG-69368"); -#endif // QT_VERSION != 0x050B01 QTransform q2; QVERIFY(passpoints.estimateSimilarityTransformation(&q2));