diff --git a/3rdparty/deepin-pdfium/include/dpdfdoc.h b/3rdparty/deepin-pdfium/include/dpdfdoc.h index fc00ac432..32ffd365b 100755 --- a/3rdparty/deepin-pdfium/include/dpdfdoc.h +++ b/3rdparty/deepin-pdfium/include/dpdfdoc.h @@ -81,7 +81,8 @@ class DPdfDoc : public QObject /** * @brief 创建新的page返回 * @param i - * @return + * @return 所有权归文档:返回的 DPdfPage 由文档缓存并在析构时释放, + * 调用方不得 delete(重复释放将导致 double-free)。 */ DPdfPage *page(int i, qreal xRes, qreal yRes); diff --git a/3rdparty/deepin-pdfium/include/dpdfpage.h b/3rdparty/deepin-pdfium/include/dpdfpage.h index f7cf6f40c..612b2f6dc 100755 --- a/3rdparty/deepin-pdfium/include/dpdfpage.h +++ b/3rdparty/deepin-pdfium/include/dpdfpage.h @@ -14,6 +14,13 @@ class DPdfAnnot; class DPdfPagePrivate; class DPdfDocHandler; +/** + * @brief PDF 页面对象 + * + * 所有权契约:DPdfPage 实例由 DPdfDoc::page() 创建并缓存于文档内部, + * 生命周期由所属 DPdfDoc 管理(文档析构时统一释放)。 + * 调用方不得 delete 该指针,否则将与文档析构产生双重释放。 + */ class DPdfPage : public QObject { Q_OBJECT diff --git a/reader/Application.cpp b/reader/Application.cpp index faf628a23..dec309db0 100644 --- a/reader/Application.cpp +++ b/reader/Application.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. +// Copyright (C) 2019 ~ 2026 Uniontech Software Technology Co.,Ltd. // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -22,7 +22,10 @@ Application::Application(int &argc, char **argv) qCDebug(appLog) << "Initializing application"; loadTranslator(); qCDebug(appLog) << "Translations loaded"; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + // Qt5 下该属性控制 HiDPI 图标渲染;Qt6 中始终启用,属性已废弃无效果 setAttribute(Qt::AA_UseHighDpiPixmaps); +#endif setApplicationName("deepin-reader"); setOrganizationName("deepin"); //setWindowIcon(QIcon::fromTheme("deepin-reader")); //耗时40ms @@ -103,7 +106,7 @@ bool Application::notify(QObject *object, QEvent *event) QFocusEvent *fe = dynamic_cast(event); QWidget *widget = qobject_cast(object); - if (widget && fe && fe->reason() == Qt::ActiveWindowFocusReason && !widget->isTopLevel() + if (widget && fe && fe->reason() == Qt::ActiveWindowFocusReason && !widget->isWindow() && (widget->focusPolicy() & Qt::StrongFocus) != Qt::StrongFocus) { // 针对激活窗口所获得的焦点,为了避免被默认给到窗口内部的控件上,此处将焦点还给主窗口 // 并且只设置一次 diff --git a/reader/MainWindow.cpp b/reader/MainWindow.cpp index b709ebbba..da543c17e 100755 --- a/reader/MainWindow.cpp +++ b/reader/MainWindow.cpp @@ -232,16 +232,22 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event) if (m_TitleAnimation->state() != QPropertyAnimation::Running) { // qCDebug(appLog) << "MainWindow::eventFilter() - Starting title animation"; m_TitleAnimation->stop(); +#if (QT_VERSION > QT_VERSION_CHECK(6, 0, 0)) + // Qt6 中 QHoverEvent::pos() 已废弃,用 position() 替代 + const int hoverPosY = mouseEvent->position().toPoint().y(); +#else + const int hoverPosY = mouseEvent->pos().y(); +#endif int duration = 200 * (50 + m_FullTitleWidget->pos().y()) / 50; duration = duration <= 0 ? 200 : duration; m_TitleAnimation->setDuration(duration); m_TitleAnimation->setStartValue(QRect(0, m_FullTitleWidget->pos().y(), dApp->primaryScreen()->size().width(), m_FullTitleWidget->height())); - if (m_FullTitleWidget->pos().y() >= 0 && mouseEvent->pos().y() > m_FullTitleWidget->height()) { + if (m_FullTitleWidget->pos().y() >= 0 && hoverPosY > m_FullTitleWidget->height()) { // qCDebug(appLog) << "MainWindow::eventFilter() - Hiding title widget"; m_TitleAnimation->setEndValue(QRect(0, -m_FullTitleWidget->height(), dApp->primaryScreen()->size().width(), m_FullTitleWidget->height())); m_TitleAnimation->start(); - } else if (m_FullTitleWidget->pos().y() < 0 && mouseEvent->pos().y() < 2) { + } else if (m_FullTitleWidget->pos().y() < 0 && hoverPosY < 2) { // qCDebug(appLog) << "MainWindow::eventFilter() - Showing title widget"; setTitleBarFocusEnable(true); if (m_docTabWidget && m_FullTitleWidget->height() > titlebar()->height()) @@ -592,7 +598,12 @@ QString MainWindow::libPath(const QString &strlib) { qCDebug(appLog) << "MainWindow::libPath() - Searching for library:" << strlib; QDir dir; +#if (QT_VERSION > QT_VERSION_CHECK(6, 0, 0)) + // Qt6 中 QLibraryInfo::location() 已废弃,用 path() 替代 + QString path = QLibraryInfo::path(QLibraryInfo::LibrariesPath); +#else QString path = QLibraryInfo::location(QLibraryInfo::LibrariesPath); +#endif dir.setPath(path); QStringList list = dir.entryList(QStringList() << (strlib + "*"), QDir::NoDotAndDotDot | QDir::Files); //filter name with strlib diff --git a/reader/browser/SheetBrowser.cpp b/reader/browser/SheetBrowser.cpp index 433304ac4..3677d4f33 100644 --- a/reader/browser/SheetBrowser.cpp +++ b/reader/browser/SheetBrowser.cpp @@ -946,22 +946,22 @@ bool SheetBrowser::gestureEvent(QGestureEvent *event) void SheetBrowser::pinchTriggered(QPinchGesture *gesture) { // qCDebug(appLog) << "SheetBrowser::pinchTriggered() - Starting pinch triggered"; - static bool canRotate = false; - static qreal currentStepScaleFactor = 1.0; - static qreal tempScalefactor = 1.0; if (gesture->state() == Qt::GestureStarted) { // qCDebug(appLog) << "SheetBrowser::pinchTriggered() - Gesture started"; m_startPinch = true; - canRotate = true; - tempScalefactor = m_lastScaleFactor; + m_canRotate = true; + m_tempScalefactor = m_lastScaleFactor; + // Reset the scale baseline so a previously interrupted gesture + // cannot pollute this new pinch (too-sensitive scaling, BUG44491). + m_currentStepScaleFactor = 1.0; this->setProperty("pinchgetsturing", true); scene()->setSelectionArea(QPainterPath()); } QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags(); if (changeFlags & QPinchGesture::RotationAngleChanged) { - if (canRotate && qAbs(gesture->rotationAngle()) > 35.0) { + if (m_canRotate && qAbs(gesture->rotationAngle()) > 35.0) { if (gesture->rotationAngle() < 0.0) { // qCDebug(appLog) << "SheetBrowser::pinchTriggered() - Rotation angle is less than 0, rotating left"; m_sheet->rotateLeft(); @@ -969,18 +969,18 @@ void SheetBrowser::pinchTriggered(QPinchGesture *gesture) // qCDebug(appLog) << "SheetBrowser::pinchTriggered() - Rotation angle is greater than 0, rotating right"; m_sheet->rotateRight(); } - canRotate = false; + m_canRotate = false; return; } } if (changeFlags & QPinchGesture::ScaleFactorChanged) { // qCDebug(appLog) << "SheetBrowser::pinchTriggered() - Scale factor changed"; - currentStepScaleFactor = gesture->totalScaleFactor(); + m_currentStepScaleFactor = gesture->totalScaleFactor(); } - qreal curscalfactor = currentStepScaleFactor * tempScalefactor; - if (gesture->state() == Qt::GestureFinished) { + qreal curscalfactor = m_currentStepScaleFactor * m_tempScalefactor; + if (gesture->state() == Qt::GestureFinished || gesture->state() == Qt::GestureCanceled) { // qCDebug(appLog) << "SheetBrowser::pinchTriggered() - Gesture finished"; this->setProperty("pinchgetsturing", false); // 必须传 receiver=this:否则 browser 在定时器触发前被销毁时,lambda 仍会执行并写已死对象(UAF) @@ -988,9 +988,9 @@ void SheetBrowser::pinchTriggered(QPinchGesture *gesture) //稍微延迟下,不然还是会引起mouse事件触发 m_startPinch = false; }); - canRotate = false; - currentStepScaleFactor = 1.0; - tempScalefactor = m_lastScaleFactor; + m_canRotate = false; + m_currentStepScaleFactor = 1.0; + m_tempScalefactor = m_lastScaleFactor; } m_sheet->setScaleFactor(curscalfactor); diff --git a/reader/browser/SheetBrowser.h b/reader/browser/SheetBrowser.h index f50698443..43aa4e611 100644 --- a/reader/browser/SheetBrowser.h +++ b/reader/browser/SheetBrowser.h @@ -752,6 +752,9 @@ private slots: QBasicTimer m_repeatTimer; bool m_startPinch = false; //开始收缩 + bool m_canRotate = false; //捏合手势中是否允许旋转 + qreal m_currentStepScaleFactor = 1.0; //当前捏合手势的缩放因子(成员变量避免跨实例/跨手势残留) + qreal m_tempScalefactor = 1.0; //捏合手势起始时的基准缩放因子 bool m_canTouchScreen = false; QScroller *m_scroller = nullptr; }; diff --git a/reader/document/XpsDocumentAdapter.cpp b/reader/document/XpsDocumentAdapter.cpp index 9b7616cc7..07719e9f3 100644 --- a/reader/document/XpsDocumentAdapter.cpp +++ b/reader/document/XpsDocumentAdapter.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 ~ 2025 Uniontech Software Technology Co.,Ltd. +// Copyright (C) 2019 ~ 2026 Uniontech Software Technology Co.,Ltd. // SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -276,7 +277,12 @@ QDateTime fromUnixTime(time_t value) if (value <= 0) { return QDateTime(); } +#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) + // Qt6 中传 Qt::UTC 的重载已废弃,改传 QTimeZone::UTC(行为等价,均为 UTC 时间规范) + return QDateTime::fromSecsSinceEpoch(static_cast(value), QTimeZone::UTC).toLocalTime(); +#else return QDateTime::fromSecsSinceEpoch(static_cast(value), Qt::UTC).toLocalTime(); +#endif } void logGError(const QString &prefix, GError *error) diff --git a/reader/widgets/SecurityDialog.cpp b/reader/widgets/SecurityDialog.cpp index 4b062f989..6124b2081 100644 --- a/reader/widgets/SecurityDialog.cpp +++ b/reader/widgets/SecurityDialog.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. +// Copyright (C) 2019 ~ 2026 Uniontech Software Technology Co.,Ltd. // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -35,11 +35,11 @@ NewStr autoCutText(const QString &text, DLabel *pDesLbl) newstr.resultStr += strText; } else { qCDebug(appLog) << "Text width is greater than label width"; - for (int i = 0; i < strText.count(); i++) { + for (int i = 0; i < strText.size(); i++) { str += strText.at(i); if (font_label.horizontalAdvance(str) > width) { //根据label宽度调整每行字符数 - str.remove(str.count() - 1, 1); + str.remove(str.size() - 1, 1); newstr.strList.append(str); newstr.resultStr += str + "\n"; str.clear(); diff --git a/reader/widgets/TransparentTextEdit.cpp b/reader/widgets/TransparentTextEdit.cpp index 0ea20380f..1977011d7 100644 --- a/reader/widgets/TransparentTextEdit.cpp +++ b/reader/widgets/TransparentTextEdit.cpp @@ -55,7 +55,7 @@ void TransparentTextEdit::slotTextEditMaxContantNum() qCDebug(appLog) << "Checking text content length, max:" << m_nMaxContantLen; QString textContent = this->toPlainText(); - int length = textContent.count(); + int length = textContent.size(); if (length > m_nMaxContantLen) { qCDebug(appLog) << "Text length exceeds limit, trimming content";