Keep rename dialog open until the core confirms its write
This commit is contained in:
1 parent
096e721faa
commit
be11fbb8b6
2 files changed
+51
-28
No files matched your search
@@ -1,6 +1,8 @@
|
||||
#include <QCoreApplication>
|
||||
#include "renamedialog.h"
|
||||
#include "../db/db_manager.h"
|
||||
#include "../transport/member_edit.h"
|
||||
#include "debug_config.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
@@ -19,18 +21,22 @@ RenameDialog::RenameDialog(DbManager* db, const QString& channelId,
|
||||
setModal(true);
|
||||
|
||||
QString curNick;
|
||||
if (m_db->m_db) {
|
||||
bool loaded = false;
|
||||
if (m_db && m_db->m_db) {
|
||||
QString tbl = m_db->peersTableName(channelId);
|
||||
QByteArray sql = QString(
|
||||
"SELECT local_nick FROM \"%1\" WHERE node_id=?"
|
||||
).arg(tbl).toUtf8();
|
||||
sqlite3_stmt* st = nullptr;
|
||||
if (sqlite3_prepare_v2(m_db->m_db, sql.constData(), -1, &st, nullptr) == SQLITE_OK) {
|
||||
sqlite3_bind_int64(st, 1, (sqlite3_int64)nodeId);
|
||||
if (sqlite3_step(st) == SQLITE_ROW)
|
||||
curNick = DbManager::colText(st, 0);
|
||||
sqlite3_finalize(st);
|
||||
}
|
||||
int rc = sqlite3_prepare_v2(m_db->m_db, sql.constData(), -1, &st, nullptr);
|
||||
if (rc == SQLITE_OK) rc = sqlite3_bind_int64(st, 1, (sqlite3_int64)nodeId);
|
||||
if (rc == SQLITE_OK) rc = sqlite3_step(st);
|
||||
if (rc == SQLITE_ROW) curNick = DbManager::colText(st, 0);
|
||||
int finish = sqlite3_finalize(st); loaded = rc == SQLITE_ROW && finish == SQLITE_OK;
|
||||
if (!loaded) DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "rename: read ch=%s node=%016llx rc=%d finalize=%d: %s",
|
||||
qPrintable(channelId), (unsigned long long)nodeId, rc, finish, sqlite3_errmsg(m_db->m_db));
|
||||
} else {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CHAT_SYNC, "rename: database unavailable at open");
|
||||
}
|
||||
|
||||
auto* layout = new QVBoxLayout(this);
|
||||
@@ -45,6 +51,9 @@ RenameDialog::RenameDialog(DbManager* db, const QString& channelId,
|
||||
m_edit->setText(curNick);
|
||||
m_edit->setPlaceholderText(displayName);
|
||||
layout->addWidget(m_edit);
|
||||
m_errorLabel = new QLabel(this); m_errorLabel->setWordWrap(true);
|
||||
if (!loaded) m_errorLabel->setText(QCoreApplication::translate("ChatGui", "Could not load member details."));
|
||||
layout->addWidget(m_errorLabel);
|
||||
|
||||
layout->addStretch();
|
||||
|
||||
@@ -61,6 +70,7 @@ RenameDialog::RenameDialog(DbManager* db, const QString& channelId,
|
||||
btnLayout->addWidget(cancelBtn);
|
||||
|
||||
auto* saveBtn = new QPushButton(QCoreApplication::translate("ChatGui", "Save"), this);
|
||||
m_saveBtn = saveBtn;
|
||||
saveBtn->setMinimumWidth(90);
|
||||
saveBtn->setDefault(true);
|
||||
saveBtn->setStyleSheet(
|
||||
@@ -72,22 +82,26 @@ RenameDialog::RenameDialog(DbManager* db, const QString& channelId,
|
||||
btnLayout->addWidget(saveBtn);
|
||||
|
||||
layout->addLayout(btnLayout);
|
||||
connect(this, &QDialog::finished, this, [this] {
|
||||
delete m_saveContext; m_saveContext = nullptr;
|
||||
m_edit->setEnabled(true); m_saveBtn->setEnabled(true);
|
||||
});
|
||||
}
|
||||
|
||||
/* Результат адресован context запроса; после закрытия/удаления формы мост его не вызовет. */
|
||||
void RenameDialog::finishSave(int result) {
|
||||
delete m_saveContext; m_saveContext = nullptr;
|
||||
m_edit->setEnabled(true); m_saveBtn->setEnabled(true);
|
||||
if (!result) { accept(); return; }
|
||||
m_errorLabel->setText(QCoreApplication::translate("ChatGui", "Could not save member changes. Please try again."));
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CHAT_SYNC, "rename: save refused ch=%s node=%016llx result=%d",
|
||||
qPrintable(m_channelId), (unsigned long long)m_nodeId, result);
|
||||
}
|
||||
|
||||
void RenameDialog::onSave() {
|
||||
if (!m_db->m_db) return;
|
||||
QString tbl = m_db->peersTableName(m_channelId);
|
||||
QString nick = m_edit->text().trimmed();
|
||||
QByteArray sql = QString(
|
||||
"UPDATE \"%1\" SET local_nick=? WHERE node_id=?"
|
||||
).arg(tbl).toUtf8();
|
||||
sqlite3_stmt* st = nullptr;
|
||||
if (sqlite3_prepare_v2(m_db->m_db, sql.constData(), -1, &st, nullptr) == SQLITE_OK) {
|
||||
sqlite3_bind_text(st, 1, nick.isEmpty() ? nullptr : nick.toUtf8().constData(),
|
||||
-1, nick.isEmpty() ? SQLITE_STATIC : SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int64(st, 2, (sqlite3_int64)m_nodeId);
|
||||
sqlite3_step(st);
|
||||
sqlite3_finalize(st);
|
||||
}
|
||||
accept();
|
||||
if (m_saveContext) return;
|
||||
m_errorLabel->clear(); m_edit->setEnabled(false); m_saveBtn->setEnabled(false);
|
||||
m_saveContext = new QObject(this);
|
||||
if (!gui_bridge_save_member(m_db ? m_db->m_db : nullptr, m_channelId, m_nodeId, m_edit->text().trimmed(), {},
|
||||
m_saveContext, [this](int result) { finishSave(result); })) finishSave(-1);
|
||||
}
|
||||
@@ -1,25 +1,34 @@
|
||||
/* Локальное переименование участника: сохраняет local_nick в таблице peers канала для этого UI. */
|
||||
/* Локальный псевдоним участника: GUI только читает SQLite, запись подтверждает поток ядра.
|
||||
* Отказ сохраняет форму и введённый текст; закрытие формы снимает callback, но не отменяет принятую запись. */
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
#include <QString>
|
||||
#include <QPointer>
|
||||
|
||||
class DbManager;
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
|
||||
class RenameDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/* db заимствован через QPointer; channelId/nodeId выбирают строку, displayName — заголовок/подсказка, parent владеет диалогом. */
|
||||
explicit RenameDialog(DbManager* db, const QString& channelId,
|
||||
quint64 nodeId, const QString& displayName,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void onSave();
|
||||
void onSave(); // Передать собственный снимок ника в uasync; повтор до результата игнорируется.
|
||||
|
||||
private:
|
||||
DbManager* m_db;
|
||||
QString m_channelId;
|
||||
quint64 m_nodeId;
|
||||
QLineEdit* m_edit;
|
||||
void finishSave(int result); // GUI: 0 закрывает с Accepted, отказ возвращает редактирование и показывает ошибку.
|
||||
QPointer<DbManager> m_db; // Заимствованная read-only проекция, может исчезнуть во время запроса.
|
||||
QString m_channelId; // Собственный снимок канала.
|
||||
quint64 m_nodeId; // Узел участника.
|
||||
QLineEdit* m_edit; // Локальный черновик; пробелы по краям удаляются при сохранении.
|
||||
QLabel* m_errorLabel; // Ошибка чтения/сохранения без технических подробностей.
|
||||
QPushButton* m_saveBtn; // Отключена до результата.
|
||||
QObject* m_saveContext = nullptr; // Собственный context одного запроса; удаляется при результате/закрытии.
|
||||
};
|
||||
Reference in new issue
Block a user