diff --git a/reader/sidebar/SideBarImageListview.cpp b/reader/sidebar/SideBarImageListview.cpp index 6008d717..8040d84d 100644 --- a/reader/sidebar/SideBarImageListview.cpp +++ b/reader/sidebar/SideBarImageListview.cpp @@ -1,5 +1,5 @@ -// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. -// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. +// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2019 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -8,12 +8,14 @@ #include "SideBarImageViewModel.h" #include "Application.h" #include "MsgHeader.h" +#include "ThumbnailWidget.h" #include "ddlog.h" #include #include #include #include +#include #include SideBarImageListView::SideBarImageListView(DocSheet *sheet, QWidget *parent) : DListView(parent) @@ -24,7 +26,8 @@ SideBarImageListView::SideBarImageListView(DocSheet *sheet, QWidget *parent) setAutoScroll(false); setProperty("adaptScale", 1.0); setSpacing(4); - setFocusPolicy(Qt::NoFocus); + setObjectName("sideBarImageListView"); + setFocusPolicy(Qt::ClickFocus); setFrameShape(QFrame::NoFrame); setSelectionMode(QAbstractItemView::SingleSelection); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -212,6 +215,57 @@ void SideBarImageListView::mousePressEvent(QMouseEvent *event) // qCDebug(appLog) << "SideBarImageListView::mousePressEvent end"; } +void SideBarImageListView::keyPressEvent(QKeyEvent *event) +{ + if (m_docSheet) { + switch (event->key()) { + case Qt::Key_Up: + m_docSheet->jumpToPrevPage(); + event->accept(); + return; + case Qt::Key_Down: + m_docSheet->jumpToNextPage(); + event->accept(); + return; + case Qt::Key_PageUp: { + ThumbnailWidget *tw = qobject_cast(parentWidget()); + if (tw) tw->pageUp(); + event->accept(); + return; + } + case Qt::Key_PageDown: { + ThumbnailWidget *tw = qobject_cast(parentWidget()); + if (tw) tw->pageDown(); + event->accept(); + return; + } + default: + break; + } + } + DListView::keyPressEvent(event); +} + +bool SideBarImageListView::event(QEvent *event) +{ + // 焦点在缩略图列表时,接受 ShortcutOverride 以抑制 Central 注册的窗口级 + // 快捷键(Up/Down 文档滚动),使按键作为普通 KeyPress 交给 keyPressEvent 翻页 + if (event->type() == QEvent::ShortcutOverride) { + QKeyEvent *keyEvent = static_cast(event); + switch (keyEvent->key()) { + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + event->accept(); + return true; + default: + break; + } + } + return DListView::event(event); +} + void SideBarImageListView::showNoteMenu(const QPoint &point) { qCDebug(appLog) << "Showing note menu at:" << point; diff --git a/reader/sidebar/SideBarImageListview.h b/reader/sidebar/SideBarImageListview.h index 99d4e315..a9a89543 100644 --- a/reader/sidebar/SideBarImageListview.h +++ b/reader/sidebar/SideBarImageListview.h @@ -1,5 +1,5 @@ -// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2019 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -17,6 +17,7 @@ class SideBarImageViewModel; class BookMarkMenu; class NoteMenu; class QMouseEvent; +class QKeyEvent; const int LEFTMINWIDTH = 266; const int LEFTMAXWIDTH = 380; @@ -166,6 +167,21 @@ private slots: */ void mousePressEvent(QMouseEvent *event); + /** + * @brief keyPressEvent + * 键盘事件,处理 Up/Down/PageUp/PageDown 导航 + * @param event + */ + void keyPressEvent(QKeyEvent *event) override; + + /** + * @brief event + * 拦截 ShortcutOverride,抑制 Central 的窗口级翻页快捷键, + * 使方向键/翻页键交由本控件 keyPressEvent 处理 + * @param event + */ + bool event(QEvent *event) override; + private: int m_listType; DocSheet *m_docSheet; diff --git a/reader/widgets/PagingWidget.cpp b/reader/widgets/PagingWidget.cpp index 69f9ce5f..a3b994a6 100644 --- a/reader/widgets/PagingWidget.cpp +++ b/reader/widgets/PagingWidget.cpp @@ -1,5 +1,5 @@ -// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2019 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -30,6 +31,33 @@ PagingWidget::PagingWidget(DocSheet *sheet, DWidget *parent) connect(m_tmFuncThread, &TMFunctionThread::finished, this, &PagingWidget::onFuncThreadFinished); } +bool PagingWidget::eventFilter(QObject *obj, QEvent *event) +{ + // 页数框获得焦点时,方向键/翻页键应翻页,且不能让事件穿透到 Central 的窗口级 + // 快捷键(文档滚动)。必须同时处理 ShortcutOverride(抑制快捷键)和 KeyPress(执行翻页)。 + if (m_pJumpPageLineEdit && obj == m_pJumpPageLineEdit->lineEdit() + && (event->type() == QEvent::ShortcutOverride || event->type() == QEvent::KeyPress)) { + QKeyEvent *keyEvent = static_cast(event); + switch (keyEvent->key()) { + case Qt::Key_Up: + case Qt::Key_PageUp: + if (event->type() == QEvent::KeyPress && m_sheet) + m_sheet->jumpToPrevPage(); + event->accept(); + return true; + case Qt::Key_Down: + case Qt::Key_PageDown: + if (event->type() == QEvent::KeyPress && m_sheet) + m_sheet->jumpToNextPage(); + event->accept(); + return true; + default: + break; + } + } + return BaseWidget::eventFilter(obj, event); +} + PagingWidget::~PagingWidget() { qCDebug(appLog) << "PagingWidget destroyed"; @@ -59,6 +87,7 @@ void PagingWidget::initWidget() m_pJumpPageLineEdit->setClearButtonEnabled(false); connect(m_pJumpPageLineEdit, SIGNAL(returnPressed()), SLOT(SlotJumpPageLineEditReturnPressed())); connect(m_pJumpPageLineEdit, SIGNAL(editingFinished()), SLOT(onEditFinished())); + m_pJumpPageLineEdit->lineEdit()->installEventFilter(this); Dtk::Widget::DFontSizeManager::instance()->bind(m_pJumpPageLineEdit->lineEdit(), Dtk::Widget::DFontSizeManager::T6, true); diff --git a/reader/widgets/PagingWidget.h b/reader/widgets/PagingWidget.h index a7a4bf9f..29799bce 100644 --- a/reader/widgets/PagingWidget.h +++ b/reader/widgets/PagingWidget.h @@ -1,5 +1,5 @@ -// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2019 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -51,6 +51,9 @@ class PagingWidget : public BaseWidget */ void setTabOrderWidget(QList &tabWidgetlst); +protected: + bool eventFilter(QObject *obj, QEvent *event) override; + private slots: /** * @brief slotPrePageBtnClicked diff --git a/reader/widgets/ScaleWidget.cpp b/reader/widgets/ScaleWidget.cpp index ca79e8a1..09901b4d 100644 --- a/reader/widgets/ScaleWidget.cpp +++ b/reader/widgets/ScaleWidget.cpp @@ -1,5 +1,5 @@ -// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2019 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -9,6 +9,8 @@ #include #include +#include +#include #include #include @@ -64,6 +66,7 @@ void ScaleWidget::initWidget() connect(m_lineEdit, SIGNAL(returnPressed()), SLOT(onReturnPressed())); connect(m_lineEdit, SIGNAL(editingFinished()), SLOT(onEditFinished())); connect(m_arrowBtn, SIGNAL(clicked()), SLOT(onArrowBtnlicked())); + m_lineEdit->lineEdit()->installEventFilter(this); DIconButton *pPreBtn = new DIconButton(DStyle::SP_DecreaseElement, this); pPreBtn->setObjectName("SP_DecreaseElement"); @@ -84,6 +87,28 @@ void ScaleWidget::initWidget() qCDebug(appLog) << "ScaleWidget::initWidget end"; } +bool ScaleWidget::eventFilter(QObject *obj, QEvent *event) +{ + // 缩放框获得焦点时,Up/Down 调整缩放比,且不能让事件穿透到 Central 的窗口级 + // 快捷键(文档滚动)。必须同时处理 ShortcutOverride(抑制快捷键)和 KeyPress(执行缩放)。 + if (m_lineEdit && obj == m_lineEdit->lineEdit() + && (event->type() == QEvent::ShortcutOverride || event->type() == QEvent::KeyPress)) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Up) { + if (event->type() == QEvent::KeyPress) + onNextScale(); // Up = 放大 + event->accept(); + return true; + } else if (keyEvent->key() == Qt::Key_Down) { + if (event->type() == QEvent::KeyPress) + onPrevScale(); // Down = 缩小 + event->accept(); + return true; + } + } + return DWidget::eventFilter(obj, event); +} + void ScaleWidget::onPrevScale() { qCDebug(appLog) << "Zoom out requested"; diff --git a/reader/widgets/ScaleWidget.h b/reader/widgets/ScaleWidget.h index c955e723..0276e7a3 100644 --- a/reader/widgets/ScaleWidget.h +++ b/reader/widgets/ScaleWidget.h @@ -1,5 +1,5 @@ -// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd. +// SPDX-FileCopyrightText: 2019 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -45,6 +45,13 @@ class ScaleWidget : public Dtk::Widget::DWidget */ void clear(); +protected: + /** + * @brief eventFilter + * 缩放框获得焦点时拦截方向键,调整缩放比而非滚动文档 + */ + bool eventFilter(QObject *obj, QEvent *event) override; + private: /** * @brief initWidget