feat(panel/chat): 显隐切换、暂存清空隐藏、菜单避让、待办联动、DTK 关于

- 传送门 desktop 入口,--show 再点一次回 daemon;右键菜单加隐藏
- 暂存区清空后整个面板隐藏
- 右键菜单弹到面板左侧,避免被自己遮挡
- 启动悬停 80ms
- 添加待办后立即打开待办窗口;待办独立图标
- 分词胶囊按浅/深色取色,修复透明不可见
- 关于改用 DAboutDialog
- 聊天消息下方常驻 复制/编辑/重试;助手消息可编辑、可从任意一条重试
This commit is contained in:
shenmo
2026-10-30 22:27:16 +08:00
parent 630ca6cadc
commit ca088fbaa6
23 changed files with 180 additions and 55 deletions
+9 -19
View File
@@ -182,15 +182,16 @@ public:
connect(fork, &QToolButton::clicked, this,
[this]() { Q_EMIT forkRequested(m_index); });
actions->addWidget(fork);
if (m_isLast) {
auto *retry = actionButton(tr("重试"), m_actions);
connect(retry, &QToolButton::clicked, this,
[this]() { Q_EMIT retryRequested(); });
actions->addWidget(retry);
}
auto *edit = actionButton(tr("编辑"), m_actions);
connect(edit, &QToolButton::clicked, this,
[this]() { Q_EMIT editRequested(m_index); });
actions->addWidget(edit);
auto *retry = actionButton(tr("重试"), m_actions);
connect(retry, &QToolButton::clicked, this,
[this]() { Q_EMIT retryRequested(m_index); });
actions->addWidget(retry);
}
actions->addStretch();
m_actions->hide();
column->addWidget(m_actions);
if (m_isUser) {
@@ -220,21 +221,10 @@ signals:
void copyRequested(int index);
void editRequested(int index);
void forkRequested(int index);
void retryRequested();
void retryRequested(int index);
void linkActivated(const QUrl &url);
protected:
void enterEvent(QEnterEvent *event) override
{
m_actions->show();
QWidget::enterEvent(event);
}
void leaveEvent(QEvent *event) override
{
m_actions->hide();
QWidget::leaveEvent(event);
}
private:
ChatMessage m_message;
+1 -1
View File
@@ -36,7 +36,7 @@ signals:
void copyRequested(int index);
void editRequested(int index);
void forkRequested(int index);
void retryRequested();
void retryRequested(int index);
void linkActivated(const QUrl &url);
protected:
+27 -13
View File
@@ -5,6 +5,8 @@
#include "config.h"
#include "chatview.h"
#include "../ui/aboutdialog.h"
#include "markdown.h"
#include "mcpclient.h"
@@ -555,7 +557,9 @@ void ChatWindow::setupUi()
});
connect(m_messages, &ChatMessageList::editRequested, this, &ChatWindow::editMessage);
connect(m_messages, &ChatMessageList::forkRequested, this, &ChatWindow::forkFrom);
connect(m_messages, &ChatMessageList::retryRequested, this, &ChatWindow::retryLast);
connect(m_messages, &ChatMessageList::retryRequested, this, [this](int index) {
retryFrom(index);
});
auto *menu = new QMenu(menuButton);
menu->addAction(tr("压缩上下文"), this, [this]() { beginCompression(false); });
@@ -925,9 +929,6 @@ void ChatWindow::editMessage(int index)
if (index < 0 || index >= conversation.messages.size()) {
return;
}
if (conversation.messages.at(index).role != QStringLiteral("user")) {
return;
}
QDialog dialog(this);
dialog.setWindowTitle(tr("编辑消息"));
@@ -959,6 +960,27 @@ void ChatWindow::editMessage(int index)
requestCompletion();
}
void ChatWindow::retryFrom(int index)
{
if (m_client->busy() || m_compressing || m_current < 0) {
return;
}
ChatConversation &conversation = m_conversations[m_current];
if (index < 0 || index >= conversation.messages.size()) {
return;
}
if (conversation.messages.at(index).role != QStringLiteral("assistant")) {
return;
}
/* drop everything from the assistant answer on, then regenerate it */
conversation.messages.resize(index);
conversation.updatedAt = QDateTime::currentMSecsSinceEpoch();
save();
renderConversation();
requestCompletion();
}
void ChatWindow::retryLast()
{
if (m_client->busy() || m_compressing || m_current < 0) {
@@ -1028,15 +1050,7 @@ void ChatWindow::handleAnchor(const QUrl &url)
void ChatWindow::showAbout()
{
QMessageBox::about(
this, tr("关于小埃同学"),
tr("<h3>GXDE 小埃同学</h3>"
"<p>版本 %1</p>"
"<p>GXDE 桌面的 AI 助手:传送门、内容工厂、待办与对话。</p>"
"<p>许可证:GPL-3.0-or-later<br/>"
"仓库:<a href='https://gitee.com/GXDE-OS/gxde-ai-see'>"
"gitee.com/GXDE-OS/gxde-ai-see</a></p>")
.arg(QCoreApplication::applicationVersion()));
showAboutDialog(this, tr("GXDE 桌面的 AI 助手:传送门、内容工厂、待办与对话。"));
}
void ChatWindow::appendError(const QString &message)
+1
View File
@@ -68,6 +68,7 @@ private:
void sendPayload();
void editMessage(int index);
void retryLast();
void retryFrom(int index);
void forkFrom(int index);
void beginCompression(bool thenSend);
void handleAnchor(const QUrl &url);