Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions dde-clipboard/iconbutton.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand Down Expand Up @@ -55,7 +55,10 @@ void IconButton::paintEvent(QPaintEvent *event)
QColor color;
if (m_hasBackColor) {
color = palette().color(QPalette::Base);
color.setAlpha(m_hover ? m_opacity : (m_opacity / 2));
if (m_hasFocus)
color.setAlpha(m_opacity);
else
color.setAlpha(m_hover ? m_opacity : (m_opacity / 2));
} else {
color = palette().color(QPalette::WindowText);
color.setAlpha(m_hasFocus ? 80 : (m_hover ? 50 : 20));
Expand Down Expand Up @@ -154,3 +157,29 @@ void IconButton::leaveEvent(QEvent *event)

return DWidget::leaveEvent(event);
}

void IconButton::focusInEvent(QFocusEvent *event)
{
m_hasFocus = true;
update();
DWidget::focusInEvent(event);
}

void IconButton::focusOutEvent(QFocusEvent *event)
{
m_hasFocus = false;
update();
DWidget::focusOutEvent(event);
}

void IconButton::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Enter ||
event->key() == Qt::Key_Return ||
event->key() == Qt::Key_Space) {
Q_EMIT clicked();
event->accept();
return;
}
DWidget::keyPressEvent(event);
}
5 changes: 4 additions & 1 deletion dde-clipboard/iconbutton.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand Down Expand Up @@ -71,6 +71,9 @@ class IconButton : public DWidget
virtual void leaveEvent(QEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
virtual QSize sizeHint() const override;
virtual void focusInEvent(QFocusEvent *event) override;
virtual void focusOutEvent(QFocusEvent *event) override;
virtual void keyPressEvent(QKeyEvent *event) override;
};

#endif // ICONBUTTON_
28 changes: 22 additions & 6 deletions dde-clipboard/itemdelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,28 @@ bool ItemDelegate::eventFilter(QObject *obj, QEvent *event)
if (QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(event)) {
switch (keyEvent->key()) {
case Qt::Key_Tab:
case Qt::Key_Backtab: if (keyEvent->type() == QKeyEvent::KeyPress) {
//转变为特殊按键事件,表示切换内部‘焦点’,tab事件会被listview的viewport捕获
QKeyEvent kEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "change focus");
qApp->sendEvent(obj, &kEvent);
}
return true;
if (keyEvent->type() == QKeyEvent::KeyPress) {
ItemWidget *item = qobject_cast<ItemWidget *>(obj);
if (item && item->closeButtonHasFocus()) {
Q_EMIT focusEscapeRequested(true);
return true;
}
//转变为特殊按键事件,表示切换内部’焦点’,tab事件会被listview的viewport捕获
QKeyEvent kEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "change focus");
qApp->sendEvent(obj, &kEvent);
}
return true;
case Qt::Key_Backtab:
if (keyEvent->type() == QKeyEvent::KeyPress) {
ItemWidget *item = qobject_cast<ItemWidget *>(obj);
if (item && !item->closeButtonHasFocus()) {
Q_EMIT focusEscapeRequested(false);
return true;
}
QKeyEvent kEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "change focus");
qApp->sendEvent(obj, &kEvent);
}
return true;
default:
break;
}
Expand Down
1 change: 1 addition & 0 deletions dde-clipboard/itemdelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class ItemDelegate : public QStyledItemDelegate
* \~chinese \brief 请求隐藏主窗口的信号
*/
void hideWindow();
void focusEscapeRequested(bool forward);
};

#endif // LISTDELEGATE_H
6 changes: 6 additions & 0 deletions dde-clipboard/itemwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,12 @@ void ItemWidget::focusOutEvent(QFocusEvent *event)
return DWidget::focusOutEvent(event);
}

void ItemWidget::setCloseButtonFocusState(bool focus)
{
m_closeFocus = focus;
Q_EMIT closeHasFocus(focus);
}

