Skip to content

Commit 38703de

Browse files
committed
fix
1 parent c460a93 commit 38703de

4 files changed

Lines changed: 72 additions & 64 deletions

File tree

src/Plugins/Qt/qt_chat_controller.cpp

Lines changed: 56 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,19 @@ using namespace moebius;
2828
* ChatController 实现
2929
******************************************************************************/
3030

31+
static ChatController* g_chat_controller= nullptr;
32+
3133
ChatController::ChatController (QObject* parent) : QObject (parent) {}
3234

33-
ChatController::~ChatController () {}
35+
ChatController::~ChatController () {
36+
view_= nullptr;
37+
g_chat_controller= nullptr;
38+
}
39+
40+
void
41+
ChatController::destroyView () {
42+
view_= nullptr;
43+
}
3444

3545
QWidget*
3646
ChatController::createView (QWidget* parent, qt_tm_widget_rep* tm) {
@@ -140,8 +150,7 @@ ChatController::onSendRequested (const string& sessionId) {
140150
ChatSession* session= sessionManager_.getSession (sessionId);
141151
if (!session || !session->panel) return;
142152

143-
ChatConversationPanel* panel=
144-
static_cast<ChatConversationPanel*> (session->panel);
153+
ChatConversationPanel* panel= static_cast<ChatConversationPanel*> (session->panel);
145154
tree inputBody= panel->readInputMessage ();
146155
if (ChatConversationPanel::is_empty_document_body (inputBody)) return;
147156

@@ -176,19 +185,16 @@ ChatController::onDeleteRequested (const QList<string>& sessionIds) {
176185

177186
for (const string& sid : sessionIds) {
178187
ChatSession* s= sessionManager_.getSession (sid);
179-
if (!s || !s->panel) continue;
188+
if (!s) continue;
180189

181-
ChatConversationPanel* panel=
182-
static_cast<ChatConversationPanel*> (s->panel);
190+
ChatConversationPanel* panel= static_cast<ChatConversationPanel*> (s->panel);
183191

184-
// 1. 从持久化数据删除
185192
call ("chat-persist-delete-one", sid);
186-
// 2. 清理 Scheme 会话状态
187193
call ("chat-tab-session-destroy", sid);
188-
// 3. 从 SessionManager 移除
194+
view_->sidebar ()->removeItem (sid);
189195
sessionManager_.removeSession (sid);
190-
// 4. 从 View 移除面板
191-
view_->removePanel (panel);
196+
197+
if (panel) view_->removePanel (panel);
192198
}
193199

194200
// 激活下一个可用会话
@@ -205,9 +211,6 @@ ChatController::onDeleteRequested (const QList<string>& sessionIds) {
205211
if (!is_empty (nextSid)) {
206212
activateSession (nextSid);
207213
}
208-
else if (!allIds.empty ()) {
209-
activateSession (allIds.front ());
210-
}
211214
else {
212215
ensureNewConversation ();
213216
}
@@ -298,22 +301,23 @@ ChatController::notifyStateChanged (const string& sessionId,
298301
sessionManager_.setState (sessionId, newState);
299302

300303
if (!session->panel || !view_) return;
301-
ChatConversationPanel* panel=
302-
static_cast<ChatConversationPanel*> (session->panel);
304+
ChatConversationPanel* panel= static_cast<ChatConversationPanel*> (session->panel);
303305
QPushButton* btn= panel->sendButton ();
304306
if (!btn) return;
305307

306308
if (newState == ChatState::Generating) {
307309
btn->setToolTip ("Stop");
308-
disconnect (btn, nullptr, this, nullptr);
309-
connect (btn, &QPushButton::clicked, this,
310-
[this, sessionId] () { onCancelRequested (sessionId); });
310+
disconnect (session->sendBtnConnection);
311+
session->sendBtnConnection=
312+
connect (btn, &QPushButton::clicked, this,
313+
[this, sessionId] () { onCancelRequested (sessionId); });
311314
}
312315
else {
313316
btn->setToolTip ("Send");
314-
disconnect (btn, nullptr, this, nullptr);
315-
connect (btn, &QPushButton::clicked, this,
316-
[this, sessionId] () { onSendRequested (sessionId); });
317+
disconnect (session->sendBtnConnection);
318+
session->sendBtnConnection=
319+
connect (btn, &QPushButton::clicked, this,
320+
[this, sessionId] () { onSendRequested (sessionId); });
317321
saveOneSession (sessionId);
318322
}
319323
}
@@ -482,9 +486,9 @@ ChatController::getOrCreatePanel (const string& sessionId) {
482486
* ChatController 辅助方法
483487
******************************************************************************/
484488

485-
QList<SessionDisplayInfo>
486-
ChatController::buildDisplayInfos () {
487-
QList<SessionDisplayInfo> infos;
489+
QMap<string, string>
490+
ChatController::computeDisplayTitles () {
491+
QMap<string, string> result;
488492

489493
// 标题去重计数
490494
QMap<QString, int> titleCounts;
@@ -494,29 +498,45 @@ ChatController::buildDisplayInfos () {
494498
if (s && !is_empty (s->title)) titleCounts[to_qstring (s->title)]++;
495499
}
496500

501+
// 分配去重序号
497502
QMap<QString, int> titleSeq;
498503
for (const string& sid : allIds) {
499504
ChatSession* s= sessionManager_.getSession (sid);
500505
if (!s) continue;
501506

502-
SessionDisplayInfo info;
503-
info.sessionId= s->sessionId;
504-
info.model = s->model;
505-
info.archived = s->archived;
506-
507507
if (!is_empty (s->title)) {
508508
QString qtTitle= to_qstring (s->title);
509509
if (titleCounts[qtTitle] > 1) {
510-
int seq = ++titleSeq[qtTitle];
511-
info.displayTitle= from_qstring (qtTitle + QString (" (%1)").arg (seq));
510+
int seq= ++titleSeq[qtTitle];
511+
result[sid]= from_qstring (qtTitle + QString (" (%1)").arg (seq));
512512
}
513513
else {
514-
info.displayTitle= s->title;
514+
result[sid]= s->title;
515515
}
516516
}
517517
else {
518-
info.displayTitle= "新会话";
518+
result[sid]= "新会话";
519519
}
520+
}
521+
522+
return result;
523+
}
524+
525+
QList<SessionDisplayInfo>
526+
ChatController::buildDisplayInfos () {
527+
QList<SessionDisplayInfo> infos;
528+
QMap<string, string> titles= computeDisplayTitles ();
529+
auto allIds= sessionManager_.getAllSessionIds ();
530+
531+
for (const string& sid : allIds) {
532+
ChatSession* s= sessionManager_.getSession (sid);
533+
if (!s) continue;
534+
535+
SessionDisplayInfo info;
536+
info.sessionId = s->sessionId;
537+
info.model = s->model;
538+
info.archived = s->archived;
539+
info.displayTitle= titles.value (sid, "新会话");
520540

521541
infos.append (info);
522542
}
@@ -536,37 +556,14 @@ ChatController::determineInitialActiveSession () {
536556

537557
string
538558
ChatController::deduplicateTitle (const string& sessionId) {
539-
ChatSession* s= sessionManager_.getSession (sessionId);
540-
if (!s) return "新会话";
541-
542-
if (is_empty (s->title)) return "新会话";
543-
544-
// 检查是否有同名会话
545-
QString qtTitle = to_qstring (s->title);
546-
int sameNameCount= 0;
547-
int mySeq = 0;
548-
auto allIds = sessionManager_.getAllSessionIds ();
549-
for (const string& sid : allIds) {
550-
ChatSession* other= sessionManager_.getSession (sid);
551-
if (!other || is_empty (other->title)) continue;
552-
if (to_qstring (other->title) == qtTitle) {
553-
++sameNameCount;
554-
if (sid == sessionId) mySeq= sameNameCount;
555-
}
556-
}
557-
558-
if (sameNameCount > 1) {
559-
return from_qstring (qtTitle + QString (" (%1)").arg (mySeq));
560-
}
561-
return s->title;
559+
QMap<string, string> titles= computeDisplayTitles ();
560+
return titles.value (sessionId, "新会话");
562561
}
563562

564563
/******************************************************************************
565564
* 自由函数回调(Scheme→C++)
566565
******************************************************************************/
567566

568-
static ChatController* g_chat_controller= nullptr;
569-
570567
ChatController*
571568
get_chat_controller () {
572569
if (!g_chat_controller) {

src/Plugins/Qt/qt_chat_controller.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define QT_CHAT_CONTROLLER_HPP
1414

1515
#include "qt_chat_tab_widget.hpp"
16+
#include <QMap>
1617
#include <QObject>
1718

1819
/**
@@ -63,6 +64,11 @@ class ChatController : public QObject {
6364
void restoreSessionMeta (const string& sessionId, const string& title,
6465
const string& model, bool archived);
6566

67+
/**
68+
* @brief 销毁 View 引用,防止悬垂指针。
69+
*/
70+
void destroyView ();
71+
6672
private:
6773
QTChatTabWidget* view_= nullptr;
6874
ChatSessionManager sessionManager_;
@@ -75,6 +81,7 @@ class ChatController : public QObject {
7581
ChatConversationPanel* getOrCreatePanel (const string& sessionId);
7682
QList<SessionDisplayInfo> buildDisplayInfos ();
7783
string determineInitialActiveSession ();
84+
QMap<string, string> computeDisplayTitles ();
7885
string deduplicateTitle (const string& sessionId);
7986

8087
friend void qt_chat_tab_set_state (string sessionId, string stateStr);

src/Plugins/Qt/qt_chat_session.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,15 @@ ChatSessionManager::getAllSessionIds () const {
8787
}
8888

8989
ChatSession*
90-
ChatSessionManager::findSessionByPanel (void* panel) {
90+
ChatSessionManager::findSessionByPanel (ChatConversationPanel* panel) {
9191
for (auto& kv : sessions_) {
9292
if (kv.second.panel == panel) return &kv.second;
9393
}
9494
return nullptr;
9595
}
9696

9797
void
98-
ChatSessionManager::setPanel (const string& sessionId, void* panel) {
98+
ChatSessionManager::setPanel (const string& sessionId, ChatConversationPanel* panel) {
9999
ChatSession* s= getSession (sessionId);
100100
if (s) s->panel= panel;
101101
}

src/Plugins/Qt/qt_chat_session.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
#include "url.hpp"
1616
#include <map>
1717
#include <vector>
18+
#include <QMetaObject>
19+
20+
class ChatConversationPanel;
1821

1922
/**
2023
* @brief 聊天会话的生成状态。
@@ -33,7 +36,8 @@ struct ChatSession {
3336
string model; ///< 绑定的模型名称
3437
ChatState state; ///< 当前生成状态
3538
bool archived; ///< 是否归档
36-
void* panel; ///< 关联的 ChatConversationPanel 指针
39+
ChatConversationPanel* panel; ///< 关联的面板指针
40+
QMetaObject::Connection sendBtnConnection; ///< send/stop 按钮信号连接句柄
3741
};
3842

3943
/**
@@ -51,8 +55,8 @@ class ChatSessionManager {
5155
string getModel (const string& sessionId);
5256
std::vector<string> getAllSessionIds () const;
5357
ChatSession* getSession (const string& sessionId);
54-
ChatSession* findSessionByPanel (void* panel);
55-
void setPanel (const string& sessionId, void* panel);
58+
ChatSession* findSessionByPanel (ChatConversationPanel* panel);
59+
void setPanel (const string& sessionId, ChatConversationPanel* panel);
5660
void insertSession (const ChatSession& session);
5761
static url messageBufferUrl (const string& sessionId);
5862
static url inputBufferUrl (const string& sessionId);

0 commit comments

Comments
 (0)