bool ItemWidget::eventFilter(QObject *watcher, QEvent *event)
{
if (watcher == qApp && event->type() == QEvent::ThemeChange) {
Expand Down
3 changes: 3 additions & 0 deletions dde-clipboard/itemwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ class ItemWidget : public DWidget
static QPixmap GetFileIcon(QString path);
static QPixmap GetFileIcon(const FileIconData &data);

bool closeButtonHasFocus() const { return m_closeFocus; }
void setCloseButtonFocusState(bool focus);

Q_SIGNALS:
void close();
/*!
Expand Down
64 changes: 64 additions & 0 deletions dde-clipboard/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
#include <DIcon>
#include <DDciIcon>
#include <DConfig>
#include <DFloatingMessage>

Check warning on line 23 in dde-clipboard/mainwindow.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <DFloatingMessage> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include "messagemanager.h"
#include "itemwidget.h"

#define DOCK_TOP 0
#define DOCK_RIGHT 1
Expand Down Expand Up @@ -329,7 +330,9 @@
m_clearButton->setFixedHeight(36);
m_clearButton->setBackOpacity(200);
m_clearButton->setRadius(8);
m_clearButton->setFocusPolicy(Qt::StrongFocus);
m_clearButton->setVisible(false);
m_clearButton->installEventFilter(this);
titleWidget->setFixedSize(WindowWidth, WindowTitleHeight);

// Tips widget shows when data is copied, supports closing
Expand Down Expand Up @@ -487,6 +490,29 @@
hideAni();
});

connect(m_itemDelegate, &ItemDelegate::focusEscapeRequested, this, [this](bool forward) {
QModelIndex currentIdx = m_listview->currentIndex();
int rowCount = m_model->data().size();

if (forward) {
// Tab: 尝试跳到下一个 item,如果是最后一个则跳到清除按钮
int nextRow = currentIdx.isValid() ? currentIdx.row() + 1 : 0;
if (nextRow < rowCount) {
setFocusToItem(nextRow);
} else {
m_clearButton->setFocus();
}
} else {
// Backtab: 尝试跳到上一个 item 的关闭按钮,如果是第一个则跳到清除按钮
int prevRow = currentIdx.isValid() ? currentIdx.row() - 1 : rowCount - 1;
if (prevRow >= 0) {
setFocusToItem(prevRow, true);
} else {
m_clearButton->setFocus();
}
}
});

connect(m_daemonDockInter, &DBusDaemonDock::FrontendWindowRectChanged, this, &MainWindow::onFrontendWindowRectChanged, Qt::UniqueConnection);
connect(m_daemonDockInter, &DBusDaemonDock::PositionChanged, this, &MainWindow::geometryChanged);

Expand Down Expand Up @@ -677,3 +703,41 @@

return DBlurEffectWidget::event(event);
}

void MainWindow::setFocusToItem(int row, bool focusCloseButton)
{
QModelIndex idx = m_model->index(row, 0);
if (!idx.isValid())
return;

m_listview->setCurrentIndex(idx);
if (QWidget *w = m_listview->indexWidget(idx)) {
w->setFocus();
if (focusCloseButton) {
if (ItemWidget *item = qobject_cast<ItemWidget *>(w))
item->setCloseButtonFocusState(true);
}
}
}

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
if (watched == m_clearButton && event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Tab) {
// 从清除按钮按 Tab,跳到第一个 item
if (m_model->data().size() > 0) {
setFocusToItem(0);
return true;
}
} else if (keyEvent->key() == Qt::Key_Backtab) {
// 从清除按钮按 Backtab,跳到最后一个 item 的关闭按钮
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
int lastRow = m_model->data().size() - 1;
if (lastRow >= 0) {
setFocusToItem(lastRow, true);
return true;
}
}
}
return DBlurEffectWidget::eventFilter(watched, event);
}
11 changes: 10 additions & 1 deletion dde-clipboard/mainwindow.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand Down Expand Up @@ -69,6 +69,7 @@ class MainWindow : public DBlurEffectWidget
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;
bool event(QEvent *event) override;
bool eventFilter(QObject *watched, QEvent *event) override;

signals:
void OpacityChanged(double value) const;
Expand Down Expand Up @@ -166,6 +167,14 @@ private Q_SLOTS:
int getWidth() const { return this->width(); }
int getX() const { return this->pos().x(); }

/*!
* \~chinese \name setFocusToItem
* \~chinese \brief 设置焦点到指定行的 item
* \~chinese \param row 行号
* \~chinese \param focusCloseButton 是否将焦点设置到关闭按钮
*/
void setFocusToItem(int row, bool focusCloseButton = false);

private:
DBusDisplay *m_displayInter;
DBusDaemonDock *m_daemonDockInter;
Expand Down
Loading